@@ -1357,8 +1357,9 @@ spec) without requiring all events to use the same margin width."
13571357(ement-room-define-event-formatter ?S
13581358 "Sender display name."
13591359 (ignore session)
1360- (pcase-let ((sender (ement--format-user (ement-event-sender event) room))
1361- ((cl-struct ement-room (local (map buffer))) room))
1360+ (pcase-let* ((per-message-displayname (ement-room--per-message-profile-displayname event))
1361+ (sender (ement--format-user (ement-event-sender event) room nil per-message-displayname))
1362+ ((cl-struct ement-room (local (map buffer))) room))
13621363 ;; NOTE: When called from an `ement-notify' function, ROOM may have no buffer. In
13631364 ;; that case, just use the current buffer (which should be a temp buffer used to
13641365 ;; format the event).
@@ -4199,6 +4200,21 @@ Format defaults to `ement-room-message-format-spec', which see."
41994200 'display `((margin right-margin) ,string))))))
42004201 (buffer-string))))
42014202
4203+ ;; https://github.com/beeper/matrix-spec-proposals/blob/b24060e2a66dc3e9b459f634ba91d3a34d702efa/proposals/4144-per-message-profile.md
4204+ (defun ement-room--per-message-profile-p (event)
4205+ "Test if EVENT contains a per-messsage-profile, if so return it."
4206+ ;; NOTE: The per message profile is essentially a ement-user but with additional
4207+ ;; has_fallback flag. Not sure if it actually should be it's own type.
4208+ (or (alist-get 'm.per_message_profile (ement-event-content event) )
4209+ (alist-get 'com.beeper.per_message_profile (ement-event-content event) )))
4210+
4211+ (defun ement-room--per-message-profile-displayname (event)
4212+ "Return displayname of the EVENT if it contains a per-message profile fallback."
4213+ (when-let* ((profile (ement-room--per-message-profile-p event)))
4214+ (and (alist-get 'has_fallback profile)
4215+ (alist-get 'displayname profile))))
4216+ (defalias 'ement-room--per-message-profile-fallback-p 'ement-room--per-message-profile-displayname)
4217+
42024218(cl-defun ement-room--format-message-body (event session &key (formatted-p t))
42034219 "Return formatted body of \"m.room.message\" EVENT on SESSION.
42044220If FORMATTED-P, return the formatted body content, when available."
@@ -4213,13 +4229,16 @@ If FORMATTED-P, return the formatted body content, when available."
42134229 content)
42144230 (body (or new-body main-body))
42154231 (formatted-body (or new-formatted-body formatted-body))
4232+ (fallback-username (ement-room--per-message-profile-fallback-p event))
42164233 (body (if (or (not formatted-p) (not formatted-body))
42174234 ;; Copy the string so as not to add face properties to the one in the struct.
4218- (copy-sequence body)
4235+ (if fallback-username
4236+ (string-trim-left body (concat fallback-username ": "))
4237+ (copy-sequence body))
42194238 (pcase (or new-content-format content-format)
42204239 ("org.matrix.custom.html"
42214240 (save-match-data
4222- (ement-room--render-html formatted-body)))
4241+ (ement-room--render-html formatted-body fallback-username )))
42234242 (_ (format "[unknown body format: %s] %s"
42244243 (or new-content-format content-format) body)))))
42254244 (appendix (pcase msgtype
@@ -4261,8 +4280,9 @@ If FORMATTED-P, return the formatted body content, when available."
42614280 (setf body "[redacted]"))
42624281 body))
42634282
4264- (defun ement-room--render-html (string )
4283+ (defun ement-room--render-html (string &optional has-fallback )
42654284 "Return rendered version of HTML STRING.
4285+ Remove per-message-profile fallback if HAS-FALLBACK is non-nil.
42664286HTML is rendered to Emacs text using `shr-insert-document'."
42674287 (with-current-buffer
42684288 (or (get-buffer " *ement-room--render-html*")
@@ -4281,6 +4301,8 @@ HTML is rendered to Emacs text using `shr-insert-document'."
42814301 ;; resized (i.e. the wrapping is adjusted automatically by redisplay
42824302 ;; rather than requiring the message to be re-rendered to HTML).
42834303 (let ((shr-use-fonts ement-room-use-variable-pitch)
4304+ (dom (libxml-parse-html-region (point-min) (point-max)))
4305+
42844306 (old-fn (symbol-function 'shr-tag-blockquote))) ;; Bind to a var to avoid unknown-function linting errors.
42854307 (cl-letf (((symbol-function 'shr-fill-line) #'ignore)
42864308 ((symbol-function 'shr-tag-blockquote)
@@ -4292,8 +4314,9 @@ HTML is rendered to Emacs text using `shr-insert-document'."
42924314 line-prefix " "))
42934315 ;; NOTE: We use our own gv, `ement-text-property'; very convenient.
42944316 (add-face-text-property beg (point-max) 'ement-room-quote 'append)))))
4295- (shr-insert-document
4296- (libxml-parse-html-region (point-min ) (point-max ))))))
4317+ (when-let* ((data-mx-profile-fallback-tag (and has-fallback (dom-child-by-tag dom 'strong))))
4318+ (setq dom (dom-remove-node dom data-mx-profile-fallback-tag))))
4319+ (shr-insert-document dom)))
42974320 (string-trim (buffer-substring (point) (point-max)))))
42984321
42994322(cl-defun ement-room--event-mentions-user-p (event user &optional (room ement-room))
0 commit comments