import { MatrixClient, Room, RoomEvent } from 'matrix-js-sdk'; import { useEffect } from 'react'; import { AccountDataEvent } from '../../types/matrix/accountData'; import { Membership } from '../../types/matrix/room'; import { getAccountData, getMDirects, isBridgedRoom } from '../utils/room'; import { addRoomIdToMDirect } from '../utils/matrix'; export function useAutoDirectSync(mx: MatrixClient): void { useEffect(() => { const handleMembership = (room: Room, _membership: string, prevMembership?: string) => { if (prevMembership !== Membership.Invite) return; if (room.getMyMembership() !== Membership.Join) return; const dmInviter = room.getDMInviter(); if (!dmInviter) return; const joinedAndInvited = room.getJoinedMemberCount() + room.getInvitedMemberCount(); if (joinedAndInvited > 2) return; // Bridged portal rooms (mautrix-telegram/whatsapp/discord/…) live in the // per-bridge personal filtering space (Channels tab) — don't pollute // `m.direct` with them. `useDirectRooms` already filters bridged rooms // out of the Direct tab visually; this prevents the underlying account // data from accruing stale entries for other clients to misclassify. if (isBridgedRoom(room)) return; const mDirectEvent = getAccountData(mx, AccountDataEvent.Direct); if (mDirectEvent) { const directs = getMDirects(mDirectEvent); if (directs.has(room.roomId)) return; } addRoomIdToMDirect(mx, room.roomId, dmInviter).catch(() => undefined); }; mx.on(RoomEvent.MyMembership, handleMembership); return () => { mx.removeListener(RoomEvent.MyMembership, handleMembership); }; }, [mx]); }