Consolidate all group call creation into useLoadGroupCall
This enables us to automatically create a group call in rooms that exist, but contain no calls.
This commit is contained in:
parent
b4a56f6dd7
commit
fae4c504c9
4 changed files with 124 additions and 130 deletions
|
@ -10,10 +10,6 @@ import { ICreateClientOpts } from "matrix-js-sdk/src/matrix";
|
|||
import { ClientEvent } from "matrix-js-sdk/src/client";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { Visibility, Preset } from "matrix-js-sdk/src/@types/partials";
|
||||
import {
|
||||
GroupCallIntent,
|
||||
GroupCallType,
|
||||
} from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import { ISyncStateData, SyncState } from "matrix-js-sdk/src/sync";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
|
@ -224,8 +220,7 @@ export function isLocalRoomId(roomId: string): boolean {
|
|||
|
||||
export async function createRoom(
|
||||
client: MatrixClient,
|
||||
name: string,
|
||||
isPtt = false
|
||||
name: string
|
||||
): Promise<string> {
|
||||
let setExpectedRoomId: (roomId: string) => void;
|
||||
const expectedRoomId = new Promise<string>(
|
||||
|
@ -278,15 +273,6 @@ export async function createRoom(
|
|||
setExpectedRoomId(createRoomResult.room_id);
|
||||
await roomReceived;
|
||||
|
||||
console.log(`Creating ${isPtt ? "PTT" : "video"} group call room`);
|
||||
|
||||
await client.createGroupCall(
|
||||
createRoomResult.room_id,
|
||||
isPtt ? GroupCallType.Voice : GroupCallType.Video,
|
||||
isPtt,
|
||||
GroupCallIntent.Prompt
|
||||
);
|
||||
|
||||
return fullAliasFromRoomName(name, client);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ export function GroupCallLoader({
|
|||
client,
|
||||
roomId,
|
||||
viaServers,
|
||||
true,
|
||||
createPtt
|
||||
);
|
||||
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { isLocalRoomId, createRoom, roomNameFromRoomId } from "../matrix-utils";
|
||||
|
||||
async function fetchGroupCall(
|
||||
client,
|
||||
roomIdOrAlias,
|
||||
viaServers = undefined,
|
||||
timeout = 5000
|
||||
) {
|
||||
const { roomId } = await client.joinRoom(roomIdOrAlias, { viaServers });
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let timeoutId;
|
||||
|
||||
function onGroupCallIncoming(groupCall) {
|
||||
if (groupCall && groupCall.room.roomId === roomId) {
|
||||
clearTimeout(timeoutId);
|
||||
client.removeListener("GroupCall.incoming", onGroupCallIncoming);
|
||||
resolve(groupCall);
|
||||
}
|
||||
}
|
||||
|
||||
const groupCall = client.getGroupCallForRoom(roomId);
|
||||
|
||||
if (groupCall) {
|
||||
resolve(groupCall);
|
||||
}
|
||||
|
||||
client.on("GroupCall.incoming", onGroupCallIncoming);
|
||||
|
||||
if (timeout) {
|
||||
timeoutId = setTimeout(() => {
|
||||
client.removeListener("GroupCall.incoming", onGroupCallIncoming);
|
||||
reject(new Error("Fetching group call timed out."));
|
||||
}, timeout);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function useLoadGroupCall(
|
||||
client,
|
||||
roomId,
|
||||
viaServers,
|
||||
createIfNotFound,
|
||||
createPtt
|
||||
) {
|
||||
const [state, setState] = useState({
|
||||
loading: true,
|
||||
error: undefined,
|
||||
groupCall: undefined,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchOrCreateGroupCall() {
|
||||
try {
|
||||
const groupCall = await fetchGroupCall(
|
||||
client,
|
||||
roomId,
|
||||
viaServers,
|
||||
30000
|
||||
);
|
||||
return groupCall;
|
||||
} catch (error) {
|
||||
if (
|
||||
createIfNotFound &&
|
||||
(error.errcode === "M_NOT_FOUND" ||
|
||||
(error.message &&
|
||||
error.message.indexOf("Failed to fetch alias") !== -1)) &&
|
||||
isLocalRoomId(roomId)
|
||||
) {
|
||||
const roomName = roomNameFromRoomId(roomId);
|
||||
await createRoom(client, roomName, createPtt);
|
||||
const groupCall = await fetchGroupCall(
|
||||
client,
|
||||
roomId,
|
||||
viaServers,
|
||||
30000
|
||||
);
|
||||
return groupCall;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
setState({ loading: true });
|
||||
|
||||
fetchOrCreateGroupCall()
|
||||
.then((groupCall) =>
|
||||
setState((prevState) => ({ ...prevState, loading: false, groupCall }))
|
||||
)
|
||||
.catch((error) =>
|
||||
setState((prevState) => ({ ...prevState, loading: false, error }))
|
||||
);
|
||||
}, [client, roomId, state.reloadId, createIfNotFound, viaServers, createPtt]);
|
||||
|
||||
return state;
|
||||
}
|
123
src/room/useLoadGroupCall.ts
Normal file
123
src/room/useLoadGroupCall.ts
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
Copyright 2022 Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||
import {
|
||||
GroupCallType,
|
||||
GroupCallIntent,
|
||||
} from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import { GroupCallEventHandlerEvent } from "matrix-js-sdk/src/webrtc/groupCallEventHandler";
|
||||
|
||||
import type { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import type { Room } from "matrix-js-sdk/src/models/room";
|
||||
import type { GroupCall } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import { isLocalRoomId, createRoom, roomNameFromRoomId } from "../matrix-utils";
|
||||
|
||||
export interface GroupCallLoadState {
|
||||
loading: boolean;
|
||||
error?: Error;
|
||||
groupCall?: GroupCall;
|
||||
}
|
||||
|
||||
export const useLoadGroupCall = (
|
||||
client: MatrixClient,
|
||||
roomIdOrAlias: string,
|
||||
viaServers: string[],
|
||||
createPtt: boolean
|
||||
) => {
|
||||
const [state, setState] = useState<GroupCallLoadState>({ loading: true });
|
||||
|
||||
useEffect(() => {
|
||||
setState({ loading: true });
|
||||
|
||||
const fetchOrCreateRoom = async (): Promise<Room> => {
|
||||
try {
|
||||
return await client.joinRoom(roomIdOrAlias, { viaServers });
|
||||
} catch (error) {
|
||||
if (
|
||||
isLocalRoomId(roomIdOrAlias) &&
|
||||
(error.errcode === "M_NOT_FOUND" ||
|
||||
(error.message &&
|
||||
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 });
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const fetchOrCreateGroupCall = async (): Promise<GroupCall> => {
|
||||
const room = await fetchOrCreateRoom();
|
||||
const groupCall = client.getGroupCallForRoom(room.roomId);
|
||||
|
||||
if (groupCall) {
|
||||
return groupCall;
|
||||
} else if (
|
||||
room.currentState.mayClientSendStateEvent(
|
||||
EventType.GroupCallPrefix,
|
||||
client
|
||||
)
|
||||
) {
|
||||
// The call doesn't exist, but we can create it
|
||||
console.log(`Creating ${createPtt ? "PTT" : "video"} group call room`);
|
||||
return await client.createGroupCall(
|
||||
room.roomId,
|
||||
createPtt ? GroupCallType.Voice : GroupCallType.Video,
|
||||
createPtt,
|
||||
GroupCallIntent.Room
|
||||
);
|
||||
} else {
|
||||
// We don't have permission to create the call, so all we can do is wait
|
||||
// for one to come in
|
||||
return new Promise((resolve, reject) => {
|
||||
const onGroupCallIncoming = (groupCall: GroupCall) => {
|
||||
if (groupCall?.room.roomId === room.roomId) {
|
||||
clearTimeout(timeout);
|
||||
client.off(
|
||||
GroupCallEventHandlerEvent.Incoming,
|
||||
onGroupCallIncoming
|
||||
);
|
||||
resolve(groupCall);
|
||||
}
|
||||
};
|
||||
client.on(GroupCallEventHandlerEvent.Incoming, onGroupCallIncoming);
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
client.off(
|
||||
GroupCallEventHandlerEvent.Incoming,
|
||||
onGroupCallIncoming
|
||||
);
|
||||
reject(new Error("Fetching group call timed out."));
|
||||
}, 30000);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
fetchOrCreateGroupCall()
|
||||
.then((groupCall) =>
|
||||
setState((prevState) => ({ ...prevState, loading: false, groupCall }))
|
||||
)
|
||||
.catch((error) =>
|
||||
setState((prevState) => ({ ...prevState, loading: false, error }))
|
||||
);
|
||||
}, [client, roomIdOrAlias, viaServers, createPtt]);
|
||||
|
||||
return state;
|
||||
};
|
Loading…
Reference in a new issue