diff --git a/package.json b/package.json
index 4bdcbbb..0e3d1f3 100644
--- a/package.json
+++ b/package.json
@@ -11,9 +11,12 @@
"@react-aria/focus": "^3.5.0",
"@react-aria/menu": "^3.3.0",
"@react-aria/overlays": "^3.7.3",
+ "@react-aria/select": "^3.6.0",
+ "@react-aria/tabs": "^3.1.0",
"@react-aria/utils": "^3.10.0",
"@react-stately/collections": "^3.3.4",
"@react-stately/overlays": "^3.1.3",
+ "@react-stately/select": "^3.1.3",
"@react-stately/tree": "^3.2.0",
"@sentry/react": "^6.13.3",
"@sentry/tracing": "^6.13.3",
diff --git a/src/App.jsx b/src/App.jsx
index 52150b8..026d24c 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -30,6 +30,7 @@ import { RegisterPage } from "./RegisterPage";
import { LoginPage } from "./LoginPage";
import { Center } from "./Layout";
import { GuestAuthPage } from "./GuestAuthPage";
+import { OverlayProvider } from "@react-aria/overlays";
const SentryRoute = Sentry.withSentryRouting(Route);
@@ -49,7 +50,7 @@ export default function App() {
return (
- <>
+
{loading ? (
Loading...
@@ -74,7 +75,7 @@ export default function App() {
)}
- >
+
);
}
diff --git a/src/GridLayoutMenu.jsx b/src/GridLayoutMenu.jsx
index 57eee1f..a5d5665 100644
--- a/src/GridLayoutMenu.jsx
+++ b/src/GridLayoutMenu.jsx
@@ -1,36 +1,36 @@
import React, { useCallback } from "react";
import { ButtonTooltip, HeaderButton } from "./RoomButton";
-import { Popover, PopoverMenu, PopoverMenuItem } from "./PopoverMenu";
+import { PopoverMenuTrigger } from "./PopoverMenu";
import { ReactComponent as SpotlightIcon } from "./icons/Spotlight.svg";
import { ReactComponent as FreedomIcon } from "./icons/Freedom.svg";
import { ReactComponent as CheckIcon } from "./icons/Check.svg";
import styles from "./GridLayoutMenu.module.css";
+import { Menu } from "./Menu";
+import { Item } from "@react-stately/collections";
export function GridLayoutMenu({ layout, setLayout }) {
- const onAction = useCallback((value) => setLayout(value));
-
return (
-
+
Layout Type
{layout === "spotlight" ? : }
{(props) => (
-
-
+
-
+
+ -
Spotlight
{layout === "spotlight" && (
)}
-
-
+
+
)}
-
+
);
}
diff --git a/src/InviteModal.jsx b/src/InviteModal.jsx
index 7986896..18c35ac 100644
--- a/src/InviteModal.jsx
+++ b/src/InviteModal.jsx
@@ -1,25 +1,14 @@
import React from "react";
-import { Overlay } from "./Overlay";
import { Modal, ModalContent } from "./Modal";
import { CopyButton } from "./CopyButton";
-import { HeaderButton, ButtonTooltip } from "./RoomButton";
-import { ReactComponent as AddUserIcon } from "./icons/AddUser.svg";
-export function InviteModalButton({ roomUrl }) {
+export function InviteModal({ roomUrl, ...rest }) {
return (
-
-
- Add User
-
-
- {(modalProps) => (
-
-
- Copy and share this meeting link
-
-
-
- )}
-
+
+
+ Copy and share this meeting link
+
+
+
);
}
diff --git a/src/ListBox.jsx b/src/ListBox.jsx
new file mode 100644
index 0000000..478b6f0
--- /dev/null
+++ b/src/ListBox.jsx
@@ -0,0 +1,50 @@
+import React, { useRef } from "react";
+import { useListBox, useOption } from "@react-aria/listbox";
+import styles from "./ListBox.module.css";
+import classNames from "classnames";
+
+export function ListBox(props) {
+ const ref = useRef();
+ let { listBoxRef = ref, state } = props;
+ const { listBoxProps } = useListBox(props, state, listBoxRef);
+
+ return (
+
+
- {popoverMenuState.isOpen &&
- popover({
- isOpen: popoverMenuState.isOpen,
- onClose: popoverMenuState.close,
- autoFocus: popoverMenuState.focusStrategy,
- domProps: menuProps,
- ref: popoverRef,
- positionProps,
- ...rest,
- })}
+ {popoverMenuState.isOpen && (
+
+ {popoverMenu({
+ ...menuProps,
+ autoFocus: popoverMenuState.focusStrategy,
+ onClose: popoverMenuState.close,
+ })}
+
+ )}
);
}
-
-export const Popover = forwardRef((props, ref) => {
- const state = useTreeState({ ...props, selectionMode: "none" });
- const menuRef = useRef();
- const { menuProps } = useMenu(props, state, menuRef);
- const { overlayProps } = useOverlay(
- {
- onClose: props.onClose,
- shouldCloseOnBlur: true,
- isOpen: true,
- isDismissable: true,
- },
- ref
- );
-
- return (
-
-
-
-
-
- {[...state.collection].map((item) => (
-
- ))}
-
-
-
-
-
- );
-});
-
-function PopoverMenuItemContainer({ item, state, onAction, onClose }) {
- const ref = useRef();
- const { menuItemProps } = useMenuItem(
- {
- key: item.key,
- isDisabled: item.isDisabled,
- onAction,
- onClose,
- },
- state,
- ref
- );
-
- const [isFocused, setFocused] = useState(false);
- const { focusProps } = useFocus({ onFocusChange: setFocused });
-
- return (
-
- {item.rendered}
-
- );
-}
-
-export const PopoverMenuItem = Item;
diff --git a/src/PopoverMenu.module.css b/src/PopoverMenu.module.css
index 241f7b8..f0efdc9 100644
--- a/src/PopoverMenu.module.css
+++ b/src/PopoverMenu.module.css
@@ -1,49 +1,4 @@
-.popover {
- display: flex;
- flex-direction: column;
- width: 194px;
- background: var(--bgColor2);
- box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
- border-radius: 8px;
-}
-
-.popoverMenu {
- width: 100%;
- padding: 0;
- margin: 0;
- list-style: none;
-}
-
-.popoverMenuItem {
- cursor: pointer;
- height: 48px;
- display: flex;
- align-items: center;
- padding: 0 12px;
- color: var(--textColor1);
- font-size: 14px;
-}
-
-.popoverMenuItem > * {
- margin-right: 10px;
-}
-
-.popoverMenuItem > :last-child {
- margin-right: 0;
-}
-
-.popoverMenuItem.focused,
-.popoverMenuItem:hover {
- background-color: var(--bgColor3);
- outline: none;
-}
-
-.popoverMenuItem.focused:first-child,
-.popoverMenuItem:hover:first-child {
- border-radius: 8px 8px 0 0;
-}
-
-.popoverMenuItem.focused:last-child,
-.popoverMenuItem:hover:last-child {
- border-radius: 0 0 8px 8px;
+.popoverMenuTrigger {
+ position: relative;
+ display: inline-block;
}
diff --git a/src/Room.jsx b/src/Room.jsx
index c39b367..c427312 100644
--- a/src/Room.jsx
+++ b/src/Room.jsx
@@ -21,7 +21,6 @@ import {
HangupButton,
MicButton,
VideoButton,
- LayoutToggleButton,
ScreenshareButton,
DropdownButton,
} from "./RoomButton";
@@ -47,10 +46,10 @@ import { fetchGroupCall } from "./ConferenceCallManagerHooks";
import { ErrorModal } from "./ErrorModal";
import { GroupCallInspector } from "./GroupCallInspector";
import * as Sentry from "@sentry/react";
-import { InviteModalButton } from "./InviteModal";
import { OverflowMenu } from "./OverflowMenu";
import { GridLayoutMenu } from "./GridLayoutMenu";
import { UserMenu } from "./UserMenu";
+import { useMediaHandler } from "./useMediaHandler";
const canScreenshare = "getDisplayMedia" in navigator.mediaDevices;
// There is currently a bug in Safari our our code with cloning and sending MediaStreams
@@ -351,77 +350,6 @@ function RoomSetupView({
);
}
-function useMediaHandler(client) {
- const [{ audioInput, videoInput, audioInputs, videoInputs }, setState] =
- useState(() => {
- const mediaHandler = client.getMediaHandler();
-
- return {
- audioInput: mediaHandler.audioInput,
- videoInput: mediaHandler.videoInput,
- audioInputs: [],
- videoInputs: [],
- };
- });
-
- useEffect(() => {
- const mediaHandler = client.getMediaHandler();
-
- 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) => ({
- audioInput: mediaHandler.audioInput,
- videoInput: mediaHandler.videoInput,
- audioInputs,
- videoInputs,
- }));
- });
- }
-
- updateDevices();
-
- mediaHandler.on("local_streams_changed", updateDevices);
- navigator.mediaDevices.addEventListener("devicechange", updateDevices);
-
- return () => {
- mediaHandler.removeListener("local_streams_changed", updateDevices);
- 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({
onLogout,
client,
@@ -443,15 +371,6 @@ function InRoomView({
const [layout, setLayout] = useVideoGridLayout();
- const {
- audioInput,
- audioInputs,
- setAudioInput,
- videoInput,
- videoInputs,
- setVideoInput,
- } = useMediaHandler(client);
-
const items = useMemo(() => {
const participants = [];
@@ -539,7 +458,12 @@ function InRoomView({
onPress={toggleScreensharing}
/>
)}
-
+