This commit is contained in:
Robert Long 2021-10-07 17:25:40 -07:00
parent 333dc81fb6
commit 2e7dfe85e6
3 changed files with 125 additions and 12 deletions

View file

@ -78,7 +78,7 @@ export function Room({ client }) {
return ( return (
<div className={styles.room}> <div className={styles.room}>
<GroupCallView groupCall={groupCall} /> <GroupCallView client={client} groupCall={groupCall} />
</div> </div>
); );
} }
@ -224,6 +224,8 @@ function RoomSetupView({
); );
} }
function useMediaManager() {}
function InRoomView({ function InRoomView({
roomName, roomName,
microphoneMuted, microphoneMuted,
@ -239,6 +241,15 @@ function InRoomView({
}) { }) {
const [layout, toggleLayout] = useVideoGridLayout(); const [layout, toggleLayout] = useVideoGridLayout();
const {
audioDeviceId,
audioDevices,
setAudioDevice,
videoDeviceId,
videoDevices,
setVideoDevice,
} = useMediaManager();
const items = useMemo(() => { const items = useMemo(() => {
const participants = []; const participants = [];
@ -284,10 +295,25 @@ function InRoomView({
<VideoGrid items={items} layout={layout} /> <VideoGrid items={items} layout={layout} />
)} )}
<div className={styles.footer}> <div className={styles.footer}>
<MicButton muted={microphoneMuted} onClick={toggleMicrophoneMuted} /> <MicButton
muted={microphoneMuted}
onClick={toggleMicrophoneMuted}
value={audioDeviceId}
onChange={({ value }) => setAudioDevice(value)}
options={audioDevices.map(({ label, deviceId }) => ({
label,
value: deviceId,
}))}
/>
<VideoButton <VideoButton
enabled={localVideoMuted} enabled={localVideoMuted}
onClick={toggleLocalVideoMuted} onClick={toggleLocalVideoMuted}
value={videoDeviceId}
onChange={({ value }) => setVideoDevice(value)}
options={videoDevices.map(({ label, deviceId }) => ({
label,
value: deviceId,
}))}
/> />
<ScreenshareButton <ScreenshareButton
enabled={isScreensharing} enabled={isScreensharing}

View file

@ -10,6 +10,8 @@ import { ReactComponent as SettingsIcon } from "./icons/Settings.svg";
import { ReactComponent as GridIcon } from "./icons/Grid.svg"; import { ReactComponent as GridIcon } from "./icons/Grid.svg";
import { ReactComponent as SpeakerIcon } from "./icons/Speaker.svg"; import { ReactComponent as SpeakerIcon } from "./icons/Speaker.svg";
import { ReactComponent as ScreenshareIcon } from "./icons/Screenshare.svg"; import { ReactComponent as ScreenshareIcon } from "./icons/Screenshare.svg";
import { ReactComponent as ChevronIcon } from "./icons/Chevron.svg";
import { useEffect } from "react";
export function RoomButton({ on, className, children, ...rest }) { export function RoomButton({ on, className, children, ...rest }) {
return ( return (
@ -22,19 +24,72 @@ export function RoomButton({ on, className, children, ...rest }) {
); );
} }
export function MicButton({ muted, ...rest }) { export function DropdownButton({ onChange, options, children }) {
const buttonRef = useRef();
const [open, setOpen] = useState(false);
useEffect(() => {
function onClick() {
if (open) {
setOpen(false);
}
}
window.addEventListener("click", onClick);
return () => {
window.removeEventListener("click", onClick);
};
}, [open]);
return ( return (
<RoomButton {...rest} on={muted}> <div className={styles.dropDownButtonContainer}>
{muted ? <MuteMicIcon /> : <MicIcon />} {children}
</RoomButton> <button
ref={buttonRef}
className={styles.dropdownButton}
onClick={() => setOpen(true)}
>
<ChevronIcon />
</button>
{open && (
<div className={styles.dropDownContainer}>
<ul>
{options.map((item) => (
<li
key={item.value}
className={classNames({
[styles.dropDownActiveItem]: item.value === value,
})}
onClick={() => onChange(item)}
>
{item.label}
</li>
))}
</ul>
</div>
)}
</div>
); );
} }
export function VideoButton({ enabled, ...rest }) { export function MicButton({ muted, onChange, value, options, ...rest }) {
return ( return (
<RoomButton {...rest} on={enabled}> <DropdownButton onChange={onChange} options={options} value={value}>
{enabled ? <DisableVideoIcon /> : <VideoIcon />} <RoomButton {...rest} on={muted}>
</RoomButton> {muted ? <MuteMicIcon /> : <MicIcon />}
</RoomButton>
</DropdownButton>
);
}
export function VideoButton({ enabled, onChange, value, ...rest }) {
return (
<DropdownButton onChange={onChange} options={options} value={value}>
<RoomButton {...rest} on={enabled}>
{enabled ? <DisableVideoIcon /> : <VideoIcon />}
</RoomButton>
</DropdownButton>
); );
} }

View file

@ -15,7 +15,8 @@ limitations under the License.
*/ */
.roomButton, .roomButton,
.headerButton { .headerButton,
.dropdownButton {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -29,7 +30,7 @@ limitations under the License.
width: 50px; width: 50px;
height: 50px; height: 50px;
border-radius: 50px; border-radius: 50px;
background-color: rgba(111, 120, 130, 0.3); background-color: #394049;
} }
.roomButton:hover { .roomButton:hover {
@ -73,3 +74,34 @@ limitations under the License.
.screenshareButton.on svg * { .screenshareButton.on svg * {
fill: #0dbd8b; fill: #0dbd8b;
} }
.dropdownButtonContainer {
position: relative;
}
.dropdownButton {
width: 15px;
height: 15px;
border-radius: 15px;
background-color: #394049;
position: absolute;
bottom: 0;
right: 0;
}
.dropdownButton:hover {
background-color: #8d97a5;
}
.dropdownButton:hover svg * {
fill: #8d97a5;
}
.dropdownContainer {
position: absolute;
left: 50%;
transform: translate(-50%, -100%);
top: 0;
background-color: #394049;
border-radius: 8px;
}