Fix presence indicator

master
Nicolas Werner 4 years ago committed by CH Chethan Reddy
parent 1633650303
commit 4862be06be
  1. 10
      resources/qml/Avatar.qml
  2. 6
      resources/qml/MatrixText.qml
  3. 13
      resources/qml/Reactions.qml
  4. 12
      resources/qml/TimelineRow.qml
  5. 21
      resources/qml/TimelineView.qml
  6. 3
      resources/qml/UserProfile.qml
  7. 4
      resources/qml/delegates/FileMessage.qml
  8. 2
      resources/qml/delegates/ImageMessage.qml
  9. 12
      resources/qml/delegates/MessageDelegate.qml
  10. 4
      resources/qml/delegates/PlayableMediaMessage.qml
  11. 4
      resources/qml/delegates/Reply.qml
  12. 4
      resources/qml/delegates/TextMessage.qml
  13. 9
      resources/qml/device-verification/DeviceVerification.qml
  14. 4
      resources/qml/emoji/EmojiPicker.qml
  15. 20
      src/timeline/TimelineViewManager.cpp
  16. 2
      src/timeline/TimelineViewManager.h

@ -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

@ -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)

@ -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
}

@ -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

@ -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 {

@ -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
}

@ -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
}
}

@ -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)
}
}
}

@ -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 {

@ -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

@ -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 {

@ -1,10 +1,12 @@
import ".."
import im.nheko 1.0
MatrixText {
property string formatted: model.data.formattedBody
text: "<style type=\"text/css\">a { color:"+colors.link+";}</style>" + formatted.replace("<pre>", "<pre style='white-space: pre-wrap'>")
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
}

@ -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

@ -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)
}
}

@ -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<UserSettings> userSettin
qmlRegisterType<DeviceVerificationFlow>("im.nheko", 1, 0, "DeviceVerificationFlow");
qmlRegisterType<UserProfileModel>("im.nheko", 1, 0, "UserProfileModel");
qmlRegisterType<UserProfile>("im.nheko", 1, 0, "UserProfileList");
qmlRegisterSingletonInstance("im.nheko", 1, 0, "TimelineManager", this);
qmlRegisterSingletonInstance("im.nheko", 1, 0, "Settings", settings.data());
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel");
@ -144,8 +150,6 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> 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);

@ -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:

Loading…
Cancel
Save