diff --git a/package.json b/package.json index c3a511f7..4242b19c 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "react-use-clipboard": "^1.0.7", "react-use-measure": "^2.1.1", "sdp-transform": "^2.14.1", + "tinyqueue": "^2.0.3", "unique-names-generator": "^4.6.0" }, "devDependencies": { diff --git a/public/locales/en-GB/app.json b/public/locales/en-GB/app.json index b2bfc56d..809f5e4a 100644 --- a/public/locales/en-GB/app.json +++ b/public/locales/en-GB/app.json @@ -124,6 +124,7 @@ "Turn off camera": "Turn off camera", "Turn on camera": "Turn on camera", "Unmute microphone": "Unmute microphone", + "Use the upcoming grid system": "Use the upcoming grid system", "User ID": "User ID", "User menu": "User menu", "Username": "Username", diff --git a/src/room/InCallView.module.css b/src/room/InCallView.module.css index 8c37d465..04228aa9 100644 --- a/src/room/InCallView.module.css +++ b/src/room/InCallView.module.css @@ -20,9 +20,10 @@ limitations under the License. flex-direction: column; overflow: hidden; min-height: 100%; - position: fixed; height: 100%; width: 100%; + --footerPadding: 8px; + --footerHeight: calc(50px + 2 * var(--footerPadding)); } .centerMessage { @@ -39,11 +40,27 @@ limitations under the License. } .footer { - position: relative; + position: absolute; + left: 0; + bottom: 0; + width: 100%; display: flex; justify-content: center; align-items: center; - height: calc(50px + 2 * 8px); + padding: var(--footerPadding) 0; + /* TODO: Un-hardcode these colors */ + background: linear-gradient( + 360deg, + #15191e 0%, + rgba(21, 25, 30, 0.9) 37%, + rgba(21, 25, 30, 0.8) 49.68%, + rgba(21, 25, 30, 0.7) 56.68%, + rgba(21, 25, 30, 0.427397) 72.92%, + rgba(21, 25, 30, 0.257534) 81.06%, + rgba(21, 25, 30, 0.136986) 87.29%, + rgba(21, 25, 30, 0.0658079) 92.4%, + rgba(21, 25, 30, 0) 100% + ); } .footer > * { @@ -65,16 +82,22 @@ limitations under the License. top: 50%; left: 50%; transform: translate(-50%, -50%); + /* To make avatars scale smoothly with their tiles during animations, we + override the styles set on the element */ + --avatarSize: calc(min(var(--tileWidth), var(--tileHeight)) / 2); + width: var(--avatarSize) !important; + height: var(--avatarSize) !important; + border-radius: 10000px !important; } @media (min-height: 300px) { - .footer { - height: calc(50px + 2 * 24px); + .inRoom { + --footerPadding: 24px; } } @media (min-width: 800px) { - .footer { - height: calc(50px + 2 * 32px); + .inRoom { + --footerPadding: 32px; } } diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index 22145012..17a0fde4 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -41,7 +41,11 @@ import { RoomHeaderInfo, VersionMismatchWarning, } from "../Header"; -import { VideoGrid, useVideoGridLayout } from "../video-grid/VideoGrid"; +import { + VideoGrid, + useVideoGridLayout, + ChildrenProperties, +} from "../video-grid/VideoGrid"; import { VideoTileContainer } from "../video-grid/VideoTileContainer"; import { GroupCallInspector } from "./GroupCallInspector"; import { OverflowMenu } from "./OverflowMenu"; @@ -51,7 +55,11 @@ import { UserMenuContainer } from "../UserMenuContainer"; import { useRageshakeRequestModal } from "../settings/submit-rageshake"; import { RageshakeRequestModal } from "./RageshakeRequestModal"; import { useMediaHandler } from "../settings/useMediaHandler"; -import { useShowInspector, useSpatialAudio } from "../settings/useSetting"; +import { + useNewGrid, + useShowInspector, + useSpatialAudio, +} from "../settings/useSetting"; import { useModalTriggerState } from "../Modal"; import { useAudioContext } from "../video-grid/useMediaStream"; import { useFullscreen } from "../video-grid/useFullscreen"; @@ -64,6 +72,7 @@ import { ParticipantInfo } from "./useGroupCall"; import { TileDescriptor } from "../video-grid/TileDescriptor"; import { AudioSink } from "../video-grid/AudioSink"; import { useCallViewKeyboardShortcuts } from "../useCallViewKeyboardShortcuts"; +import { NewVideoGrid } from "../video-grid/NewVideoGrid"; const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {}); // There is currently a bug in Safari our our code with cloning and sending MediaStreams @@ -276,6 +285,8 @@ export function InCallView({ [] ); + const [newGrid] = useNewGrid(); + const Grid = newGrid ? NewVideoGrid : VideoGrid; const prefersReducedMotion = usePrefersReducedMotion(); const renderContent = (): JSX.Element => { @@ -289,8 +300,8 @@ export function InCallView({ if (maximisedParticipant) { return ( - {({ - item, - ...rest - }: { - item: TileDescriptor; - [x: string]: unknown; - }) => ( + {({ item, ...rest }: ChildrenProperties) => ( )} - + ); }; diff --git a/src/settings/SettingsModal.tsx b/src/settings/SettingsModal.tsx index 106ef9e0..244d1d15 100644 --- a/src/settings/SettingsModal.tsx +++ b/src/settings/SettingsModal.tsx @@ -33,6 +33,7 @@ import { useShowInspector, useOptInAnalytics, canEnableSpatialAudio, + useNewGrid, } from "./useSetting"; import { FieldRow, InputField } from "../input/Input"; import { Button } from "../button"; @@ -62,6 +63,7 @@ export const SettingsModal = (props: Props) => { const [showInspector, setShowInspector] = useShowInspector(); const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics(); const [keyboardShortcuts, setKeyboardShortcuts] = useKeyboardShortcuts(); + const [newGrid, setNewGrid] = useNewGrid(); const downloadDebugLog = useDownloadDebugLog(); @@ -216,6 +218,17 @@ export const SettingsModal = (props: Props) => { } /> + + ) => + setNewGrid(e.target.checked) + } + /> +