From c0467b1f137c6ce7bd7568a6bdd8461e95154770 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 15 May 2024 14:56:59 -0400 Subject: [PATCH 1/4] Fix video osd not hiding in experimental layout --- .../components/AppToolbar/index.tsx | 10 ++- .../experimental/routes/legacyRoutes/user.ts | 10 --- src/apps/experimental/routes/routes.tsx | 10 ++- src/apps/experimental/routes/video/index.tsx | 71 +++++++++++++++++++ src/components/toolbar/AppToolbar.tsx | 27 +++---- src/controllers/playback/video/index.js | 2 + 6 files changed, 101 insertions(+), 29 deletions(-) create mode 100644 src/apps/experimental/routes/video/index.tsx 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(); From 32a91eabf1acd8bf99588a2864540cb2ccd8739c Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 16 May 2024 00:28:07 -0400 Subject: [PATCH 2/4] Use constant for event name --- src/apps/experimental/routes/video/index.tsx | 5 +++-- src/controllers/playback/video/index.js | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/apps/experimental/routes/video/index.tsx b/src/apps/experimental/routes/video/index.tsx index 2630f843fd..1889ae5937 100644 --- a/src/apps/experimental/routes/video/index.tsx +++ b/src/apps/experimental/routes/video/index.tsx @@ -6,6 +6,7 @@ import RemotePlayButton from 'apps/experimental/components/AppToolbar/RemotePlay import SyncPlayButton from 'apps/experimental/components/AppToolbar/SyncPlayButton'; import AppToolbar from 'components/toolbar/AppToolbar'; import ViewManagerPage from 'components/viewManager/ViewManagerPage'; +import { SHOW_OSD_EVENT } from 'controllers/playback/video'; import Events, { type Event } from 'utils/events'; /** @@ -22,10 +23,10 @@ const VideoPage: FC = () => { useEffect(() => { const doc = documentRef.current; - if (doc) Events.on(doc, 'showVideoOsd', onShowVideoOsd); + if (doc) Events.on(doc, SHOW_OSD_EVENT, onShowVideoOsd); return () => { - if (doc) Events.off(doc, 'showVideoOsd', onShowVideoOsd); + if (doc) Events.off(doc, SHOW_OSD_EVENT, onShowVideoOsd); }; }, []); diff --git a/src/controllers/playback/video/index.js b/src/controllers/playback/video/index.js index 5381820095..70bf73d5fd 100644 --- a/src/controllers/playback/video/index.js +++ b/src/controllers/playback/video/index.js @@ -32,6 +32,8 @@ import { PluginType } from '../../../types/plugin.ts'; const TICKS_PER_MINUTE = 600000000; const TICKS_PER_SECOND = 10000000; +export const SHOW_OSD_EVENT = 'showVideoOsd'; + function getOpenedDialog() { return document.querySelector('.dialogContainer .dialog.opened'); } @@ -280,14 +282,14 @@ export default function (view) { let mouseIsDown = false; function showOsd(focusElement) { - Events.trigger(document, 'showVideoOsd', [ true ]); + Events.trigger(document, SHOW_OSD_EVENT, [ true ]); slideDownToShow(headerElement); showMainOsdControls(focusElement); resetIdle(); } function hideOsd() { - Events.trigger(document, 'showVideoOsd', [ false ]); + Events.trigger(document, SHOW_OSD_EVENT, [ false ]); slideUpToHide(headerElement); hideMainOsdControls(); mouseManager.hideCursor(); From 1a172bdb1b85769132385a546bc3689506ce657f Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 16 May 2024 12:34:41 -0400 Subject: [PATCH 3/4] Move event type to enum --- src/apps/experimental/routes/video/index.tsx | 6 +++--- src/controllers/playback/video/index.js | 7 +++---- src/types/eventType.ts | 6 ++++++ 3 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 src/types/eventType.ts diff --git a/src/apps/experimental/routes/video/index.tsx b/src/apps/experimental/routes/video/index.tsx index 1889ae5937..f9322352d5 100644 --- a/src/apps/experimental/routes/video/index.tsx +++ b/src/apps/experimental/routes/video/index.tsx @@ -6,7 +6,7 @@ import RemotePlayButton from 'apps/experimental/components/AppToolbar/RemotePlay import SyncPlayButton from 'apps/experimental/components/AppToolbar/SyncPlayButton'; import AppToolbar from 'components/toolbar/AppToolbar'; import ViewManagerPage from 'components/viewManager/ViewManagerPage'; -import { SHOW_OSD_EVENT } from 'controllers/playback/video'; +import { EventType } from 'types/eventType'; import Events, { type Event } from 'utils/events'; /** @@ -23,10 +23,10 @@ const VideoPage: FC = () => { useEffect(() => { const doc = documentRef.current; - if (doc) Events.on(doc, SHOW_OSD_EVENT, onShowVideoOsd); + if (doc) Events.on(doc, EventType.SHOW_VIDEO_OSD, onShowVideoOsd); return () => { - if (doc) Events.off(doc, SHOW_OSD_EVENT, onShowVideoOsd); + if (doc) Events.off(doc, EventType.SHOW_VIDEO_OSD, onShowVideoOsd); }; }, []); diff --git a/src/controllers/playback/video/index.js b/src/controllers/playback/video/index.js index 70bf73d5fd..6fa5798f79 100644 --- a/src/controllers/playback/video/index.js +++ b/src/controllers/playback/video/index.js @@ -28,12 +28,11 @@ import LibraryMenu from '../../../scripts/libraryMenu'; import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components/backdrop/backdrop'; import { pluginManager } from '../../../components/pluginManager'; import { PluginType } from '../../../types/plugin.ts'; +import { EventType } from 'types/eventType'; const TICKS_PER_MINUTE = 600000000; const TICKS_PER_SECOND = 10000000; -export const SHOW_OSD_EVENT = 'showVideoOsd'; - function getOpenedDialog() { return document.querySelector('.dialogContainer .dialog.opened'); } @@ -282,14 +281,14 @@ export default function (view) { let mouseIsDown = false; function showOsd(focusElement) { - Events.trigger(document, SHOW_OSD_EVENT, [ true ]); + Events.trigger(document, EventType.SHOW_VIDEO_OSD, [ true ]); slideDownToShow(headerElement); showMainOsdControls(focusElement); resetIdle(); } function hideOsd() { - Events.trigger(document, SHOW_OSD_EVENT, [ false ]); + Events.trigger(document, EventType.SHOW_VIDEO_OSD, [ false ]); slideUpToHide(headerElement); hideMainOsdControls(); mouseManager.hideCursor(); diff --git a/src/types/eventType.ts b/src/types/eventType.ts new file mode 100644 index 0000000000..929893ccbc --- /dev/null +++ b/src/types/eventType.ts @@ -0,0 +1,6 @@ +/** + * Custom event types. + */ +export enum EventType { + SHOW_VIDEO_OSD = 'SHOW_VIDEO_OSD' +} From 37b1d5cbea98951199e1c729bcf31c004ddaff0f Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 16 May 2024 16:58:40 -0400 Subject: [PATCH 4/4] Add more public paths to toolbar check --- src/apps/experimental/components/AppToolbar/index.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/apps/experimental/components/AppToolbar/index.tsx b/src/apps/experimental/components/AppToolbar/index.tsx index 6a3016cafa..e8626fd397 100644 --- a/src/apps/experimental/components/AppToolbar/index.tsx +++ b/src/apps/experimental/components/AppToolbar/index.tsx @@ -18,6 +18,14 @@ interface AppToolbarProps { onDrawerButtonClick: (event: React.MouseEvent) => void } +const PUBLIC_PATHS = [ + '/addserver.html', + '/selectserver.html', + '/login.html', + '/forgotpassword.html', + '/forgotpasswordpin.html' +]; + const ExperimentalAppToolbar: FC = ({ isDrawerAvailable, isDrawerOpen, @@ -29,7 +37,7 @@ const ExperimentalAppToolbar: FC = ({ if (location.pathname === '/video') return null; const isTabsAvailable = isTabPath(location.pathname); - const isPublicPath = location.pathname === '/selectserver.html'; + const isPublicPath = PUBLIC_PATHS.includes(location.pathname); return (