From a1f38fe8d866f985bba505162fba979fbd3d02de Mon Sep 17 00:00:00 2001 From: vslg Date: Fri, 3 Jul 2020 02:28:27 -0300 Subject: [PATCH] Add support for status message, use new icons --- src/backend/matrix_client.py | 21 +++- src/gui/MainPane/AccountContextMenu.qml | 127 +++++++++++++++++------- src/gui/MainPane/AccountDelegate.qml | 33 ++++-- src/icons/thin/presence-busy.svg | 1 + src/icons/thin/presence-invisible.svg | 13 +++ src/icons/thin/presence.svg | 1 + src/icons/thin/user-presence.svg | 39 -------- src/themes/Glass.qpl | 8 +- src/themes/Midnight.qpl | 6 +- 9 files changed, 149 insertions(+), 100 deletions(-) create mode 100644 src/icons/thin/presence-busy.svg create mode 100644 src/icons/thin/presence-invisible.svg create mode 100644 src/icons/thin/presence.svg delete mode 100644 src/icons/thin/user-presence.svg diff --git a/src/backend/matrix_client.py b/src/backend/matrix_client.py index 64435288..2076168b 100644 --- a/src/backend/matrix_client.py +++ b/src/backend/matrix_client.py @@ -253,10 +253,13 @@ class MatrixClient(nio.AsyncClient): response = nio.LoginResponse(user_id, device_id, token) await self.receive_response(response) - # Need to await, else presence will flash on other clients - await self.set_presence(state) + self._presence = "offline" if state == "invisible" else state self.start_task = asyncio.ensure_future(self._start()) + if state == "invisible": + self.models["accounts"][self.user_id].presence = \ + Presence.State.invisible + async def logout(self) -> None: """Logout from the server. This will delete the device.""" @@ -1218,11 +1221,19 @@ class MatrixClient(nio.AsyncClient): await self.set_avatar(mxc) - async def set_presence(self, presence: str) -> None: + async def set_presence( + self, presence: str, status_msg: str = None, + ) -> None: """Set presence state for this account.""" - await super().set_presence("offline" if presence == "invisible" - else presence) + status_msg = status_msg or ( + self.models["accounts"][self.user_id].status_msg + ) + + await super().set_presence( + "offline" if presence == "invisible" else presence, + status_msg, + ) # Assign invisible on model in here, because server will tell us we are # offline diff --git a/src/gui/MainPane/AccountContextMenu.qml b/src/gui/MainPane/AccountContextMenu.qml index b4f08dbd..681527d4 100644 --- a/src/gui/MainPane/AccountContextMenu.qml +++ b/src/gui/MainPane/AccountContextMenu.qml @@ -2,20 +2,107 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 import Clipboard 0.1 import "../Base" HMenu { + id: accountMenu + property string userId property string presence + property string statusMsg property bool firstSyncDone - function setPresence(presence) { - py.callClientCoro(userId, "set_presence", [presence]) + function setPresence(presence, statusMsg = null) { + py.callClientCoro(userId, "set_presence", [presence, statusMsg]) } + HMenuItem { + enabled: presence !== "online" && firstSyncDone + icon.name: "presence" + icon.color: theme.controls.presence.online + text: qsTr("Online") + onTriggered: setPresence("online") + } + + HMenuItem { + visible: presence + enabled: presence !== "unavailable" && firstSyncDone + icon.name: "presence-busy" + icon.color: theme.controls.presence.unavailable + text: qsTr("Unavailable") + onTriggered: setPresence("unavailable") + } + + HMenuItem { + enabled: presence !== "offline" && firstSyncDone + icon.name: "presence" + icon.color: theme.controls.presence.offline + text: qsTr("Offline") + onTriggered: setPresence("offline") + } + + HMenuItem { + visible: presence + enabled: presence !== "invisible" && firstSyncDone + icon.name: "presence-invisible" + icon.color: theme.controls.presence.offline + text: qsTr("Invisible") + onTriggered: setPresence("invisible") + } + + HMenuSeparator { } + + HLabeledItem { + id: statusMsgLabel + visible: presence + enabled: firstSyncDone + width: parent.width + height: visible ? implicitHeight : 0 + label.text: qsTr("Status message:") + label.horizontalAlignment: Qt.AlignHCenter + + HRowLayout { + width: parent.width + + HTextField { + id: statusText + maximumLength: 255 + horizontalAlignment: Qt.AlignHCenter + onAccepted: { + setPresence(presence, statusText.text) + accountMenu.close() + } + + defaultText: statusMsg + placeholderText: qsTr("Beautiful day!") + + Layout.fillWidth: true + } + + HButton { + id: button + + icon.name: "apply" + icon.color: theme.colors.positiveBackground + onClicked: { + setPresence(presence, statusText.text) + accountMenu.close() + } + + Layout.fillHeight: true + } + } + } + + HMenuSeparator { + visible: statusMsgLabel.visible + height: visible ? implicitHeight : 0 + } + HMenuItem { icon.name: "account-settings" text: qsTr("Account settings") @@ -44,40 +131,4 @@ HMenu { popup: "Popups/SignOutPopup.qml" properties: { "userId": userId } } - - HMenuSeparator { } - - HMenuItem { - enabled: presence !== "online" && firstSyncDone - icon.name: "user-presence" - icon.color: theme.controls.presence.online - text: qsTr("Online") - onTriggered: setPresence("online") - } - - HMenuItem { - visible: presence - enabled: presence !== "unavailable" && firstSyncDone - icon.name: "user-presence" - icon.color: theme.controls.presence.unavailable - text: qsTr("Unavailable") - onTriggered: setPresence("unavailable") - } - - HMenuItem { - visible: presence - enabled: presence !== "invisible" && firstSyncDone - icon.name: "user-presence" - icon.color: theme.controls.presence.offline - text: qsTr("Invisible") - onTriggered: setPresence("invisible") - } - - HMenuItem { - enabled: presence !== "offline" && firstSyncDone - icon.name: "user-presence" - icon.color: theme.controls.presence.offline - text: qsTr("Offline") - onTriggered: setPresence("offline") - } } diff --git a/src/gui/MainPane/AccountDelegate.qml b/src/gui/MainPane/AccountDelegate.qml index fc9d35be..fdd0540b 100644 --- a/src/gui/MainPane/AccountDelegate.qml +++ b/src/gui/MainPane/AccountDelegate.qml @@ -65,19 +65,29 @@ HTile { } - TitleLabel { - id: title - text: model.display_name || model.id - color: - hovered ? - utils.nameColor( - model.display_name || model.id.substring(1), - ) : - theme.mainPane.listView.account.name + HColumnLayout { + TitleLabel { + id: title + text: model.display_name || model.id + color: + hovered ? + utils.nameColor( + model.display_name || model.id.substring(1), + ) : + theme.mainPane.listView.account.name - Behavior on color { HColorAnimation {} } + Behavior on color { HColorAnimation {} } - Layout.leftMargin: theme.spacing + Layout.leftMargin: theme.spacing + } + + SubtitleLabel { + tile: account + text: model.status_msg + visible: model.status_msg + + Layout.leftMargin: theme.spacing + } } HButton { @@ -138,6 +148,7 @@ HTile { contextMenu: AccountContextMenu { userId: model.id presence: model.presence_support ? model.presence : null + statusMsg: model.status_msg // Gray out buttons before first sync firstSyncDone: model.first_sync_done diff --git a/src/icons/thin/presence-busy.svg b/src/icons/thin/presence-busy.svg new file mode 100644 index 00000000..60aeca8b --- /dev/null +++ b/src/icons/thin/presence-busy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/thin/presence-invisible.svg b/src/icons/thin/presence-invisible.svg new file mode 100644 index 00000000..a777f95f --- /dev/null +++ b/src/icons/thin/presence-invisible.svg @@ -0,0 +1,13 @@ + + + + background + + + + Layer 1 + + + + + \ No newline at end of file diff --git a/src/icons/thin/presence.svg b/src/icons/thin/presence.svg new file mode 100644 index 00000000..8fa51c2e --- /dev/null +++ b/src/icons/thin/presence.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/thin/user-presence.svg b/src/icons/thin/user-presence.svg deleted file mode 100644 index 32f2e293..00000000 --- a/src/icons/thin/user-presence.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/themes/Glass.qpl b/src/themes/Glass.qpl index 70ded9a9..ac385b4f 100644 --- a/src/themes/Glass.qpl +++ b/src/themes/Glass.qpl @@ -268,11 +268,11 @@ controls: int dimLightness: colors.dimColoredTextIntensity presence: - color online: hsluv(125, 100, 80, 1) - color unavailable: hsluv(0, 100, 80, 1) - color offline: hsluv(0, 0, 45, 1) + color online: colors.positiveText + color unavailable: hsluv(0, 90, 35, 1) + color offline: hsluv(0, 0, 30, 1) color border: "black" - real opacity: 0.6 + real opacity: 1.0 // Specific interface parts diff --git a/src/themes/Midnight.qpl b/src/themes/Midnight.qpl index 636e1eaa..67f60800 100644 --- a/src/themes/Midnight.qpl +++ b/src/themes/Midnight.qpl @@ -274,9 +274,9 @@ controls: int dimLightness: colors.dimColoredTextIntensity presence: - color online: hsluv(125, 100, 80, 1) - color unavailable: hsluv(0, 100, 80, 1) - color offline: hsluv(0, 0, 45, 1) + color online: colors.positiveText + color unavailable: hsluv(0, 90, 35, 1) + color offline: hsluv(0, 0, 30, 1) color border: "black" real opacity: 1.0