Add a batch set_fields method to Model
This commit is contained in:
parent
5476e00b9b
commit
4752abf6e5
|
@ -301,13 +301,14 @@ class Backend:
|
||||||
|
|
||||||
async def update(client: MatrixClient) -> None:
|
async def update(client: MatrixClient) -> None:
|
||||||
room = self.models[client.user_id, "rooms"].get(room_id)
|
room = self.models[client.user_id, "rooms"].get(room_id)
|
||||||
local = room.local_unreads or room.local_highlights
|
|
||||||
|
|
||||||
if room and (room.unreads or room.highlights or local):
|
if room:
|
||||||
room.unreads = 0
|
room.set_fields(
|
||||||
room.highlights = 0
|
unreads = 0,
|
||||||
room.local_unreads = False
|
highlights = 0,
|
||||||
room.local_highlights = False
|
local_unreads = False,
|
||||||
|
local_highlights = False,
|
||||||
|
)
|
||||||
await client.update_account_unread_counts()
|
await client.update_account_unread_counts()
|
||||||
await client.update_receipt_marker(room_id, event_id)
|
await client.update_receipt_marker(room_id, event_id)
|
||||||
|
|
||||||
|
|
|
@ -354,9 +354,11 @@ class MatrixClient(nio.AsyncClient):
|
||||||
resp = await self.backend.get_profile(self.user_id, use_cache=False)
|
resp = await self.backend.get_profile(self.user_id, use_cache=False)
|
||||||
|
|
||||||
account = self.models["accounts"][self.user_id]
|
account = self.models["accounts"][self.user_id]
|
||||||
account.profile_updated = datetime.now()
|
account.set_fields(
|
||||||
account.display_name = resp.displayname or ""
|
profile_updated = datetime.now(),
|
||||||
account.avatar_url = resp.avatar_url or ""
|
display_name = resp.displayname or "",
|
||||||
|
avatar_url = resp.avatar_url or "",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def get_server_config(self) -> int:
|
async def get_server_config(self) -> int:
|
||||||
|
@ -528,8 +530,10 @@ class MatrixClient(nio.AsyncClient):
|
||||||
upload_item.uploaded = transferred
|
upload_item.uploaded = transferred
|
||||||
|
|
||||||
def on_speed_changed(speed: float) -> None:
|
def on_speed_changed(speed: float) -> None:
|
||||||
upload_item.speed = speed
|
upload_item.set_fields(
|
||||||
upload_item.time_left = monitor.remaining_time or timedelta(0)
|
speed = speed,
|
||||||
|
time_left = monitor.remaining_time or timedelta(0),
|
||||||
|
)
|
||||||
|
|
||||||
monitor.on_transferred = on_transferred
|
monitor.on_transferred = on_transferred
|
||||||
monitor.on_speed_changed = on_speed_changed
|
monitor.on_speed_changed = on_speed_changed
|
||||||
|
@ -548,9 +552,11 @@ class MatrixClient(nio.AsyncClient):
|
||||||
raise nio.TransferCancelledError()
|
raise nio.TransferCancelledError()
|
||||||
|
|
||||||
except (MatrixError, OSError) as err:
|
except (MatrixError, OSError) as err:
|
||||||
upload_item.status = UploadStatus.Error
|
upload_item.set_fields(
|
||||||
upload_item.error = type(err)
|
status = UploadStatus.Error,
|
||||||
upload_item.error_args = err.args
|
error = type(err),
|
||||||
|
error_args = err.args,
|
||||||
|
)
|
||||||
|
|
||||||
# Wait for cancellation from UI, see parent send_file() method
|
# Wait for cancellation from UI, see parent send_file() method
|
||||||
while True:
|
while True:
|
||||||
|
@ -605,9 +611,11 @@ class MatrixClient(nio.AsyncClient):
|
||||||
thumb_ext = "png" if thumb_info.mime == "image/png" else "jpg"
|
thumb_ext = "png" if thumb_info.mime == "image/png" else "jpg"
|
||||||
thumb_name = f"{path.stem}_thumbnail.{thumb_ext}"
|
thumb_name = f"{path.stem}_thumbnail.{thumb_ext}"
|
||||||
|
|
||||||
upload_item.status = UploadStatus.Uploading
|
upload_item.set_fields(
|
||||||
upload_item.filepath = Path(thumb_name)
|
status = UploadStatus.Uploading,
|
||||||
upload_item.total_size = len(thumb_data)
|
filepath = Path(thumb_name),
|
||||||
|
total_size = len(thumb_data),
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
upload_item.total_size = thumb_info.size
|
upload_item.total_size = thumb_info.size
|
||||||
|
@ -1385,10 +1393,12 @@ class MatrixClient(nio.AsyncClient):
|
||||||
local_highlights = True
|
local_highlights = True
|
||||||
|
|
||||||
account = self.models["accounts"][self.user_id]
|
account = self.models["accounts"][self.user_id]
|
||||||
account.total_unread = unreads
|
account.set_fields(
|
||||||
account.total_highlights = highlights
|
total_unread = unreads,
|
||||||
account.local_unreads = local_unreads
|
total_highlights = highlights,
|
||||||
account.local_highlights = local_highlights
|
local_unreads = local_unreads,
|
||||||
|
local_highlights = local_highlights,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def event_is_past(self, ev: Union[nio.Event, Event]) -> bool:
|
async def event_is_past(self, ev: Union[nio.Event, Event]) -> bool:
|
||||||
|
@ -1552,13 +1562,11 @@ class MatrixClient(nio.AsyncClient):
|
||||||
|
|
||||||
if not ev.sender_name and not ev.sender_avatar:
|
if not ev.sender_name and not ev.sender_avatar:
|
||||||
sender_name, sender_avatar, _ = await get_profile(ev.sender_id)
|
sender_name, sender_avatar, _ = await get_profile(ev.sender_id)
|
||||||
ev.sender_name = sender_name
|
ev.set_fields(sender_name=sender_name, sender_avatar=sender_avatar)
|
||||||
ev.sender_avatar = sender_avatar
|
|
||||||
|
|
||||||
if ev.target_id and not ev.target_name and not ev.target_avatar:
|
if ev.target_id and not ev.target_name and not ev.target_avatar:
|
||||||
target_name, target_avatar, _ = await get_profile(ev.target_id)
|
target_name, target_avatar, _ = await get_profile(ev.target_id)
|
||||||
ev.target_name = target_name
|
ev.set_fields(target_name=target_name, target_avatar=target_avatar)
|
||||||
ev.target_avatar = target_avatar
|
|
||||||
|
|
||||||
if ev.redacter_id and not ev.redacter_name:
|
if ev.redacter_id and not ev.redacter_name:
|
||||||
redacter_name, _, _ = await get_profile(ev.target_id)
|
redacter_name, _, _ = await get_profile(ev.target_id)
|
||||||
|
|
|
@ -33,32 +33,34 @@ class ModelItem:
|
||||||
def __setattr__(self, name: str, value) -> None:
|
def __setattr__(self, name: str, value) -> None:
|
||||||
"""If this item is in a `Model`, alert it of attribute changes."""
|
"""If this item is in a `Model`, alert it of attribute changes."""
|
||||||
|
|
||||||
if name == "parent_model" or not self.parent_model:
|
if (
|
||||||
|
name == "parent_model" or
|
||||||
|
not self.parent_model or
|
||||||
|
getattr(self, name) == value
|
||||||
|
):
|
||||||
super().__setattr__(name, value)
|
super().__setattr__(name, value)
|
||||||
return
|
return
|
||||||
|
|
||||||
if getattr(self, name) == value:
|
|
||||||
return
|
|
||||||
|
|
||||||
super().__setattr__(name, value)
|
super().__setattr__(name, value)
|
||||||
|
self._notify_parent_model({name: self.serialize_field(name)})
|
||||||
|
|
||||||
|
|
||||||
|
def _notify_parent_model(self, changed_fields: Dict[str, Any]) -> None:
|
||||||
parent = self.parent_model
|
parent = self.parent_model
|
||||||
|
|
||||||
if not parent.sync_id:
|
if not parent or not parent.sync_id or not changed_fields:
|
||||||
return
|
return
|
||||||
|
|
||||||
fields = {name: self.serialize_field(name)}
|
|
||||||
|
|
||||||
with parent.write_lock:
|
with parent.write_lock:
|
||||||
index_then = parent._sorted_data.index(self)
|
index_then = parent._sorted_data.index(self)
|
||||||
parent._sorted_data.sort()
|
parent._sorted_data.sort()
|
||||||
index_now = parent._sorted_data.index(self)
|
index_now = parent._sorted_data.index(self)
|
||||||
|
|
||||||
ModelItemSet(parent.sync_id, index_then, index_now, fields)
|
ModelItemSet(parent.sync_id, index_then, index_now, changed_fields)
|
||||||
|
|
||||||
for sync_id, proxy in parent.proxies.items():
|
for sync_id, proxy in parent.proxies.items():
|
||||||
if sync_id != parent.sync_id:
|
if sync_id != parent.sync_id:
|
||||||
proxy.source_item_set(parent, self.id, self, fields)
|
proxy.source_item_set(parent, self.id, self, changed_fields)
|
||||||
|
|
||||||
|
|
||||||
def __delattr__(self, name: str) -> None:
|
def __delattr__(self, name: str) -> None:
|
||||||
|
@ -82,3 +84,20 @@ class ModelItem:
|
||||||
name.startswith("_") or name in ("parent_model", "serialized")
|
name.startswith("_") or name in ("parent_model", "serialized")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def set_fields(self, **fields: Any) -> None:
|
||||||
|
"""Set multiple fields's values at once.
|
||||||
|
|
||||||
|
The parent model will be resorted only once, and one `ModelItemSet`
|
||||||
|
event will be sent informing QML of all the changed fields.
|
||||||
|
"""
|
||||||
|
|
||||||
|
for name, value in fields.copy().items():
|
||||||
|
if getattr(self, name) == value:
|
||||||
|
del fields[name]
|
||||||
|
else:
|
||||||
|
super().__setattr__(name, value)
|
||||||
|
fields[name] = self.serialize_field(name)
|
||||||
|
|
||||||
|
self._notify_parent_model(fields)
|
||||||
|
|
|
@ -388,9 +388,11 @@ class NioCallbacks:
|
||||||
account = self.models["accounts"][self.user_id]
|
account = self.models["accounts"][self.user_id]
|
||||||
|
|
||||||
if account.profile_updated < ev_date:
|
if account.profile_updated < ev_date:
|
||||||
account.profile_updated = ev_date
|
account.set_fields(
|
||||||
account.display_name = now.get("displayname") or ""
|
profile_updated = ev_date,
|
||||||
account.avatar_url = now.get("avatar_url") or ""
|
display_name = now.get("displayname") or "",
|
||||||
|
avatar_url = now.get("avatar_url") or "",
|
||||||
|
)
|
||||||
|
|
||||||
if self.client.backend.ui_settings["hideProfileChangeEvents"]:
|
if self.client.backend.ui_settings["hideProfileChangeEvents"]:
|
||||||
return None
|
return None
|
||||||
|
@ -568,6 +570,8 @@ class NioCallbacks:
|
||||||
member = model.get(receipt.user_id)
|
member = model.get(receipt.user_id)
|
||||||
|
|
||||||
if member:
|
if member:
|
||||||
member.last_read_event = receipt.event_id
|
|
||||||
timestamp = receipt.timestamp / 1000
|
timestamp = receipt.timestamp / 1000
|
||||||
member.last_read_at = datetime.fromtimestamp(timestamp)
|
member.set_fields(
|
||||||
|
last_read_event = receipt.event_id,
|
||||||
|
last_read_at = datetime.fromtimestamp(timestamp),
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user