diff --git a/apps/client/src/AppRouter.tsx b/apps/client/src/AppRouter.tsx index 0669c288c..308a52361 100644 --- a/apps/client/src/AppRouter.tsx +++ b/apps/client/src/AppRouter.tsx @@ -100,7 +100,7 @@ export default function AppRouter() { path='teleprompter' element={ - + } @@ -225,7 +225,11 @@ function PresetView() { const Component = PresetViewMap[preset.target as OntimeViewPresettable]; return ( - + {Component ? : } ); diff --git a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx index 7bf1f9181..cdc2c869f 100644 --- a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx +++ b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx @@ -3,7 +3,6 @@ import { memo } from 'react'; import { useSearchParams } from 'react-router'; import { hasCustomParams } from '../../stores/savedViewParams'; -import { useViewHotkeysStore } from '../../stores/viewHotkeys'; import { useViewParamsEditorStore } from '../view-params-editor/viewParamsEditor.store'; import FloatingNavigation from './floating-navigation/FloatingNavigation'; import NavigationMenu from './NavigationMenu'; @@ -14,10 +13,12 @@ interface ViewNavigationMenuProps { isNavigationLocked?: boolean; /** prevent showing settings */ suppressSettings?: boolean; + /** leave Space to the view, for views which need the key themselves */ + suppressSpaceHotkey?: boolean; } export default memo(ViewNavigationMenu); -function ViewNavigationMenu({ isNavigationLocked, suppressSettings }: ViewNavigationMenuProps) { +function ViewNavigationMenu({ isNavigationLocked, suppressSettings, suppressSpaceHotkey }: ViewNavigationMenuProps) { const [isMenuOpen, menuHandler] = useDisclosure(); const { open: showEditFormDrawer } = useViewParamsEditorStore(); const [searchParams] = useSearchParams(); @@ -27,9 +28,7 @@ function ViewNavigationMenu({ isNavigationLocked, suppressSettings }: ViewNaviga [ 'Space', () => { - if (isNavigationLocked) return; - // a view can take over Space for itself, see viewHotkeys store - if (useViewHotkeysStore.getState().spaceClaimed) return; + if (isNavigationLocked || suppressSpaceHotkey) return; menuHandler.toggle(); }, { preventDefault: true }, diff --git a/apps/client/src/common/stores/viewHotkeys.ts b/apps/client/src/common/stores/viewHotkeys.ts deleted file mode 100644 index 0d74754ce..000000000 --- a/apps/client/src/common/stores/viewHotkeys.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { create } from 'zustand'; - -interface ViewHotkeysStore { - /** a view has taken over the Space key and the navigation menu must not react to it */ - spaceClaimed: boolean; - claimSpace: () => void; - releaseSpace: () => void; -} - -/** - * Lets a view take ownership of a hotkey which the view chrome also binds. - * - * The navigation menu binds Space at document level, but the teleprompter needs - * it for playback, which is the convention every prompter and every foot pedal - * follows. Prop threading does not work here because AppRouter renders - * ViewNavigationMenu generically for presets, so the claim lives in a store - * which the view sets on mount and clears on unmount. - */ -export const useViewHotkeysStore = create((set) => ({ - spaceClaimed: false, - claimSpace: () => set({ spaceClaimed: true }), - releaseSpace: () => set({ spaceClaimed: false }), -})); diff --git a/apps/client/src/views/teleprompter/useTeleprompterControls.ts b/apps/client/src/views/teleprompter/useTeleprompterControls.ts index 5d827d785..af98d265a 100644 --- a/apps/client/src/views/teleprompter/useTeleprompterControls.ts +++ b/apps/client/src/views/teleprompter/useTeleprompterControls.ts @@ -1,7 +1,6 @@ import { useEffect, useRef } from 'react'; import { useViewParamsEditorStore } from '../../common/components/view-params-editor/viewParamsEditor.store'; -import { useViewHotkeysStore } from '../../common/stores/viewHotkeys'; import { resolveTeleprompterAction } from './teleprompter.keymap'; import type { TeleprompterAction, TeleprompterController } from './teleprompter.types'; @@ -18,22 +17,15 @@ const ignoredTags = new Set(['INPUT', 'TEXTAREA', 'SELECT']); /** * Binds the prompter keymap. * - * Space is claimed from the navigation menu for the lifetime of the view: it is - * the universal run/stop key on prompter software and on the centre pedal of - * every three pedal controller, so the view cannot leave it to the menu. + * Space is the universal run/stop key on prompter software and the centre pedal + * of every three pedal controller, so this view cannot leave it to the + * navigation menu. The routes which render the teleprompter pass + * suppressSpaceHotkey to ViewNavigationMenu so the menu stands down. */ export function useTeleprompterControls(args: UseTeleprompterControlsArgs) { const argsRef = useRef(args); argsRef.current = args; - const claimSpace = useViewHotkeysStore((state) => state.claimSpace); - const releaseSpace = useViewHotkeysStore((state) => state.releaseSpace); - - useEffect(() => { - claimSpace(); - return releaseSpace; - }, [claimSpace, releaseSpace]); - useEffect(() => { function applyAction(action: TeleprompterAction) { const { controller, onFlip, onFontSize, onResetFontSize, onToggleHelp } = argsRef.current;