1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Backport pull request #5517 from jellyfin-web/release-10.9.z

Fix video osd not hiding in experimental layout

Original-merge: ea1d069e90

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
This commit is contained in:
thornbill 2024-05-17 13:52:45 -04:00 committed by Joshua M. Boniface
parent cb01afce02
commit 017734a0bb
7 changed files with 117 additions and 29 deletions

View file

@ -18,17 +18,30 @@ interface AppToolbarProps {
onDrawerButtonClick: (event: React.MouseEvent<HTMLElement>) => void
}
const PUBLIC_PATHS = [
'/addserver.html',
'/selectserver.html',
'/login.html',
'/forgotpassword.html',
'/forgotpasswordpin.html'
];
const ExperimentalAppToolbar: FC<AppToolbarProps> = ({
isDrawerAvailable,
isDrawerOpen,
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 = PUBLIC_PATHS.includes(location.pathname);
return (
<AppToolbar
buttons={
buttons={!isPublicPath && (
<>
<SyncPlayButton />
<RemotePlayButton />
@ -45,10 +58,11 @@ const ExperimentalAppToolbar: FC<AppToolbarProps> = ({
</IconButton>
</Tooltip>
</>
}
)}
isDrawerAvailable={isDrawerAvailable}
isDrawerOpen={isDrawerOpen}
onDrawerButtonClick={onDrawerButtonClick}
isUserMenuAvailable={!isPublicPath}
>
{isTabsAvailable && (<AppTabs isDrawerOpen={isDrawerOpen} />)}
</AppToolbar>

View file

@ -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: {

View file

@ -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: <ConnectionRequired isUserRequired />,
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: <VideoPage />
}
]
},

View file

@ -0,0 +1,72 @@
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 { EventType } from 'types/eventType';
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>(document);
const [ isVisible, setIsVisible ] = useState(true);
const onShowVideoOsd = (_e: Event, isShowing: boolean) => {
setIsVisible(isShowing);
};
useEffect(() => {
const doc = documentRef.current;
if (doc) Events.on(doc, EventType.SHOW_VIDEO_OSD, onShowVideoOsd);
return () => {
if (doc) Events.off(doc, EventType.SHOW_VIDEO_OSD, onShowVideoOsd);
};
}, []);
return (
<>
<Fade
in={isVisible}
easing='fade-out'
>
<Box sx={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
color: 'white'
}}>
<AppToolbar
isDrawerAvailable={false}
isDrawerOpen={false}
isUserMenuAvailable={false}
buttons={
<>
<SyncPlayButton />
<RemotePlayButton />
</>
}
/>
</Box>
</Fade>
<ViewManagerPage
controller='playback/video/index'
view='playback/video/index.html'
type='video-osd'
isFullscreen
isNowPlayingBarEnabled={false}
isThemeMediaSupported
/>
</>
);
};
export default VideoPage;

View file

@ -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<HTMLElement>) => void
onDrawerButtonClick?: (event: React.MouseEvent<HTMLElement>) => void,
isUserMenuAvailable?: boolean
}
const onBackButtonClick = () => {
@ -32,17 +32,14 @@ const AppToolbar: FC<AppToolbarProps> = ({
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 (
<Toolbar
variant='dense'
@ -84,16 +81,14 @@ const AppToolbar: FC<AppToolbarProps> = ({
{children}
{isUserLoggedIn && isUserMenuAvailable && (
<>
<Box sx={{ display: 'flex', flexGrow: 1, justifyContent: 'flex-end' }}>
{buttons}
</Box>
{isUserLoggedIn && isUserMenuAvailable && (
<Box sx={{ flexGrow: 0 }}>
<UserMenuButton />
</Box>
</>
)}
</Toolbar>
);

View file

@ -28,6 +28,7 @@ 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;
@ -280,12 +281,14 @@ export default function (view) {
let mouseIsDown = false;
function showOsd(focusElement) {
Events.trigger(document, EventType.SHOW_VIDEO_OSD, [ true ]);
slideDownToShow(headerElement);
showMainOsdControls(focusElement);
resetIdle();
}
function hideOsd() {
Events.trigger(document, EventType.SHOW_VIDEO_OSD, [ false ]);
slideUpToHide(headerElement);
hideMainOsdControls();
mouseManager.hideCursor();

6
src/types/eventType.ts Normal file
View file

@ -0,0 +1,6 @@
/**
* Custom event types.
*/
export enum EventType {
SHOW_VIDEO_OSD = 'SHOW_VIDEO_OSD'
}