Files
element-call/src/RoomButton.jsx

256 lines
6.5 KiB
React
Raw Normal View History

2021-12-03 13:17:44 -08:00
import React, { useRef, useState, useEffect, forwardRef } from "react";
2021-08-19 12:11:12 -07:00
import classNames from "classnames";
import styles from "./RoomButton.module.css";
import { ReactComponent as MicIcon } from "./icons/Mic.svg";
import { ReactComponent as MuteMicIcon } from "./icons/MuteMic.svg";
import { ReactComponent as VideoIcon } from "./icons/Video.svg";
import { ReactComponent as DisableVideoIcon } from "./icons/DisableVideo.svg";
import { ReactComponent as HangupIcon } from "./icons/Hangup.svg";
import { ReactComponent as SettingsIcon } from "./icons/Settings.svg";
2021-11-10 17:03:32 -08:00
import { ReactComponent as FreedomIcon } from "./icons/Freedom.svg";
import { ReactComponent as SpotlightIcon } from "./icons/Spotlight.svg";
2021-10-01 11:24:49 -07:00
import { ReactComponent as ScreenshareIcon } from "./icons/Screenshare.svg";
2021-10-07 17:25:40 -07:00
import { ReactComponent as ChevronIcon } from "./icons/Chevron.svg";
2021-12-02 17:21:37 -08:00
import { ReactComponent as UserIcon } from "./icons/User.svg";
import { ReactComponent as CheckIcon } from "./icons/Check.svg";
2021-12-03 16:42:29 -08:00
import { useButton } from "@react-aria/button";
2021-08-19 12:11:12 -07:00
2021-12-03 13:17:44 -08:00
export const RoomButton = forwardRef(
2021-12-06 12:19:38 -08:00
({ on, off, className, children, ...rest }, ref) => {
2021-12-03 16:42:29 -08:00
const { buttonProps } = useButton(rest, ref);
2021-12-03 13:17:44 -08:00
return (
<button
className={classNames(styles.roomButton, className, {
[styles.on]: on,
2021-12-06 12:19:38 -08:00
[styles.off]: off,
2021-12-03 13:17:44 -08:00
})}
2021-12-03 16:42:29 -08:00
{...buttonProps}
2021-12-03 13:17:44 -08:00
ref={ref}
>
{children}
</button>
);
}
);
2021-08-19 12:11:12 -07:00
2021-10-12 16:52:20 -07:00
export function DropdownButton({ onChange, options, value, children }) {
2021-10-07 17:25:40 -07:00
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 (
2021-10-12 16:52:20 -07:00
<div className={styles.dropdownButtonContainer}>
2021-10-07 17:25:40 -07:00
{children}
<button
ref={buttonRef}
className={styles.dropdownButton}
onClick={() => setOpen(true)}
>
<ChevronIcon />
</button>
{open && (
2021-10-12 16:52:20 -07:00
<div className={styles.dropdownContainer}>
2021-10-07 17:25:40 -07:00
<ul>
{options.map((item) => (
<li
key={item.value}
className={classNames({
2021-10-12 16:52:20 -07:00
[styles.dropdownActiveItem]: item.value === value,
2021-10-07 17:25:40 -07:00
})}
onClick={() => onChange(item)}
>
{item.label}
</li>
))}
</ul>
</div>
)}
</div>
);
}
2021-10-12 16:52:20 -07:00
export function MicButton({ muted, ...rest }) {
2021-08-19 12:11:12 -07:00
return (
2021-12-06 12:19:38 -08:00
<RoomButton {...rest} off={muted}>
2021-11-24 13:33:32 -08:00
<ButtonTooltip>
{muted ? "Unmute microphone" : "Mute microphone"}
</ButtonTooltip>
2021-10-12 16:52:20 -07:00
{muted ? <MuteMicIcon /> : <MicIcon />}
</RoomButton>
2021-08-19 12:11:12 -07:00
);
}
2021-12-06 12:19:38 -08:00
export function VideoButton({ muted, ...rest }) {
2021-08-19 12:11:12 -07:00
return (
2021-12-06 12:19:38 -08:00
<RoomButton {...rest} off={muted}>
2021-11-24 13:33:32 -08:00
<ButtonTooltip>
2021-12-06 12:19:38 -08:00
{muted ? "Turn on camera" : "Turn off camera"}
2021-11-24 13:33:32 -08:00
</ButtonTooltip>
2021-12-06 12:19:38 -08:00
{muted ? <DisableVideoIcon /> : <VideoIcon />}
2021-10-12 16:52:20 -07:00
</RoomButton>
2021-08-19 12:11:12 -07:00
);
}
2021-10-01 11:24:49 -07:00
export function ScreenshareButton({ enabled, className, ...rest }) {
return (
2021-12-06 12:19:38 -08:00
<RoomButton {...rest} on={enabled}>
2021-11-24 13:33:32 -08:00
<ButtonTooltip>
{enabled ? "Stop sharing screen" : "Share screen"}
</ButtonTooltip>
2021-10-01 11:24:49 -07:00
<ScreenshareIcon />
</RoomButton>
);
}
2021-08-19 12:11:12 -07:00
export function HangupButton({ className, ...rest }) {
return (
<RoomButton
className={classNames(styles.hangupButton, className)}
{...rest}
>
2021-11-24 13:33:32 -08:00
<ButtonTooltip>Leave</ButtonTooltip>
2021-08-19 12:11:12 -07:00
<HangupIcon />
</RoomButton>
);
}
2021-12-03 13:17:44 -08:00
export const HeaderButton = forwardRef(
({ on, className, children, ...rest }, ref) => {
2021-12-03 16:42:29 -08:00
const { buttonProps } = useButton(rest, ref);
2021-12-03 13:17:44 -08:00
return (
<button
className={classNames(styles.headerButton, className, {
[styles.on]: on,
})}
2021-12-03 16:42:29 -08:00
{...buttonProps}
2021-12-03 13:17:44 -08:00
ref={ref}
>
{children}
</button>
);
}
);
2021-08-19 12:11:12 -07:00
2021-12-02 17:21:37 -08:00
export function HeaderDropdownButton({ children, content }) {
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 (
<div className={styles.dropdownButtonContainer}>
<button
ref={buttonRef}
className={classNames(styles.headerButton, { [styles.on]: open })}
onClick={() => setOpen(true)}
>
{children}
</button>
{open && (
<div
className={classNames(
styles.dropdownContainer,
styles.headerDropdownContainer
)}
>
<ul>{content}</ul>
</div>
)}
</div>
);
}
export function HeaderDropdownItem({ active, children, className, ...rest }) {
return (
<li
className={classNames(className, {
[styles.dropdownActiveItem]: active,
})}
{...rest}
>
{children}
</li>
);
}
export function UserMenu({ userName, children }) {
return (
<HeaderDropdownButton content={children}>
<ButtonTooltip>Profile</ButtonTooltip>
<div className={styles.userButton}>
<UserIcon />
<span>{userName}</span>
</div>
</HeaderDropdownButton>
);
}
2021-08-19 12:11:12 -07:00
export function SettingsButton(props) {
return (
<HeaderButton {...props}>
2021-11-24 15:05:43 -08:00
<ButtonTooltip>Show Dev Tools</ButtonTooltip>
2021-11-10 17:03:32 -08:00
<SettingsIcon width={20} height={20} />
2021-08-19 12:11:12 -07:00
</HeaderButton>
);
}
2021-09-01 16:42:01 -07:00
2021-12-02 17:21:37 -08:00
export function LayoutToggleButton({ layout, setLayout, ...rest }) {
2021-09-01 16:42:01 -07:00
return (
2021-12-02 17:21:37 -08:00
<HeaderDropdownButton
{...rest}
content={
<>
<HeaderDropdownItem onClick={() => setLayout("freedom")}>
<FreedomIcon />
<span>Freedom</span>
{layout === "freedom" && <CheckIcon className={styles.checkIcon} />}
</HeaderDropdownItem>
<HeaderDropdownItem onClick={() => setLayout("spotlight")}>
<SpotlightIcon />
<span>Spotlight</span>
{layout === "spotlight" && (
<CheckIcon className={styles.checkIcon} />
)}
</HeaderDropdownItem>
</>
}
>
<ButtonTooltip>Layout Type</ButtonTooltip>
{layout === "spotlight" ? <SpotlightIcon /> : <FreedomIcon />}
</HeaderDropdownButton>
2021-09-01 16:42:01 -07:00
);
}
2021-11-24 13:33:32 -08:00
2021-11-24 15:05:43 -08:00
export function ButtonTooltip({ className, children }) {
return (
<div className={classNames(styles.buttonTooltip, className)}>
{children}
</div>
);
2021-11-24 13:33:32 -08:00
}