diff --git a/src/app/commoncomponents/CallMessageDelegate.qml b/src/app/commoncomponents/CallMessageDelegate.qml index 01529c216c59f55628976f449021b6987444bc82..4256ac113ecd2c5ed00dffa46d2a2e227b5e54af 100644 --- a/src/app/commoncomponents/CallMessageDelegate.qml +++ b/src/app/commoncomponents/CallMessageDelegate.qml @@ -61,12 +61,10 @@ SBSMessageBase { if (ConfId === "" && Duration === 0) { // If missed, we can add a darker pattern return isOutgoing ? - Qt.darker(JamiTheme.messageOutBgColor, 1.5) : + Qt.lighter(CurrentConversation.color, 1.5) : Qt.darker(JamiTheme.messageInBgColor, 1.5) } - return isOutgoing ? - JamiTheme.messageOutBgColor : - CurrentConversation.isCoreDialog ? JamiTheme.messageInBgColor : Qt.lighter(CurrentConversation.color, 1.5) + return isOutgoing ? CurrentConversation.color : JamiTheme.messageInBgColor } innerContent.children: [ @@ -88,8 +86,13 @@ SBSMessageBase { return Body } horizontalAlignment: Qt.AlignHCenter - font.pointSize: JamiTheme.contactEventPointSize + + font.pixelSize: JamiTheme.emojiBubbleSize + font.hintingPreference: Font.PreferNoHinting font.bold: true + renderType: Text.NativeRendering + textFormat: Text.MarkdownText + color: UtilsAdapter.luma(bubble.color) ? JamiTheme.chatviewTextColorLight : JamiTheme.chatviewTextColorDark @@ -115,4 +118,4 @@ SBSMessageBase { opacity: 0 Behavior on opacity { NumberAnimation { duration: 100 } } Component.onCompleted: opacity = 1 -} \ No newline at end of file +} diff --git a/src/app/commoncomponents/MessageBubble.qml b/src/app/commoncomponents/MessageBubble.qml index ffdeb34ed4bee3edd2585a41493fcdd52af5d4ce..ec0612017e7bbbe4ba23ead7a4ad46c41480fc99 100644 --- a/src/app/commoncomponents/MessageBubble.qml +++ b/src/app/commoncomponents/MessageBubble.qml @@ -26,9 +26,10 @@ Rectangle { id: root property bool out: true property int type: MsgSeq.single + property bool isReply: false Rectangle { id: mask - visible: type !== MsgSeq.single + visible: type !== MsgSeq.single && !isReply z: -1 radius: 5 color: root.color @@ -40,4 +41,34 @@ Rectangle { bottomMargin: type === MsgSeq.last ? root.height /2 : 0 } } + + Rectangle { + id: maskReply + visible: isReply + z: -1 + radius: 5 + color: root.color + anchors { + fill: parent + leftMargin: out ? 0 : root.width/2 + rightMargin: !out ? 0 : root.width/2 + topMargin: 0 + bottomMargin: root.height /2 + } + } + + Rectangle { + id: maskReplyFirst + visible: isReply && type === MsgSeq.first + z: -2 + radius: 5 + color: root.color + anchors { + fill: parent + leftMargin: out ? root.width/2 : 0 + rightMargin: out ? 0 : root.width/2 + topMargin: root.width/5 + bottomMargin: 0 + } + } } diff --git a/src/app/commoncomponents/ReplyToRow.qml b/src/app/commoncomponents/ReplyToRow.qml index 8542a3bc43e7b286940959815dc4e4e04a14b11a..6d9ea0678dfdb9aa46bb8960ab6dbcf1a24d5f44 100644 --- a/src/app/commoncomponents/ReplyToRow.qml +++ b/src/app/commoncomponents/ReplyToRow.qml @@ -19,92 +19,89 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts +import net.jami.Models 1.1 import net.jami.Adapters 1.1 import net.jami.Constants 1.1 + Item { id: root - anchors.right: isOutgoing ? parent.right : undefined - visible: ReplyTo !== "" - width: visible ? replyToRow.width : 0 - height: replyToRow.height + replyToRow.anchors.topMargin + width: body.width + height: Math.min(JamiTheme.sbsMessageBaseMaximumReplyHeight, body.height) + clip: true + + property int requestId: -1 + property var replyTransferName: MessagesAdapter.dataForInteraction(ReplyTo, MessageList.TransferName) + Component.onCompleted: { // Make sure we show the original post // In the future, we may just want to load the previous interaction of the thread // and not show it, but for now we can simplify. - if (ReplyTo !== "") - MessagesAdapter.loadConversationUntil(ReplyTo) + if (ReplyTo !== "") { + // Store the request Id for later filtering. + requestId = MessagesAdapter.loadConversationUntil(ReplyTo) + } } - MouseArea { - - z: 2 - anchors.fill: parent - RowLayout { - id: replyToRow - anchors.top: parent.top - anchors.topMargin: JamiTheme.preferredMarginSize / 2 - - property bool isSelf: ReplyToAuthor === CurrentAccount.uri || ReplyToAuthor === "" - - Label { - id: replyTo - - text: JamiStrings.inReplyTo + Connections { + target: MessagesAdapter - color: UtilsAdapter.luma(bubble.color) ? - JamiTheme.chatviewTextColorLight : - JamiTheme.chatviewTextColorDark - font.pointSize: JamiTheme.textFontSize - font.kerning: true - font.bold: true - Layout.leftMargin: JamiTheme.preferredMarginSize - } - - Avatar { - id: avatarReply - - Layout.preferredWidth: JamiTheme.avatarReadReceiptSize - Layout.preferredHeight: JamiTheme.avatarReadReceiptSize - - showPresenceIndicator: false - - imageId: { - if (replyToRow.isSelf) - return CurrentAccount.id - return ReplyToAuthor - } - mode: replyToRow.isSelf ? Avatar.Mode.Account : Avatar.Mode.Contact + function onMoreMessagesLoaded(loadingRequestId) { + // Filter for the request Id we're waiting for (now the message is loaded). + if (requestId === loadingRequestId) { + requestId = -1 + replyTransferName = MessagesAdapter.dataForInteraction(ReplyTo, MessageList.TransferName) } + } + } - Text { - id: body - Layout.maximumWidth: JamiTheme.preferredFieldWidth - JamiTheme.preferredMarginSize - Layout.rightMargin: JamiTheme.preferredMarginSize - - TextMetrics { - id: metrics - elide: Text.ElideRight - elideWidth: JamiTheme.preferredFieldWidth - JamiTheme.preferredMarginSize - text: ReplyToBody === "" && ReplyToAuthor !== "" ? "*(Deleted Message)*" : ReplyToBody - } - - textFormat: Text.MarkdownText - text: metrics.elidedText - - color: UtilsAdapter.luma(bubble.color) ? - JamiTheme.chatviewTextColorLight : - JamiTheme.chatviewTextColorDark - font.pointSize: JamiTheme.textFontSize - font.kerning: true - font.bold: true + TextEdit { + id: body + + text: replyTransferName ? + replyTransferName : + (ReplyToBody === "" && ReplyToAuthor !== "") ? + JamiStrings.deleteReplyMessage : + (ReplyToBody ? ReplyToBody : "") + + width: Math.min(JamiTheme.sbsMessageBaseMaximumReplyWidth, implicitWidth) + + horizontalAlignment: Text.AlignLeft + + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + selectByMouse: true + font.pixelSize: IsEmojiOnly? JamiTheme.chatviewEmojiSize : JamiTheme.emojiBubbleSize + font.hintingPreference: Font.PreferNoHinting + renderType: Text.NativeRendering + textFormat: Text.MarkdownText + readOnly: true + color: getBaseColor() + + function getBaseColor() { + var baseColor + if (IsEmojiOnly) { + if (JamiTheme.darkTheme) + baseColor = JamiTheme.chatviewTextColorLight + else + baseColor = JamiTheme.chatviewTextColorDark + } else { + if (UtilsAdapter.luma(replyBubble.color)) + baseColor = JamiTheme.chatviewTextColorLight + else + baseColor = JamiTheme.chatviewTextColorDark } + return baseColor } + } - onClicked: function(mouse) { - CurrentConversation.scrollToMsg(ReplyTo) + Rectangle { + anchors.fill: parent + visible: body.height > JamiTheme.sbsMessageBaseMaximumReplyHeight + gradient: Gradient { + GradientStop {position: 0.66 ; color: "transparent"} + GradientStop {position: 1 ; color: replyBubble.color} } } } diff --git a/src/app/commoncomponents/SBSMessageBase.qml b/src/app/commoncomponents/SBSMessageBase.qml index 36f24cf641e78609077b5aa59c1cdef46fb6432f..a95c4f9253695976ef26a0b77aa5bbb81fe7c6f9 100644 --- a/src/app/commoncomponents/SBSMessageBase.qml +++ b/src/app/commoncomponents/SBSMessageBase.qml @@ -58,6 +58,10 @@ Control { width: listView.width height: mainColumnLayout.implicitHeight + property real textContentWidth + property real textContentHeight + property bool isReply: ReplyTo !== "" + // If the ListView attached properties are not available, // then the root delegate is likely a Loader. readonly property ListView listView: ListView.view ? @@ -89,6 +93,7 @@ Control { Item { id: usernameblock Layout.preferredHeight: (seq === MsgSeq.first || seq === MsgSeq.single) ? 10 : 0 + visible: !isReply Label { id: username @@ -104,11 +109,104 @@ Control { } + Item { + id: replyItem + property bool isSelf: ReplyToAuthor === CurrentAccount.uri + + visible: root.isReply + width: parent.width + + Layout.fillWidth: true + Layout.preferredHeight: childrenRect.height + + Layout.topMargin: JamiTheme.sbsMessageBaseReplyTopMargin + Layout.leftMargin: isOutgoing ? undefined : JamiTheme.sbsMessageBaseReplyMargin + Layout.rightMargin: !isOutgoing ? undefined : JamiTheme.sbsMessageBaseReplyMargin + + transform: Translate { y: JamiTheme.sbsMessageBaseReplyBottomMargin } + + + ColumnLayout { + width: parent.width + spacing: 2 + + RowLayout{ + id: replyToLayout + + Layout.alignment: isOutgoing ? Qt.AlignRight : Qt.AlignLeft + property var replyUserName: UtilsAdapter.getBestNameForUri(CurrentAccount.id, ReplyToAuthor) + + Label { + id: replyTo + + text: isOutgoing ? JamiStrings.inReplyTo : UtilsAdapter.getBestNameForUri(CurrentAccount.id, Author) + JamiStrings.repliedTo + color: JamiTheme.messageReplyColor + font.pointSize: JamiTheme.textFontSize + font.kerning: true + font.bold: true + } + + Avatar { + id: avatarReply + + visible: !replyItem.isSelf + Layout.preferredWidth: JamiTheme.avatarReadReceiptSize + Layout.preferredHeight: JamiTheme.avatarReadReceiptSize + showPresenceIndicator: false + imageId: { + if (replyItem.isSelf) + return CurrentAccount.id + return ReplyToAuthor + } + mode: replyItem.isSelf ? Avatar.Mode.Account : Avatar.Mode.Contact + } + + Label { + id: replyToUserName + + text: replyItem.isSelf ? JamiStrings.inReplyToMe : replyToLayout.replyUserName + color: JamiTheme.messageReplyColor + font.pointSize: JamiTheme.textFontSize + font.kerning: true + font.bold: true + } + } + + Rectangle { + id: replyBubble + + z: -2 + color: replyItem.isSelf ? Qt.lighter(CurrentConversation.color, 1.15) : Qt.lighter(JamiTheme.messageInBgColor, 1.05) + radius: msgRadius + + Layout.preferredWidth: replyToRow.width + 2*JamiTheme.preferredMarginSize + Layout.preferredHeight: replyToRow.height + 2*JamiTheme.preferredMarginSize + Layout.alignment: isOutgoing ? Qt.AlignRight : Qt.AlignLeft + + + // place actual content here + ReplyToRow { + id: replyToRow + + anchors.centerIn: parent + } + + MouseArea { + z: 2 + anchors.fill: parent + onClicked: function(mouse) { + CurrentConversation.scrollToMsg(ReplyTo) + } + } + } + } + } + RowLayout { id: msgRowlayout Layout.preferredHeight: innerContent.height + root.extraHeight - Layout.topMargin: (seq === MsgSeq.first || seq === MsgSeq.single) ? 6 : 0 + Layout.topMargin: ((seq === MsgSeq.first || seq === MsgSeq.single) && !root.isReply) ? 6 : 0 Item { id: avatarBlock @@ -151,9 +249,6 @@ Control { width: parent.width visible: true - - // place actual content here - ReplyToRow {} } Item { @@ -232,33 +327,37 @@ Control { MessageBubble { id: bubble + property bool isEdited: PreviousBodies.length !== 0 visible: !IsEmojiOnly z:-1 out: isOutgoing type: seq + isReply: root.isReply + + function getBaseColor() { - var baseColor = isOutgoing ? JamiTheme.messageOutBgColor - : CurrentConversation.isCoreDialog ? - JamiTheme.messageInBgColor : - Qt.lighter(CurrentConversation.color, 1.5) + var baseColor = isOutgoing ? CurrentConversation.color : JamiTheme.messageInBgColor if (Id === MessagesAdapter.replyToId || Id === MessagesAdapter.editId) { // If we are replying to or editing the message return Qt.darker(baseColor, 1.5) } return baseColor } + color: getBaseColor() radius: msgRadius anchors.right: isOutgoing ? parent.right : undefined anchors.top: parent.top - width: innerContent.childrenRect.width + + width: Type === Interaction.Type.TEXT && !isEdited ? root.textContentWidth : innerContent.childrenRect.width height: innerContent.childrenRect.height + (visible ? root.extraHeight : 0) + } + Rectangle { id: bg - color: bubble.getBaseColor() anchors.fill: parent visible: false } diff --git a/src/app/commoncomponents/TextMessageDelegate.qml b/src/app/commoncomponents/TextMessageDelegate.qml index 41f2ecc85b91e821a43c0c7b6408ee529b7fff9d..312cf6a828750badf1c8c120573bb988a9611505 100644 --- a/src/app/commoncomponents/TextMessageDelegate.qml +++ b/src/app/commoncomponents/TextMessageDelegate.qml @@ -45,6 +45,9 @@ SBSMessageBase { formattedDay: MessagesAdapter.getFormattedDay(Timestamp) extraHeight: extraContent.active && !isRemoteImage ? msgRadius : -isRemoteImage textHovered: textHoverhandler.hovered + textContentWidth: textEditId.width + textContentHeight: textEditId.height + innerContent.children: [ TextEdit { @@ -67,12 +70,12 @@ SBSMessageBase { width: { if (extraContent.active) Math.max(extraContent.width, - Math.min(implicitWidth - avatarBlockWidth, + Math.min((2/3)*root.maxMsgWidth,implicitWidth - avatarBlockWidth, extraContent.minSize) - senderMargin ) else if (isEmojiOnly) - Math.min(implicitWidth, innerContent.width - senderMargin - (innerContent.width - senderMargin) % (JamiTheme.chatviewEmojiSize + 2)) + Math.min((2/3)*root.maxMsgWidth,implicitWidth, innerContent.width - senderMargin - (innerContent.width - senderMargin) % (JamiTheme.chatviewEmojiSize + 2)) else - Math.min(implicitWidth, innerContent.width - senderMargin) + Math.min((2/3)*root.maxMsgWidth,implicitWidth, innerContent.width - senderMargin) } wrapMode: Label.WrapAtWordBoundaryOrAnywhere diff --git a/src/app/constant/JamiStrings.qml b/src/app/constant/JamiStrings.qml index 362c9752594d7414db50d1c8b8045131bb1a6864..4c4b85dcac83a464a688f2e0c2d8e1db233f150e 100644 --- a/src/app/constant/JamiStrings.qml +++ b/src/app/constant/JamiStrings.qml @@ -361,7 +361,7 @@ Item { property string search: qsTr("Search") // Chatview footer - property string jumpToLatest: qsTr("Jump to latest") + property string scrollToEnd: qsTr("Scroll to end of conversation") property string typeIndicatorSingle: qsTr("{} is typing…") property string typeIndicatorPlural: qsTr("{} are typing…") property string typeIndicatorMax: qsTr("Several people are typing…") @@ -787,6 +787,8 @@ Item { property string remove: qsTr("Remove") property string replyTo: qsTr("Reply to") property string inReplyTo: qsTr("In reply to") + property string repliedTo: qsTr(" replied to") + property string inReplyToMe: qsTr("Me") property string reply: qsTr("Reply") property string writeTo: qsTr("Write to %1") property string edit: qsTr("Edit") @@ -848,6 +850,7 @@ Item { //message options property string deleteMessage: qsTr("Delete message") + property string deleteReplyMessage: qsTr("*(Deleted Message)*") property string editMessage: qsTr("Edit message") } diff --git a/src/app/constant/JamiTheme.qml b/src/app/constant/JamiTheme.qml index a8cf11707464dc620024d8e798ddb61c934ab4df..7847bdf407760c7a146161a7e559251861914e40 100644 --- a/src/app/constant/JamiTheme.qml +++ b/src/app/constant/JamiTheme.qml @@ -201,8 +201,9 @@ Item { property real chatviewFontSize: calcSize(15) property real chatviewEmojiSize: calcSize(60) property color timestampColor: darkTheme ? "#bbb" : "#777" + property color messageReplyColor: darkTheme ? "#bbb" : "#A7A7A7" property color messageOutTxtColor: "#000000" - property color messageInBgColor: darkTheme ? "#28b1ed" : "#e5e5e5" + property color messageInBgColor: "#e5e5e5" property color messageOutBgColor: darkTheme? "#616161" : "#005699" property color messageInTxtColor: "#FFFFFF" property color fileOutTimestampColor: darkTheme ? "#eee" : "#555" @@ -441,6 +442,12 @@ Item { // SBSMessageBase property int sbsMessageBasePreferredPadding: 12 + property int sbsMessageBaseMaximumReplyWidth: baseZoom * 300 + property int sbsMessageBaseMaximumReplyHeight: baseZoom * 40 + property int sbsMessageBaseReplyBottomMargin: baseZoom * 10 + property int sbsMessageBaseReplyMargin: 45 + property int sbsMessageBaseReplyTopMargin: 6 + // MessageBar property int messageBarMarginSize: 10 diff --git a/src/app/mainview/components/MessageListView.qml b/src/app/mainview/components/MessageListView.qml index 12e51901ff25cbcb3a2c05805057408f90d1dbdf..17f476bd5e36535d151e9b7cd23baba3bc50e509 100644 --- a/src/app/mainview/components/MessageListView.qml +++ b/src/app/mainview/components/MessageListView.qml @@ -31,6 +31,7 @@ import "../../commoncomponents" JamiListView { id: root + function getDistanceToBottom() { const scrollDiff = ScrollBar.vertical.position - (1.0 - ScrollBar.vertical.size) @@ -107,7 +108,7 @@ JamiListView { function isFirst() { if (!nItem) return true else { - if (item.showTime) { + if (item.showTime || item.isReply ) { return true } else if (nItem.author !== item.author) { return true @@ -119,7 +120,7 @@ JamiListView { function isLast() { if (!pItem) return true else { - if (pItem.showTime) { + if (pItem.showTime || pItem.isReply) { return true } else if (pItem.author !== item.author) { return true @@ -202,12 +203,10 @@ JamiListView { model: MessagesAdapter.messageListModel delegate: DelegateChooser { id: delegateChooser - role: "Type" DelegateChoice { id: delegateChoice - roleValue: Interaction.Type.TEXT TextMessageDelegate { @@ -257,8 +256,10 @@ JamiListView { } } } + } + onAtYBeginningChanged: loadMoreMsgsIfNeeded() Connections { @@ -271,7 +272,7 @@ JamiListView { } } - function onMoreMessagesLoaded() { + function onMoreMessagesLoaded(loadingRequestId) { if (root.contentHeight < root.height || root.atYBeginning) { root.loadMoreMsgsIfNeeded() } diff --git a/src/app/mainview/components/ScrollToBottomButton.qml b/src/app/mainview/components/ScrollToBottomButton.qml index 0d4404f5efbebb197e64f390b17c18cdee71b6b0..2614c466f72dbd265ca539efc2d042e8c95c118d 100644 --- a/src/app/mainview/components/ScrollToBottomButton.qml +++ b/src/app/mainview/components/ScrollToBottomButton.qml @@ -21,6 +21,8 @@ import QtQuick.Controls import Qt5Compat.GraphicalEffects import net.jami.Constants 1.1 +import net.jami.Adapters 1.1 + import "../../commoncomponents" @@ -28,12 +30,10 @@ Control { id: root property alias activeStateTrigger: activeState.when - signal clicked height: jumpToLatestText.contentHeight + 15 width: jumpToLatestText.contentWidth + arrowDropDown.width + 50 - opacity: 0 states: State { @@ -76,38 +76,41 @@ Control { Text { id: jumpToLatestText - anchors.left: parent.left + anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - font.weight: Font.DemiBold + font.weight: Font.Bold font.pointSize: JamiTheme.textFontSize + 2 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter - text: JamiStrings.jumpToLatest - color: JamiTheme.whiteColor + text: JamiStrings.scrollToEnd + color: UtilsAdapter.luma(CurrentConversation.color) ? JamiTheme.chatviewTextColorLight : JamiTheme.chatviewTextColorDark + + } ResponsiveImage { id: arrowDropDown - anchors.left: jumpToLatestText.right - anchors.leftMargin: 3 + anchors.right: jumpToLatestText.left + anchors.rightMargin: 3 anchors.verticalCenter: parent.verticalCenter - anchors.verticalCenterOffset: 2 + anchors.verticalCenterOffset: 0 - containerWidth: 12 - containerHeight: 12 + containerWidth: jumpToLatestText.contentHeight + containerHeight: jumpToLatestText.contentHeight + rotation: -90 - color: JamiTheme.whiteColor - source: JamiResources.down_triangle_arrow_black_24dp_svg + color: UtilsAdapter.luma(CurrentConversation.color) ? JamiTheme.chatviewTextColorLight : JamiTheme.chatviewTextColorDark + source: JamiResources.back_24dp_svg } } } background: Rectangle { radius: 20 - color: JamiTheme.jamiDarkBlue + color: CurrentConversation.color MouseArea { anchors.fill: parent diff --git a/src/app/messagesadapter.cpp b/src/app/messagesadapter.cpp index b96f68e069ba6c26b5b25ceea05ef126072121fd..1481996f5b9d296301b391cab17d568a3accc53f 100644 --- a/src/app/messagesadapter.cpp +++ b/src/app/messagesadapter.cpp @@ -106,7 +106,7 @@ MessagesAdapter::loadMoreMessages() } } -void +int MessagesAdapter::loadConversationUntil(const QString& to) { try { @@ -118,13 +118,14 @@ MessagesAdapter::loadConversationUntil(const QString& to) const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId, accountId); if (convInfo.isSwarm()) { auto* convModel = lrcInstance_->getCurrentConversationModel(); - convModel->loadConversationUntil(convId, to); + return convModel->loadConversationUntil(convId, to); } } } } catch (const std::exception& e) { qWarning() << e.what(); } + return 0; } void @@ -550,11 +551,11 @@ MessagesAdapter::onPreviewInfoReady(QString messageId, QVariantMap info) } void -MessagesAdapter::onConversationMessagesLoaded(uint32_t, const QString& convId) +MessagesAdapter::onConversationMessagesLoaded(uint32_t loadingRequestId, const QString& convId) { if (convId != lrcInstance_->get_selectedConvUid()) return; - Q_EMIT moreMessagesLoaded(); + Q_EMIT moreMessagesLoaded(loadingRequestId); } void diff --git a/src/app/messagesadapter.h b/src/app/messagesadapter.h index afa1389d58745c4b353833a348e455bf36d56892..992b3fc5edc9f21f7d03144b71d41b0a63315a8c 100644 --- a/src/app/messagesadapter.h +++ b/src/app/messagesadapter.h @@ -75,13 +75,13 @@ Q_SIGNALS: void newFilePasted(QString filePath); void newTextPasted(); void previewInformationToQML(QString messageId, QStringList previewInformation); - void moreMessagesLoaded(); + void moreMessagesLoaded(qint32 loadingRequestId); void timestampUpdated(); protected: Q_INVOKABLE bool isDocument(const interaction::Type& type); Q_INVOKABLE void loadMoreMessages(); - Q_INVOKABLE void loadConversationUntil(const QString& to); + Q_INVOKABLE qint32 loadConversationUntil(const QString& to); Q_INVOKABLE void connectConversationModel(); Q_INVOKABLE void sendConversationRequest(); Q_INVOKABLE void removeConversation(const QString& convUid); diff --git a/src/libclient/messagelistmodel.cpp b/src/libclient/messagelistmodel.cpp index 19fb865ba12f6976bb2fda612a7cfc1bf5ac5630..ab88187a0fcf4b674e842548478ac07ba8b0cecd 100644 --- a/src/libclient/messagelistmodel.cpp +++ b/src/libclient/messagelistmodel.cpp @@ -485,8 +485,8 @@ MessageListModel::dataForItem(item_t item, int, int role) const return QVariant(""); auto linkified = data(repliedMsg, Role::Linkified).toString(); if (!linkified.isEmpty()) - return QVariant(linkified.replace("\n", " ")); - return QVariant(data(repliedMsg, Role::Body).toString().replace("\n", " ")); + return QVariant(linkified); + return QVariant(data(repliedMsg, Role::Body).toString()); } case Role::TotalSize: return QVariant(item.second.commit["totalSize"].toInt());