Replace the duplicated per-platform segment-skip logic with a shared
useMediaSegments hook: per-type skippers, overlap priority
(Commercial > Recap > Intro > Preview > Outro) and a single auto-skip
driver so both platforms behave identically.
- One auto-skip effect on the priority-resolved active segment, so
overlapping auto segments can't fire competing seeks.
- Sub-second precision (stop flooring currentTime to whole seconds).
- Gate auto-skip on !isBuffering plus a short arm delay so it never
seeks a not-yet-seekable transcoded stream at a 0:00 intro.
- Dedup guard survives the transient null when a transcoded stream
bounces the reported position, instead of looping seeks.
Closes#1312Fixes#883
Adds a unified segment skip feature using the Jellyfin 10.11+
MediaSegments API. Replaces the legacy intro-only and credits-only
hooks with a single useSegmentSkipper hook covering Intro, Outro,
Recap, Commercial, and Preview.
Three modes per segment type: none, ask (show button), auto (skip
automatically). A dedicated submenu under Playback Controls keeps
the main settings page uncluttered.
Highlights:
- utils/segments.ts uses getMediaSegmentsApi from @jellyfin/sdk so
includeSegmentTypes is serialized as repeated keys instead of the
bracket-encoded form axios produces by default (the Jellyfin
server silently ignored the filter otherwise). Falls back to the
pre-10.11 intro-skipper / chapter-credits plugin endpoints when
the new API is unavailable.
- hooks/useSegmentSkipper.ts stores seek and haptic in refs so the
auto-skip effect does not re-run when their identities change
(useHaptic returns a fresh no-op every render when disabled).
currentSegment is memoized; the per-segment-type setting lookup
uses a small map instead of a switch IIFE.
- components/video-player/controls/Controls.tsx prioritizes
Commercial > Recap > Intro > Preview > Outro when multiple
segments overlap and exposes the active type to BottomControls
via skipButtonText.
- components/video-player/controls/BottomControls.tsx accepts the
dynamic skipButtonText/skipCreditButtonText props.
- providers/Downloads/types.ts extends DownloadedItem with the
three new segment buckets for offline playback.
- utils/atoms/settings.ts adds SegmentSkipMode and the five skip
settings, defaulting to "ask".
- app/(auth)/(tabs)/(home)/settings/segment-skip/page.tsx renders
the five dropdowns from a data table.
- translations/en.json and translations/fr.json add the new keys.