Merge pull request #479 from vector-im/dbkr/wait_for_room

Fix 'cannot find room' error
This commit is contained in:
David Baker 2022-07-21 11:48:23 +01:00 committed by GitHub
commit 075049abc4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 8 deletions

View file

@ -47,7 +47,7 @@ export function RegisteredView({ client }) {
setError(undefined);
setLoading(true);
const roomIdOrAlias = await createRoom(client, roomName, ptt);
const [roomIdOrAlias] = await createRoom(client, roomName, ptt);
if (roomIdOrAlias) {
history.push(`/room/${roomIdOrAlias}`);

View file

@ -70,7 +70,7 @@ export function UnauthenticatedView() {
let roomIdOrAlias;
try {
roomIdOrAlias = await createRoom(client, roomName, ptt);
[roomIdOrAlias] = await createRoom(client, roomName, ptt);
} catch (error) {
if (error.errcode === "M_ROOM_IN_USE") {
setOnFinished(() => () => {

View file

@ -220,8 +220,8 @@ export function isLocalRoomId(roomId: string): boolean {
export async function createRoom(
client: MatrixClient,
name: string
): Promise<string> {
await client.createRoom({
): Promise<[string, string]> {
const result = await client.createRoom({
visibility: Visibility.Private,
preset: Preset.PublicChat,
name,
@ -251,7 +251,7 @@ export async function createRoom(
},
});
return fullAliasFromRoomName(name, client);
return [fullAliasFromRoomName(name, client), result.room_id];
}
export function getRoomUrl(roomId: string): string {

View file

@ -21,6 +21,7 @@ import {
GroupCallIntent,
} from "matrix-js-sdk/src/webrtc/groupCall";
import { GroupCallEventHandlerEvent } from "matrix-js-sdk/src/webrtc/groupCallEventHandler";
import { ClientEvent } from "matrix-js-sdk/src/client";
import type { MatrixClient } from "matrix-js-sdk/src/client";
import type { Room } from "matrix-js-sdk/src/models/room";
@ -44,9 +45,38 @@ export const useLoadGroupCall = (
useEffect(() => {
setState({ loading: true });
const waitForRoom = async (roomId: string): Promise<Room> => {
const room = client.getRoom(roomId);
if (room) return room;
console.log(`Room ${roomId} hasn't arrived yet: waiting`);
const waitPromise = new Promise<Room>((resolve) => {
const onRoomEvent = async (room: Room) => {
if (room.roomId === roomId) {
client.removeListener(ClientEvent.Room, onRoomEvent);
resolve(room);
}
};
client.on(ClientEvent.Room, onRoomEvent);
});
// race the promise with a timeout so we don't
// wait forever for the room
const timeoutPromise = new Promise<Room>((_, reject) => {
setTimeout(() => {
reject(new Error("Timed out trying to join room"));
}, 30000);
});
return Promise.race([waitPromise, timeoutPromise]);
};
const fetchOrCreateRoom = async (): Promise<Room> => {
try {
return await client.joinRoom(roomIdOrAlias, { viaServers });
const room = await client.joinRoom(roomIdOrAlias, { viaServers });
// wait for the room to come down the sync stream, otherwise
// client.getRoom() won't return the room.
return waitForRoom(room.roomId);
} catch (error) {
if (
isLocalRoomId(roomIdOrAlias) &&
@ -55,8 +85,12 @@ export const useLoadGroupCall = (
error.message.indexOf("Failed to fetch alias") !== -1))
) {
// The room doesn't exist, but we can create it
await createRoom(client, roomNameFromRoomId(roomIdOrAlias));
return await client.joinRoom(roomIdOrAlias, { viaServers });
const [, roomId] = await createRoom(
client,
roomNameFromRoomId(roomIdOrAlias)
);
// likewise, wait for the room
return await waitForRoom(roomId);
} else {
throw error;
}