From 9c4a9251718c7bd3d4123cf5101fcba50481f43c Mon Sep 17 00:00:00 2001 From: Tobias Fella Date: Wed, 22 Feb 2023 20:52:31 +0100 Subject: [PATCH] Indicate messages that are not sent yet --- src/models/messageeventmodel.cpp | 6 + src/models/messageeventmodel.h | 1 + .../Component/Timeline/TimelineContainer.qml | 127 ++++++++++-------- 3 files changed, 79 insertions(+), 55 deletions(-) diff --git a/src/models/messageeventmodel.cpp b/src/models/messageeventmodel.cpp index e854d8ff2..f0a9a290b 100644 --- a/src/models/messageeventmodel.cpp +++ b/src/models/messageeventmodel.cpp @@ -68,6 +68,7 @@ QHash MessageEventModel::roleNames() const roles[IsAvatarChangeRole] = "isAvatarChange"; roles[IsRedactedRole] = "isRedacted"; roles[GenericDisplayRole] = "genericDisplay"; + roles[IsPendingRole] = "isPending"; return roles; } @@ -176,6 +177,7 @@ void MessageEventModel::setRoom(NeoChatRoom *room) }); connect(m_currentRoom, &Room::pendingEventAdded, this, &MessageEventModel::endInsertRows); connect(m_currentRoom, &Room::pendingEventAboutToMerge, this, [this](RoomEvent *, int i) { + Q_EMIT dataChanged(index(i, 0), index(i, 0), {IsPendingRole}); if (i == 0) { return; // No need to move anything, just refresh } @@ -908,6 +910,10 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const return evt.isRedacted(); } + if (role == IsPendingRole) { + return row < m_currentRoom->pendingEvents().size(); + } + return {}; } diff --git a/src/models/messageeventmodel.h b/src/models/messageeventmodel.h index 982b57eed..71614dcf7 100644 --- a/src/models/messageeventmodel.h +++ b/src/models/messageeventmodel.h @@ -73,6 +73,7 @@ public: IsNameChangeRole, IsAvatarChangeRole, IsRedactedRole, + IsPendingRole, LastRole, // Keep this last }; Q_ENUM(EventRoles) diff --git a/src/qml/Component/Timeline/TimelineContainer.qml b/src/qml/Component/Timeline/TimelineContainer.qml index 62f2b85f0..de4fb7c11 100644 --- a/src/qml/Component/Timeline/TimelineContainer.qml +++ b/src/qml/Component/Timeline/TimelineContainer.qml @@ -197,76 +197,93 @@ ColumnLayout { } ] - contentItem: ColumnLayout { - id: column - spacing: Kirigami.Units.smallSpacing - RowLayout { - id: rowLayout - + contentItem: RowLayout { + Kirigami.Icon { + source: "content-loading-symbolic" + width: height + Layout.preferredWidth: Kirigami.Units.iconSizes.small + Layout.preferredHeight: Kirigami.Units.iconSizes.small + visible: model.isPending && Config.showLocalMessagesOnRight + } + ColumnLayout { + id: column spacing: Kirigami.Units.smallSpacing - visible: model.showAuthor && !isEmote + RowLayout { + id: rowLayout - QQC2.Label { - id: nameLabel + spacing: Kirigami.Units.smallSpacing + visible: model.showAuthor && !isEmote - Layout.maximumWidth: contentMaxWidth - timeLabel.implicitWidth - rowLayout.spacing + QQC2.Label { + id: nameLabel - text: visible ? author.displayName : "" - textFormat: Text.PlainText - font.weight: Font.Bold - color: author.color - elide: Text.ElideRight - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: { - userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, { - room: currentRoom, - user: author.object, - displayName: author.displayName, - avatarMediaId: author.avatarMediaId, - avatarUrl: author.avatarUrl - }).open(); + Layout.maximumWidth: contentMaxWidth - timeLabel.implicitWidth - rowLayout.spacing + + text: visible ? author.displayName : "" + textFormat: Text.PlainText + font.weight: Font.Bold + color: author.color + elide: Text.ElideRight + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, { + room: currentRoom, + user: author.object, + displayName: author.displayName, + avatarMediaId: author.avatarMediaId, + avatarUrl: author.avatarUrl + }).open(); + } + } + } + QQC2.Label { + id: timeLabel + + text: visible ? model.time.toLocaleTimeString(Qt.locale(), Locale.ShortFormat) : "" + color: Kirigami.Theme.disabledTextColor + QQC2.ToolTip.visible: hoverHandler.hovered + QQC2.ToolTip.text: model.time.toLocaleString(Qt.locale(), Locale.LongFormat) + QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay + + HoverHandler { + id: hoverHandler } } } - QQC2.Label { - id: timeLabel + Loader { + id: replyLoader - text: visible ? model.time.toLocaleTimeString(Qt.locale(), Locale.ShortFormat) : "" - color: Kirigami.Theme.disabledTextColor - QQC2.ToolTip.visible: hoverHandler.hovered - QQC2.ToolTip.text: model.time.toLocaleString(Qt.locale(), Locale.LongFormat) - QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay + Layout.maximumWidth: contentMaxWidth - HoverHandler { - id: hoverHandler + active: model.reply !== undefined + visible: active + + sourceComponent: ReplyComponent { + name: currentRoom.htmlSafeMemberName(reply.author.id) + avatar: reply.author.avatarMediaId ? ("image://mxc/" + reply.author.avatarMediaId) : "" + color: reply.author.color + } + + Connections { + target: replyLoader.item + function onReplyClicked() { + replyClicked(reply.eventId) + } } } } - Loader { - id: replyLoader - - Layout.maximumWidth: contentMaxWidth - - active: model.reply !== undefined - visible: active - - sourceComponent: ReplyComponent { - name: currentRoom.htmlSafeMemberName(reply.author.id) - avatar: reply.author.avatarMediaId ? ("image://mxc/" + reply.author.avatarMediaId) : "" - color: reply.author.color - } - - Connections { - target: replyLoader.item - function onReplyClicked() { - replyClicked(reply.eventId) - } - } + Kirigami.Icon { + source: "content-loading-symbolic" + width: height + Layout.preferredWidth: Kirigami.Units.iconSizes.small + Layout.preferredHeight: Kirigami.Units.iconSizes.small + visible: model.isPending && !Config.showLocalMessagesOnRight } } + background: Item { Kirigami.ShadowedRectangle { id: bubbleBackground