From 7676f21292db3336c3d8d03618a804dd36ca30bf Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 19 Oct 2024 17:41:24 +0300 Subject: [PATCH] web/timeline: add different rendering for m.notice and m.emote messages --- web/src/ui/timeline/ReplyBody.tsx | 2 +- web/src/ui/timeline/TimelineEvent.css | 14 +++++++++-- web/src/ui/timeline/TimelineEvent.tsx | 2 +- web/src/ui/timeline/content/MessageBody.tsx | 27 +++++++++++++++------ 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/web/src/ui/timeline/ReplyBody.tsx b/web/src/ui/timeline/ReplyBody.tsx index d05b723..3c7a978 100644 --- a/web/src/ui/timeline/ReplyBody.tsx +++ b/web/src/ui/timeline/ReplyBody.tsx @@ -79,7 +79,7 @@ export const ReplyBody = ({ room, event, onClose }: ReplyBodyProps) => { alt="" /> - {memberEvtContent?.displayname ?? event.sender} + {memberEvtContent?.displayname || event.sender} {onClose && } diff --git a/web/src/ui/timeline/TimelineEvent.css b/web/src/ui/timeline/TimelineEvent.css index a72bf3c..1602706 100644 --- a/web/src/ui/timeline/TimelineEvent.css +++ b/web/src/ui/timeline/TimelineEvent.css @@ -176,8 +176,18 @@ div.member-body { gap: .25rem; } -div.plaintext-body { - white-space: pre-wrap; +div.message-text { + &.plaintext-body { + white-space: pre-wrap; + } + + &.notice-message { + opacity: .6; + } + + &.emote-message::before { + content: "* " attr(data-event-sender) " "; + } } div.html-body { diff --git a/web/src/ui/timeline/TimelineEvent.tsx b/web/src/ui/timeline/TimelineEvent.tsx index 19c4fe7..8a82ff4 100644 --- a/web/src/ui/timeline/TimelineEvent.tsx +++ b/web/src/ui/timeline/TimelineEvent.tsx @@ -146,7 +146,7 @@ const TimelineEvent = ({ room, evt, prevEvt, setReplyToRef }: TimelineEventProps />
- {memberEvtContent?.displayname ?? evt.sender} + {memberEvtContent?.displayname || evt.sender} {shortTime} {(editEventTS && editTime) ? (edited at {formatShortTime(editEventTS)}) diff --git a/web/src/ui/timeline/content/MessageBody.tsx b/web/src/ui/timeline/content/MessageBody.tsx index a85110d..0991248 100644 --- a/web/src/ui/timeline/content/MessageBody.tsx +++ b/web/src/ui/timeline/content/MessageBody.tsx @@ -13,7 +13,7 @@ // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import type { MediaMessageEventContent, MessageEventContent } from "@/api/types" +import { MediaMessageEventContent, MemberEventContent, MessageEventContent } from "@/api/types" import { EventContentProps } from "./props.ts" import { useMediaContent } from "./useMediaContent.tsx" @@ -24,18 +24,31 @@ const onClickHTML = (evt: React.MouseEvent) => { } } -export const TextMessageBody = ({ event }: EventContentProps) => { +export const TextMessageBody = ({ event, room }: EventContentProps) => { const content = event.content as MessageEventContent + const classNames = ["message-text"] + let eventSenderName: string | undefined + if (content.msgtype === "m.notice") { + classNames.push("notice-message") + } else if (content.msgtype === "m.emote") { + classNames.push("emote-message") + const memberEvt = room.getStateEvent("m.room.member", event.sender) + const memberEvtContent = memberEvt?.content as MemberEventContent | undefined + eventSenderName = memberEvtContent?.displayname || event.sender + } if (event.local_content?.sanitized_html) { - const classNames = ["message-text", "html-body"] + classNames.push("html-body") if (event.local_content.was_plaintext) { classNames.push("plaintext-body") } - return
+ return
} - return
{content.body}
+ return
{content.body}
} export const MediaMessageBody = ({ event, room }: EventContentProps) => {