screentinker/frontend/js/i18n
screentinker 8529be5a30
feat(content): subtitle/caption support as a content property (#223)
Subtitles/captions are set once in the content library and applied
automatically by the player — no in-player controls (the player stays bare).

- DB: 4 new content columns (captions_enabled, captions_lang for YouTube;
  subtitle_url, subtitle_lang for uploaded videos), all default off/NULL.
- buildSnapshotItems: denormalize the 4 fields into published_snapshot so the
  player receives them (enumerated query).
- content.js PUT: accept the 4 fields (subtitle_url only clearable here).
- POST /:id/subtitle: dedicated .vtt uploader (separate multer, since the main
  filter is video/image-only); stores the file in the content dir, records
  subtitle_url + subtitle_lang. Old subtitle file replaced; DELETE cleans up
  the sidecar.
- Player: YouTube -> loadModule('captions') + setOption(...languageCode) in
  onReady (best-effort, wrapped). Uploaded video -> a <track kind="subtitles">
  appended to the <video>, forced mode='showing' on load (same-origin, so
  CORS-clean like the video).
- Edit modal: YouTube gets an enable-captions checkbox + language; uploaded
  video gets a .vtt file picker + language + a remove-subtitle option. en/es.

Honest limitation (in the PR): YouTube caption control via the IFrame API is
undocumented/version-dependent and only works if the video actually has
captions — hence best-effort and wrapped so it can never break playback.

Test: content-subtitles.test.js — the 4 fields survive publish -> snapshot,
the .vtt upload endpoint stores + records the file, and a non-.vtt is rejected.
Suite 550/550.

Closes #216

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 12:33:35 -05:00
..
de.js feat(widgets): directory-search widget (interactive search of a directory board, live-sync) (#188) 2026-07-15 08:00:22 -05:00
en.js feat(content): subtitle/caption support as a content property (#223) 2026-07-23 12:33:35 -05:00
es.js feat(content): subtitle/caption support as a content property (#223) 2026-07-23 12:33:35 -05:00
fr.js feat(widgets): directory-search widget (interactive search of a directory board, live-sync) (#188) 2026-07-15 08:00:22 -05:00
hi.js i18n: extract all strings, add 6 language translations, restructure i18n module 2026-04-29 19:25:22 -05:00
it.js feat(widgets): directory-search widget (interactive search of a directory board, live-sync) (#188) 2026-07-15 08:00:22 -05:00
pt.js feat(widgets): directory-search widget (interactive search of a directory board, live-sync) (#188) 2026-07-15 08:00:22 -05:00