import { useCallback } from 'react'; import { MatrixClient, Method } from 'matrix-js-sdk'; import { useMatrixClient } from './useMatrixClient'; import { AsyncState, useAsyncCallbackValue } from './useAsyncCallback'; import { useSpecVersions } from './useSpecVersions'; export const useUnstableMutualRoomsSupport = (): boolean => { const { unstable_features: unstableFeatures } = useSpecVersions(); const supported = unstableFeatures?.['uk.half-shot.msc2666'] || unstableFeatures?.['uk.half-shot.msc2666.mutual_rooms'] || unstableFeatures?.['uk.half-shot.msc2666.query_mutual_rooms']; return !!supported; }; export const useMutualRoomsSupport = (): boolean => { const { unstable_features: unstableFeatures, versions } = useSpecVersions(); const supported = versions.includes('v1.19') || unstableFeatures?.['uk.half-shot.msc2666.query_mutual_rooms.stable']; return !!supported; }; type MutualRoomsOK = { joined: string[]; next_batch?: string; count: number; }; const fetchAllMutualRooms = async (mx: MatrixClient, userId: string): Promise => { const mutualRooms: Set = new Set(); let nextBatch: string | undefined; do { // eslint-disable-next-line no-await-in-loop const result = await mx.http.authedRequest( Method.Get, '/mutual_rooms', { user_id: userId, from: nextBatch, }, undefined, { prefix: '/_matrix/client/v1', }, ); result.joined.forEach((r) => mutualRooms.add(r)); nextBatch = result.next_batch; } while (typeof nextBatch === 'string'); return Array.from(mutualRooms); }; export const useMutualRooms = (userId: string): AsyncState => { const mx = useMatrixClient(); const unstableSupport = useUnstableMutualRoomsSupport(); const support = useMutualRoomsSupport(); const [mutualRoomsState] = useAsyncCallbackValue( useCallback(() => { if (support) return fetchAllMutualRooms(mx, userId); if (unstableSupport) return mx._unstable_getSharedRooms(userId); return Promise.resolve([]); }, [mx, userId, unstableSupport, support]), ); return mutualRoomsState; };