1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-08-04 06:45:45 +02:00

feature: Display emojis stand alone

-Emojis are shown without bubbles when sent alone
-Changes on message reply design ( animation now include files and emojis)

GitLab: #690
Signed-off-by: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
Change-Id: I81d128367a9c393c76493e02ce88daf4f6a11bf4
This commit is contained in:
Nicolas Vengeon 2022-10-03 15:38:44 -04:00
parent b2c7fc0414
commit eb55c3193a
7 changed files with 103 additions and 17 deletions

View file

@ -326,8 +326,10 @@ Loader {
Component {
id: imageComp
Image {
id: img
anchors.right: isOutgoing ? parent.right : undefined
property real minSize: 192
property real maxSize: 256
@ -346,6 +348,7 @@ Loader {
innerContent.width - senderMargin))
width: adjustedWidth
height: Math.ceil(adjustedWidth / aspectRatio)
Rectangle {
color: JamiTheme.previewImageBackgroundColor
z: -1

View file

@ -32,7 +32,6 @@ Control {
property alias avatarBlockWidth: avatarBlock.width
property alias innerContent: innerContent
property alias bubble: bubble
property alias selectAnimation: selectAnimation
property real extraHeight: 0
// these MUST be set but we won't use the 'required' keyword yet
@ -145,6 +144,8 @@ Control {
MessageBubble {
id: bubble
visible: !IsEmojiOnly
z:-1
out: isOutgoing
type: seq
@ -166,15 +167,48 @@ Control {
height: innerContent.childrenRect.height + (visible ? root.extraHeight : 0)
}
Rectangle {
id: bg
color: bubble.getBaseColor()
anchors.fill: parent
visible: false
}
SequentialAnimation {
id: selectAnimation
ColorAnimation {
target: bubble; property: "color"
to: Qt.darker(bubble.getBaseColor(), 1.5); duration: 240
PropertyAnimation {
properties: "opacity"
target: opacityMask
from: 0
to: 1
duration: JamiTheme.longFadeDuration
}
ColorAnimation {
target: bubble; property: "color"
to: bubble.getBaseColor(); duration: 240
PropertyAnimation {
properties: "opacity"
target: opacityMask
from: 1
to: 0
duration: JamiTheme.longFadeDuration
}
}
OpacityMask {
id: opacityMask
opacity: 0
anchors.fill: bubble
source: bubble
maskSource: bg
}
Connections {
target: CurrentConversation
function onScrollTo(id) {
if (id !== root.id)
return
selectAnimation.start()
}
}
}

View file

@ -21,6 +21,7 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
@ -30,7 +31,9 @@ SBSMessageBase {
id : root
property bool isRemoteImage
property bool isEmojiOnly: IsEmojiOnly
property real maxMsgWidth: root.width - senderMargin - 2 * hPadding - avatarBlockWidth
isOutgoing: Author === ""
author: Author
readers: Readers
@ -41,10 +44,15 @@ SBSMessageBase {
innerContent.children: [
TextEdit {
padding: JamiTheme.preferredMarginSize
id: textEditId
padding: isEmojiOnly ? 0 : JamiTheme.preferredMarginSize
anchors.right: isOutgoing ? parent.right : undefined
text: Body
horizontalAlignment: Text.AlignLeft
horizontalAlignment: isOutgoing ? Text.AlignLeft : Text.AlignRight
width: {
if (extraContent.active)
Math.max(extraContent.width,
@ -57,16 +65,31 @@ SBSMessageBase {
height: implicitHeight
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
selectByMouse: true
font.pixelSize: JamiTheme.chatviewFontSize
font.pixelSize: isEmojiOnly? JamiTheme.chatviewEmojiSize : JamiTheme.chatviewFontSize
font.hintingPreference: Font.PreferNoHinting
renderType: Text.NativeRendering
textFormat: Text.MarkdownText
onLinkHovered: root.hoveredLink = hoveredLink
onLinkActivated: Qt.openUrlExternally(hoveredLink)
readOnly: true
color: UtilsAdapter.luma(bubble.color) ?
JamiTheme.chatviewTextColorLight :
JamiTheme.chatviewTextColorDark
color: getBaseColor()
function getBaseColor() {
var baseColor
if (isEmojiOnly) {
if (JamiTheme.darkTheme)
baseColor = JamiTheme.chatviewTextColorLight
else
baseColor = JamiTheme.chatviewTextColorDark
} else {
if (UtilsAdapter.luma(bubble.color))
baseColor = JamiTheme.chatviewTextColorLight
else
baseColor = JamiTheme.chatviewTextColorDark
}
return baseColor
}
TapHandler {
enabled: parent.selectedText.length > 0
@ -104,6 +127,7 @@ SBSMessageBase {
}
AnimatedImage {
id: img
cache: false
source: isRemoteImage ?
LinkPreviewInfo.url :

View file

@ -188,6 +188,7 @@ Item {
property color chatviewTextColorLight: "#f0f0f0"
property color chatviewTextColorDark: "#353637"
property real chatviewFontSize: calcSize(15)
property real chatviewEmojiSize: calcSize(60)
property color timestampColor: darkTheme ? "#bbb" : "#777"
property color messageOutTxtColor: "#000000"
property color messageInBgColor: darkTheme ? "#28b1ed" : "#e5e5e5"

View file

@ -166,9 +166,6 @@ JamiListView {
}
}
positionViewAtIndex(idx, ListView.Center)
var delegate = root.itemAtIndex(idx)
if (delegate.selectAnimation)
delegate.selectAnimation.start()
}
}

View file

@ -357,6 +357,29 @@ MessageListModel::roleNames() const
return roles;
}
bool
MessageListModel::isOnlyEmoji(const QString& text) const
{
auto codepointList = text.toUcs4();
for (QList<uint>::iterator it = codepointList.begin(); it != codepointList.end(); it++) {
auto cur = false;
if (*it == 20 or *it == 0x200D) {
cur = true;
} else if (0x1f000 <= *it && 0x1ffff >= *it) {
cur = true;
} else if (0x2600 <= *it && 0x27BF >= *it) {
cur = true;
} else if (0xFE00 <= *it && 0xFE0f >= *it) {
cur = true;
} else if (0xE0000 <= *it && 0xE007F >= *it) {
cur = true;
}
if (!cur)
return false;
}
return true;
}
QVariant
MessageListModel::dataForItem(item_t item, int, int role) const
{
@ -401,6 +424,8 @@ MessageListModel::dataForItem(item_t item, int, int role) const
return QVariant(item.second.commit["displayName"]);
case Role::Readers:
return QVariant(messageToReaders_[item.first]);
case Role::IsEmojiOnly:
return QVariant(isOnlyEmoji(item.second.body));
default:
return {};
}

View file

@ -50,7 +50,8 @@ struct Info;
X(ReplyToAuthor) \
X(TotalSize) \
X(TransferName) \
X(Readers)
X(Readers) \
X(IsEmojiOnly)
namespace MessageList {
Q_NAMESPACE
@ -125,6 +126,7 @@ public:
// these emission wrappers
void emitDataChanged(iterator it, VectorInt roles = {});
void emitDataChanged(const QString& msgId, VectorInt roles = {});
bool isOnlyEmoji(const QString& text) const;
Q_SIGNAL void timestampUpdate();