[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/ement 24320f23af 1/5: Fix sender header insertion with
|
From: |
ELPA Syncer |
|
Subject: |
[elpa] externals/ement 24320f23af 1/5: Fix sender header insertion with respect to membership changes |
|
Date: |
Sun, 14 Jan 2024 07:11:05 -0500 (EST) |
branch: externals/ement
commit 24320f23af15c59a53327eda8ea5b1de974b716f
Author: Steven Allen <steven@stebalien.com>
Commit: Adam Porter <adam@alphapapa.net>
Fix sender header insertion with respect to membership changes
Only insert a sender header if the previous message is from a different
sender, and there is no sender header between the current message and
the previous message.
While the previous version of this function explicitly skipped the read
marker, this version searches for known events (messages and sender
headers), skipping everything it doesn't understand. This should make it
robust to adding new events, widgets, etc.
fixes #157
Fix new event insertion with respect to sender headers
Only skip over the read marker, don't skip over sender headers.
Make sender headers robust
1. Widen the "fixup" range to the next message after the end-node.
2. Simplify the loop logic.
3. Fixup incorrect sender headers.
---
ement-room.el | 97 ++++++++++++++++++++++++-----------------------------------
1 file changed, 40 insertions(+), 57 deletions(-)
diff --git a/ement-room.el b/ement-room.el
index ff4ecd73ea..dde1baf556 100644
--- a/ement-room.el
+++ b/ement-room.el
@@ -3014,63 +3014,43 @@ the first and last nodes in the buffer, respectively."
"Insert sender headers into EWOC.
Inserts headers between START-NODE and END-NODE, which default to
the first and last nodes in the buffer, respectively."
- (cl-labels ((read-marker-p (data)
- (member data '(ement-room-fully-read-marker
- ement-room-read-receipt-marker)))
- (message-event-p (data)
- (and (ement-event-p data)
- (equal "m.room.message" (ement-event-type data))))
- (insert-sender-before (node)
- (ewoc-enter-before ewoc node (ement-event-sender (ewoc-data
node)))))
- (let* ((event-node (if (ement-event-p (ewoc-data start-node))
- start-node
- (ement-room--ewoc-next-matching ewoc start-node
- #'ement-event-p)))
- (prev-node (when event-node
- ;; Just in case...
- (ewoc-prev ewoc event-node))))
- (while (and event-node
- ;; I don't like looking up the location of these nodes on
every loop
- ;; iteration, but it seems like the only reliable way to
determine
- ;; whether we've reached the end node. However, when this
function is
- ;; called for short batches of events (or even a single
event, like when
- ;; called from `ement-room--insert-event'), the overhead
should be
- ;; minimal.
- (<= (ewoc-location event-node) (ewoc-location end-node)))
- (when (message-event-p (ewoc-data event-node))
- (if (not prev-node)
- ;; No previous node and event is a message: insert header.
- (insert-sender-before event-node)
- ;; Previous node exists.
- (when (read-marker-p (ewoc-data prev-node))
- ;; Previous node is a read marker: we want to act as if they
don't exist, so
- ;; we set `prev-node' to the non-marker node before it.
- (setf prev-node (ement-room--ewoc-next-matching ewoc prev-node
- (lambda (data)
- (not (read-marker-p data)))
- #'ewoc-prev)))
- (when prev-node
- ;; A previous node still exists: maybe we need to add a header.
- (cl-typecase (ewoc-data prev-node)
- (ement-event
- ;; Previous node is an event.
- (when (and (message-event-p (ewoc-data prev-node))
- (not (equal (ement-event-sender (ewoc-data
prev-node))
- (ement-event-sender (ewoc-data
event-node)))))
- ;; Previous node is a message event with a different
sender: insert
- ;; header.
- (insert-sender-before event-node)))
- ((or ement-user ement-room-membership-events)
- ;; Previous node is a user or coalesced membership events: do
not insert
- ;; header.
- nil)
- (t
- ;; Previous node is not an event and not a read marker:
insert header.
- (insert-sender-before event-node))))))
+ (cl-labels ((message-event-p
+ (data) (and (ement-event-p data)
+ (equal "m.room.message" (ement-event-type data)))))
+ ;; If we're not starting at a message node, forward to the previous
message.
+ ;; If we don't find any messages, there's nothing to do anyways.
+ (when (and start-node (not (message-event-p (ewoc-data start-node))))
+ (setf start-node (ement-room--ewoc-next-matching ewoc start-node
#'message-event-p)))
+
+ ;; Set the end node to the next message after the end node, if any. This:
+ ;; 1. Makes the loop check simple (we continue going until we run out of
nodes or our
+ ;; we find the end node).
+ ;; 2. Ensures we fix up sender headers after any inserted messages.
+ (when end-node
+ (setf end-node (ement-room--ewoc-next-matching ewoc end-node
#'message-event-p)))
+
+ (let* ((event-node start-node) prev-node)
+ (while (and event-node (not (eq event-node end-node)))
+ ;; Scan back for the previous message or user header, if any.
+ (setf prev-node (ement-room--ewoc-next-matching ewoc event-node
+ (lambda (data)
+ (or (ement-user-p data) (message-event-p data)))
+ #'ewoc-prev))
+
+ (let ((sender (ement-event-sender (ewoc-data event-node))))
+ (cond
+ ;; No previous message/sender, insert a sender.
+ ((not prev-node) (ewoc-enter-before ewoc event-node sender))
+ ;; We have a previous sender, but it's wrong. Fix it.
+ ((ement-user-p (ewoc-data prev-node))
+ (unless (equal sender (ewoc-data prev-node))
+ (ewoc-set-data prev-node sender)))
+ ;; Otherwise, it's a message. Insert a sender if it's from a
different user.
+ ((not (equal sender (ement-event-sender (ewoc-data prev-node))))
+ (ewoc-enter-before ewoc event-node sender))))
+
(setf event-node (ement-room--ewoc-next-matching ewoc event-node
- #'ement-event-p)
- prev-node (when event-node
- (ewoc-prev ewoc event-node)))))))
+ #'message-event-p))))))
(defun ement-room--coalesce-nodes (a b ewoc)
"Try to coalesce events in nodes A and B in EWOC.
@@ -3118,6 +3098,9 @@ Search starts from node START and moves by NEXT."
((pred ement-event-p) t)
((pred ement-room-membership-events-p) t)
(`(ts . ,_) t)))
+ (read-marker-p
+ (data) (member data '(ement-room-fully-read-marker
+ ement-room-read-receipt-marker)))
(node-ts (data)
(pcase data
((pred ement-event-p) (ement-event-origin-server-ts data))
@@ -3137,7 +3120,7 @@ Search starts from node START and moves by NEXT."
;; HACK: Insert after any read markers.
(cl-loop for node-after-node-before = (ewoc-next ewoc event-node-before)
while node-after-node-before
- while (not (ement-event-p (ewoc-data node-after-node-before)))
+ while (read-marker-p (ewoc-data node-after-node-before))
do (setf event-node-before node-after-node-before))
(setf new-node (if (not event-node-before)
(progn
- [elpa] externals/ement updated (c8fa9444cd -> 4a25cc0991), ELPA Syncer, 2024/01/14
- [elpa] externals/ement eec3327149 4/5: Docs: Update changelog, ELPA Syncer, 2024/01/14
- [elpa] externals/ement 24320f23af 1/5: Fix sender header insertion with respect to membership changes,
ELPA Syncer <=
- [elpa] externals/ement a9d9d230eb 3/5: Tidy: Formatting, comments, ELPA Syncer, 2024/01/14
- [elpa] externals/ement 4a25cc0991 5/5: Merge: (ement-room--insert-sender-headers) Refactor/fix, ELPA Syncer, 2024/01/14
- [elpa] externals/ement eed5f27942 2/5: Tidy: Indentation, ELPA Syncer, 2024/01/14