feat(threads): enable SDK threadSupport + unthreaded read receipts (P3-8 step 0)

threadSupport:true makes matrix-js-sdk partition m.thread relations into Thread
objects (replies leave the main timeline; roots stay). markAsRead now sends
UNTHREADED receipts so one receipt still clears room + thread notification
counts — without this, badges would stick unread. The thread panel + summary
chips land in the same push.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 21:27:57 -04:00
parent 39cfc23ebe
commit 15ac538a4b
2 changed files with 10 additions and 0 deletions
+5
View File
@@ -21,8 +21,13 @@ export async function markAsRead(mx: MatrixClient, roomId: string, privateReceip
const latestEvent = getLatestValidEvent();
if (latestEvent === null) return;
// Unthreaded receipt: with client threadSupport enabled the SDK would
// otherwise scope this to the main timeline (thread_id: "main"), leaving
// per-thread notification counts permanently unread. Unthreaded preserves
// the pre-threads wire behavior — one receipt clears everything.
await mx.sendReadReceipt(
latestEvent,
privateReceipt || privateReadReceipts ? ReceiptType.ReadPrivate : ReceiptType.Read,
true,
);
}
+5
View File
@@ -64,6 +64,11 @@ export const initClient = async (session: Session): Promise<MatrixClient> => {
export const startClient = async (mx: MatrixClient) => {
await mx.startClient({
lazyLoadMembers: true,
// P3-8: partition m.thread relations into Thread objects/timelines. Thread
// replies leave the main timeline (roots stay + get a summary chip); the
// thread panel renders them. markAsRead sends UNTHREADED receipts
// (utils/notifications.ts) so room badges keep clearing.
threadSupport: true,
});
};