+
+ {t("settings.preferences.spatialNavigation")}
+
+
+ {t("settings.preferences.spatialNavigationDescription")}
+
+
+
+
+ {t("settings.preferences.spatialNavigationLabel")}
+
+
+
+
{/* Keyboard Shortcuts Preference */}
diff --git a/src/setup/App.tsx b/src/setup/App.tsx
index aa3cd373b..de8a79fd1 100644
--- a/src/setup/App.tsx
+++ b/src/setup/App.tsx
@@ -18,8 +18,10 @@ import { KeyboardCommandsModal } from "@/components/overlays/KeyboardCommandsMod
import { NotificationModal } from "@/components/overlays/notificationsModal";
import { SupportInfoModal } from "@/components/overlays/SupportInfoModal";
import { TraktAuthHandler } from "@/components/TraktAuthHandler";
+import { useGamepadPolling } from "@/hooks/useGamepad";
import { useGlobalKeyboardEvents } from "@/hooks/useGlobalKeyboardEvents";
import { useOnlineListener } from "@/hooks/usePing";
+import { useSpatialNavigation } from "@/hooks/useSpatialNavigation";
import { AboutPage } from "@/pages/About";
import { AdminPage } from "@/pages/admin/AdminPage";
import { AllBookmarks } from "@/pages/bookmarks/AllBookmarks";
@@ -108,13 +110,23 @@ function QueryView() {
export const maintenanceTime = "March 31th 11:00 PM - 5:00 AM EST";
function App() {
+ const location = useLocation();
useHistoryListener();
useOnlineListener();
- useGlobalKeyboardEvents();
useClearModalsOnNavigation();
const maintenance = false; // Shows maintance page
const [showDowntime, setShowDowntime] = useState(maintenance);
+ const {
+ handleAction,
+ currentRect,
+ resetNavigation,
+ updateFocusableElements,
+ } = useSpatialNavigation();
+
+ useGlobalKeyboardEvents(handleAction);
+ useGamepadPolling({ onAction: handleAction, enabled: true });
+
const handleButtonClick = () => {
setShowDowntime(false);
};
@@ -127,6 +139,13 @@ function App() {
}
}, [setShowDowntime, maintenance]);
+ useEffect(() => {
+ resetNavigation();
+ requestAnimationFrame(() => {
+ updateFocusableElements();
+ });
+ }, [location.pathname, resetNavigation, updateFocusableElements]);
+
return (
@@ -231,6 +250,17 @@ function App() {
} />
)}
+ {currentRect && (
+
+ )}
{showDowntime && (
)}
diff --git a/src/stores/player/slices/source.ts b/src/stores/player/slices/source.ts
index b3c9b566a..edc311591 100644
--- a/src/stores/player/slices/source.ts
+++ b/src/stores/player/slices/source.ts
@@ -431,9 +431,8 @@ export const createSourceSlice: MakeSlice = (set, get) => ({
});
try {
- const { scrapeExternalSubtitles } = await import(
- "@/utils/externalSubtitles"
- );
+ const { scrapeExternalSubtitles } =
+ await import("@/utils/externalSubtitles");
const externalCaptions = await scrapeExternalSubtitles(store.meta);
if (externalCaptions.length > 0) {
diff --git a/src/stores/preferences/index.tsx b/src/stores/preferences/index.tsx
index 1c744df18..3923df261 100644
--- a/src/stores/preferences/index.tsx
+++ b/src/stores/preferences/index.tsx
@@ -41,6 +41,7 @@ export interface PreferencesStore {
enableNumberKeySeeking: boolean;
enablePauseOverlay: boolean;
enableGamepadControls: boolean;
+ enableSpatialNavigation: boolean;
gamepadMapping: Record;
keyboardShortcuts: KeyboardShortcuts;
@@ -77,6 +78,7 @@ export interface PreferencesStore {
setEnableNumberKeySeeking(v: boolean): void;
setEnablePauseOverlay(v: boolean): void;
setEnableGamepadControls(v: boolean): void;
+ setEnableSpatialNavigation(v: boolean): void;
setGamepadMapping(v: Record): void;
setKeyboardShortcuts(v: KeyboardShortcuts): void;
}
@@ -117,6 +119,7 @@ export const usePreferencesStore = create(
enableNumberKeySeeking: true,
enablePauseOverlay: false,
enableGamepadControls: false,
+ enableSpatialNavigation: true,
gamepadMapping: {},
keyboardShortcuts: DEFAULT_KEYBOARD_SHORTCUTS,
setEnableThumbnails(v) {
@@ -289,6 +292,11 @@ export const usePreferencesStore = create(
s.enableGamepadControls = v;
});
},
+ setEnableSpatialNavigation(v) {
+ set((s) => {
+ s.enableSpatialNavigation = v;
+ });
+ },
setGamepadMapping(v) {
set((s) => {
s.gamepadMapping = v;
diff --git a/src/utils/autoplay.ts b/src/utils/autoplay.ts
index aee01ffbc..99f18cab1 100644
--- a/src/utils/autoplay.ts
+++ b/src/utils/autoplay.ts
@@ -5,7 +5,7 @@ import { useAuthStore } from "@/stores/auth";
export function isAutoplayAllowed() {
return Boolean(
conf().ALLOW_AUTOPLAY ||
- isExtensionActiveCached() ||
- useAuthStore.getState().proxySet,
+ isExtensionActiveCached() ||
+ useAuthStore.getState().proxySet,
);
}