From 248da3705609ff3f0a65f203f09569ba0fb58c31 Mon Sep 17 00:00:00 2001
From: Pas <74743263+Pasithea0@users.noreply.github.com>
Date: Fri, 13 Feb 2026 14:29:27 -0700
Subject: [PATCH] add auto segment skipping
---
src/assets/locales/en.json | 3 +
src/backend/accounts/settings.ts | 2 +
src/components/player/base/Container.tsx | 2 +
.../player/internals/AutoSkipSegments.tsx | 87 +++++++++++++++++++
src/hooks/useSettingsState.ts | 16 +++-
src/pages/Settings.tsx | 16 +++-
src/pages/parts/settings/PreferencesPart.tsx | 25 ++++++
src/stores/preferences/index.tsx | 8 ++
8 files changed, 157 insertions(+), 2 deletions(-)
create mode 100644 src/components/player/internals/AutoSkipSegments.tsx
diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json
index eaa5ef13..d0e66a16 100644
--- a/src/assets/locales/en.json
+++ b/src/assets/locales/en.json
@@ -1330,6 +1330,9 @@
"skipCredits": "Skip End Credits",
"skipCreditsDescription": "When enabled, automatically play the next episode at 99% completion to skip end credits. When disabled, wait until the episode is fully completed.",
"skipCreditsLabel": "Skip end credits",
+ "autoSkipSegments": "Auto Skip Segments",
+ "autoSkipSegmentsDescription": "When enabled, automatically skip intro, recap, and preview segments while watching.",
+ "autoSkipSegmentsLabel": "Auto skip segments",
"lowPerformanceMode": "Low performance/bandwidth mode",
"lowPerformanceModeDescription": "Optimizes the application for slower connections and devices by disabling bandwidth-heavy features. This mode reduces data usage and improves performance while keeping the core search and watch functionality intact. ",
"lowPerformanceModeLabel": "Low performance mode",
diff --git a/src/backend/accounts/settings.ts b/src/backend/accounts/settings.ts
index 83993b0f..304f360a 100644
--- a/src/backend/accounts/settings.ts
+++ b/src/backend/accounts/settings.ts
@@ -15,6 +15,7 @@ export interface SettingsInput {
enableThumbnails?: boolean;
enableAutoplay?: boolean;
enableSkipCredits?: boolean;
+ enableAutoSkipSegments?: boolean;
enableDiscover?: boolean;
enableFeatured?: boolean;
enableDetailsModal?: boolean;
@@ -50,6 +51,7 @@ export interface SettingsResponse {
enableThumbnails?: boolean;
enableAutoplay?: boolean;
enableSkipCredits?: boolean;
+ enableAutoSkipSegments?: boolean;
enableDiscover?: boolean;
enableFeatured?: boolean;
enableDetailsModal?: boolean;
diff --git a/src/components/player/base/Container.tsx b/src/components/player/base/Container.tsx
index 9f37b87d..27bac29d 100644
--- a/src/components/player/base/Container.tsx
+++ b/src/components/player/base/Container.tsx
@@ -1,6 +1,7 @@
import { ReactNode, RefObject, useEffect, useRef } from "react";
import { OverlayDisplay } from "@/components/overlays/OverlayDisplay";
+import { AutoSkipSegments } from "@/components/player/internals/AutoSkipSegments";
import { SkipTracker } from "@/components/player/internals/Backend/SkipTracker";
import { CastingInternal } from "@/components/player/internals/CastingInternal";
import { HeadUpdater } from "@/components/player/internals/HeadUpdater";
@@ -100,6 +101,7 @@ export function Container(props: PlayerProps) {
+
diff --git a/src/components/player/internals/AutoSkipSegments.tsx b/src/components/player/internals/AutoSkipSegments.tsx
new file mode 100644
index 00000000..9d296826
--- /dev/null
+++ b/src/components/player/internals/AutoSkipSegments.tsx
@@ -0,0 +1,87 @@
+import { useEffect, useRef } from "react";
+
+import { useSkipTime } from "@/components/player/hooks/useSkipTime";
+import { usePlayerStore } from "@/stores/player/store";
+import { usePreferencesStore } from "@/stores/preferences";
+
+interface SegmentSkipState {
+ segmentId: string;
+ hasSkipped: boolean;
+}
+
+/**
+ * Component that automatically skips segments (intro, recap, preview, credits)
+ * when the enableAutoSkipSegments preference is enabled.
+ * For credits segments, only skips if end_ms is null (end of video).
+ */
+export function AutoSkipSegments() {
+ const enableAutoSkipSegments = usePreferencesStore(
+ (s) => s.enableAutoSkipSegments,
+ );
+ const skipCredits = usePreferencesStore((s) => s.enableSkipCredits);
+ const display = usePlayerStore((s) => s.display);
+ const time = usePlayerStore((s) => s.progress.time);
+ const meta = usePlayerStore((s) => s.meta);
+ const segments = useSkipTime();
+
+ // Track which segments we've already skipped to avoid re-skipping
+ const skippedSegmentsRef = useRef
+
+ {/* Auto Skip Segments Preference */}
+
+
+ {t("settings.preferences.autoSkipSegments")}
+
+
+ {t("settings.preferences.autoSkipSegmentsDescription")}
+
+
+ props.setEnableAutoSkipSegments(
+ !props.enableAutoSkipSegments,
+ )
+ }
+ 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.autoSkipSegmentsLabel")}
+
+
+
)}
diff --git a/src/stores/preferences/index.tsx b/src/stores/preferences/index.tsx
index fb4d53c0..c9dcb3ab 100644
--- a/src/stores/preferences/index.tsx
+++ b/src/stores/preferences/index.tsx
@@ -11,6 +11,7 @@ export interface PreferencesStore {
enableThumbnails: boolean;
enableAutoplay: boolean;
enableSkipCredits: boolean;
+ enableAutoSkipSegments: boolean;
enableDiscover: boolean;
enableFeatured: boolean;
enableDetailsModal: boolean;
@@ -42,6 +43,7 @@ export interface PreferencesStore {
setEnableThumbnails(v: boolean): void;
setEnableAutoplay(v: boolean): void;
setEnableSkipCredits(v: boolean): void;
+ setEnableAutoSkipSegments(v: boolean): void;
setEnableDiscover(v: boolean): void;
setEnableFeatured(v: boolean): void;
setEnableDetailsModal(v: boolean): void;
@@ -77,6 +79,7 @@ export const usePreferencesStore = create(
enableThumbnails: false,
enableAutoplay: true,
enableSkipCredits: true,
+ enableAutoSkipSegments: false,
enableDiscover: true,
enableFeatured: false,
enableDetailsModal: false,
@@ -119,6 +122,11 @@ export const usePreferencesStore = create(
s.enableSkipCredits = v;
});
},
+ setEnableAutoSkipSegments(v) {
+ set((s) => {
+ s.enableAutoSkipSegments = v;
+ });
+ },
setEnableDiscover(v) {
set((s) => {
s.enableDiscover = v;