diff --git a/src/components/player/atoms/Settings.tsx b/src/components/player/atoms/Settings.tsx
index 63029d1e..cc02ee4e 100644
--- a/src/components/player/atoms/Settings.tsx
+++ b/src/components/player/atoms/Settings.tsx
@@ -51,7 +51,7 @@ function SettingsOverlay({ id }: { id: string }) {
-
+
diff --git a/src/components/player/atoms/settings/CaptionSettingsView.tsx b/src/components/player/atoms/settings/CaptionSettingsView.tsx
index c42abb12..53d67cd5 100644
--- a/src/components/player/atoms/settings/CaptionSettingsView.tsx
+++ b/src/components/player/atoms/settings/CaptionSettingsView.tsx
@@ -40,6 +40,7 @@ function CaptionSetting(props: {
max: number;
label: string;
min: number;
+ decimalsAllowed?: number;
}) {
const inputRef = useRef(null);
const ref = useRef(null);
@@ -131,7 +132,10 @@ function CaptionSetting(props: {
onBlur={(e) => {
setIsFocused(false);
const num = Number((e.target as HTMLInputElement).value);
- if (!Number.isNaN(num)) props.onChange?.(Math.round(num));
+ if (!Number.isNaN(num))
+ props.onChange?.(
+ (props.decimalsAllowed ?? 0) === 0 ? Math.round(num) : num
+ );
}}
ref={inputRef}
onChange={(e) =>
@@ -142,13 +146,13 @@ function CaptionSetting(props: {
)}
@@ -163,7 +167,9 @@ export function CaptionSettingsView({ id }: { id: string }) {
const router = useOverlayRouter(id);
const styling = useSubtitleStore((s) => s.styling);
const overrideCasing = useSubtitleStore((s) => s.overrideCasing);
+ const delay = useSubtitleStore((s) => s.delay);
const setOverrideCasing = useSubtitleStore((s) => s.setOverrideCasing);
+ const setDelay = useSubtitleStore((s) => s.setDelay);
const updateStyling = useSubtitleStore((s) => s.updateStyling);
return (
@@ -172,6 +178,15 @@ export function CaptionSettingsView({ id }: { id: string }) {
Custom captions
+ setDelay(v)}
+ value={delay}
+ textTransformer={(s) => `${s}s`}
+ decimalsAllowed={1}
+ />
s.caption.selected?.srtData);
const styling = useSubtitleStore((s) => s.styling);
const overrideCasing = useSubtitleStore((s) => s.overrideCasing);
+ const delay = useSubtitleStore((s) => s.delay);
const parsedCaptions = useMemo(
() => (srtData ? parseSubtitles(srtData) : []),
@@ -79,9 +80,9 @@ export function SubtitleRenderer() {
const visibileCaptions = useMemo(
() =>
parsedCaptions.filter(({ start, end }) =>
- captionIsVisible(start, end, 0, videoTime)
+ captionIsVisible(start, end, delay, videoTime)
),
- [parsedCaptions, videoTime]
+ [parsedCaptions, videoTime, delay]
);
return (
diff --git a/src/stores/subtitles/index.ts b/src/stores/subtitles/index.ts
index bf22b071..45da117a 100644
--- a/src/stores/subtitles/index.ts
+++ b/src/stores/subtitles/index.ts
@@ -24,9 +24,11 @@ export interface SubtitleStore {
lastSelectedLanguage: string | null;
styling: SubtitleStyling;
overrideCasing: boolean;
+ delay: number;
updateStyling(newStyling: Partial): void;
setLanguage(language: string | null): void;
setOverrideCasing(enabled: boolean): void;
+ setDelay(delay: number): void;
}
// TODO add migration from previous stored settings
@@ -36,6 +38,7 @@ export const useSubtitleStore = create(
enabled: false,
lastSelectedLanguage: null,
overrideCasing: false,
+ delay: 0,
styling: {
color: "#ffffff",
backgroundOpacity: 0.5,
@@ -62,6 +65,11 @@ export const useSubtitleStore = create(
s.overrideCasing = enabled;
});
},
+ setDelay(delay) {
+ set((s) => {
+ s.delay = delay;
+ });
+ },
})),
{
name: "__MW::subtitles",