diff --git a/src/backend/matrix_client.py b/src/backend/matrix_client.py index 7aca3d98..279019ce 100644 --- a/src/backend/matrix_client.py +++ b/src/backend/matrix_client.py @@ -2078,6 +2078,7 @@ class MatrixClient(nio.AsyncClient): target_avatar = target_avatar, links = Event.parse_links(content), last_read_by = last_read_by, + read_by_count = len(last_read_by), fetch_profile = (must_fetch_sender or must_fetch_target) diff --git a/src/backend/models/items.py b/src/backend/models/items.py index c7be827a..53d42a71 100644 --- a/src/backend/models/items.py +++ b/src/backend/models/items.py @@ -332,6 +332,7 @@ class Event(ModelItem): # {user_id: server_timestamp} - QML can't parse dates from JSONified dicts last_read_by: Dict[str, int] = field(default_factory=dict) + read_by_count: int = 0 is_local_echo: bool = False source: Optional[nio.Event] = None diff --git a/src/backend/nio_callbacks.py b/src/backend/nio_callbacks.py index 97ce1a50..e79c2a23 100644 --- a/src/backend/nio_callbacks.py +++ b/src/backend/nio_callbacks.py @@ -734,6 +734,7 @@ class NioCallbacks: event_model = self.models[self.user_id, room.room_id, "events"] unassigned_mems = self.client.unassigned_member_last_read_event unassigned_evs = self.client.unassigned_event_last_read_by + recount_markers = [] for receipt in ev.receipts: if receipt.user_id in self.client.backend.clients: @@ -747,6 +748,7 @@ class NioCallbacks: timestamp = receipt.timestamp if read_event: + recount_markers.append(read_event) read_event.last_read_by[receipt.user_id] = timestamp read_event.notify_change("last_read_by") else: @@ -764,11 +766,15 @@ class NioCallbacks: if previous_read_event: # Remove the read marker from the previous last read event + recount_markers.append(previous_read_event) previous_read_event.last_read_by.pop(receipt.user_id, None) previous_read_event.notify_change("last_read_by") member.last_read_event = echo_id or receipt.event_id + for ev in recount_markers: + ev.read_by_count = len(ev.last_read_by) + # Presence event callbacks diff --git a/src/gui/Pages/Chat/Timeline/EventContent.qml b/src/gui/Pages/Chat/Timeline/EventContent.qml index 0eb321b6..2867118e 100644 --- a/src/gui/Pages/Chat/Timeline/EventContent.qml +++ b/src/gui/Pages/Chat/Timeline/EventContent.qml @@ -34,10 +34,14 @@ HRowLayout { ) property string contentText: utils.processedEventText(model) readonly property string timeText: utils.formatTime(model.date, false) - readonly property string localEchoText: - model.is_local_echo ? - ` ` : - "" + + readonly property string readInfoText: + `` + ( + model.is_local_echo ? ` ⏳` : + model.read_by_count ? ` ⦿ ${model.read_by_count}` : + "" + ) + "" readonly property bool pureMedia: ! contentText && linksRepeater.count @@ -166,9 +170,7 @@ HRowLayout { timeText + "" + - // Local echo icon - (model.is_local_echo ? - ` ` : "") + readInfoText transform: Translate { x: xOffset } @@ -315,7 +317,7 @@ HRowLayout { mediaUrl: modelData showSender: pureMedia ? senderText : "" showDate: pureMedia ? timeText : "" - showLocalEcho: pureMedia ? localEchoText : "" + showLocalEcho: pureMedia ? readInfoText : "" transform: Translate { x: xOffset }