)}
- {localMediaInfo.audio && (
+ {audio.localTrack && (
setAudioEnabled(!audioEnabled)}
/>
)}
- {localMediaInfo.video && (
+ {video.localTrack && (
setVideoEnabled(!videoEnabled)}
/>
)}
diff --git a/src/room/useRoom.ts b/src/room/useRoom.ts
deleted file mode 100644
index 63bb153..0000000
--- a/src/room/useRoom.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-import * as React from "react";
-import {
- ConnectionState,
- MediaDeviceFailure,
- Room,
- RoomEvent,
-} from "livekit-client";
-import { LiveKitRoomProps } from "@livekit/components-react/src/components/LiveKitRoom";
-import { logger } from "matrix-js-sdk/src/logger";
-
-const defaultRoomProps: Partial = {
- connect: true,
- audio: false,
- video: false,
-};
-
-export function useRoom(props: LiveKitRoomProps) {
- const {
- token,
- serverUrl,
- options,
- room: passedRoom,
- connectOptions,
- connect,
- audio,
- video,
- screen,
- onConnected,
- onDisconnected,
- onError,
- onMediaDeviceFailure,
- } = { ...defaultRoomProps, ...props };
- if (options && passedRoom) {
- logger.warn(
- "when using a manually created room, the options object will be ignored. set the desired options directly when creating the room instead."
- );
- }
-
- const [room, setRoom] = React.useState();
-
- React.useEffect(() => {
- setRoom(passedRoom ?? new Room(options));
- }, [options, passedRoom]);
-
- React.useEffect(() => {
- if (!room) return;
- const onSignalConnected = () => {
- const localP = room.localParticipant;
- try {
- logger.debug("trying to publish local tracks");
- localP.setMicrophoneEnabled(
- !!audio,
- typeof audio !== "boolean" ? audio : undefined
- );
- localP.setCameraEnabled(
- !!video,
- typeof video !== "boolean" ? video : undefined
- );
- localP.setScreenShareEnabled(
- !!screen,
- typeof screen !== "boolean" ? screen : undefined
- );
- } catch (e) {
- logger.warn(e);
- onError?.(e as Error);
- }
- };
-
- const onMediaDeviceError = (e: Error) => {
- const mediaDeviceFailure = MediaDeviceFailure.getFailure(e);
- onMediaDeviceFailure?.(mediaDeviceFailure);
- };
- room.on(RoomEvent.SignalConnected, onSignalConnected);
- room.on(RoomEvent.MediaDevicesError, onMediaDeviceError);
-
- return () => {
- room.off(RoomEvent.SignalConnected, onSignalConnected);
- room.off(RoomEvent.MediaDevicesError, onMediaDeviceError);
- };
- }, [room, audio, video, screen, onError, onMediaDeviceFailure]);
-
- React.useEffect(() => {
- if (!room) return;
- if (!token) {
- logger.debug("no token yet");
- return;
- }
- if (!serverUrl) {
- logger.warn("no livekit url provided");
- onError?.(Error("no livekit url provided"));
- return;
- }
- if (connect) {
- logger.debug("connecting");
- room.connect(serverUrl, token, connectOptions).catch((e) => {
- logger.warn(e);
- onError?.(e as Error);
- });
- } else {
- logger.debug("disconnecting because connect is false");
- room.disconnect();
- }
- }, [connect, token, connectOptions, room, onError, serverUrl]);
-
- React.useEffect(() => {
- if (!room) return;
- const connectionStateChangeListener = (state: ConnectionState) => {
- switch (state) {
- case ConnectionState.Disconnected:
- if (onDisconnected) onDisconnected();
- break;
- case ConnectionState.Connected:
- if (onConnected) onConnected();
- break;
-
- default:
- break;
- }
- };
- room.on(RoomEvent.ConnectionStateChanged, connectionStateChangeListener);
- return () => {
- room.off(RoomEvent.ConnectionStateChanged, connectionStateChangeListener);
- };
- }, [token, onConnected, onDisconnected, room]);
-
- React.useEffect(() => {
- if (!room) return;
- return () => {
- logger.info("disconnecting on onmount");
- room.disconnect();
- };
- }, [room]);
-
- return { room };
-}
diff --git a/src/settings/SettingsModal.tsx b/src/settings/SettingsModal.tsx
index 4dd9170..f1d56a8 100644
--- a/src/settings/SettingsModal.tsx
+++ b/src/settings/SettingsModal.tsx
@@ -29,7 +29,6 @@ import { ReactComponent as OverflowIcon } from "../icons/Overflow.svg";
import { ReactComponent as UserIcon } from "../icons/User.svg";
import { ReactComponent as FeedbackIcon } from "../icons/Feedback.svg";
import { SelectInput } from "../input/SelectInput";
-import { MediaDevicesState } from "./mediaDevices";
import {
useShowInspector,
useOptInAnalytics,
@@ -42,9 +41,10 @@ import { Body, Caption } from "../typography/Typography";
import { AnalyticsNotice } from "../analytics/AnalyticsNotice";
import { ProfileSettingsTab } from "./ProfileSettingsTab";
import { FeedbackSettingsTab } from "./FeedbackSettingsTab";
+import { MediaDevices, MediaDevicesState } from "../livekit/useMediaDevices";
interface Props {
- mediaDevices: MediaDevicesState;
+ mediaDevices?: MediaDevicesState;
isOpen: boolean;
client: MatrixClient;
roomId?: string;
@@ -63,17 +63,14 @@ export const SettingsModal = (props: Props) => {
const downloadDebugLog = useDownloadDebugLog();
// Generate a `SelectInput` with a list of devices for a given device kind.
- const generateDeviceSelection = (kind: MediaDeviceKind, caption: string) => {
- const devices = props.mediaDevices.state.get(kind);
- if (!devices || devices.available.length == 0) return null;
+ const generateDeviceSelection = (devices: MediaDevices, caption: string) => {
+ if (devices.available.length == 0) return null;
return (
- props.mediaDevices.selectActiveDevice(kind, id.toString())
- }
+ onSelectionChange={(id) => devices.setSelected(id.toString())}
>
{devices.available.map(({ deviceId, label }, index) => (
-
@@ -106,6 +103,8 @@ export const SettingsModal = (props: Props) => {
);
+ const devices = props.mediaDevices;
+
return (
{
>
}
>
- {generateDeviceSelection("audioinput", t("Microphone"))}
- {generateDeviceSelection("audiooutput", t("Speaker"))}
+ {devices && generateDeviceSelection(devices.audioIn, t("Microphone"))}
+ {devices && generateDeviceSelection(devices.audioOut, t("Speaker"))}
{
>
}
>
- {generateDeviceSelection("videoinput", t("Camera"))}
+ {devices && generateDeviceSelection(devices.videoIn, t("Camera"))}
;
- selectActiveDevice: (
- kind: MediaDeviceKind,
- deviceId: string
- ) => Promise;
-};