Add support for status message, use new icons
This commit is contained in:
parent
91ed600997
commit
a1f38fe8d8
|
@ -253,10 +253,13 @@ class MatrixClient(nio.AsyncClient):
|
||||||
response = nio.LoginResponse(user_id, device_id, token)
|
response = nio.LoginResponse(user_id, device_id, token)
|
||||||
await self.receive_response(response)
|
await self.receive_response(response)
|
||||||
|
|
||||||
# Need to await, else presence will flash on other clients
|
self._presence = "offline" if state == "invisible" else state
|
||||||
await self.set_presence(state)
|
|
||||||
self.start_task = asyncio.ensure_future(self._start())
|
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:
|
async def logout(self) -> None:
|
||||||
"""Logout from the server. This will delete the device."""
|
"""Logout from the server. This will delete the device."""
|
||||||
|
@ -1218,11 +1221,19 @@ class MatrixClient(nio.AsyncClient):
|
||||||
await self.set_avatar(mxc)
|
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."""
|
"""Set presence state for this account."""
|
||||||
|
|
||||||
await super().set_presence("offline" if presence == "invisible"
|
status_msg = status_msg or (
|
||||||
else presence)
|
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
|
# Assign invisible on model in here, because server will tell us we are
|
||||||
# offline
|
# offline
|
||||||
|
|
|
@ -2,20 +2,107 @@
|
||||||
|
|
||||||
import QtQuick 2.12
|
import QtQuick 2.12
|
||||||
import QtQuick.Controls 2.12
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
import Clipboard 0.1
|
import Clipboard 0.1
|
||||||
import "../Base"
|
import "../Base"
|
||||||
|
|
||||||
HMenu {
|
HMenu {
|
||||||
|
id: accountMenu
|
||||||
|
|
||||||
property string userId
|
property string userId
|
||||||
property string presence
|
property string presence
|
||||||
|
property string statusMsg
|
||||||
property bool firstSyncDone
|
property bool firstSyncDone
|
||||||
|
|
||||||
|
|
||||||
function setPresence(presence) {
|
function setPresence(presence, statusMsg = null) {
|
||||||
py.callClientCoro(userId, "set_presence", [presence])
|
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 {
|
HMenuItem {
|
||||||
icon.name: "account-settings"
|
icon.name: "account-settings"
|
||||||
text: qsTr("Account settings")
|
text: qsTr("Account settings")
|
||||||
|
@ -44,40 +131,4 @@ HMenu {
|
||||||
popup: "Popups/SignOutPopup.qml"
|
popup: "Popups/SignOutPopup.qml"
|
||||||
properties: { "userId": userId }
|
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")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ HTile {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HColumnLayout {
|
||||||
TitleLabel {
|
TitleLabel {
|
||||||
id: title
|
id: title
|
||||||
text: model.display_name || model.id
|
text: model.display_name || model.id
|
||||||
|
@ -80,6 +81,15 @@ HTile {
|
||||||
Layout.leftMargin: theme.spacing
|
Layout.leftMargin: theme.spacing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SubtitleLabel {
|
||||||
|
tile: account
|
||||||
|
text: model.status_msg
|
||||||
|
visible: model.status_msg
|
||||||
|
|
||||||
|
Layout.leftMargin: theme.spacing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HButton {
|
HButton {
|
||||||
id: addChat
|
id: addChat
|
||||||
iconItem.small: true
|
iconItem.small: true
|
||||||
|
@ -138,6 +148,7 @@ HTile {
|
||||||
contextMenu: AccountContextMenu {
|
contextMenu: AccountContextMenu {
|
||||||
userId: model.id
|
userId: model.id
|
||||||
presence: model.presence_support ? model.presence : null
|
presence: model.presence_support ? model.presence : null
|
||||||
|
statusMsg: model.status_msg
|
||||||
|
|
||||||
// Gray out buttons before first sync
|
// Gray out buttons before first sync
|
||||||
firstSyncDone: model.first_sync_done
|
firstSyncDone: model.first_sync_done
|
||||||
|
|
1
src/icons/thin/presence-busy.svg
Normal file
1
src/icons/thin/presence-busy.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M8.602 3.7c-1.154 1.937-.635 5.227 1.424 9.025.93 1.712.697 3.02.338 3.815-.982 2.178-3.675 2.799-6.525 3.456-1.964.454-1.839.87-1.839 4.004h-1.995l-.005-1.241c0-2.52.199-3.975 3.178-4.663 3.365-.777 6.688-1.473 5.09-4.418-4.733-8.729-1.35-13.678 3.732-13.678 3.321 0 5.97 2.117 5.97 6.167 0 3.555-1.949 6.833-2.383 7.833h-2.115c.392-1.536 2.499-4.366 2.499-7.842 0-5.153-5.867-4.985-7.369-2.458zm15.398 15.8c0 2.485-2.017 4.5-4.5 4.5s-4.5-2.015-4.5-4.5 2.017-4.5 4.5-4.5 4.5 2.015 4.5 4.5zm-2-.5h-5v1h5v-1z"/></svg>
|
After Width: | Height: | Size: 608 B |
13
src/icons/thin/presence-invisible.svg
Normal file
13
src/icons/thin/presence-invisible.svg
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<svg width="23.999999999999996" height="23.999999999999996" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|
||||||
|
<g>
|
||||||
|
<title>background</title>
|
||||||
|
<rect fill="none" id="canvas_background" height="402" width="582" y="-1" x="-1"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<path stroke="#303C42" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" id="XMLID_1348_" d="m2.5,22.984425c1.19,0 1.19,-0.955166 2.38,-0.955166s1.19,0.955166 2.38,0.955166c1.188,0 1.188,-0.955166 2.376,-0.955166s1.188,0.955166 2.375,0.955166s1.187,-0.955166 2.375,-0.955166c1.186,0 1.186,0.955166 2.372,0.955166c1.184,0 1.184,-0.955166 2.369,-0.955166c1.187,0 1.187,0.955166 2.374,0.955166l-0.638,-4.266728c-0.241,-1.61041 -0.362,-3.236103 -0.362,-4.862751l0,-4.441523c0,-4.324038 -3.416,-8.09981 -7.934,-8.379673c-4.952,-0.306608 -9.067,3.438598 -9.067,8.10172l0,4.720432c0,1.626648 -0.121,3.252341 -0.362,4.862751l-0.638,4.265772z"/>
|
||||||
|
<ellipse stroke-width="2" fill="none" stroke="#303C42" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" ry="1.5" rx="0.5" id="XMLID_1349_" cy="9" cx="9"/>
|
||||||
|
<ellipse stroke-width="2" fill="none" stroke="#303C42" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" ry="1.5" rx="0.5" id="XMLID_1350_" cy="9" cx="15"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/icons/thin/presence.svg
Normal file
1
src/icons/thin/presence.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20.822 18.096c-3.439-.794-6.641-1.49-5.09-4.418 4.719-8.912 1.251-13.678-3.732-13.678-5.082 0-8.465 4.949-3.732 13.678 1.598 2.945-1.725 3.641-5.09 4.418-2.979.688-3.178 2.143-3.178 4.663l.005 1.241h1.995c0-3.134-.125-3.55 1.838-4.003 2.851-.657 5.543-1.278 6.525-3.456.359-.795.592-2.103-.338-3.815-2.058-3.799-2.578-7.089-1.423-9.026 1.354-2.275 5.426-2.264 6.767-.034 1.15 1.911.639 5.219-1.403 9.076-.91 1.719-.671 3.023-.31 3.814.99 2.167 3.707 2.794 6.584 3.458 1.879.436 1.76.882 1.76 3.986h1.995l.005-1.241c0-2.52-.199-3.975-3.178-4.663z"/></svg>
|
After Width: | Height: | Size: 647 B |
|
@ -1,39 +0,0 @@
|
||||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 258.75 258.75" style="enable-background:new 0 0 258.75 258.75;" xml:space="preserve">
|
|
||||||
<g>
|
|
||||||
<circle cx="129.375" cy="60" r="60"/>
|
|
||||||
<path d="M129.375,150c-60.061,0-108.75,48.689-108.75,108.75h217.5C238.125,198.689,189.436,150,129.375,150z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 706 B |
|
@ -268,11 +268,11 @@ controls:
|
||||||
int dimLightness: colors.dimColoredTextIntensity
|
int dimLightness: colors.dimColoredTextIntensity
|
||||||
|
|
||||||
presence:
|
presence:
|
||||||
color online: hsluv(125, 100, 80, 1)
|
color online: colors.positiveText
|
||||||
color unavailable: hsluv(0, 100, 80, 1)
|
color unavailable: hsluv(0, 90, 35, 1)
|
||||||
color offline: hsluv(0, 0, 45, 1)
|
color offline: hsluv(0, 0, 30, 1)
|
||||||
color border: "black"
|
color border: "black"
|
||||||
real opacity: 0.6
|
real opacity: 1.0
|
||||||
|
|
||||||
|
|
||||||
// Specific interface parts
|
// Specific interface parts
|
||||||
|
|
|
@ -274,9 +274,9 @@ controls:
|
||||||
int dimLightness: colors.dimColoredTextIntensity
|
int dimLightness: colors.dimColoredTextIntensity
|
||||||
|
|
||||||
presence:
|
presence:
|
||||||
color online: hsluv(125, 100, 80, 1)
|
color online: colors.positiveText
|
||||||
color unavailable: hsluv(0, 100, 80, 1)
|
color unavailable: hsluv(0, 90, 35, 1)
|
||||||
color offline: hsluv(0, 0, 45, 1)
|
color offline: hsluv(0, 0, 30, 1)
|
||||||
color border: "black"
|
color border: "black"
|
||||||
real opacity: 1.0
|
real opacity: 1.0
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user