) => {
if (
@@ -141,7 +216,7 @@ export function VideoClickTarget(props: { showingControls: boolean }) {
if (isPendingBoost) {
clearTimeout(boostTimeoutRef.current!);
setIsPendingBoost(false);
- togglePause(e);
+ handleTap(e);
return;
}
@@ -170,12 +245,12 @@ export function VideoClickTarget(props: { showingControls: boolean }) {
}, 1500);
} else {
// Regular click handler
- togglePause(e);
+ handleTap(e);
}
},
[
display,
- togglePause,
+ handleTap,
setSpeedBoosted,
setShowSpeedIndicator,
setCurrentOverlay,
@@ -221,15 +296,29 @@ export function VideoClickTarget(props: { showingControls: boolean }) {
if (!show) return null;
return (
-
+ <>
+ {seekDirection ? (
+ setSeekDirection(null)}
+ className={
+ seekDirection === "backward"
+ ? "absolute inset-0 flex items-center justify-start ml-32"
+ : "absolute inset-0 flex items-center justify-end mr-32"
+ }
+ >
+
+
+ ) : null}
+
+ >
);
}
diff --git a/src/hooks/useSettingsState.ts b/src/hooks/useSettingsState.ts
index 7f8ddef8..8d3932fb 100644
--- a/src/hooks/useSettingsState.ts
+++ b/src/hooks/useSettingsState.ts
@@ -66,6 +66,7 @@ export function useSettingsState(
forceCompactEpisodeView: boolean,
enableLowPerformanceMode: boolean,
enableHoldToBoost: boolean,
+ enableDoubleClickToSeek: boolean,
homeSectionOrder: string[],
manualSourceSelection: boolean,
) {
@@ -183,6 +184,12 @@ export function useSettingsState(
resetEnableHoldToBoost,
enableHoldToBoostChanged,
] = useDerived(enableHoldToBoost);
+ const [
+ enableDoubleClickToSeekState,
+ setEnableDoubleClickToSeekState,
+ resetEnableDoubleClickToSeek,
+ enableDoubleClickToSeekChanged,
+ ] = useDerived(enableDoubleClickToSeek);
const [
homeSectionOrderState,
setHomeSectionOrderState,
@@ -221,6 +228,7 @@ export function useSettingsState(
resetForceCompactEpisodeView();
resetEnableLowPerformanceMode();
resetEnableHoldToBoost();
+ resetEnableDoubleClickToSeek();
resetHomeSectionOrder();
resetManualSourceSelection();
}
@@ -249,6 +257,7 @@ export function useSettingsState(
forceCompactEpisodeViewChanged ||
enableLowPerformanceModeChanged ||
enableHoldToBoostChanged ||
+ enableDoubleClickToSeekChanged ||
homeSectionOrderChanged ||
manualSourceSelectionChanged;
@@ -370,6 +379,11 @@ export function useSettingsState(
set: setEnableHoldToBoostState,
changed: enableHoldToBoostChanged,
},
+ enableDoubleClickToSeek: {
+ state: enableDoubleClickToSeekState,
+ set: setEnableDoubleClickToSeekState,
+ changed: enableDoubleClickToSeekChanged,
+ },
homeSectionOrder: {
state: homeSectionOrderState,
set: setHomeSectionOrderState,
diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx
index fc0b4d20..4b30350a 100644
--- a/src/pages/Settings.tsx
+++ b/src/pages/Settings.tsx
@@ -197,6 +197,13 @@ export function SettingsPage() {
(s) => s.setEnableHoldToBoost,
);
+ const enableDoubleClickToSeek = usePreferencesStore(
+ (s) => s.enableDoubleClickToSeek,
+ );
+ const setEnableDoubleClickToSeek = usePreferencesStore(
+ (s) => s.setEnableDoubleClickToSeek,
+ );
+
const homeSectionOrder = usePreferencesStore((s) => s.homeSectionOrder);
const setHomeSectionOrder = usePreferencesStore((s) => s.setHomeSectionOrder);
@@ -259,6 +266,7 @@ export function SettingsPage() {
forceCompactEpisodeView,
enableLowPerformanceMode,
enableHoldToBoost,
+ enableDoubleClickToSeek,
homeSectionOrder,
manualSourceSelection,
);
@@ -320,6 +328,7 @@ export function SettingsPage() {
state.forceCompactEpisodeView.changed ||
state.enableLowPerformanceMode.changed ||
state.enableHoldToBoost.changed ||
+ state.enableDoubleClickToSeek.changed ||
state.manualSourceSelection.changed
) {
await updateSettings(backendUrl, account, {
@@ -342,6 +351,7 @@ export function SettingsPage() {
forceCompactEpisodeView: state.forceCompactEpisodeView.state,
enableLowPerformanceMode: state.enableLowPerformanceMode.state,
enableHoldToBoost: state.enableHoldToBoost.state,
+ enableDoubleClickToSeek: state.enableDoubleClickToSeek.state,
manualSourceSelection: state.manualSourceSelection.state,
});
}
@@ -383,6 +393,7 @@ export function SettingsPage() {
setForceCompactEpisodeView(state.forceCompactEpisodeView.state);
setEnableLowPerformanceMode(state.enableLowPerformanceMode.state);
setEnableHoldToBoost(state.enableHoldToBoost.state);
+ setEnableDoubleClickToSeek(state.enableDoubleClickToSeek.state);
setHomeSectionOrder(state.homeSectionOrder.state);
setManualSourceSelection(state.manualSourceSelection.state);
@@ -483,6 +494,8 @@ export function SettingsPage() {
setEnableLowPerformanceMode={state.enableLowPerformanceMode.set}
enableHoldToBoost={state.enableHoldToBoost.state}
setEnableHoldToBoost={state.enableHoldToBoost.set}
+ enableDoubleClickToSeek={state.enableDoubleClickToSeek.state}
+ setEnableDoubleClickToSeek={state.enableDoubleClickToSeek.set}
manualSourceSelection={state.manualSourceSelection.state}
setManualSourceSelection={state.manualSourceSelection.set}
/>
diff --git a/src/pages/parts/settings/PreferencesPart.tsx b/src/pages/parts/settings/PreferencesPart.tsx
index 00a873e4..f523ecc0 100644
--- a/src/pages/parts/settings/PreferencesPart.tsx
+++ b/src/pages/parts/settings/PreferencesPart.tsx
@@ -31,6 +31,8 @@ export function PreferencesPart(props: {
setEnableLowPerformanceMode: (v: boolean) => void;
enableHoldToBoost: boolean;
setEnableHoldToBoost: (v: boolean) => void;
+ enableDoubleClickToSeek: boolean;
+ setEnableDoubleClickToSeek: (v: boolean) => void;
manualSourceSelection: boolean;
setManualSourceSelection: (v: boolean) => void;
}) {
@@ -217,6 +219,26 @@ export function PreferencesPart(props: {
+ {/* double click to seek preference */}
+
+
+ {t("settings.preferences.doubleClickToSeek")}
+
+
+ {t("settings.preferences.doubleClickToSeekDescription")}
+
+
+ props.setEnableDoubleClickToSeek(!props.enableDoubleClickToSeek)
+ }
+ className="bg-dropdown-background hover:bg-dropdown-hoverBackground select-none my-4 cursor-pointer space-x-3 flex items-center max-w-[25rem] py-3 px-4 rounded-lg"
+ >
+
+
+ {t("settings.preferences.doubleClickToSeekLabel")}
+
+
+
{/* Column */}
diff --git a/src/stores/preferences/index.tsx b/src/stores/preferences/index.tsx
index 6354bfb3..f1c2129e 100644
--- a/src/stores/preferences/index.tsx
+++ b/src/stores/preferences/index.tsx
@@ -22,6 +22,7 @@ export interface PreferencesStore {
enableLowPerformanceMode: boolean;
enableNativeSubtitles: boolean;
enableHoldToBoost: boolean;
+ enableDoubleClickToSeek: boolean;
homeSectionOrder: string[];
manualSourceSelection: boolean;
@@ -44,6 +45,7 @@ export interface PreferencesStore {
setEnableLowPerformanceMode(v: boolean): void;
setEnableNativeSubtitles(v: boolean): void;
setEnableHoldToBoost(v: boolean): void;
+ setEnableDoubleClickToSeek(v: boolean): void;
setHomeSectionOrder(v: string[]): void;
setManualSourceSelection(v: boolean): void;
}
@@ -70,6 +72,7 @@ export const usePreferencesStore = create(
enableLowPerformanceMode: false,
enableNativeSubtitles: false,
enableHoldToBoost: true,
+ enableDoubleClickToSeek: false,
homeSectionOrder: ["watching", "bookmarks"],
manualSourceSelection: false,
setEnableThumbnails(v) {
@@ -167,6 +170,11 @@ export const usePreferencesStore = create(
s.enableHoldToBoost = v;
});
},
+ setEnableDoubleClickToSeek(v) {
+ set((s) => {
+ s.enableDoubleClickToSeek = v;
+ });
+ },
setHomeSectionOrder(v) {
set((s) => {
s.homeSectionOrder = v;
diff --git a/tailwind.config.ts b/tailwind.config.ts
index a56abebc..4c82fbae 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -33,10 +33,20 @@ const config: Config = {
"0%": { opacity: "0" },
"100%": { opacity: "1" },
},
+ "seek-left": {
+ "0%": { transform: "translateX(0) scale(1)", opacity: "1" },
+ "100%": { transform: "translateX(-50px) scale(1.2)", opacity: "0" },
+ },
+ "seek-right": {
+ "0%": { transform: "translateX(0) scale(1)", opacity: "1" },
+ "100%": { transform: "translateX(50px) scale(1.2)", opacity: "0" },
+ },
},
animation: {
"loading-pin": "loading-pin 1.8s ease-in-out infinite",
"fade-in": "fade-in 200ms ease-out forwards",
+ "seek-left": "seek-left 0.5s cubic-bezier(0, 0, 0.2, 1) forwards",
+ "seek-right": "seek-right 0.5s cubic-bezier(0, 0, 0.2, 1) forwards",
},
},
},