Add account presences to account context menu
This commit is contained in:
parent
6e202c3e27
commit
0eda6eb278
|
@ -18,14 +18,11 @@ from .matrix_client import MatrixClient
|
|||
from .media_cache import MediaCache
|
||||
from .models import SyncId
|
||||
from .models.filters import FieldSubstringFilter
|
||||
from .models.items import Account
|
||||
from .models.items import Account, Presence
|
||||
from .models.model import Model
|
||||
from .models.model_store import ModelStore
|
||||
from .user_files import Accounts, History, Theme, UISettings, UIState
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .models.items import Presence
|
||||
|
||||
# Logging configuration
|
||||
log.getLogger().setLevel(log.INFO)
|
||||
nio.logger_group.level = nio.log.logbook.ERROR
|
||||
|
@ -112,7 +109,7 @@ class Backend:
|
|||
|
||||
self.media_cache: MediaCache = MediaCache(self, cache_dir)
|
||||
|
||||
self.presences: Dict[str, "Presence"] = {}
|
||||
self.presences: Dict[str, Presence] = {}
|
||||
|
||||
|
||||
def __repr__(self) -> str:
|
||||
|
@ -154,7 +151,12 @@ class Backend:
|
|||
) + 1
|
||||
|
||||
self.clients[client.user_id] = client
|
||||
self.models["accounts"][client.user_id] = Account(client.user_id,order)
|
||||
self.models["accounts"][client.user_id] = Account(
|
||||
client.user_id,
|
||||
order,
|
||||
presence = Presence.State.online,
|
||||
)
|
||||
|
||||
return client.user_id
|
||||
|
||||
|
||||
|
@ -165,6 +167,7 @@ class Backend:
|
|||
device_id: str,
|
||||
homeserver: str = "https://matrix.org",
|
||||
order: int = -1,
|
||||
presence: str = "online",
|
||||
) -> None:
|
||||
"""Create and register a `MatrixClient` with known account details."""
|
||||
|
||||
|
@ -176,7 +179,7 @@ class Backend:
|
|||
self.clients[user_id] = client
|
||||
self.models["accounts"][user_id] = Account(user_id, order)
|
||||
|
||||
await client.resume(user_id=user_id, token=token, device_id=device_id)
|
||||
await client.resume(user_id, token, device_id, presence)
|
||||
|
||||
|
||||
async def load_saved_accounts(self) -> List[str]:
|
||||
|
@ -189,6 +192,7 @@ class Backend:
|
|||
device_id = info["device_id"],
|
||||
homeserver = info["homeserver"],
|
||||
order = info.get("order", -1),
|
||||
presence = info.get("presence", "online"),
|
||||
)
|
||||
return user_id
|
||||
|
||||
|
|
|
@ -237,15 +237,23 @@ class MatrixClient(nio.AsyncClient):
|
|||
await super().login(
|
||||
password, device_name or self.default_device_name(),
|
||||
)
|
||||
|
||||
self.start_task = asyncio.ensure_future(self._start())
|
||||
|
||||
|
||||
async def resume(self, user_id: str, token: str, device_id: str) -> None:
|
||||
async def resume(
|
||||
self,
|
||||
user_id: str,
|
||||
token: str,
|
||||
device_id: str,
|
||||
presence: str = "online",
|
||||
) -> None:
|
||||
"""Login to the server using an existing access token."""
|
||||
|
||||
response = nio.LoginResponse(user_id, device_id, token)
|
||||
await self.receive_response(response)
|
||||
|
||||
await self.set_presence(presence)
|
||||
self.start_task = asyncio.ensure_future(self._start())
|
||||
|
||||
|
||||
|
@ -1209,6 +1217,16 @@ class MatrixClient(nio.AsyncClient):
|
|||
await self.set_avatar(mxc)
|
||||
|
||||
|
||||
async def set_presence(self, presence: str) -> None:
|
||||
"""Set presence state for this account."""
|
||||
|
||||
await super().set_presence("offline" if presence == "invisible"
|
||||
else presence)
|
||||
self.models["accounts"][self.user].presence = Presence.State(presence)
|
||||
|
||||
await self.backend.saved_accounts.add(self.user)
|
||||
|
||||
|
||||
async def import_keys(self, infile: str, passphrase: str) -> None:
|
||||
"""Import decryption keys from a file, then retry decrypting events."""
|
||||
|
||||
|
|
|
@ -35,9 +35,15 @@ class Presence():
|
|||
offline = auto() # can mean offline, invisible or unknwon
|
||||
unavailable = auto()
|
||||
online = auto()
|
||||
invisible = auto()
|
||||
|
||||
def __lt__(self, other: "Presence.State") -> bool:
|
||||
order = [self.online, self.unavailable, self.offline]
|
||||
order = [
|
||||
self.online,
|
||||
self.unavailable,
|
||||
self.invisible,
|
||||
self.offline,
|
||||
]
|
||||
|
||||
return (
|
||||
order.index(self) # type: ignore
|
||||
|
@ -45,9 +51,9 @@ class Presence():
|
|||
order.index(other) # type: ignore
|
||||
)
|
||||
|
||||
last_active_ago: int = -1
|
||||
status_msg: str = ""
|
||||
presence: State = State.offline
|
||||
last_active_ago: int = -1
|
||||
currently_active: bool = False
|
||||
|
||||
|
||||
|
@ -67,6 +73,8 @@ class Account(ModelItem):
|
|||
local_unreads: bool = False
|
||||
local_highlights: bool = False
|
||||
|
||||
presence: Presence.State = Presence.State.offline
|
||||
|
||||
def __lt__(self, other: "Account") -> bool:
|
||||
"""Sort by order, then by user ID."""
|
||||
return (self.order, self.id.lower()) < (other.order, other.id.lower())
|
||||
|
|
|
@ -192,6 +192,7 @@ class Accounts(JSONDataFile):
|
|||
"token": client.access_token,
|
||||
"device_id": client.device_id,
|
||||
"enabled": True,
|
||||
"presence": client._presence or "online",
|
||||
"order": max([
|
||||
account.get("order", i)
|
||||
for i, account in enumerate(saved.values())
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import Clipboard 0.1
|
||||
import "../Base"
|
||||
|
||||
HMenu {
|
||||
property string userId
|
||||
property string presence
|
||||
property bool firstSyncDone
|
||||
|
||||
|
||||
function setPresence(presence) {
|
||||
py.callClientCoro(userId, "set_presence", [presence])
|
||||
}
|
||||
|
||||
|
||||
HMenuItem {
|
||||
|
@ -36,4 +44,38 @@ 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 {
|
||||
enabled: presence !== "unavailable" && firstSyncDone
|
||||
icon.name: "user-presence"
|
||||
icon.color: theme.controls.presence.unavailable
|
||||
text: qsTr("Unavailable")
|
||||
onTriggered: setPresence("unavailable")
|
||||
}
|
||||
|
||||
HMenuItem {
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,7 @@ HTile {
|
|||
radius: theme.mainPane.listView.account.avatarRadius
|
||||
compact: account.compact
|
||||
|
||||
// XXX
|
||||
presence: model.first_sync_done ? "online" : ""
|
||||
presence: model.presence
|
||||
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
|
@ -136,7 +135,11 @@ HTile {
|
|||
}
|
||||
}
|
||||
|
||||
contextMenu: AccountContextMenu { userId: model.id }
|
||||
contextMenu: AccountContextMenu {
|
||||
userId: model.id
|
||||
presence: model.presence
|
||||
firstSyncDone: model.first_sync_done
|
||||
}
|
||||
|
||||
|
||||
property bool enableKeybinds: false
|
||||
|
|
39
src/icons/thin/user-presence.svg
Normal file
39
src/icons/thin/user-presence.svg
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?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>
|
After Width: | Height: | Size: 706 B |
Loading…
Reference in New Issue
Block a user