diff --git a/src/app/components/user-profile/UserChips.tsx b/src/app/components/user-profile/UserChips.tsx index 8288063..c65e2ce 100644 --- a/src/app/components/user-profile/UserChips.tsx +++ b/src/app/components/user-profile/UserChips.tsx @@ -28,7 +28,11 @@ import { copyToClipboard } from '../../utils/dom'; import { getExploreServerPath } from '../../pages/pathUtils'; import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; import { factoryRoomIdByAtoZ } from '../../utils/sort'; -import { useMutualRooms, useMutualRoomsSupport } from '../../hooks/useMutualRooms'; +import { + useMutualRooms, + useMutualRoomsSupport, + useUnstableMutualRoomsSupport, +} from '../../hooks/useMutualRooms'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; import { useDirectRooms } from '../../pages/client/direct/useDirectRooms'; import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; @@ -233,7 +237,9 @@ type MutualRoomsData = { export function MutualRoomsChip({ userId }: { userId: string }) { const mx = useMatrixClient(); const mutualRoomSupported = useMutualRoomsSupport(); + const mutualRoomUnstable = useUnstableMutualRoomsSupport(); const mutualRoomsState = useMutualRooms(userId); + console.log(mutualRoomSupported, mutualRoomsState); const { navigateRoom, navigateSpace } = useRoomNavigate(); const closeUserRoomProfile = useCloseUserRoomProfile(); const directs = useDirectRooms(); @@ -279,7 +285,7 @@ export function MutualRoomsChip({ userId }: { userId: string }) { if ( userId === mx.getSafeUserId() || - !mutualRoomSupported || + (!mutualRoomSupported && !mutualRoomUnstable) || mutualRoomsState.status === AsyncStatus.Error ) { return null; diff --git a/src/app/hooks/useMutualRooms.ts b/src/app/hooks/useMutualRooms.ts index a7b3893..28c5060 100644 --- a/src/app/hooks/useMutualRooms.ts +++ b/src/app/hooks/useMutualRooms.ts @@ -1,9 +1,10 @@ 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 useMutualRoomsSupport = (): boolean => { +export const useUnstableMutualRoomsSupport = (): boolean => { const { unstable_features: unstableFeatures } = useSpecVersions(); const supported = @@ -14,16 +15,59 @@ export const useMutualRoomsSupport = (): boolean => { 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 supported = useMutualRoomsSupport(); + const unstableSupport = useUnstableMutualRoomsSupport(); + const support = useMutualRoomsSupport(); const [mutualRoomsState] = useAsyncCallbackValue( - useCallback( - () => (supported ? mx._unstable_getSharedRooms(userId) : Promise.resolve([])), - [mx, userId, supported] - ) + useCallback(() => { + if (support) return fetchAllMutualRooms(mx, userId); + if (unstableSupport) return mx._unstable_getSharedRooms(userId); + return Promise.resolve([]); + }, [mx, userId, unstableSupport, support]) ); return mutualRoomsState;