branch: externals/ement commit b07b7c0da16d8b915865b5e04a32d87a715e2df7 Author: Adam Porter <a...@alphapapa.net> Commit: Adam Porter <a...@alphapapa.net>
Change/Fix: (ement-room-read-receipt-timer) When read receipt is unseen - Move function called by timer to a named function. - Send read receipt even if its position is outside the range of retrieved events. Otherwise, it could be so far back that it never gets updated, which doesn't seem useful. The fully-read marker remains unmoved until the user gets to the end of the room's events and marks them all as read, which seems right and useful. --- README.org | 1 + ement-room.el | 46 +++++++++++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/README.org b/README.org index 3a005c1700..50be3eff6a 100644 --- a/README.org +++ b/README.org @@ -274,6 +274,7 @@ Note that, while ~matrix-client~ remains usable, and probably will for some time *Fixed* + Read receipt-sending function was called too many times when scrolling. ++ Send read receipts even when the last receipt is outside the range of retrieved events. ** 0.1.2 diff --git a/ement-room.el b/ement-room.el index 5a142d31fc..a0c2bcb515 100644 --- a/ement-room.el +++ b/ement-room.el @@ -2452,25 +2452,33 @@ WINDOW's end is beyond the marker. For use in (let ((room-buffer (window-buffer window))) (setf ement-room-read-receipt-timer (run-with-idle-timer - 3 nil (lambda () - (when (and (windowp window) - (eq (window-buffer window) room-buffer)) - (with-selected-window window - (when-let ((read-receipt-node (ement-room--ewoc-last-matching ement-ewoc - (lambda (node-data) - (eq 'ement-room-read-receipt-marker node-data))))) - ;; The read-receipt marker is visible (i.e. it's not between - ;; earlier events which we have not retrieved). - (when (> (window-end) (ewoc-location read-receipt-node)) - ;; The window's end has been scrolled past the position of the receipt marker. - (when-let* ((window-end-node (or (ewoc-locate ement-ewoc (window-end)) - (ewoc-nth ement-ewoc -1))) - (event-node (cl-typecase (ewoc-data window-end-node) - (ement-event window-end-node) - (t (ement-room--ewoc-next-matching ement-ewoc window-end-node - #'ement-event-p #'ewoc-prev))))) - (ement-room-mark-read ement-room ement-session - :read-event (ewoc-data event-node)))))))))))))) + 3 nil #'ement-room-read-receipt-timer window room-buffer)))))) + +(defun ement-room-read-receipt-timer (window room-buffer) + "Send read receipt for WINDOW displaying ROOM-BUFFER. +To be called by timer run by +`ement-room-start-read-receipt-timer'." + (when (and (windowp window) + (eq (window-buffer window) room-buffer)) + (with-selected-window window + (let ((read-receipt-node (ement-room--ewoc-last-matching ement-ewoc + (lambda (node-data) + (eq 'ement-room-read-receipt-marker node-data))))) + (when (or + ;; The window's end has been scrolled to or past the position of the + ;; receipt marker. + (and read-receipt-node + (>= (window-end) (ewoc-location read-receipt-node))) + ;; The read receipt is outside of retrieved events. + (not read-receipt-node)) + (when-let* ((window-end-node (or (ewoc-locate ement-ewoc (window-end)) + (ewoc-nth ement-ewoc -1))) + (event-node (cl-typecase (ewoc-data window-end-node) + (ement-event window-end-node) + (t (ement-room--ewoc-next-matching ement-ewoc window-end-node + #'ement-event-p #'ewoc-prev))))) + (ement-room-mark-read ement-room ement-session + :read-event (ewoc-data event-node)))))))) (defun ement-room-goto-fully-read-marker () "Move to the fully-read marker in the current room."