-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ement Taxy Room List: Unread category is filled with read rooms #97
Comments
Hi Julien, Thanks for reporting this. Do those "unread" rooms have buffers opened for them? If so, please evaluate this function, refresh the room list, and see if they're still shown as unread: (defun ement--room-unread-p (room session)
"Return non-nil if ROOM is considered unread for SESSION.
The room is unread if it has a modified, live buffer; if it has
non-zero unread notification counts; or if its fully-read marker
is not at the latest known message event."
;; Roughly equivalent to the "red/gray/bold/idle" states listed in
;; <https://github.com/matrix-org/matrix-react-sdk/blob/b0af163002e8252d99b6d7075c83aadd91866735/docs/room-list-store.md#list-ordering-algorithm-importance>.
(pcase-let* (((cl-struct ement-room timeline account-data unread-notifications receipts
(local (map buffer)))
room)
((cl-struct ement-session user) session)
((cl-struct ement-user (id our-id)) user)
((map notification_count highlight_count) unread-notifications)
(fully-read-event-id (map-nested-elt (alist-get "m.fully_read" account-data nil nil #'equal)
'(content event_id))))
(or (and unread-notifications
(or (not (zerop notification_count))
(not (zerop highlight_count))))
;; NOTE: This is *WAY* too complicated, but it seems roughly equivalent to doesRoomHaveUnreadMessages() from
;; <https://github.com/matrix-org/matrix-react-sdk/blob/7fa01ffb068f014506041bce5f02df4f17305f02/src/Unread.ts#L52>.
(when timeline
;; A room should rarely, if ever, have a nil timeline, but in case it does
;; (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")))))
(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.
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.
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.
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.
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)))))
t)))))))) |
Thanks for the prompt response |
Ok, please evaluate this function: (defun test/ement--room-unread-p (room session)
"Return non-nil if ROOM is considered unread for SESSION.
The room is unread if it has a modified, live buffer; if it has
non-zero unread notification counts; or if its fully-read marker
is not at the latest known message event."
;; Roughly equivalent to the "red/gray/bold/idle" states listed in
;; <https://github.com/matrix-org/matrix-react-sdk/blob/b0af163002e8252d99b6d7075c83aadd91866735/docs/room-list-store.md#list-ordering-algorithm-importance>.
(pcase-let* (((cl-struct ement-room timeline account-data unread-notifications receipts
(local (map buffer)))
room)
((cl-struct ement-session user) session)
((cl-struct ement-user (id our-id)) user)
((map notification_count highlight_count) unread-notifications)
(fully-read-event-id (map-nested-elt (alist-get "m.fully_read" account-data nil nil #'equal)
'(content event_id))))
(or (and unread-notifications
(or (not (zerop notification_count))
(not (zerop highlight_count))))
;; NOTE: This is *WAY* too complicated, but it seems roughly equivalent to doesRoomHaveUnreadMessages() from
;; <https://github.com/matrix-org/matrix-react-sdk/blob/7fa01ffb068f014506041bce5f02df4f17305f02/src/Unread.ts#L52>.
(when timeline
;; A room should rarely, if ever, have a nil timeline, but in case it does
;; (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")))))
(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.
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)))))))
(message "test/ement--room-unread-p: FAILSAFE FOR ROOM:%S" (ement-room-display-name room))
;; 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.
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.
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.
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)))))
(message "test/ement--room-unread-p: FOUND EVENT FOR ROOM:%S" (ement-room-display-name room))
t)))))))) Then switch to one of the incorrectly marked rooms' buffers, and do |
I get the following messages:
|
Oops, sorry. Please do this: |
I get this output: |
Ok, I added another debug output that will show the event being found, please eval this function and repeat the test: ;; This buffer is for text that is not saved, and for Lisp evaluation.
;; To create a file, visit it with C-x C-f and enter text in its buffer.
(defun test/ement--room-unread-p (room session)
"Return non-nil if ROOM is considered unread for SESSION.
The room is unread if it has a modified, live buffer; if it has
non-zero unread notification counts; or if its fully-read marker
is not at the latest known message event."
;; Roughly equivalent to the "red/gray/bold/idle" states listed in
;; <https://github.com/matrix-org/matrix-react-sdk/blob/b0af163002e8252d99b6d7075c83aadd91866735/docs/room-list-store.md#list-ordering-algorithm-importance>.
(pcase-let* (((cl-struct ement-room timeline account-data unread-notifications receipts
(local (map buffer)))
room)
((cl-struct ement-session user) session)
((cl-struct ement-user (id our-id)) user)
((map notification_count highlight_count) unread-notifications)
(fully-read-event-id (map-nested-elt (alist-get "m.fully_read" account-data nil nil #'equal)
'(content event_id))))
(or (and unread-notifications
(or (not (zerop notification_count))
(not (zerop highlight_count))))
;; NOTE: This is *WAY* too complicated, but it seems roughly equivalent to doesRoomHaveUnreadMessages() from
;; <https://github.com/matrix-org/matrix-react-sdk/blob/7fa01ffb068f014506041bce5f02df4f17305f02/src/Unread.ts#L52>.
(when timeline
;; A room should rarely, if ever, have a nil timeline, but in case it does
;; (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")))))
(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.
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)))))))
(message "test/ement--room-unread-p: FAILSAFE FOR ROOM:%S" (ement-room-display-name room))
;; 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.
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.
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.
nil)
((cl-loop for event in timeline
when (event-counts-toward-unread-p event)
do (message "test/ement--room-unread-p: FOUND EVENT FOR ROOM:%S EVENT:%S" (ement-room-display-name room) event)
return (and (not (equal our-read-receipt-event-id (ement-event-id event)))
(not (equal fully-read-event-id (ement-event-id event)))))
t)))))))) |
In the room I ran it before (
Then, evaluating the command you sent me prints the following: |
Hm, this gets confusing. Please try this one: (defun test/ement--room-unread-p (room session)
"Return non-nil if ROOM is considered unread for SESSION.
The room is unread if it has a modified, live buffer; if it has
non-zero unread notification counts; or if its fully-read marker
is not at the latest known message event."
;; Roughly equivalent to the "red/gray/bold/idle" states listed in
;; <https://github.com/matrix-org/matrix-react-sdk/blob/b0af163002e8252d99b6d7075c83aadd91866735/docs/room-list-store.md#list-ordering-algorithm-importance>.
(pcase-let* (((cl-struct ement-room timeline account-data unread-notifications receipts
(local (map buffer)))
room)
((cl-struct ement-session user) session)
((cl-struct ement-user (id our-id)) user)
((map notification_count highlight_count) unread-notifications)
(fully-read-event-id (map-nested-elt (alist-get "m.fully_read" account-data nil nil #'equal)
'(content event_id))))
(or (and unread-notifications
(or (not (zerop notification_count))
(not (zerop highlight_count))))
;; NOTE: This is *WAY* too complicated, but it seems roughly equivalent to doesRoomHaveUnreadMessages() from
;; <https://github.com/matrix-org/matrix-react-sdk/blob/7fa01ffb068f014506041bce5f02df4f17305f02/src/Unread.ts#L52>.
(when timeline
;; A room should rarely, if ever, have a nil timeline, but in case it does
;; (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")))))
(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.
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)))))))
(message "test/ement--room-unread-p: FAILSAFE FOR ROOM:%S OUR-READ-RECEIPT-EVENT-ID:%S FIRST-COUNTING-EVENT:%S FULLY-READ-EVENT-ID:%S OUR-ID:%S"
(ement-room-display-name room) our-read-receipt-event-id first-counting-event fully-read-event-id our-id)
;; 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.
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.
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.
nil)
((cl-loop for event in timeline
when (event-counts-toward-unread-p event)
do (message "test/ement--room-unread-p: FOUND EVENT FOR ROOM:%S EVENT:%S" (ement-room-display-name room) event)
return (and (not (equal our-read-receipt-event-id (ement-event-id event)))
(not (equal fully-read-event-id (ement-event-id event)))))
t)))))))) |
Here's the output for one of the rooms:
Let me know if you want me to try it on more rooms |
Ok, please evaluate this function, refresh the room list, and see if the spuriously unread rooms are no longer unread: (defun ement--room-unread-p (room session)
"Return non-nil if ROOM is considered unread for SESSION.
The room is unread if it has a modified, live buffer; if it has
non-zero unread notification counts; or if its fully-read marker
is not at the latest known message event."
;; Roughly equivalent to the "red/gray/bold/idle" states listed in
;; <https://github.com/matrix-org/matrix-react-sdk/blob/b0af163002e8252d99b6d7075c83aadd91866735/docs/room-list-store.md#list-ordering-algorithm-importance>.
(pcase-let* (((cl-struct ement-room timeline account-data unread-notifications receipts
(local (map buffer)))
room)
((cl-struct ement-session user) session)
((cl-struct ement-user (id our-id)) user)
((map notification_count highlight_count) unread-notifications)
(fully-read-event-id (map-nested-elt (alist-get "m.fully_read" account-data nil nil #'equal)
'(content event_id))))
;; MAYBE: Ignore whether the buffer is modified. Since we have a better handle on how
;; Matrix does notifications/unreads/highlights, maybe that's not needed, and it would
;; be more consistent to ignore it.
(or (and buffer (buffer-modified-p buffer))
(and unread-notifications
(or (not (zerop notification_count))
(not (zerop highlight_count))))
;; NOTE: This is *WAY* too complicated, but it seems roughly equivalent to doesRoomHaveUnreadMessages() from
;; <https://github.com/matrix-org/matrix-react-sdk/blob/7fa01ffb068f014506041bce5f02df4f17305f02/src/Unread.ts#L52>.
(when timeline
;; A room should rarely, if ever, have a nil timeline, but in case it does
;; (which apparently can happen, given user reports), it should not be
;; considered unread.
(cl-labels ((event-counts-toward-unread-p
(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.
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.
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.
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.
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)))))
t)))))))) |
Yes! Well, mostly. I'm down to 9 rooms now. Much better now :) |
Doing |
Hello,
In the ement-taxy-room-list, I have 128 rooms which are present in the unread category, despite actually being read. When I open them and mark them as read using the space bar, it closes the room but the room stays in the unread category. Opening another Matrix client doesn't show these rooms as unread. Also, the 'unread' column is empty for those rooms.
![swappy-20220915_202239](https://user-images.githubusercontent.com/1154706/190530976-503c5440-90f2-467b-9b52-a8118a3adcb6.png)
The Messages buffer doesn't show anything when using these rooms, or marking them as read
Not sure if it is relevant, but all of these rooms are rooms created from Matrix bridges (Facebook and Telegram mainly), though I do have bridged rooms that aren't stuck in the unread category.
The text was updated successfully, but these errors were encountered: