From 603b11288fc145b7969e16703ae990c9b2e2f753 Mon Sep 17 00:00:00 2001 From: 7w1 Date: Sun, 21 Jun 2026 17:30:33 -0500 Subject: [PATCH] Fix encrypted thread messages not appearing --- .changeset/fix-encrypted-thread-messages.md | 5 +++++ src/app/features/room/ThreadBrowser.tsx | 13 ++++++++++++- src/app/features/room/ThreadDrawer.tsx | 8 ++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 .changeset/fix-encrypted-thread-messages.md diff --git a/.changeset/fix-encrypted-thread-messages.md b/.changeset/fix-encrypted-thread-messages.md new file mode 100644 index 000000000..3be0d0f51 --- /dev/null +++ b/.changeset/fix-encrypted-thread-messages.md @@ -0,0 +1,5 @@ +--- +default: patch +--- + +Fix encrypted thread messages not appearing until reopened. diff --git a/src/app/features/room/ThreadBrowser.tsx b/src/app/features/room/ThreadBrowser.tsx index 72d967db8..ad55d0fdc 100644 --- a/src/app/features/room/ThreadBrowser.tsx +++ b/src/app/features/room/ThreadBrowser.tsx @@ -14,7 +14,7 @@ import { toRem, } from 'folds'; import type { EventTimelineSet, MatrixEvent, Room, Thread } from '$types/matrix-sdk'; -import { NotificationCountType, RoomEvent, ThreadEvent } from '$types/matrix-sdk'; +import { MatrixEventEvent, NotificationCountType, RoomEvent, ThreadEvent } from '$types/matrix-sdk'; import { useAtomValue } from 'jotai'; import type { HTMLReactParserOptions } from 'html-react-parser'; import type { Opts as LinkifyOpts } from 'linkifyjs'; @@ -316,9 +316,19 @@ export function ThreadBrowser({ room, onOpenThread, onClose, overlay }: ThreadBr // always be a no-op and left threadsReady=true prematurely. useEffect(() => { const onUpdate = () => forceUpdate((n) => n + 1); + const onDecrypted = (mEvent: MatrixEvent) => { + if (mEvent.getRoomId() !== room.roomId) return; + const relation = mEvent.getRelation(); + const isThreadRelation = relation?.rel_type === 'm.thread'; + const threadId = isThreadRelation ? relation.event_id : mEvent.getId(); + if (threadId && room.getThread(threadId)) { + onUpdate(); + } + }; room.on(ThreadEvent.New, onUpdate); room.on(ThreadEvent.Update, onUpdate); room.on(ThreadEvent.NewReply, onUpdate); + mx.on(MatrixEventEvent.Decrypted, onDecrypted); let cancelled = false; const loadThreads = async () => { @@ -381,6 +391,7 @@ export function ThreadBrowser({ room, onOpenThread, onClose, overlay }: ThreadBr room.off(ThreadEvent.New, onUpdate); room.off(ThreadEvent.Update, onUpdate); room.off(ThreadEvent.NewReply, onUpdate); + mx.off(MatrixEventEvent.Decrypted, onDecrypted); }; }, [room, mx]); diff --git a/src/app/features/room/ThreadDrawer.tsx b/src/app/features/room/ThreadDrawer.tsx index 4c631a5af..e956c744c 100644 --- a/src/app/features/room/ThreadDrawer.tsx +++ b/src/app/features/room/ThreadDrawer.tsx @@ -6,6 +6,7 @@ import type { IEvent, Room } from '$types/matrix-sdk'; import { Direction, MatrixEvent, + MatrixEventEvent, PushProcessor, ReceiptType, RelationType, @@ -389,6 +390,11 @@ export function ThreadDrawer({ room, threadRootId, onClose, overlay }: ThreadDra forceUpdate((n) => n + 1); } }; + const onDecrypted = (mEvent: MatrixEvent) => { + if (isEventInThread(mEvent)) { + forceUpdate((n) => n + 1); + } + }; const onRedaction = (mEvent: MatrixEvent) => { // Redactions (removing reactions/messages) should also trigger updates if (isEventInThread(mEvent)) { @@ -397,11 +403,13 @@ export function ThreadDrawer({ room, threadRootId, onClose, overlay }: ThreadDra }; const onThreadUpdate = () => forceUpdate((n) => n + 1); mx.on(RoomEvent.Timeline, onTimeline); + mx.on(MatrixEventEvent.Decrypted, onDecrypted); room.on(RoomEvent.Redaction, onRedaction); room.on(ThreadEvent.Update, onThreadUpdate); room.on(ThreadEvent.NewReply, onThreadUpdate); return () => { mx.off(RoomEvent.Timeline, onTimeline); + mx.off(MatrixEventEvent.Decrypted, onDecrypted); room.removeListener(RoomEvent.Redaction, onRedaction); room.removeListener(ThreadEvent.Update, onThreadUpdate); room.removeListener(ThreadEvent.NewReply, onThreadUpdate);