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:
parent
b2c7fc0414
commit
eb55c3193a
7 changed files with 103 additions and 17 deletions
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 :
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -166,9 +166,6 @@ JamiListView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
positionViewAtIndex(idx, ListView.Center)
|
positionViewAtIndex(idx, ListView.Center)
|
||||||
var delegate = root.itemAtIndex(idx)
|
|
||||||
if (delegate.selectAnimation)
|
|
||||||
delegate.selectAnimation.start()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue