Make EditAccount show a spinner until ready
Instead of crashing if userInfo is not yet available. statusMessage is removed for now from UserUpdated events, and the users model items will have a "loading" property.
This commit is contained in:
parent
71f78feec6
commit
853bb350b4
|
@ -3,7 +3,7 @@
|
|||
|
||||
import asyncio
|
||||
import random
|
||||
from typing import Dict, Optional, Set, Tuple
|
||||
from typing import Any, Dict, Optional, Set, Tuple
|
||||
|
||||
from .app import App
|
||||
from .events import users
|
||||
|
@ -18,6 +18,7 @@ class Backend:
|
|||
from . import config_files
|
||||
self.saved_accounts = config_files.Accounts(self)
|
||||
self.ui_settings = config_files.UISettings(self)
|
||||
self.ui_state = config_files.UIState(self)
|
||||
|
||||
self.clients: Dict[str, MatrixClient] = {}
|
||||
|
||||
|
@ -92,7 +93,14 @@ class Backend:
|
|||
|
||||
# General functions
|
||||
|
||||
async def load_settings(self) -> Tuple[Dict[str, Any], ...]:
|
||||
return (await self.ui_settings.read(), await self.ui_state.read())
|
||||
|
||||
|
||||
async def request_user_update_event(self, user_id: str) -> None:
|
||||
if not self.clients:
|
||||
return
|
||||
|
||||
client = self.clients.get(
|
||||
user_id,
|
||||
random.choice(tuple(self.clients.values()))
|
||||
|
|
|
@ -18,7 +18,7 @@ WRITE_LOCK = asyncio.Lock()
|
|||
|
||||
@dataclass
|
||||
class ConfigFile:
|
||||
backend: Backend = field()
|
||||
backend: Backend = field(repr=False)
|
||||
filename: str = field()
|
||||
use_data_dir: bool = False
|
||||
|
||||
|
|
|
@ -29,8 +29,6 @@ class UserUpdated(Event):
|
|||
user_id: str = field()
|
||||
display_name: str = ""
|
||||
avatar_url: str = ""
|
||||
status_message: str = ""
|
||||
|
||||
|
||||
@classmethod
|
||||
def from_nio(cls, user: MatrixUser) -> "UserUpdated":
|
||||
|
|
|
@ -131,7 +131,6 @@ class MatrixClient(nio.AsyncClient):
|
|||
async def request_user_update_event(self, user_id: str) -> None:
|
||||
if user_id in self.backend.pending_profile_requests:
|
||||
return
|
||||
print("Requesting profile for", user_id)
|
||||
self.backend.pending_profile_requests.add(user_id)
|
||||
|
||||
response = await self.get_profile(user_id)
|
||||
|
@ -143,7 +142,6 @@ class MatrixClient(nio.AsyncClient):
|
|||
user_id = user_id,
|
||||
display_name = getattr(response, "displayname", "") or "",
|
||||
avatar_url = getattr(response, "avatar_url", "") or "",
|
||||
status_message = "", # TODO
|
||||
)
|
||||
|
||||
self.backend.pending_profile_requests.discard(user_id)
|
||||
|
|
4
src/qml/Base/HBusyIndicator.qml
Normal file
4
src/qml/Base/HBusyIndicator.qml
Normal file
|
@ -0,0 +1,4 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
BusyIndicator {}
|
|
@ -11,8 +11,8 @@ function onAccountDeleted(userId) {
|
|||
accounts.popWhere({userId}, 1)
|
||||
}
|
||||
|
||||
function onUserUpdated(userId, displayName, avatarUrl, statusMessage) {
|
||||
users.upsert({userId}, {userId, displayName, avatarUrl, statusMessage})
|
||||
function onUserUpdated(userId, displayName, avatarUrl) {
|
||||
users.upsert({userId}, {userId, displayName, avatarUrl, loading: false})
|
||||
}
|
||||
|
||||
function onDeviceUpdated(userId, deviceId, ed25519Key, trust, displayName,
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
// This file is part of harmonyqml, licensed under LGPLv3.
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import "Base"
|
||||
|
||||
Rectangle {
|
||||
color: "lightgray"
|
||||
|
||||
BusyIndicator {
|
||||
HBusyIndicator {
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ HListModel {
|
|||
userId,
|
||||
displayName: "",
|
||||
avatarUrl: "",
|
||||
statusMessage: "",
|
||||
loading: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,17 @@ HPage {
|
|||
|
||||
property string userId: ""
|
||||
readonly property var userInfo: users.find(userId)
|
||||
readonly property bool ready: userInfo && ! userInfo.loading
|
||||
|
||||
hideHeaderUnderHeight: avatarPreferredSize
|
||||
headerLabel.text: qsTr("Account settings for %1")
|
||||
.arg(Utils.coloredNameHtml(userInfo.displayName, userId))
|
||||
headerLabel.text:
|
||||
qsTr("Account settings for %1").arg(
|
||||
Utils.coloredNameHtml(userInfo ? userInfo.displayName : "", userId)
|
||||
)
|
||||
|
||||
HRectangle {
|
||||
color: theme.box.background
|
||||
color: ready ? theme.box.background : "transparent"
|
||||
Behavior on color { HColorAnimation {} }
|
||||
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
|
@ -31,18 +35,9 @@ HPage {
|
|||
|
||||
Layout.preferredHeight: childrenRect.height
|
||||
|
||||
Profile { width: parent.width }
|
||||
Loader {
|
||||
width: parent.width
|
||||
source: ready ? "Profile.qml" : "../../Base/HBusyIndicator.qml"
|
||||
}
|
||||
}
|
||||
|
||||
// HRectangle {
|
||||
// color: theme.box.background
|
||||
// radius: theme.box.radius
|
||||
// ClientSettings { width: parent.width }
|
||||
// }
|
||||
|
||||
// HRectangle {
|
||||
// color: theme.box.background
|
||||
// radius: theme.box.radius
|
||||
// Devices { width: parent.width }
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@ Python {
|
|||
call("APP.call_client_coro", [accountId, name, uuid, args])
|
||||
}
|
||||
|
||||
function saveSettings(callback=null) {
|
||||
function saveConfig(backend_attribute, data, callback=null) {
|
||||
if (! py.ready) { return } // config not loaded yet
|
||||
callCoro("ui_settings.write", [window.settings], callback)
|
||||
callCoro(backend_attribute + ".write", [data], callback)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
|
@ -51,8 +51,9 @@ Python {
|
|||
call("APP.is_debug_on", [Qt.application.arguments], on => {
|
||||
window.debug = on
|
||||
|
||||
callCoro("ui_settings.read", [], settings => {
|
||||
callCoro("load_settings", [], ([settings, uiState]) => {
|
||||
window.settings = settings
|
||||
window.uiState = uiState
|
||||
|
||||
callCoro("saved_accounts.any_saved", [], any => {
|
||||
py.ready = true
|
||||
|
|
|
@ -53,7 +53,7 @@ Column {
|
|||
visible: false // TODO
|
||||
|
||||
id: statusEdit
|
||||
text: userInfo.statusMessage
|
||||
// text: userInfo.statusMessage
|
||||
placeholderText: qsTr("Set status message")
|
||||
font.pixelSize: theme.fontSize.small
|
||||
background: null
|
||||
|
|
|
@ -14,8 +14,8 @@ Item {
|
|||
Connections {
|
||||
target: py
|
||||
onWillLoadAccounts: will => {
|
||||
pageStack.showPage(will ? "Default": "SignIn")
|
||||
// if (will) { initialRoomTimer.start() }
|
||||
if (! will) { pageStack.showPage("SignIn") }
|
||||
pageStack.show(window.uiState.page)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,33 +60,17 @@ Item {
|
|||
id: pageStack
|
||||
property bool isWide: width > theme.contentIsWideAbove
|
||||
|
||||
function show(componentUrl, properties={}) {
|
||||
pageStack.replace(componentUrl, properties)
|
||||
}
|
||||
|
||||
function showPage(name, properties={}) {
|
||||
pageStack.replace("Pages/" + name + ".qml", properties)
|
||||
show("Pages/" + name + ".qml", properties)
|
||||
}
|
||||
|
||||
function showRoom(userId, category, roomId) {
|
||||
let info = rooms.getWhere({userId, roomId, category}, 1)[0]
|
||||
pageStack.replace("Chat/Chat.qml", {"roomInfo": info})
|
||||
}
|
||||
|
||||
Timer {
|
||||
// TODO: remove this, debug
|
||||
id: initialRoomTimer
|
||||
interval: 4000
|
||||
repeat: false
|
||||
// onTriggered: pageStack.showRoom(
|
||||
// "@test_mary:matrix.org",
|
||||
// "Rooms",
|
||||
// "!TSXGsbBbdwsdylIOJZ:matrix.org" // st
|
||||
// "!VDSsFIzQnXARSCVNxS:matrix.org" // hs
|
||||
// "!XhxUcnVhVhUHkBZEIL:matrix.org" // nc
|
||||
// "Invites",
|
||||
// "!xjqvLOGhMVutPXpAqi:matrix.org"
|
||||
// )
|
||||
onTriggered: pageStack.showPage(
|
||||
"EditAccount/EditAccount",
|
||||
{"userId": "@test_mary:matrix.org"}
|
||||
)
|
||||
show("Chat/Chat.qml", {"roomInfo": info})
|
||||
}
|
||||
|
||||
onCurrentItemChanged: if (currentItem) {
|
||||
|
|
|
@ -27,9 +27,12 @@ ApplicationWindow {
|
|||
property bool debug: false
|
||||
property bool ready: false
|
||||
|
||||
// Note: window.settingsChanged() must be called manually
|
||||
// Note: settingsChanged(), uiStateChanged(), etc must be called manually
|
||||
property var settings: ({})
|
||||
onSettingsChanged: py.saveSettings()
|
||||
onSettingsChanged: py.saveConfig("ui_settings", settings)
|
||||
|
||||
property var uiState: ({})
|
||||
onUiStateChanged: py.saveConfig("ui_state", uiState)
|
||||
|
||||
Theme { id: theme }
|
||||
Shortcuts { id: shortcuts}
|
||||
|
|
Loading…
Reference in New Issue
Block a user