Change/Fix: (ement--room-unread-p) Ignore non-message events

Fixes #97.  Thanks to Julien Roy (@MrRoy) for reporting and testing.
This commit is contained in:
Adam Porter 2022-09-15 21:43:54 -05:00
parent ddd31da32e
commit 345bf71766
2 changed files with 23 additions and 9 deletions

View file

@ -282,6 +282,7 @@ Note that, while ~matrix-client~ remains usable, and probably will for some time
*Changes*
+ Read receipts are re-enabled. (They're now implemented with a global idle timer rather than ~window-scroll-functions~, which sometimes caused a strange race condition that could cause Emacs to become unresponsive or crash.)
+ When determining whether a room is considered unread, non-message events like membership changes, reactions, etc. are ignored. This fixes a bug that caused certain rooms that had no message events (like some bridged rooms) to appear as unread when they shouldn't have been. But it's unclear whether this is always preferable (e.g. one might want a member leaving a room to cause it to be marked unread), so this is classified as a change rather than simply a fix, and more improvements may be made to this in the future. (Fixes [[https://github.com/alphapapa/ement.el/issues/97][#97]]. Thanks to [[https://github.com/MrRoy][Julien Roy]] for reporting and testing.)
*Fixes*
+ Links to only rooms (as opposed to links to events in rooms) may be joined by activating them.

View file

@ -1035,33 +1035,46 @@ is not at the latest known message event."
;; (which apparently can happen, given user reports), it should not be
;; considered unread.
(cl-labels ((event-counts-toward-unread-p
(event) (not (member (ement-event-type event) '("m.room.member" "m.reaction")))))
;; NOTE: We only consider message events, so membership, reaction,
;; etc. events will not mark a room as unread. Ideally, I think
;; that join/leave events should, at least optionally, mark a room
;; as unread (e.g. in a 1:1 room with a friend, if the other user
;; left, one would probably want to know, and marking the room
;; unread would help the user notice), but since membership events
;; have to be processed to understand their meaning, it's not
;; straightforward to know whether one should mark a room unread.
;; FIXME: Use code from `ement-room--format-member-event' to
;; distinguish ones that should count.
(event) (equal "m.room.message" (ement-event-type event))))
(let ((our-read-receipt-event-id (car (gethash our-id receipts)))
(first-counting-event (cl-find-if #'event-counts-toward-unread-p timeline)))
(cond ((equal fully-read-event-id (ement-event-id (car timeline)))
;; The fully-read marker is at the last known event: not unread.
;; The fully-read marker is at the last known event: the room is read.
nil)
((and (not our-read-receipt-event-id)
(when first-counting-event
(and (not (equal fully-read-event-id (ement-event-id first-counting-event)))
(not (equal our-id (ement-user-id (ement-event-sender first-counting-event)))))))
;; A missing read-receipt failsafes to marking the
;; room unread, unless the fully-read marker is at
;; the latest counting event or we sent the latest
;; counting event.
;; The room has no read receipt, and the latest message event is not
;; the event at which our fully-read marker is at, and it is not sent
;; by us: the room is unread. (This is a kind of failsafe to ensure
;; the user doesn't miss any messages, but it's unclear whether this
;; is really correct or best.)
t)
((not (equal our-id (ement-user-id (ement-event-sender (car timeline)))))
;; If we sent the last event in the room, the room is not unread.
;; We sent the last event: the room is read.
nil)
((and first-counting-event
(equal our-id (ement-user-id (ement-event-sender first-counting-event))))
;; If we sent the last counting event in the room,
;; the room is not unread.
;; We sent the last message event: the room is read.
nil)
((cl-loop for event in timeline
when (event-counts-toward-unread-p event)
return (and (not (equal our-read-receipt-event-id (ement-event-id event)))
(not (equal fully-read-event-id (ement-event-id event)))))
;; The latest message event is not the event at which our
;; read-receipt or fully-read marker are at: the room is unread.
t))))))))
(defun ement--update-transaction-id (session)