From efceb930e51ea8a62c4b357f235687268c2905da Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Mon, 11 Aug 2025 06:35:54 +0200 Subject: [PATCH] refactor: improve navigation and settings locks --- apps/client/src/AppRouter.tsx | 20 ++++++++--------- .../navigation-menu/ViewNavigationMenu.tsx | 18 +++++++-------- .../FloatingNavigation.tsx | 22 ++++++++++--------- apps/client/src/externals.ts | 2 +- .../src/features/operator/OperatorExport.tsx | 4 ++-- .../src/features/rundown/RundownExport.tsx | 3 ++- .../src/features/sharing/GenerateLinkForm.tsx | 13 +++++++++-- .../src/views/cuesheet/CuesheetPage.tsx | 4 ++-- 8 files changed, 49 insertions(+), 37 deletions(-) diff --git a/apps/client/src/AppRouter.tsx b/apps/client/src/AppRouter.tsx index 4c372d62c..711b5e13c 100644 --- a/apps/client/src/AppRouter.tsx +++ b/apps/client/src/AppRouter.tsx @@ -11,7 +11,7 @@ import Log from './features/log/Log'; import Loader from './views/common/loader/Loader'; import NotFound from './views/common/not-found/NotFound'; import ViewLoader from './views/ViewLoader'; -import { getIsViewLocked, sessionScope } from './externals'; +import { getIsNavigationLocked, sessionScope } from './externals'; import { initializeSentry } from './sentry.config'; const Timer = lazy(() => import('./views/timer/Timer')); @@ -45,7 +45,7 @@ export default function AppRouter() { path='timer' element={ - + } @@ -54,7 +54,7 @@ export default function AppRouter() { path='countdown' element={ - + } @@ -63,7 +63,7 @@ export default function AppRouter() { path='backstage' element={ - + } @@ -72,7 +72,7 @@ export default function AppRouter() { path='studio' element={ - + } @@ -81,7 +81,7 @@ export default function AppRouter() { path='timeline' element={ - + } @@ -90,7 +90,7 @@ export default function AppRouter() { path='info' element={ - + } @@ -198,7 +198,7 @@ function PresetView() { if (!preset) { return ( <> - + ); @@ -212,7 +212,7 @@ function PresetView() { return ( {preset.target !== OntimeView.Cuesheet && ( - + )} {Component ? : } @@ -243,7 +243,7 @@ function RedirectPreset() { return ( <> - + ); diff --git a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx index df039d939..bd4271528 100644 --- a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx +++ b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx @@ -8,14 +8,14 @@ import ViewLockedIcon from './view-locked-icon/ViewLockedIcon'; import NavigationMenu from './NavigationMenu'; interface ViewNavigationMenuProps { - /** prevent navigation and settings*/ - isViewLocked?: boolean; + /** prevent navigation */ + isNavigationLocked?: boolean; /** prevent showing settings */ suppressSettings?: boolean; } export default memo(ViewNavigationMenu); -function ViewNavigationMenu({ isViewLocked, suppressSettings }: ViewNavigationMenuProps) { +function ViewNavigationMenu({ isNavigationLocked, suppressSettings }: ViewNavigationMenuProps) { const [isMenuOpen, menuHandler] = useDisclosure(); const { open: showEditFormDrawer } = useViewParamsEditorStore(); @@ -23,7 +23,7 @@ function ViewNavigationMenu({ isViewLocked, suppressSettings }: ViewNavigationMe [ 'Space', () => { - if (isViewLocked) return; + if (isNavigationLocked) return; menuHandler.toggle(); }, { preventDefault: true }, @@ -31,24 +31,24 @@ function ViewNavigationMenu({ isViewLocked, suppressSettings }: ViewNavigationMe [ 'mod + ,', () => { - if (isViewLocked || suppressSettings) return; + if (suppressSettings) return; showEditFormDrawer(); }, { preventDefault: true }, ], ]); - if (isViewLocked) { + if (isNavigationLocked && suppressSettings) { return ; } return ( <> showEditFormDrawer()} + toggleMenu={isNavigationLocked ? undefined : menuHandler.toggle} + toggleSettings={suppressSettings ? undefined : showEditFormDrawer} /> - + {!isNavigationLocked && } ); } diff --git a/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.tsx b/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.tsx index f9f6643ae..9c695b04a 100644 --- a/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.tsx +++ b/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.tsx @@ -8,7 +8,7 @@ import IconButton from '../../buttons/IconButton'; import style from './FloatingNavigation.module.scss'; interface FloatingNavigationProps { - toggleMenu: () => void; + toggleMenu?: () => void; toggleSettings?: () => void; } @@ -20,15 +20,17 @@ export default function FloatingNavigation({ toggleMenu, toggleSettings }: Float id='fadeable-navigation' className={cx([style.fadeable, style.buttonContainer, !isButtonShown && style.hidden])} > - - - + {toggleMenu && ( + + + + )} {toggleSettings && ( window.location.search.includes('n=1'); +export const getIsNavigationLocked = () => new URLSearchParams(window.location.search).get('n') === '1'; /** * The session scope is read from the cookie and will only exist if the app is password protected diff --git a/apps/client/src/features/operator/OperatorExport.tsx b/apps/client/src/features/operator/OperatorExport.tsx index 57bc65224..fc5bc47d9 100644 --- a/apps/client/src/features/operator/OperatorExport.tsx +++ b/apps/client/src/features/operator/OperatorExport.tsx @@ -1,13 +1,13 @@ import ViewNavigationMenu from '../../common/components/navigation-menu/ViewNavigationMenu'; import ProtectRoute from '../../common/components/protect-route/ProtectRoute'; -import { getIsViewLocked } from '../../externals'; +import { getIsNavigationLocked } from '../../externals'; import Operator from './Operator'; export default function OperatorExport() { return ( - + ); diff --git a/apps/client/src/features/rundown/RundownExport.tsx b/apps/client/src/features/rundown/RundownExport.tsx index b46c6d38a..b410d64ab 100644 --- a/apps/client/src/features/rundown/RundownExport.tsx +++ b/apps/client/src/features/rundown/RundownExport.tsx @@ -55,10 +55,11 @@ function RundownExport() {
+ {isExtracted && }
- handleLinks('rundown', event)} /> + {!isExtracted && handleLinks('rundown', event)} />} diff --git a/apps/client/src/features/sharing/GenerateLinkForm.tsx b/apps/client/src/features/sharing/GenerateLinkForm.tsx index 1d43779c2..a54730254 100644 --- a/apps/client/src/features/sharing/GenerateLinkForm.tsx +++ b/apps/client/src/features/sharing/GenerateLinkForm.tsx @@ -227,16 +227,25 @@ export default function GenerateLinkForm({ hostOptions, pathOptions, presets, is name='lockNav' checked={watch('lockNav')} onCheckedChange={(checked) => setValue('lockNav', checked, { shouldDirty: true })} + disabled={watch('lockConfig')} /> {watch('path') !== OntimeView.Cuesheet && ( - + setValue('lockConfig', checked, { shouldDirty: true })} + onCheckedChange={(checked) => { + if (checked) { + setValue('lockNav', checked, { shouldDirty: true }); + } + setValue('lockConfig', checked, { shouldDirty: true }); + }} /> )} diff --git a/apps/client/src/views/cuesheet/CuesheetPage.tsx b/apps/client/src/views/cuesheet/CuesheetPage.tsx index 37daf3c92..8d56b02f5 100644 --- a/apps/client/src/views/cuesheet/CuesheetPage.tsx +++ b/apps/client/src/views/cuesheet/CuesheetPage.tsx @@ -4,7 +4,7 @@ import { useDisclosure } from '@mantine/hooks'; import IconButton from '../../common/components/buttons/IconButton'; import NavigationMenu from '../../common/components/navigation-menu/NavigationMenu'; import { useWindowTitle } from '../../common/hooks/useWindowTitle'; -import { getIsViewLocked } from '../../externals'; +import { getIsNavigationLocked } from '../../externals'; import CuesheetOverview from '../../features/overview/CuesheetOverview'; import CuesheetEditModal from './cuesheet-edit-modal/CuesheetEditModal'; @@ -18,7 +18,7 @@ export default function CuesheetPage() { useWindowTitle('Cuesheet'); - const isLocked = getIsViewLocked(); + const isLocked = getIsNavigationLocked(); return ( <>