5.5 KiB
Subtitle Properties Panel Design
Goal: Turn the editor's right sidebar into a real subtitle properties panel that edits the selected subtitle's display settings, shows real speaker metadata, and can optionally apply style changes to all subtitles.
Context
The current editor already presents the right side as a properties area, but most of it is still static UI. The Wife and Husband labels are hard-coded, the text style controls only update a single top-level textStyles state object, and the preview overlay always renders with those shared settings instead of reading from the active subtitle.
That makes the panel look like a subtitle control surface while behaving more like a mock. The user expectation is that this area should control subtitle presentation for the selected item and optionally propagate those style changes across the full subtitle list.
Approaches Considered
Option A: Keep a single global style object
Continue storing one textStyles object in EditorScreen and wire the right panel to that object only.
Pros
- Smallest code change
- Minimal test churn
Cons
- Does not match the "current subtitle properties" mental model
- Makes "Apply to all subtitles" redundant
- Prevents subtitle-level overrides later
Option B: Store style state per subtitle with optional bulk apply
Add a style object to each subtitle, derive the right panel from the active subtitle, and let bulk apply copy style changes to every subtitle.
Pros
- Matches the current UI language and user expectation
- Keeps the implementation scoped to the existing editor screen
- Leaves room for richer per-speaker or per-preset styling later
Cons
- Requires subtitle normalization when data is loaded
- Slightly more state update logic in the editor
Recommendation
Use Option B. It gives the right sidebar a truthful interaction model without forcing a much larger style system redesign.
Architecture
Data Model
Introduce a SubtitleTextStyle shape that extends the current style fields with the controls surfaced by the panel:
fontFamilyfontSizecolorstrokeColorstrokeWidthalignmentisBoldisItalicisUnderline
Each Subtitle will gain an optional textStyle field. When subtitle data is generated or loaded, the editor will normalize every subtitle to ensure a complete style object is present.
Editor State
EditorScreen will:
- Keep a single source of truth in
subtitles - Derive
activeSubtitlefromactiveSubtitleId - Replace the old shared
textStylesstate with helper functions that update:- only the active subtitle
- or every subtitle when "Apply to all subtitles" is enabled
The checkbox will become real state instead of a static default value.
Right Sidebar Behavior
The properties panel will become data-driven:
- Speaker badge/label will read from the active subtitle's speaker metadata
- The text field will show the active subtitle's translated text as contextual reference instead of a hard-coded name
- Controls will read and write the active subtitle's
textStyle - The panel will show a friendly empty state if no subtitle is selected
This keeps the right column focused on subtitle properties without introducing an unrelated metadata editor.
Preview Behavior
The video subtitle overlay will render the style of the subtitle currently visible at the playback position. This means:
- editing the selected subtitle updates the preview immediately when that subtitle is active
- bulk apply updates every visible subtitle style consistently
Stroke rendering will be added via CSS textShadow so the preview reflects the new sidebar control.
Interaction Details
Size Presets
Keep the existing "Normal / Large / Small" control, but wire it to concrete font sizes:
Small-> 20Normal-> 24Large-> 30
This matches the current UI affordance without adding a freeform number input yet.
Apply To All
When checked, any style change initiated from the right panel copies the changed style keys to all subtitles. It will not overwrite subtitle text, timing, voice, or speaker data.
Speaker Information
The top block will present the active subtitle's speaker identity:
- badge uses the first letter of the speaker label
- label shows
subtitle.speaker - secondary read-only field shows the active subtitle text for context
This keeps the section meaningful even if there is no separate speaker alias dataset yet.
Error Handling
- If no subtitles are loaded, the right panel stays disabled with helper text
- If a subtitle lacks style data, normalization fills defaults before rendering controls
- If the active subtitle disappears after regeneration, the editor selects the first subtitle as it already does today
Testing Strategy
Component Tests
Add tests that verify:
- the right panel reflects the active subtitle's speaker and style values
- changing a style control updates only the selected subtitle when bulk apply is off
- changing a style control updates every subtitle when bulk apply is on
- the preview overlay renders the visible subtitle using its style values
Type Safety
Update shared types so exports and preview rendering both receive the richer subtitle style data without unsafe casts.
Rollout Notes
This design intentionally stays inside EditorScreen and current data structures. It does not add saved presets, per-speaker style inheritance, or backend persistence, which keeps the work focused on making the existing panel real and trustworthy.