Fix presence indicator

This commit is contained in:
Nicolas Werner 2020-06-24 16:24:22 +02:00 committed by CH Chethan Reddy
parent 1633650303
commit 4862be06be
16 changed files with 76 additions and 56 deletions

View File

@ -2,11 +2,13 @@ import QtQuick 2.6
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import QtGraphicalEffects 1.0 import QtGraphicalEffects 1.0
import im.nheko 1.0
Rectangle { Rectangle {
id: avatar id: avatar
width: 48 width: 48
height: 48 height: 48
radius: settings.avatarCircles ? height/2 : 3 radius: Settings.avatarCircles ? height/2 : 3
property alias url: img.source property alias url: img.source
property string userid property string userid
@ -40,7 +42,7 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
width: avatar.width width: avatar.width
height: avatar.height height: avatar.height
radius: settings.avatarCircles ? height/2 : 3 radius: Settings.avatarCircles ? height/2 : 3
} }
} }
@ -52,8 +54,8 @@ Rectangle {
height: avatar.height / 6 height: avatar.height / 6
width: height width: height
radius: settings.avatarCircles ? height / 2 : height / 4 radius: Settings.avatarCircles ? height / 2 : height / 4
color: switch (timelineManager.userPresence(userid)) { color: switch (TimelineManager.userPresence(userid)) {
case "online": return "#00cc66" case "online": return "#00cc66"
case "unavailable": return "#ff9933" case "unavailable": return "#ff9933"
case "offline": // return "#a82353" don't show anything if offline, since it is confusing, if presence is disabled case "offline": // return "#a82353" don't show anything if offline, since it is confusing, if presence is disabled

View File

@ -1,6 +1,8 @@
import QtQuick 2.5 import QtQuick 2.5
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import im.nheko 1.0
TextEdit { TextEdit {
textFormat: TextEdit.RichText textFormat: TextEdit.RichText
readOnly: true readOnly: true
@ -10,10 +12,10 @@ TextEdit {
onLinkActivated: { onLinkActivated: {
if (/^https:\/\/matrix.to\/#\/(@.*)$/.test(link)) chat.model.openUserProfile(/^https:\/\/matrix.to\/#\/(@.*)$/.exec(link)[1]) 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)) { else if (/^https:\/\/matrix.to\/#\/(![^\/]*)\/(\$.*)$/.test(link)) {
var match = /^https:\/\/matrix.to\/#\/(![^\/]*)\/(\$.*)$/.exec(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) chat.positionViewAtIndex(chat.model.idToIndex(match[2]), ListView.Contain)
} }
else Qt.openUrlExternally(link) else Qt.openUrlExternally(link)

View File

@ -1,6 +1,8 @@
import QtQuick 2.6 import QtQuick 2.6
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import im.nheko 1.0
// This class is for showing Reactions in the timeline row, not for // This class is for showing Reactions in the timeline row, not for
// adding new reactions via the emoji picker // adding new reactions via the emoji picker
Flow { Flow {
@ -33,8 +35,13 @@ Flow {
ToolTip.text: modelData.users ToolTip.text: modelData.users
onClicked: { onClicked: {
<<<<<<< HEAD
console.debug("Picked " + modelData.key + "in response to " + reactionFlow.eventId + " in room " + reactionFlow.roomId + ". selfReactedEvent: " + modelData.selfReactedEvent) console.debug("Picked " + modelData.key + "in response to " + reactionFlow.eventId + " in room " + reactionFlow.roomId + ". selfReactedEvent: " + modelData.selfReactedEvent)
timelineManager.queueReactionMessage(reactionFlow.eventId, modelData.key) 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 { TextMetrics {
id: textMetrics id: textMetrics
font.family: settings.emojiFont font.family: Settings.emojiFont
elide: Text.ElideRight elide: Text.ElideRight
elideWidth: 150 elideWidth: 150
text: modelData.key text: modelData.key
@ -55,8 +62,8 @@ Flow {
Text { Text {
anchors.baseline: reactionCounter.baseline anchors.baseline: reactionCounter.baseline
id: reactionText id: reactionText
text: textMetrics.elidedText + (textMetrics.elidedText == modelData.key ? "" : "…") text: textMetrics.elidedText + (textMetrics.elidedText == model.key ? "" : "…")
font.family: settings.emojiFont font.family: Settings.emojiFont
color: reaction.hovered ? colors.highlight : colors.text color: reaction.hovered ? colors.highlight : colors.text
maximumLineCount: 1 maximumLineCount: 1
} }

View File

@ -29,7 +29,7 @@ Item {
} }
} }
Rectangle { Rectangle {
color: (settings.messageHoverHighlight && parent.containsMouse) ? colors.base : "transparent" color: (Settings.messageHoverHighlight && parent.containsMouse) ? colors.base : "transparent"
anchors.fill: row anchors.fill: row
} }
RowLayout { RowLayout {
@ -48,8 +48,8 @@ Item {
// fancy reply, if this is a reply // fancy reply, if this is a reply
Reply { Reply {
visible: model.replyTo visible: model.replyTo
modelData: chat.model.getDump(model.replyTo, model.id) modelData: chat.model.getDump(model.replyTo)
userColor: timelineManager.userColor(modelData.userId, colors.window) userColor: TimelineManager.userColor(modelData.userId, colors.window)
} }
// actual message content // actual message content
@ -84,7 +84,7 @@ Item {
width: 16 width: 16
} }
EmojiButton { EmojiButton {
visible: settings.buttonsInTimeline visible: Settings.buttonsInTimeline
Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.alignment: Qt.AlignRight | Qt.AlignTop
Layout.preferredHeight: 16 Layout.preferredHeight: 16
width: 16 width: 16
@ -96,7 +96,7 @@ Item {
event_id: model.id event_id: model.id
} }
ImageButton { ImageButton {
visible: settings.buttonsInTimeline visible: Settings.buttonsInTimeline
Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.alignment: Qt.AlignRight | Qt.AlignTop
Layout.preferredHeight: 16 Layout.preferredHeight: 16
width: 16 width: 16
@ -112,7 +112,7 @@ Item {
onClicked: chat.model.replyAction(model.id) onClicked: chat.model.replyAction(model.id)
} }
ImageButton { ImageButton {
visible: settings.buttonsInTimeline visible: Settings.buttonsInTimeline
Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.alignment: Qt.AlignRight | Qt.AlignTop
Layout.preferredHeight: 16 Layout.preferredHeight: 16
width: 16 width: 16

View File

@ -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 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 height: visible ? implicitHeight : 0
text: qsTr("Save as") text: qsTr("Save as")
onTriggered: timelineManager.timeline.saveMedia(messageContextMenu.eventId) onTriggered: TimelineManager.timeline.saveMedia(messageContextMenu.eventId)
} }
} }
@ -104,7 +104,7 @@ Page {
DeviceVerification {} DeviceVerification {}
} }
Connections { Connections {
target: timelineManager target: TimelineManager
onNewDeviceVerificationRequest: { onNewDeviceVerificationRequest: {
flow.userId = userId; flow.userId = userId;
flow.sender = false; flow.sender = false;
@ -118,7 +118,7 @@ Page {
} }
Label { Label {
visible: !timelineManager.timeline && !timelineManager.isInitialSync visible: !TimelineManager.timeline && !TimelineManager.isInitialSync
anchors.centerIn: parent anchors.centerIn: parent
text: qsTr("No room open") text: qsTr("No room open")
font.pointSize: 24 font.pointSize: 24
@ -128,7 +128,7 @@ Page {
BusyIndicator { BusyIndicator {
visible: running visible: running
anchors.centerIn: parent anchors.centerIn: parent
running: timelineManager.isInitialSync running: TimelineManager.isInitialSync
height: 200 height: 200
width: 200 width: 200
z: 3 z: 3
@ -137,7 +137,7 @@ Page {
ListView { ListView {
id: chat id: chat
visible: !!timelineManager.timeline visible: TimelineManager.timeline != null
cacheBuffer: 400 cacheBuffer: 400
@ -149,7 +149,7 @@ Page {
anchors.leftMargin: 4 anchors.leftMargin: 4
anchors.rightMargin: scrollbar.width anchors.rightMargin: scrollbar.width
model: timelineManager.timeline model: TimelineManager.timeline
boundsBehavior: Flickable.StopAtBounds 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 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 { delegate: Rectangle {
// This would normally be previousSection, but our model's order is inverted. // This would normally be previousSection, but our model's order is inverted.
@ -303,7 +303,7 @@ Page {
Label { Label {
id: userName id: userName
text: chat.model.escapeEmoji(modelData.userName) text: chat.model.escapeEmoji(modelData.userName)
color: timelineManager.userColor(modelData.userId, colors.window) color: TimelineManager.userColor(modelData.userId, colors.window)
textFormat: Text.RichText textFormat: Text.RichText
MouseArea { MouseArea {
@ -381,8 +381,13 @@ Page {
anchors.rightMargin: 20 anchors.rightMargin: 20
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
<<<<<<< HEAD
modelData: chat.model ? chat.model.getDump(chat.model.reply, chat.model.id) : {} modelData: chat.model ? chat.model.getDump(chat.model.reply, chat.model.id) : {}
userColor: timelineManager.userColor(modelData.userId, colors.window) 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 { ImageButton {

View File

@ -57,6 +57,7 @@ ApplicationWindow{
height: 130 height: 130
width: 130 width: 130
displayName: modelData.userName displayName: modelData.userName
userid: modelData.userId
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
} }
@ -65,7 +66,7 @@ ApplicationWindow{
text: user_data.userName text: user_data.userName
fontSizeMode: Text.HorizontalFit fontSizeMode: Text.HorizontalFit
font.pixelSize: 16 font.pixelSize: 16
color:timelineManager.userColor(modelData.userId, colors.window) color:TimelineManager.userColor(modelData.userId, colors.window)
font.bold: true font.bold: true
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
} }

View File

@ -1,6 +1,8 @@
import QtQuick 2.6 import QtQuick 2.6
import QtQuick.Layouts 1.2 import QtQuick.Layouts 1.2
import im.nheko 1.0
Item { Item {
height: row.height + 24 height: row.height + 24
width: parent ? parent.width : undefined width: parent ? parent.width : undefined
@ -29,7 +31,7 @@ Item {
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: timelineManager.timeline.saveMedia(model.data.id) onClicked: TimelineManager.timeline.saveMedia(model.data.id)
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
} }
} }

View File

@ -36,7 +36,7 @@ Item {
MouseArea { MouseArea {
enabled: model.data.type == MtxEvent.ImageMessage && img.status == Image.Ready enabled: model.data.type == MtxEvent.ImageMessage && img.status == Image.Ready
anchors.fill: parent anchors.fill: parent
onClicked: timelineManager.openImageOverlay(model.data.url, model.data.id) onClicked: TimelineManager.openImageOverlay(model.data.url, model.data.id)
} }
} }
} }

View File

@ -37,7 +37,7 @@ Item {
roleValue: MtxEvent.EmoteMessage roleValue: MtxEvent.EmoteMessage
NoticeMessage { NoticeMessage {
formatted: chat.model.escapeEmoji(modelData.userName) + " " + model.data.formattedBody formatted: chat.model.escapeEmoji(modelData.userName) + " " + model.data.formattedBody
color: timelineManager.userColor(modelData.userId, colors.window) color: TimelineManager.userColor(modelData.userId, colors.window)
} }
} }
DelegateChoice { DelegateChoice {
@ -100,31 +100,31 @@ Item {
// TODO: make a more complex formatter for the power levels. // TODO: make a more complex formatter for the power levels.
roleValue: MtxEvent.PowerLevels roleValue: MtxEvent.PowerLevels
NoticeMessage { NoticeMessage {
text: timelineManager.timeline.formatPowerLevelEvent(model.data.id) text: TimelineManager.timeline.formatPowerLevelEvent(model.data.id)
} }
} }
DelegateChoice { DelegateChoice {
roleValue: MtxEvent.RoomJoinRules roleValue: MtxEvent.RoomJoinRules
NoticeMessage { NoticeMessage {
text: timelineManager.timeline.formatJoinRuleEvent(model.data.id) text: TimelineManager.timeline.formatJoinRuleEvent(model.data.id)
} }
} }
DelegateChoice { DelegateChoice {
roleValue: MtxEvent.RoomHistoryVisibility roleValue: MtxEvent.RoomHistoryVisibility
NoticeMessage { NoticeMessage {
text: timelineManager.timeline.formatHistoryVisibilityEvent(model.data.id) text: TimelineManager.timeline.formatHistoryVisibilityEvent(model.data.id)
} }
} }
DelegateChoice { DelegateChoice {
roleValue: MtxEvent.RoomGuestAccess roleValue: MtxEvent.RoomGuestAccess
NoticeMessage { NoticeMessage {
text: timelineManager.timeline.formatGuestAccessEvent(model.data.id) text: TimelineManager.timeline.formatGuestAccessEvent(model.data.id)
} }
} }
DelegateChoice { DelegateChoice {
roleValue: MtxEvent.Member roleValue: MtxEvent.Member
NoticeMessage { NoticeMessage {
text: timelineManager.timeline.formatMemberEvent(model.data.id); text: TimelineManager.timeline.formatMemberEvent(model.data.id);
} }
} }
DelegateChoice { DelegateChoice {

View File

@ -106,7 +106,7 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
switch (button.state) { switch (button.state) {
case "": timelineManager.timeline.cacheMedia(model.data.id); break; case "": TimelineManager.timeline.cacheMedia(model.data.id); break;
case "stopped": case "stopped":
media.play(); console.log("play"); media.play(); console.log("play");
button.state = "playing" button.state = "playing"
@ -127,7 +127,7 @@ Rectangle {
} }
Connections { Connections {
target: timelineManager.timeline target: TimelineManager.timeline
onMediaCached: { onMediaCached: {
if (mxcUrl == model.data.url) { if (mxcUrl == model.data.url) {
media.source = "file://" + cacheUrl media.source = "file://" + cacheUrl

View File

@ -3,6 +3,8 @@ import QtQuick.Controls 2.3
import QtQuick.Layouts 1.2 import QtQuick.Layouts 1.2
import QtQuick.Window 2.2 import QtQuick.Window 2.2
import im.nheko 1.0
Item { Item {
id: replyComponent id: replyComponent
@ -26,7 +28,7 @@ Item {
anchors.bottom: replyContainer.bottom anchors.bottom: replyContainer.bottom
width: 4 width: 4
color: timelineManager.userColor(reply.modelData.userId, colors.window) color: TimelineManager.userColor(reply.modelData.userId, colors.window)
} }
Column { Column {

View File

@ -1,10 +1,12 @@
import ".." import ".."
import im.nheko 1.0
MatrixText { MatrixText {
property string formatted: model.data.formattedBody 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'>") text: "<style type=\"text/css\">a { color:"+colors.link+";}</style>" + formatted.replace("<pre>", "<pre style='white-space: pre-wrap'>")
width: parent ? parent.width : undefined width: parent ? parent.width : undefined
height: isReply ? Math.round(Math.min(timelineRoot.height / 8, implicitHeight)) : undefined height: isReply ? Math.round(Math.min(timelineRoot.height / 8, implicitHeight)) : undefined
clip: true 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
} }

View File

@ -2,7 +2,6 @@ import QtQuick 2.3
import QtQuick.Controls 2.10 import QtQuick.Controls 2.10
import QtQuick.Window 2.2 import QtQuick.Window 2.2
import QtQuick.Layouts 1.10 import QtQuick.Layouts 1.10
import Qt.labs.settings 1.0
import im.nheko 1.0 import im.nheko 1.0
@ -14,12 +13,6 @@ ApplicationWindow {
palette: colors palette: colors
Settings {
id: settings
category: "user"
property bool emoji_font_family: true
}
height: stack.implicitHeight height: stack.implicitHeight
width: stack.implicitWidth width: stack.implicitWidth
StackView { StackView {
@ -417,7 +410,7 @@ ApplicationWindow {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: col.emoji.emoji text: col.emoji.emoji
font.pixelSize: Qt.application.font.pixelSize * 2 font.pixelSize: Qt.application.font.pixelSize * 2
font.family: settings.emoji_font_family font.family: Settings.emojiFont
} }
Label { Label {
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom

View File

@ -73,7 +73,7 @@ Popup {
contentItem: Text { contentItem: Text {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
font.family: settings.emojiFont font.family: Settings.emojiFont
font.pixelSize: 36 font.pixelSize: 36
text: model.unicode text: model.unicode
@ -104,7 +104,7 @@ Popup {
onClicked: { onClicked: {
console.debug("Picked " + model.unicode + "in response to " + emojiPopup.event_id) console.debug("Picked " + model.unicode + "in response to " + emojiPopup.event_id)
emojiPopup.close() emojiPopup.close()
timelineManager.queueReactionMessage(emojiPopup.event_id, model.unicode) TimelineManager.queueReactionMessage(emojiPopup.room_id, emojiPopup.event_id, model.unicode)
} }
} }

View File

@ -80,12 +80,16 @@ TimelineViewManager::userColor(QString id, QColor background)
return userColors.value(id); return userColors.value(id);
} }
// QString QString
// TimelineViewManager::userPresence(QString id) const TimelineViewManager::userPresence(QString id) const
// { {
// return QString::fromStdString( if (id.isEmpty())
// mtx::presence::to_string(cache::presenceState(id.toStdString()))); return "";
// } else
return QString::fromStdString(
mtx::presence::to_string(cache::presenceState(id.toStdString())));
}
QString QString
TimelineViewManager::userStatus(QString id) const TimelineViewManager::userStatus(QString id) const
{ {
@ -110,6 +114,8 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
qmlRegisterType<DeviceVerificationFlow>("im.nheko", 1, 0, "DeviceVerificationFlow"); qmlRegisterType<DeviceVerificationFlow>("im.nheko", 1, 0, "DeviceVerificationFlow");
qmlRegisterType<UserProfileModel>("im.nheko", 1, 0, "UserProfileModel"); qmlRegisterType<UserProfileModel>("im.nheko", 1, 0, "UserProfileModel");
qmlRegisterType<UserProfile>("im.nheko", 1, 0, "UserProfileList"); 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>(); qRegisterMetaType<mtx::events::collections::TimelineEvents>();
qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel"); qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel");
@ -144,8 +150,6 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
}); });
#endif #endif
container->setMinimumSize(200, 200); container->setMinimumSize(200, 200);
view->rootContext()->setContextProperty("timelineManager", this);
view->rootContext()->setContextProperty("settings", settings.data());
view->rootContext()->setContextProperty("deviceVerificationList", this->dvList); view->rootContext()->setContextProperty("deviceVerificationList", this->dvList);
updateColorPalette(); updateColorPalette();
view->engine()->addImageProvider("MxcImage", imgProvider); view->engine()->addImageProvider("MxcImage", imgProvider);

View File

@ -57,7 +57,7 @@ public:
Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId) const; Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId) const;
Q_INVOKABLE QColor userColor(QString id, QColor background); 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; Q_INVOKABLE QString userStatus(QString id) const;
signals: signals:
@ -131,4 +131,4 @@ private:
DeviceVerificationList *dvList; DeviceVerificationList *dvList;
}; };
Q_DECLARE_METATYPE(mtx::events::collections::DeviceEvents) Q_DECLARE_METATYPE(mtx::events::collections::DeviceEvents)