Skip to content

Commit 213a2c7

Browse files
committed
Support proposed MSC4144: Per-message profiles
matrix-org/matrix-spec-proposals#4144
1 parent 9c87772 commit 213a2c7

2 files changed

Lines changed: 38 additions & 12 deletions

File tree

ement-lib.el

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -997,11 +997,13 @@ avatars, etc."
997997
"white" "black")))))))
998998
(apply #'color-rgb-to-hex (append color-rgb (list 2))))))
999999

1000-
(cl-defun ement--format-user (user &optional (room ement-room) (session ement-session))
1000+
(cl-defun ement--format-user (user &optional (room ement-room) (session ement-session) per-message-displayname)
10011001
"Format `ement-user' USER for ROOM on SESSION.
1002-
ROOM defaults to the value of `ement-room'."
1003-
(let ((face (cond ((equal (ement-user-id (ement-session-user session))
1004-
(ement-user-id user))
1002+
ROOM defaults to the value of `ement-room'.
1003+
Optionally use PER-MESSAGE-DISPLAYNAME instead of the users global displayname."
1004+
(let ((face (cond ((and session
1005+
(equal (ement-user-id (ement-session-user session))
1006+
(ement-user-id user)))
10051007
'ement-room-self)
10061008
(ement-room-prism
10071009
`(:inherit ement-room-user :foreground ,(or (ement-user-color user)
@@ -1011,7 +1013,8 @@ ROOM defaults to the value of `ement-room'."
10111013
;; FIXME: If a membership state event has not yet been received, this
10121014
;; sets the display name in the room to the user ID, and that prevents
10131015
;; the display name from being used if the state event arrives later.
1014-
(propertize (ement--user-displayname-in room user)
1016+
(propertize (or per-message-displayname
1017+
(ement--user-displayname-in room user))
10151018
'face face
10161019
'help-echo (ement-user-id user))))
10171020

ement-room.el

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
42044220
If 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.
42664286
HTML 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

Comments
 (0)