1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-08-04 14:55:43 +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 { Component {
id: imageComp id: imageComp
Image { Image {
id: img id: img
anchors.right: isOutgoing ? parent.right : undefined anchors.right: isOutgoing ? parent.right : undefined
property real minSize: 192 property real minSize: 192
property real maxSize: 256 property real maxSize: 256
@ -346,6 +348,7 @@ Loader {
innerContent.width - senderMargin)) innerContent.width - senderMargin))
width: adjustedWidth width: adjustedWidth
height: Math.ceil(adjustedWidth / aspectRatio) height: Math.ceil(adjustedWidth / aspectRatio)
Rectangle { Rectangle {
color: JamiTheme.previewImageBackgroundColor color: JamiTheme.previewImageBackgroundColor
z: -1 z: -1

View file

@ -32,7 +32,6 @@ Control {
property alias avatarBlockWidth: avatarBlock.width property alias avatarBlockWidth: avatarBlock.width
property alias innerContent: innerContent property alias innerContent: innerContent
property alias bubble: bubble property alias bubble: bubble
property alias selectAnimation: selectAnimation
property real extraHeight: 0 property real extraHeight: 0
// these MUST be set but we won't use the 'required' keyword yet // these MUST be set but we won't use the 'required' keyword yet
@ -145,6 +144,8 @@ Control {
MessageBubble { MessageBubble {
id: bubble id: bubble
visible: !IsEmojiOnly
z:-1 z:-1
out: isOutgoing out: isOutgoing
type: seq type: seq
@ -166,15 +167,48 @@ Control {
height: innerContent.childrenRect.height + (visible ? root.extraHeight : 0) height: innerContent.childrenRect.height + (visible ? root.extraHeight : 0)
} }
Rectangle {
id: bg
color: bubble.getBaseColor()
anchors.fill: parent
visible: false
}
SequentialAnimation { SequentialAnimation {
id: selectAnimation id: selectAnimation
ColorAnimation {
target: bubble; property: "color" PropertyAnimation {
to: Qt.darker(bubble.getBaseColor(), 1.5); duration: 240 properties: "opacity"
target: opacityMask
from: 0
to: 1
duration: JamiTheme.longFadeDuration
} }
ColorAnimation { PropertyAnimation {
target: bubble; property: "color" properties: "opacity"
to: bubble.getBaseColor(); duration: 240 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.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import net.jami.Models 1.1 import net.jami.Models 1.1
import net.jami.Adapters 1.1 import net.jami.Adapters 1.1
import net.jami.Constants 1.1 import net.jami.Constants 1.1
@ -30,7 +31,9 @@ SBSMessageBase {
id : root id : root
property bool isRemoteImage property bool isRemoteImage
property bool isEmojiOnly: IsEmojiOnly
property real maxMsgWidth: root.width - senderMargin - 2 * hPadding - avatarBlockWidth property real maxMsgWidth: root.width - senderMargin - 2 * hPadding - avatarBlockWidth
isOutgoing: Author === "" isOutgoing: Author === ""
author: Author author: Author
readers: Readers readers: Readers
@ -41,10 +44,15 @@ SBSMessageBase {
innerContent.children: [ innerContent.children: [
TextEdit { TextEdit {
padding: JamiTheme.preferredMarginSize id: textEditId
padding: isEmojiOnly ? 0 : JamiTheme.preferredMarginSize
anchors.right: isOutgoing ? parent.right : undefined anchors.right: isOutgoing ? parent.right : undefined
text: Body text: Body
horizontalAlignment: Text.AlignLeft
horizontalAlignment: isOutgoing ? Text.AlignLeft : Text.AlignRight
width: { width: {
if (extraContent.active) if (extraContent.active)
Math.max(extraContent.width, Math.max(extraContent.width,
@ -57,16 +65,31 @@ SBSMessageBase {
height: implicitHeight height: implicitHeight
wrapMode: Label.WrapAtWordBoundaryOrAnywhere wrapMode: Label.WrapAtWordBoundaryOrAnywhere
selectByMouse: true selectByMouse: true
font.pixelSize: JamiTheme.chatviewFontSize font.pixelSize: isEmojiOnly? JamiTheme.chatviewEmojiSize : JamiTheme.chatviewFontSize
font.hintingPreference: Font.PreferNoHinting font.hintingPreference: Font.PreferNoHinting
renderType: Text.NativeRendering renderType: Text.NativeRendering
textFormat: Text.MarkdownText textFormat: Text.MarkdownText
onLinkHovered: root.hoveredLink = hoveredLink onLinkHovered: root.hoveredLink = hoveredLink
onLinkActivated: Qt.openUrlExternally(hoveredLink) onLinkActivated: Qt.openUrlExternally(hoveredLink)
readOnly: true readOnly: true
color: UtilsAdapter.luma(bubble.color) ? color: getBaseColor()
JamiTheme.chatviewTextColorLight :
JamiTheme.chatviewTextColorDark 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 { TapHandler {
enabled: parent.selectedText.length > 0 enabled: parent.selectedText.length > 0
@ -104,6 +127,7 @@ SBSMessageBase {
} }
AnimatedImage { AnimatedImage {
id: img id: img
cache: false cache: false
source: isRemoteImage ? source: isRemoteImage ?
LinkPreviewInfo.url : LinkPreviewInfo.url :

View file

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

View file

@ -166,9 +166,6 @@ JamiListView {
} }
} }
positionViewAtIndex(idx, ListView.Center) 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; 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 QVariant
MessageListModel::dataForItem(item_t item, int, int role) const 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"]); return QVariant(item.second.commit["displayName"]);
case Role::Readers: case Role::Readers:
return QVariant(messageToReaders_[item.first]); return QVariant(messageToReaders_[item.first]);
case Role::IsEmojiOnly:
return QVariant(isOnlyEmoji(item.second.body));
default: default:
return {}; return {};
} }

View file

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