Skip to content

Commit

Permalink
Fix: Quote event being replied to in original message for a reply
Browse files Browse the repository at this point in the history
If message A replies to message R, and message A is edited to message
B, now correctly include message R in message B too.

* ement-room.el (ement-room--format-message-body): Check for original
event's m.in_reply_to event ID for potential quotation.
(ement-room--rich-reply-callback): Factor out the callback function
again.
  • Loading branch information
Visuwesh authored and Phil Sainty committed Oct 20, 2024
1 parent 0ff4210 commit 5a07545
Showing 1 changed file with 27 additions and 13 deletions.
40 changes: 27 additions & 13 deletions ement-room.el
Original file line number Diff line number Diff line change
Expand Up @@ -4120,26 +4120,26 @@ If FORMATTED-P, return the formatted body content, when available."
nil
(format "[unsupported msgtype: %s]" msgtype)))))
(event-replied-to))
;; This is an edit event and this doesn't have the quoted event ID in m.relates_to,
;; only the message being edited (even if it is an edit of an edit)
(when (and (equal rel-type "m.replace") (null replied-to-event-id))
;; The original event is already fetched, use it.
(if-let ((orig-event-id (map-nested-elt content '(m.relates_to event_id)))
(orig-event (gethash orig-event-id (ement-session-events ement-session))))
(setq replied-to-event-id
(map-nested-elt (ement-event-content orig-event)
'(m.relates_to m.in_reply_to event_id)))
;; The original event is not found: fetch it and redisplay this event.
(ement-api ement-session (format "rooms/%s/event/%s" (ement-room-id ement-room) orig-event-id)
:then (ement-room--rich-reply-callback ement-room ement-session event))))
(when replied-to-event-id
;; Message is a reply, find or fetch the event being replied to.
(if-let ((replied-to-event (gethash replied-to-event-id (ement-session-events ement-session))))
;; Found event in session's events table: use it.
(setf event-replied-to replied-to-event)
;; Replied-to event not found: fetch it and redisplay this event.
(ement-api ement-session (format "rooms/%s/event/%s" (ement-room-id ement-room) replied-to-event-id)
:then (let ((room ement-room)
(session ement-session))
(lambda (fetched-event)
(pcase-let* ((new-event (ement--make-event fetched-event))
((cl-struct ement-room (local (map buffer))) room))
(ement--put-event new-event room session)
(when (buffer-live-p buffer)
(with-current-buffer buffer
(when-let ((node (ement-room--ewoc-last-matching ement-ewoc
;; This is probably ok, but it might be safer
;; to test the event ID.
(lambda (data) (eq data event)))))
(ewoc-invalidate ement-ewoc node))))))))))
:then (ement-room--rich-reply-callback ement-room ement-session event))))
(setf body (if (or (not formatted-p) (not formatted-body))
;; FIXME: This should check if the quote is the plain text body but
;; that is not easy...
Expand Down Expand Up @@ -4178,6 +4178,20 @@ If FORMATTED-P, return the formatted body content, when available."
(setf body (concat body " " (propertize "[edited]" 'face 'font-lock-comment-face))))
body))

(defun ement-room--rich-reply-callback (room session event)
"Return callback function for rich reply in EVENT in ROOM of SESSION."
(lambda (fetched-event)
(pcase-let* ((new-event (ement--make-event fetched-event))
((cl-struct ement-room (local (map buffer))) room))
(ement--put-event new-event room session)
(when (buffer-live-p buffer)
(with-current-buffer buffer
(when-let ((node (ement-room--ewoc-last-matching ement-ewoc
;; This is probably ok, but it might be safer
;; to test the event ID.
(lambda (data) (eq data event)))))
(ewoc-invalidate ement-ewoc node)))))))

(defun ement-room--format-quotation-text (quoted-event)
"Return text for QUOTED-EVENT."
(pcase-let* (((cl-struct ement-event sender (content (map body))) quoted-event)
Expand Down

0 comments on commit 5a07545

Please sign in to comment.