diff --git a/src/icons/FullScreenMaximise.svg b/src/icons/FullScreenMaximise.svg new file mode 100644 index 00000000..1814f16e --- /dev/null +++ b/src/icons/FullScreenMaximise.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/icons/FullScreenMinimise.svg b/src/icons/FullScreenMinimise.svg new file mode 100644 index 00000000..204259e2 --- /dev/null +++ b/src/icons/FullScreenMinimise.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/tile/SpotlightTile.module.css b/src/tile/SpotlightTile.module.css index 78831571..622496d2 100644 --- a/src/tile/SpotlightTile.module.css +++ b/src/tile/SpotlightTile.module.css @@ -88,40 +88,48 @@ Please see LICENSE in the repository root for full details. padding: var(--cpd-space-2x); border: none; border-radius: var(--cpd-radius-pill-effect); - background: var(--cpd-color-alpha-gray-1400); + background: rgba(from var(--cpd-color-gray-100) r g b / 0.6); box-shadow: var(--small-drop-shadow); transition: opacity 0.15s, background-color 0.1s; - position: absolute; z-index: 1; --inset: 6px; inset-block-end: var(--inset); inset-inline-end: var(--inset); } +.bottomRightButtons { + display: flex; + gap: var(--cpd-space-2x); + position: absolute; + inset-block-end: var(--cpd-space-1x); + inset-inline-end: var(--cpd-space-1x); + z-index: 1; +} + .expand > svg { display: block; - color: var(--cpd-color-icon-on-solid-primary); + color: var(--cpd-color-icon-primary); } @media (hover) { .expand:hover { - background: var(--cpd-color-bg-action-primary-hovered); + background: var(--cpd-color-gray-400); } } .expand:active { - background: var(--cpd-color-bg-action-primary-pressed); + background: var(--cpd-color-gray-100); } @media (hover) { - .tile:hover > button { + .tile:hover > div > button { opacity: 1; } } -.tile:has(:focus-visible) > button { +.tile:has(:focus-visible) > div > button { opacity: 1; } diff --git a/src/tile/SpotlightTile.tsx b/src/tile/SpotlightTile.tsx index 8495e88b..8bc45a81 100644 --- a/src/tile/SpotlightTile.tsx +++ b/src/tile/SpotlightTile.tsx @@ -29,6 +29,8 @@ import classNames from "classnames"; import { type TrackReferenceOrPlaceholder } from "@livekit/components-core"; import { type RoomMember } from "matrix-js-sdk"; +import FullScreenMaximiseIcon from "../icons/FullScreenMaximise.svg?react"; +import FullScreenMinimiseIcon from "../icons/FullScreenMinimise.svg?react"; import { MediaView } from "./MediaView"; import styles from "./SpotlightTile.module.css"; import { @@ -210,6 +212,26 @@ export const SpotlightTile: FC = ({ const canGoBack = visibleIndex > 0; const canGoToNext = visibleIndex !== -1 && visibleIndex < media.length - 1; + const isFullscreen = useCallback((): boolean => { + const rootElement = document.body; + if (rootElement && document.fullscreenElement) return true; + return false; + }, []); + + const FullScreenIcon = isFullscreen() + ? FullScreenMinimiseIcon + : FullScreenMaximiseIcon; + + const onToggleFullscreen = useCallback(() => { + const rootElement = document.body; + if (!rootElement) return; + if (isFullscreen()) { + void document?.exitFullscreen(); + } else { + void rootElement.requestFullscreen(); + } + }, [isFullscreen]); + // To keep track of which item is visible, we need an intersection observer // hooked up to the root element and the items. Because the items will run // their effects before their parent does, we need to do this dance with an @@ -292,17 +314,28 @@ export const SpotlightTile: FC = ({ /> ))} - {onToggleExpanded && ( +
- )} + + {onToggleExpanded && ( + + )} +
+ {canGoToNext && (