From 340673237b152eb00332e7001513d5bbea8631b9 Mon Sep 17 00:00:00 2001 From: mrjvs Date: Mon, 20 Nov 2023 19:36:35 +0100 Subject: [PATCH] Add fullscreen preview for caption settings + optimize subtitle rendering --- src/components/player/base/SubtitleView.tsx | 46 ++++++----- src/pages/Settings.tsx | 8 +- src/pages/settings/CaptionsPart.tsx | 92 +++++++++++++++------ 3 files changed, 95 insertions(+), 51 deletions(-) diff --git a/src/components/player/base/SubtitleView.tsx b/src/components/player/base/SubtitleView.tsx index dfc6767e..d32f737e 100644 --- a/src/components/player/base/SubtitleView.tsx +++ b/src/components/player/base/SubtitleView.tsx @@ -11,6 +11,10 @@ import { Transition } from "@/components/Transition"; import { usePlayerStore } from "@/stores/player/store"; import { SubtitleStyling, useSubtitleStore } from "@/stores/subtitles"; +const wordOverrides: Record = { + i: "I", +}; + export function CaptionCue({ text, styling, @@ -20,29 +24,29 @@ export function CaptionCue({ styling: SubtitleStyling; overrideCasing: boolean; }) { - const wordOverrides: Record = { - i: "I", - }; + const parsedHtml = useMemo(() => { + let textToUse = text; + if (overrideCasing && text) { + textToUse = text.slice(0, 1) + text.slice(1).toLowerCase(); + } - let textToUse = text; - if (overrideCasing && text) { - textToUse = text.slice(0, 1) + text.slice(1).toLowerCase(); - } + const textWithNewlines = (textToUse || "") + .split(" ") + .map((word) => wordOverrides[word] ?? word) + .join(" ") + .replaceAll(/ i'/g, " I'") + .replaceAll(/\r?\n/g, "
"); - const textWithNewlines = (textToUse || "") - .split(" ") - .map((word) => wordOverrides[word] ?? word) - .join(" ") - .replaceAll(/ i'/g, " I'") - .replaceAll(/\r?\n/g, "
"); + // https://www.w3.org/TR/webvtt1/#dom-construction-rules + // added a
for newlines + const html = sanitize(textWithNewlines, { + ALLOWED_TAGS: ["c", "b", "i", "u", "span", "ruby", "rt", "br"], + ADD_TAGS: ["v", "lang"], + ALLOWED_ATTR: ["title", "lang"], + }); - // https://www.w3.org/TR/webvtt1/#dom-construction-rules - // added a
for newlines - const html = sanitize(textWithNewlines, { - ALLOWED_TAGS: ["c", "b", "i", "u", "span", "ruby", "rt", "br"], - ADD_TAGS: ["v", "lang"], - ALLOWED_ATTR: ["title", "lang"], - }); + return html; + }, [text, overrideCasing]); return (

diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index 3d35fd31..15f94e2c 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -32,7 +32,7 @@ function SettingsLayout(props: { children: React.ReactNode }) { )} > -

{props.children}
+
{props.children}
); @@ -80,13 +80,13 @@ export function SettingsPage() { )} -
+
-
+
-
+
diff --git a/src/pages/settings/CaptionsPart.tsx b/src/pages/settings/CaptionsPart.tsx index 5fa4391b..0aa0b52c 100644 --- a/src/pages/settings/CaptionsPart.tsx +++ b/src/pages/settings/CaptionsPart.tsx @@ -1,3 +1,7 @@ +import classNames from "classnames"; +import { useState } from "react"; + +import { Icon, Icons } from "@/components/Icon"; import { CaptionSetting, ColorOption, @@ -5,12 +9,61 @@ import { } from "@/components/player/atoms/settings/CaptionSettingsView"; import { Menu } from "@/components/player/internals/ContextMenu"; import { CaptionCue } from "@/components/player/Player"; +import { Transition } from "@/components/Transition"; import { Heading1 } from "@/components/utils/Text"; -import { useSubtitleStore } from "@/stores/subtitles"; +import { SubtitleStyling, useSubtitleStore } from "@/stores/subtitles"; + +export function CaptionPreview(props: { + fullscreen?: boolean; + show?: boolean; + styling: SubtitleStyling; + onToggle: () => void; +}) { + return ( +
+ +
+
+ +
+ +
+
+ +
+
+
+
+
+ ); +} export function CaptionsPart() { const styling = useSubtitleStore((s) => s.styling); - const isFullscreenPreview = false; + const [fullscreenPreview, setFullscreenPreview] = useState(false); const updateStyling = useSubtitleStore((s) => s.updateStyling); return ( @@ -48,30 +101,17 @@ export function CaptionsPart() {
-
-
-
- -
-
-
+ setFullscreenPreview((s) => !s)} + /> + setFullscreenPreview((s) => !s)} + /> );