diff --git a/src/apps/experimental/components/AppToolbar/index.tsx b/src/apps/experimental/components/AppToolbar/index.tsx index 950fb63841..6a3016cafa 100644 --- a/src/apps/experimental/components/AppToolbar/index.tsx +++ b/src/apps/experimental/components/AppToolbar/index.tsx @@ -24,11 +24,16 @@ const ExperimentalAppToolbar: FC = ({ onDrawerButtonClick }) => { const location = useLocation(); + + // The video osd does not show the standard toolbar + if (location.pathname === '/video') return null; + const isTabsAvailable = isTabPath(location.pathname); + const isPublicPath = location.pathname === '/selectserver.html'; return ( @@ -45,10 +50,11 @@ const ExperimentalAppToolbar: FC = ({ - } + )} isDrawerAvailable={isDrawerAvailable} isDrawerOpen={isDrawerOpen} onDrawerButtonClick={onDrawerButtonClick} + isUserMenuAvailable={!isPublicPath} > {isTabsAvailable && ()} diff --git a/src/apps/experimental/routes/legacyRoutes/user.ts b/src/apps/experimental/routes/legacyRoutes/user.ts index 12e137bc96..2045495a10 100644 --- a/src/apps/experimental/routes/legacyRoutes/user.ts +++ b/src/apps/experimental/routes/legacyRoutes/user.ts @@ -49,16 +49,6 @@ export const LEGACY_USER_ROUTES: LegacyRoute[] = [ controller: 'user/subtitles/index', view: 'user/subtitles/index.html' } - }, { - path: 'video', - pageProps: { - controller: 'playback/video/index', - view: 'playback/video/index.html', - type: 'video-osd', - isFullscreen: true, - isNowPlayingBarEnabled: false, - isThemeMediaSupported: true - } }, { path: 'queue', pageProps: { diff --git a/src/apps/experimental/routes/routes.tsx b/src/apps/experimental/routes/routes.tsx index 718aaf10b6..47e0a9f7f5 100644 --- a/src/apps/experimental/routes/routes.tsx +++ b/src/apps/experimental/routes/routes.tsx @@ -7,8 +7,10 @@ import { toAsyncPageRoute } from 'components/router/AsyncRoute'; import { toViewManagerPageRoute } from 'components/router/LegacyRoute'; import { toRedirectRoute } from 'components/router/Redirect'; import AppLayout from '../AppLayout'; + import { ASYNC_USER_ROUTES } from './asyncRoutes'; import { LEGACY_PUBLIC_ROUTES, LEGACY_USER_ROUTES } from './legacyRoutes'; +import VideoPage from './video'; export const EXPERIMENTAL_APP_ROUTES: RouteObject[] = [ { @@ -20,7 +22,13 @@ export const EXPERIMENTAL_APP_ROUTES: RouteObject[] = [ element: , children: [ ...ASYNC_USER_ROUTES.map(toAsyncPageRoute), - ...LEGACY_USER_ROUTES.map(toViewManagerPageRoute) + ...LEGACY_USER_ROUTES.map(toViewManagerPageRoute), + + // The video page is special since it combines new controls with the legacy view + { + path: 'video', + element: + } ] }, diff --git a/src/apps/experimental/routes/video/index.tsx b/src/apps/experimental/routes/video/index.tsx new file mode 100644 index 0000000000..2630f843fd --- /dev/null +++ b/src/apps/experimental/routes/video/index.tsx @@ -0,0 +1,71 @@ +import Box from '@mui/material/Box/Box'; +import Fade from '@mui/material/Fade/Fade'; +import React, { useRef, type FC, useEffect, useState } from 'react'; + +import RemotePlayButton from 'apps/experimental/components/AppToolbar/RemotePlayButton'; +import SyncPlayButton from 'apps/experimental/components/AppToolbar/SyncPlayButton'; +import AppToolbar from 'components/toolbar/AppToolbar'; +import ViewManagerPage from 'components/viewManager/ViewManagerPage'; +import Events, { type Event } from 'utils/events'; + +/** + * Video player page component that renders mui controls for the top controls and the legacy view for everything else. + */ +const VideoPage: FC = () => { + const documentRef = useRef(document); + const [ isVisible, setIsVisible ] = useState(true); + + const onShowVideoOsd = (_e: Event, isShowing: boolean) => { + setIsVisible(isShowing); + }; + + useEffect(() => { + const doc = documentRef.current; + + if (doc) Events.on(doc, 'showVideoOsd', onShowVideoOsd); + + return () => { + if (doc) Events.off(doc, 'showVideoOsd', onShowVideoOsd); + }; + }, []); + + return ( + <> + + + + + + + } + /> + + + + + + ); +}; + +export default VideoPage; diff --git a/src/components/toolbar/AppToolbar.tsx b/src/components/toolbar/AppToolbar.tsx index be6cf36e8b..8283860f3c 100644 --- a/src/components/toolbar/AppToolbar.tsx +++ b/src/components/toolbar/AppToolbar.tsx @@ -5,7 +5,6 @@ import IconButton from '@mui/material/IconButton'; import Toolbar from '@mui/material/Toolbar'; import Tooltip from '@mui/material/Tooltip'; import React, { FC, ReactNode } from 'react'; -import { useLocation } from 'react-router-dom'; import { appRouter } from 'components/router/appRouter'; import { useApi } from 'hooks/useApi'; @@ -17,7 +16,8 @@ interface AppToolbarProps { buttons?: ReactNode isDrawerAvailable: boolean isDrawerOpen: boolean - onDrawerButtonClick: (event: React.MouseEvent) => void + onDrawerButtonClick?: (event: React.MouseEvent) => void, + isUserMenuAvailable?: boolean } const onBackButtonClick = () => { @@ -32,17 +32,14 @@ const AppToolbar: FC = ({ children, isDrawerAvailable, isDrawerOpen, - onDrawerButtonClick + onDrawerButtonClick = () => { /* no-op */ }, + isUserMenuAvailable = true }) => { const { user } = useApi(); const isUserLoggedIn = Boolean(user); - const currentLocation = useLocation(); const isBackButtonAvailable = appRouter.canGoBack(); - // Handles a specific case to hide the user menu on the select server page while authenticated - const isUserMenuAvailable = currentLocation.pathname !== '/selectserver.html'; - return ( = ({ {children} - {isUserLoggedIn && isUserMenuAvailable && ( - <> - - {buttons} - + + {buttons} + - - - - + {isUserLoggedIn && isUserMenuAvailable && ( + + + )} ); diff --git a/src/controllers/playback/video/index.js b/src/controllers/playback/video/index.js index 5f3b101877..5381820095 100644 --- a/src/controllers/playback/video/index.js +++ b/src/controllers/playback/video/index.js @@ -280,12 +280,14 @@ export default function (view) { let mouseIsDown = false; function showOsd(focusElement) { + Events.trigger(document, 'showVideoOsd', [ true ]); slideDownToShow(headerElement); showMainOsdControls(focusElement); resetIdle(); } function hideOsd() { + Events.trigger(document, 'showVideoOsd', [ false ]); slideUpToHide(headerElement); hideMainOsdControls(); mouseManager.hideCursor();