diff --git a/src/Room.jsx b/src/Room.jsx index b6a124d7..60ccd20d 100644 --- a/src/Room.jsx +++ b/src/Room.jsx @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { useEffect, useMemo, useState } from "react"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; import styles from "./Room.module.css"; import { useLocation, useParams } from "react-router-dom"; import { @@ -23,6 +23,7 @@ import { VideoButton, LayoutToggleButton, ScreenshareButton, + DropdownButton, } from "./RoomButton"; import { Header, LeftNav, RightNav, CenterNav } from "./Header"; import { Button } from "./Input"; @@ -83,7 +84,7 @@ export function Room({ client }) { ); } -export function GroupCallView({ groupCall }) { +export function GroupCallView({ client, groupCall }) { const { state, error, @@ -108,6 +109,7 @@ export function GroupCallView({ groupCall }) { } else if (state === GroupCallState.Entered) { return ( { + function updateDevices() { + navigator.mediaDevices.enumerateDevices().then((devices) => { + const audioInputs = devices.filter( + (device) => device.kind === "audioinput" + ); + const videoInputs = devices.filter( + (device) => device.kind === "videoinput" + ); + + setState((prevState) => ({ + ...prevState, + audioInputs, + videoInputs, + })); + }); + } + + updateDevices(); + + navigator.mediaDevices.addEventListener("devicechange", updateDevices); + + return () => { + navigator.mediaDevices.removeEventListener("devicechange", updateDevices); + }; + }, []); + + const setAudioInput = useCallback( + (deviceId) => { + setState((prevState) => ({ ...prevState, audioInput: deviceId })); + client.getMediaHandler().setAudioInput(deviceId); + }, + [client] + ); + + const setVideoInput = useCallback( + (deviceId) => { + setState((prevState) => ({ ...prevState, videoInput: deviceId })); + client.getMediaHandler().setVideoInput(deviceId); + }, + [client] + ); + + return { + audioInput, + audioInputs, + setAudioInput, + videoInput, + videoInputs, + setVideoInput, + }; +} function InRoomView({ + client, roomName, microphoneMuted, localVideoMuted, @@ -242,13 +305,13 @@ function InRoomView({ const [layout, toggleLayout] = useVideoGridLayout(); const { - audioDeviceId, - audioDevices, - setAudioDevice, - videoDeviceId, - videoDevices, - setVideoDevice, - } = useMediaManager(); + audioInput, + audioInputs, + setAudioInput, + videoInput, + videoInputs, + setVideoInput, + } = useMediaHandler(client); const items = useMemo(() => { const participants = []; @@ -295,26 +358,29 @@ function InRoomView({ )}
- setAudioDevice(value)} - options={audioDevices.map(({ label, deviceId }) => ({ + setAudioInput(value)} + options={audioInputs.map(({ label, deviceId }) => ({ label, value: deviceId, }))} - /> - setVideoDevice(value)} - options={videoDevices.map(({ label, deviceId }) => ({ + > + + + setVideoInput(value)} + options={videoInputs.map(({ label, deviceId }) => ({ label, value: deviceId, }))} - /> + > + + +
{children} {open && ( -
+
    {options.map((item) => (
  • onChange(item)} > @@ -73,23 +72,19 @@ export function DropdownButton({ onChange, options, children }) { ); } -export function MicButton({ muted, onChange, value, options, ...rest }) { +export function MicButton({ muted, ...rest }) { return ( - - - {muted ? : } - - + + {muted ? : } + ); } -export function VideoButton({ enabled, onChange, value, ...rest }) { +export function VideoButton({ enabled, ...rest }) { return ( - - - {enabled ? : } - - + + {enabled ? : } + ); } diff --git a/src/RoomButton.module.css b/src/RoomButton.module.css index 97fced4c..ed38c28f 100644 --- a/src/RoomButton.module.css +++ b/src/RoomButton.module.css @@ -87,6 +87,7 @@ limitations under the License. position: absolute; bottom: 0; right: 0; + cursor: pointer; } .dropdownButton:hover { @@ -100,8 +101,29 @@ limitations under the License. .dropdownContainer { position: absolute; left: 50%; - transform: translate(-50%, -100%); - top: 0; + transform: translate(0, -100%); + top: -5px; background-color: #394049; border-radius: 8px; + overflow: hidden; +} + +.dropdownContainer ul { + list-style: none; + margin: 0; + padding: 0; +} + +.dropdownContainer li { + padding: 12px; + width: 200px; + cursor: pointer; +} + +.dropdownContainer li:hover { + background-color: #8d97a5; +} + +.dropdownActiveItem { + color: #0dbd8b; }