From 4862be06be6e32c1f4963feabfde010a9f64616c Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 24 Jun 2020 16:24:22 +0200 Subject: [PATCH] Fix presence indicator --- resources/qml/Avatar.qml | 10 +++++---- resources/qml/MatrixText.qml | 6 ++++-- resources/qml/Reactions.qml | 13 +++++++++--- resources/qml/TimelineRow.qml | 12 +++++------ resources/qml/TimelineView.qml | 21 ++++++++++++------- resources/qml/UserProfile.qml | 3 ++- resources/qml/delegates/FileMessage.qml | 4 +++- resources/qml/delegates/ImageMessage.qml | 2 +- resources/qml/delegates/MessageDelegate.qml | 12 +++++------ .../qml/delegates/PlayableMediaMessage.qml | 4 ++-- resources/qml/delegates/Reply.qml | 4 +++- resources/qml/delegates/TextMessage.qml | 4 +++- .../DeviceVerification.qml | 9 +------- resources/qml/emoji/EmojiPicker.qml | 4 ++-- src/timeline/TimelineViewManager.cpp | 20 +++++++++++------- src/timeline/TimelineViewManager.h | 4 ++-- 16 files changed, 76 insertions(+), 56 deletions(-) diff --git a/resources/qml/Avatar.qml b/resources/qml/Avatar.qml index f934e2f6..e687e170 100644 --- a/resources/qml/Avatar.qml +++ b/resources/qml/Avatar.qml @@ -2,11 +2,13 @@ import QtQuick 2.6 import QtQuick.Controls 2.3 import QtGraphicalEffects 1.0 +import im.nheko 1.0 + Rectangle { id: avatar width: 48 height: 48 - radius: settings.avatarCircles ? height/2 : 3 + radius: Settings.avatarCircles ? height/2 : 3 property alias url: img.source property string userid @@ -40,7 +42,7 @@ Rectangle { anchors.fill: parent width: avatar.width height: avatar.height - radius: settings.avatarCircles ? height/2 : 3 + radius: Settings.avatarCircles ? height/2 : 3 } } @@ -52,8 +54,8 @@ Rectangle { height: avatar.height / 6 width: height - radius: settings.avatarCircles ? height / 2 : height / 4 - color: switch (timelineManager.userPresence(userid)) { + radius: Settings.avatarCircles ? height / 2 : height / 4 + color: switch (TimelineManager.userPresence(userid)) { case "online": return "#00cc66" case "unavailable": return "#ff9933" case "offline": // return "#a82353" don't show anything if offline, since it is confusing, if presence is disabled diff --git a/resources/qml/MatrixText.qml b/resources/qml/MatrixText.qml index cbb55bea..d0910045 100644 --- a/resources/qml/MatrixText.qml +++ b/resources/qml/MatrixText.qml @@ -1,6 +1,8 @@ import QtQuick 2.5 import QtQuick.Controls 2.3 +import im.nheko 1.0 + TextEdit { textFormat: TextEdit.RichText readOnly: true @@ -10,10 +12,10 @@ TextEdit { onLinkActivated: { if (/^https:\/\/matrix.to\/#\/(@.*)$/.test(link)) chat.model.openUserProfile(/^https:\/\/matrix.to\/#\/(@.*)$/.exec(link)[1]) - else if (/^https:\/\/matrix.to\/#\/(![^\/]*)$/.test(link)) timelineManager.setHistoryView(/^https:\/\/matrix.to\/#\/(!.*)$/.exec(link)[1]) + else if (/^https:\/\/matrix.to\/#\/(![^\/]*)$/.test(link)) TimelineManager.setHistoryView(/^https:\/\/matrix.to\/#\/(!.*)$/.exec(link)[1]) else if (/^https:\/\/matrix.to\/#\/(![^\/]*)\/(\$.*)$/.test(link)) { var match = /^https:\/\/matrix.to\/#\/(![^\/]*)\/(\$.*)$/.exec(link) - timelineManager.setHistoryView(match[1]) + TimelineManager.setHistoryView(match[1]) chat.positionViewAtIndex(chat.model.idToIndex(match[2]), ListView.Contain) } else Qt.openUrlExternally(link) diff --git a/resources/qml/Reactions.qml b/resources/qml/Reactions.qml index c1091756..11109d7f 100644 --- a/resources/qml/Reactions.qml +++ b/resources/qml/Reactions.qml @@ -1,6 +1,8 @@ import QtQuick 2.6 import QtQuick.Controls 2.2 +import im.nheko 1.0 + // This class is for showing Reactions in the timeline row, not for // adding new reactions via the emoji picker Flow { @@ -33,8 +35,13 @@ Flow { ToolTip.text: modelData.users onClicked: { +<<<<<<< HEAD console.debug("Picked " + modelData.key + "in response to " + reactionFlow.eventId + " in room " + reactionFlow.roomId + ". selfReactedEvent: " + modelData.selfReactedEvent) timelineManager.queueReactionMessage(reactionFlow.eventId, modelData.key) +======= + console.debug("Picked " + model.key + "in response to " + reactionFlow.eventId + " in room " + reactionFlow.roomId + ". selfReactedEvent: " + model.selfReactedEvent) + TimelineManager.reactToMessage(reactionFlow.roomId, reactionFlow.eventId, model.key, model.selfReactedEvent) +>>>>>>> Fix presence indicator } @@ -46,7 +53,7 @@ Flow { TextMetrics { id: textMetrics - font.family: settings.emojiFont + font.family: Settings.emojiFont elide: Text.ElideRight elideWidth: 150 text: modelData.key @@ -55,8 +62,8 @@ Flow { Text { anchors.baseline: reactionCounter.baseline id: reactionText - text: textMetrics.elidedText + (textMetrics.elidedText == modelData.key ? "" : "…") - font.family: settings.emojiFont + text: textMetrics.elidedText + (textMetrics.elidedText == model.key ? "" : "…") + font.family: Settings.emojiFont color: reaction.hovered ? colors.highlight : colors.text maximumLineCount: 1 } diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index d1c20278..db58eb22 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -29,7 +29,7 @@ Item { } } Rectangle { - color: (settings.messageHoverHighlight && parent.containsMouse) ? colors.base : "transparent" + color: (Settings.messageHoverHighlight && parent.containsMouse) ? colors.base : "transparent" anchors.fill: row } RowLayout { @@ -48,8 +48,8 @@ Item { // fancy reply, if this is a reply Reply { visible: model.replyTo - modelData: chat.model.getDump(model.replyTo, model.id) - userColor: timelineManager.userColor(modelData.userId, colors.window) + modelData: chat.model.getDump(model.replyTo) + userColor: TimelineManager.userColor(modelData.userId, colors.window) } // actual message content @@ -84,7 +84,7 @@ Item { width: 16 } EmojiButton { - visible: settings.buttonsInTimeline + visible: Settings.buttonsInTimeline Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.preferredHeight: 16 width: 16 @@ -96,7 +96,7 @@ Item { event_id: model.id } ImageButton { - visible: settings.buttonsInTimeline + visible: Settings.buttonsInTimeline Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.preferredHeight: 16 width: 16 @@ -112,7 +112,7 @@ Item { onClicked: chat.model.replyAction(model.id) } ImageButton { - visible: settings.buttonsInTimeline + visible: Settings.buttonsInTimeline Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.preferredHeight: 16 width: 16 diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index e52d588c..d9302ed7 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -91,7 +91,7 @@ Page { visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker height: visible ? implicitHeight : 0 text: qsTr("Save as") - onTriggered: timelineManager.timeline.saveMedia(messageContextMenu.eventId) + onTriggered: TimelineManager.timeline.saveMedia(messageContextMenu.eventId) } } @@ -104,7 +104,7 @@ Page { DeviceVerification {} } Connections { - target: timelineManager + target: TimelineManager onNewDeviceVerificationRequest: { flow.userId = userId; flow.sender = false; @@ -118,7 +118,7 @@ Page { } Label { - visible: !timelineManager.timeline && !timelineManager.isInitialSync + visible: !TimelineManager.timeline && !TimelineManager.isInitialSync anchors.centerIn: parent text: qsTr("No room open") font.pointSize: 24 @@ -128,7 +128,7 @@ Page { BusyIndicator { visible: running anchors.centerIn: parent - running: timelineManager.isInitialSync + running: TimelineManager.isInitialSync height: 200 width: 200 z: 3 @@ -137,7 +137,7 @@ Page { ListView { id: chat - visible: !!timelineManager.timeline + visible: TimelineManager.timeline != null cacheBuffer: 400 @@ -149,7 +149,7 @@ Page { anchors.leftMargin: 4 anchors.rightMargin: scrollbar.width - model: timelineManager.timeline + model: TimelineManager.timeline boundsBehavior: Flickable.StopAtBounds @@ -197,7 +197,7 @@ Page { onCountChanged: if (atYEnd) model.currentIndex = 0 // Mark last event as read, since we are at the bottom - property int delegateMaxWidth: (settings.timelineMaxWidth > 100 && (parent.width - settings.timelineMaxWidth) > 32) ? settings.timelineMaxWidth : (parent.width - 32) + property int delegateMaxWidth: (Settings.timelineMaxWidth > 100 && (parent.width - Settings.timelineMaxWidth) > 32) ? Settings.timelineMaxWidth : (parent.width - 32) delegate: Rectangle { // This would normally be previousSection, but our model's order is inverted. @@ -303,7 +303,7 @@ Page { Label { id: userName text: chat.model.escapeEmoji(modelData.userName) - color: timelineManager.userColor(modelData.userId, colors.window) + color: TimelineManager.userColor(modelData.userId, colors.window) textFormat: Text.RichText MouseArea { @@ -381,8 +381,13 @@ Page { anchors.rightMargin: 20 anchors.bottom: parent.bottom +<<<<<<< HEAD modelData: chat.model ? chat.model.getDump(chat.model.reply, chat.model.id) : {} userColor: timelineManager.userColor(modelData.userId, colors.window) +======= + modelData: chat.model ? chat.model.getDump(chat.model.reply) : {} + userColor: TimelineManager.userColor(modelData.userId, colors.window) +>>>>>>> Fix presence indicator } ImageButton { diff --git a/resources/qml/UserProfile.qml b/resources/qml/UserProfile.qml index f060b0e3..a7ff8a35 100644 --- a/resources/qml/UserProfile.qml +++ b/resources/qml/UserProfile.qml @@ -57,6 +57,7 @@ ApplicationWindow{ height: 130 width: 130 displayName: modelData.userName + userid: modelData.userId Layout.alignment: Qt.AlignHCenter } @@ -65,7 +66,7 @@ ApplicationWindow{ text: user_data.userName fontSizeMode: Text.HorizontalFit font.pixelSize: 16 - color:timelineManager.userColor(modelData.userId, colors.window) + color:TimelineManager.userColor(modelData.userId, colors.window) font.bold: true Layout.alignment: Qt.AlignHCenter } diff --git a/resources/qml/delegates/FileMessage.qml b/resources/qml/delegates/FileMessage.qml index d8e4215f..158daf45 100644 --- a/resources/qml/delegates/FileMessage.qml +++ b/resources/qml/delegates/FileMessage.qml @@ -1,6 +1,8 @@ import QtQuick 2.6 import QtQuick.Layouts 1.2 +import im.nheko 1.0 + Item { height: row.height + 24 width: parent ? parent.width : undefined @@ -29,7 +31,7 @@ Item { } MouseArea { anchors.fill: parent - onClicked: timelineManager.timeline.saveMedia(model.data.id) + onClicked: TimelineManager.timeline.saveMedia(model.data.id) cursorShape: Qt.PointingHandCursor } } diff --git a/resources/qml/delegates/ImageMessage.qml b/resources/qml/delegates/ImageMessage.qml index 3885ddae..b5c51c2c 100644 --- a/resources/qml/delegates/ImageMessage.qml +++ b/resources/qml/delegates/ImageMessage.qml @@ -36,7 +36,7 @@ Item { MouseArea { enabled: model.data.type == MtxEvent.ImageMessage && img.status == Image.Ready anchors.fill: parent - onClicked: timelineManager.openImageOverlay(model.data.url, model.data.id) + onClicked: TimelineManager.openImageOverlay(model.data.url, model.data.id) } } } diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml index 9630ae3a..6f69f026 100644 --- a/resources/qml/delegates/MessageDelegate.qml +++ b/resources/qml/delegates/MessageDelegate.qml @@ -37,7 +37,7 @@ Item { roleValue: MtxEvent.EmoteMessage NoticeMessage { formatted: chat.model.escapeEmoji(modelData.userName) + " " + model.data.formattedBody - color: timelineManager.userColor(modelData.userId, colors.window) + color: TimelineManager.userColor(modelData.userId, colors.window) } } DelegateChoice { @@ -100,31 +100,31 @@ Item { // TODO: make a more complex formatter for the power levels. roleValue: MtxEvent.PowerLevels NoticeMessage { - text: timelineManager.timeline.formatPowerLevelEvent(model.data.id) + text: TimelineManager.timeline.formatPowerLevelEvent(model.data.id) } } DelegateChoice { roleValue: MtxEvent.RoomJoinRules NoticeMessage { - text: timelineManager.timeline.formatJoinRuleEvent(model.data.id) + text: TimelineManager.timeline.formatJoinRuleEvent(model.data.id) } } DelegateChoice { roleValue: MtxEvent.RoomHistoryVisibility NoticeMessage { - text: timelineManager.timeline.formatHistoryVisibilityEvent(model.data.id) + text: TimelineManager.timeline.formatHistoryVisibilityEvent(model.data.id) } } DelegateChoice { roleValue: MtxEvent.RoomGuestAccess NoticeMessage { - text: timelineManager.timeline.formatGuestAccessEvent(model.data.id) + text: TimelineManager.timeline.formatGuestAccessEvent(model.data.id) } } DelegateChoice { roleValue: MtxEvent.Member NoticeMessage { - text: timelineManager.timeline.formatMemberEvent(model.data.id); + text: TimelineManager.timeline.formatMemberEvent(model.data.id); } } DelegateChoice { diff --git a/resources/qml/delegates/PlayableMediaMessage.qml b/resources/qml/delegates/PlayableMediaMessage.qml index 8d2fa8a8..893325b6 100644 --- a/resources/qml/delegates/PlayableMediaMessage.qml +++ b/resources/qml/delegates/PlayableMediaMessage.qml @@ -106,7 +106,7 @@ Rectangle { anchors.fill: parent onClicked: { switch (button.state) { - case "": timelineManager.timeline.cacheMedia(model.data.id); break; + case "": TimelineManager.timeline.cacheMedia(model.data.id); break; case "stopped": media.play(); console.log("play"); button.state = "playing" @@ -127,7 +127,7 @@ Rectangle { } Connections { - target: timelineManager.timeline + target: TimelineManager.timeline onMediaCached: { if (mxcUrl == model.data.url) { media.source = "file://" + cacheUrl diff --git a/resources/qml/delegates/Reply.qml b/resources/qml/delegates/Reply.qml index f9fd3f11..d4fffb06 100644 --- a/resources/qml/delegates/Reply.qml +++ b/resources/qml/delegates/Reply.qml @@ -3,6 +3,8 @@ import QtQuick.Controls 2.3 import QtQuick.Layouts 1.2 import QtQuick.Window 2.2 +import im.nheko 1.0 + Item { id: replyComponent @@ -26,7 +28,7 @@ Item { anchors.bottom: replyContainer.bottom width: 4 - color: timelineManager.userColor(reply.modelData.userId, colors.window) + color: TimelineManager.userColor(reply.modelData.userId, colors.window) } Column { diff --git a/resources/qml/delegates/TextMessage.qml b/resources/qml/delegates/TextMessage.qml index cc2d2da0..99ff9329 100644 --- a/resources/qml/delegates/TextMessage.qml +++ b/resources/qml/delegates/TextMessage.qml @@ -1,10 +1,12 @@ import ".." +import im.nheko 1.0 + MatrixText { property string formatted: model.data.formattedBody text: "" + formatted.replace("
", "
")
 	width: parent ? parent.width : undefined
 	height: isReply ? Math.round(Math.min(timelineRoot.height / 8, implicitHeight)) : undefined
 	clip: true
-	font.pointSize: (settings.enlargeEmojiOnlyMessages && model.data.isOnlyEmoji > 0 && model.data.isOnlyEmoji < 4) ? settings.fontSize * 3 : settings.fontSize
+	font.pointSize: (Settings.enlargeEmojiOnlyMessages && model.data.isOnlyEmoji > 0 && model.data.isOnlyEmoji < 4) ? Settings.fontSize * 3 : Settings.fontSize
 }
diff --git a/resources/qml/device-verification/DeviceVerification.qml b/resources/qml/device-verification/DeviceVerification.qml
index 12e38f29..516bc74a 100644
--- a/resources/qml/device-verification/DeviceVerification.qml
+++ b/resources/qml/device-verification/DeviceVerification.qml
@@ -2,7 +2,6 @@ import QtQuick 2.3
 import QtQuick.Controls 2.10
 import QtQuick.Window 2.2
 import QtQuick.Layouts 1.10
-import Qt.labs.settings 1.0
 
 import im.nheko 1.0
 
@@ -14,12 +13,6 @@ ApplicationWindow {
 
 	palette: colors
 
-	Settings {
-		id: settings
-		category: "user"
-		property bool emoji_font_family: true
-	}
-
 	height: stack.implicitHeight
 	width: stack.implicitWidth
 	StackView {
@@ -417,7 +410,7 @@ ApplicationWindow {
 									Layout.alignment: Qt.AlignHCenter
 									text: col.emoji.emoji
 									font.pixelSize: Qt.application.font.pixelSize * 2
-									font.family: settings.emoji_font_family
+									font.family: Settings.emojiFont
 								}
 								Label {
 									Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
diff --git a/resources/qml/emoji/EmojiPicker.qml b/resources/qml/emoji/EmojiPicker.qml
index f75221d5..d2ca4da3 100644
--- a/resources/qml/emoji/EmojiPicker.qml
+++ b/resources/qml/emoji/EmojiPicker.qml
@@ -73,7 +73,7 @@ Popup {
                 contentItem: Text {
                     horizontalAlignment: Text.AlignHCenter
                     verticalAlignment: Text.AlignVCenter
-                    font.family: settings.emojiFont
+                    font.family: Settings.emojiFont
                     
                     font.pixelSize: 36
                     text: model.unicode
@@ -104,7 +104,7 @@ Popup {
                 onClicked: {
                     console.debug("Picked " + model.unicode + "in response to " + emojiPopup.event_id)
                     emojiPopup.close()
-                    timelineManager.queueReactionMessage(emojiPopup.event_id, model.unicode)
+                    TimelineManager.queueReactionMessage(emojiPopup.room_id, emojiPopup.event_id, model.unicode)
                 }
             }
 
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index a36a5bda..14c66951 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -80,12 +80,16 @@ TimelineViewManager::userColor(QString id, QColor background)
         return userColors.value(id);
 }
 
-// QString
-// TimelineViewManager::userPresence(QString id) const
-// {
-//         return QString::fromStdString(
-//           mtx::presence::to_string(cache::presenceState(id.toStdString())));
-// }
+QString
+TimelineViewManager::userPresence(QString id) const
+{
+        if (id.isEmpty())
+                return "";
+        else
+                return QString::fromStdString(
+                  mtx::presence::to_string(cache::presenceState(id.toStdString())));
+}
+
 QString
 TimelineViewManager::userStatus(QString id) const
 {
@@ -110,6 +114,8 @@ TimelineViewManager::TimelineViewManager(QSharedPointer userSettin
         qmlRegisterType("im.nheko", 1, 0, "DeviceVerificationFlow");
         qmlRegisterType("im.nheko", 1, 0, "UserProfileModel");
         qmlRegisterType("im.nheko", 1, 0, "UserProfileList");
+        qmlRegisterSingletonInstance("im.nheko", 1, 0, "TimelineManager", this);
+        qmlRegisterSingletonInstance("im.nheko", 1, 0, "Settings", settings.data());
 
         qRegisterMetaType();
         qmlRegisterType("im.nheko.EmojiModel", 1, 0, "EmojiModel");
@@ -144,8 +150,6 @@ TimelineViewManager::TimelineViewManager(QSharedPointer userSettin
         });
 #endif
         container->setMinimumSize(200, 200);
-        view->rootContext()->setContextProperty("timelineManager", this);
-        view->rootContext()->setContextProperty("settings", settings.data());
         view->rootContext()->setContextProperty("deviceVerificationList", this->dvList);
         updateColorPalette();
         view->engine()->addImageProvider("MxcImage", imgProvider);
diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index 38aba021..af8bc4b6 100644
--- a/src/timeline/TimelineViewManager.h
+++ b/src/timeline/TimelineViewManager.h
@@ -57,7 +57,7 @@ public:
         Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId) const;
         Q_INVOKABLE QColor userColor(QString id, QColor background);
 
-        // Q_INVOKABLE QString userPresence(QString id) const;
+        Q_INVOKABLE QString userPresence(QString id) const;
         Q_INVOKABLE QString userStatus(QString id) const;
 
 signals:
@@ -131,4 +131,4 @@ private:
 
         DeviceVerificationList *dvList;
 };
-Q_DECLARE_METATYPE(mtx::events::collections::DeviceEvents)
\ No newline at end of file
+Q_DECLARE_METATYPE(mtx::events::collections::DeviceEvents)