From c852b6f121942d1a456c09b48b1e26e3182baa4b Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Mon, 1 Jun 2026 22:14:21 -0400 Subject: [PATCH] fix: P0 post-deploy bug fixes from live testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - EditHistoryModal: use raw fetch with /_matrix/client/v1/ path for relations API β€” Synapse only supports relations at v1, not v3 (fixes Sentry JAVASCRIPT-REACT-K / 404 error) - RoomViewHeader: remove useReportRoomSupported spec-version gate β€” Synapse 1.114+ has the endpoint but only advertises spec v1.12; button now always shows for non-creator, non-server-notice rooms - ReportRoomModal: handle M_UNRECOGNIZED/404 with "not supported by your homeserver" message - RoomNavItem: add isServerNotice guard to Room Settings in sidebar context menu (was only guarded in header three-dots menu) - initMatrix: bump setMaxListeners from 50 β†’ 150 to prevent MaxListenersExceededWarning with large room lists - RoomProfile: save topic with formatted_body + format when markdown syntax is detected; add markdown hint below topic textarea Co-Authored-By: Claude Sonnet 4.6 --- .../common-settings/general/RoomProfile.tsx | 35 ++++++++++++++++++- src/app/features/room-nav/RoomNavItem.tsx | 23 ++++++------ src/app/features/room/ReportRoomModal.tsx | 9 +++-- src/app/features/room/RoomViewHeader.tsx | 4 +-- .../room/message/EditHistoryModal.tsx | 13 ++++--- src/client/initMatrix.ts | 5 ++- 6 files changed, 64 insertions(+), 25 deletions(-) diff --git a/src/app/features/common-settings/general/RoomProfile.tsx b/src/app/features/common-settings/general/RoomProfile.tsx index 87aa3d4db..ee283fcd4 100644 --- a/src/app/features/common-settings/general/RoomProfile.tsx +++ b/src/app/features/common-settings/general/RoomProfile.tsx @@ -41,6 +41,32 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useAlive } from '../../../hooks/useAlive'; import { RoomPermissionsAPI } from '../../../hooks/useRoomPermissions'; +const MARKDOWN_PATTERN = /(\*\*|__|\*|_|~~|`|\[.+?\]\(.+?\))/; + +function topicMarkdownToHtml(text: string): string { + return text + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/\*\*(.+?)\*\*/g, '$1') + .replace(/__(.+?)__/g, '$1') + .replace(/\*(.+?)\*/g, '$1') + .replace(/_(.+?)_/g, '$1') + .replace(/~~(.+?)~~/g, '$1') + .replace(/`(.+?)`/g, '$1') + .replace(/\[(.+?)\]\((.+?)\)/g, '$1') + .replace(/\n/g, '
'); +} + +function buildTopicContent(topic: string): Record { + if (!MARKDOWN_PATTERN.test(topic)) return { topic }; + return { + topic, + format: 'org.matrix.custom.html', + formatted_body: topicMarkdownToHtml(topic), + }; +} + type RoomProfileEditProps = { canEditAvatar: boolean; canEditName: boolean; @@ -101,7 +127,8 @@ export function RoomProfileEdit({ await mx.sendStateEvent(room.roomId, StateEvent.RoomName as any, { name: roomName }); } if (roomTopic !== undefined) { - await mx.sendStateEvent(room.roomId, StateEvent.RoomTopic as any, { topic: roomTopic }); + const topicContent = buildTopicContent(roomTopic); + await mx.sendStateEvent(room.roomId, StateEvent.RoomTopic as any, topicContent); } }, [mx, room.roomId], @@ -224,10 +251,16 @@ export function RoomProfileEdit({