diff --git a/src/app/features/bots/useBotConversations.ts b/src/app/features/bots/useBotConversations.ts index 101f4584..904594ce 100644 --- a/src/app/features/bots/useBotConversations.ts +++ b/src/app/features/bots/useBotConversations.ts @@ -1,5 +1,5 @@ import { useEffect, useMemo, useState } from 'react'; -import { MsgType, Room, ThreadEvent } from 'matrix-js-sdk'; +import { MatrixEvent, MatrixEventEvent, MsgType, Room, ThreadEvent } from 'matrix-js-sdk'; import { trimReplyFromBody } from '../../utils/room'; import { useMatrixClient } from '../../hooks/useMatrixClient'; @@ -65,12 +65,23 @@ export const useBotConversations = (room: Room): BotConversation[] => { // (which fired an extra bump per reply plus one for every unrelated main-timeline event). room.on(ThreadEvent.New, bump); room.on(ThreadEvent.Update, bump); + + // In an encrypted DM a thread root can decrypt AFTER its last ThreadEvent.Update + // (e.g. the bot's reply lands before the root is decrypted); without this the title + // stays stuck on the localized fallback until the next reply. The client re-emits + // Decrypted for every event, so re-derive when one lands in this room. + const onDecrypted = (event: MatrixEvent) => { + if (event.getRoomId() === room.roomId) bump(); + }; + mx.on(MatrixEventEvent.Decrypted, onDecrypted); + return () => { cancelled = true; room.off(ThreadEvent.New, bump); room.off(ThreadEvent.Update, bump); + mx.off(MatrixEventEvent.Decrypted, onDecrypted); }; - }, [room]); + }, [room, mx]); return useMemo(() => { const conversations = room