feat: personal room name overrides (MSC4431-style)

Users can right-click any room and 'Rename for me...' to set a local
display name visible only to them. Stored in account data under
io.lotus.room_names. Shows a pencil indicator on renamed rooms.
useLocalRoomName() hook overrides useRoomName() when a local name exists.

Also includes:
- Rich room topic rendering via RoomTopicContent object (formatted_body
  support in RoomTopicViewer with HTML sanitization via sanitizeCustomHtml)
- Edit history viewer: clicking '(edited)' on a message opens a modal
  showing all prior versions with timestamps (EditHistoryModal.tsx)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-01 17:21:11 -04:00
parent 134ebb231d
commit 3a72b7c1c5
13 changed files with 581 additions and 53 deletions
@@ -38,6 +38,7 @@ type RenderMessageContentProps = {
msgType: string;
ts: number;
edited?: boolean;
onEditHistoryClick?: () => void;
getContent: <T>() => T;
mediaAutoLoad?: boolean;
urlPreview?: boolean;
@@ -51,6 +52,7 @@ export function RenderMessageContent({
msgType,
ts,
edited,
onEditHistoryClick,
getContent,
mediaAutoLoad,
urlPreview,
@@ -77,6 +79,7 @@ export function RenderMessageContent({
<MText
style={{ marginTop: config.space.S200 }}
edited={edited}
onEditHistoryClick={onEditHistoryClick}
content={content}
renderBody={(props) => (
<RenderBody
@@ -133,6 +136,7 @@ export function RenderMessageContent({
return (
<MText
edited={edited}
onEditHistoryClick={onEditHistoryClick}
content={getContent()}
renderBody={(props) => (
<RenderBody
@@ -152,6 +156,7 @@ export function RenderMessageContent({
<MEmote
displayName={displayName}
edited={edited}
onEditHistoryClick={onEditHistoryClick}
content={getContent()}
renderBody={(props) => (
<RenderBody
@@ -170,6 +175,7 @@ export function RenderMessageContent({
return (
<MNotice
edited={edited}
onEditHistoryClick={onEditHistoryClick}
content={getContent()}
renderBody={(props) => (
<RenderBody