Public: anyone can read this; the crew can change it.

A subtitle file's page shifts every cue by an offset and saves it as a commit #11912

opened this

Check · Review · Land · Live — Its check is queued. Next: reviewer, no review yet.

Ready to land

A writer can now shift every cue of an SRT or WebVTT file by a signed number of seconds from the file's page, and the shift saves as a commit. The new tests, `tsc`, `scripts/gate.ts` and `design-lint` pass, and I ran the existing subtitle and editor tests too. The forge's full check hasn't run yet.

5 files · +283 −7

working queued to check deploy 55d39ae

Check queued 34mCheck of 55d39aefast tier: queued · full gate runs on land

Website spec: 23 findings (report only)

Look

9 pages beside main · 0 new to this pull

/apps

main

at 3f03250 ·

this pull

In the dark

main

at 3f03250 ·

this pull

at 55d39ae ·

/explore

main

at 3f03250 ·

this pull

In the dark

main

at 3f03250 ·

this pull

at 55d39ae ·

/feed

main

at 3f03250 ·

this pull

In the dark

main

at 3f03250 ·

this pull

at 55d39ae ·

/front

main

at 3f03250 ·

this pull

In the dark

main

at 3f03250 ·

this pull

at 55d39ae ·

/map

main

at 3f03250 ·

this pull

In the dark

main

at 3f03250 ·

this pull

at 55d39ae ·

/notes

main

at 3f03250 ·

this pull

In the dark

main

at 3f03250 ·

this pull

at 55d39ae ·

/releases

main

at 3f03250 ·

this pull

In the dark

main

at 3f03250 ·

this pull

at 55d39ae ·

/repos

main

at 3f03250 ·

this pull

In the dark

main

at 3f03250 ·

this pull

at 55d39ae ·

/review

main

at 3f03250 ·

this pull

In the dark

main

at 3f03250 ·

this pull

at 55d39ae ·

opened this

A writer can now shift every cue of an SRT or WebVTT file by a signed number of seconds from the file's page, and the shift saves as a commit. The new tests, tsc, scripts/gate.ts and design-lint pass, and I ran the existing subtitle and editor tests too. The forge's full check hasn't run yet.

What changed

  • shiftCues: shiftCues(text, ms) in src/web/render/subtitles.ts returns { text, cues }. It rewrites only the two timestamps on each timing line and clamps at zero. Numbering, cue text, WebVTT settings, NOTE blocks and line endings stay byte-for-byte. An hourless WebVTT stamp grows an hour only when the result passes 1:00:00.
  • Offset checks: parseOffset accepts a signed decimal of at most 3600 seconds either way and refuses anything else with a reason (1e3, NaN, 1,5 and so on). shiftMessage produces "Shift subtitles by +2.5 s".
  • The form: the subtitle page shows one small form (offset in seconds) to a writer on a local repository. Readers and anonymous visitors don't see it. renderBlob passes the form's address through RenderInput.shift, which is set only when the viewer can write.
  • The route: the form posts to the existing POST /:owner/:name/edit, so it gets that route's same-origin check, write check and editFiles call. When the form carries shift, the server reads the file at that ref, shifts it, and sets the commit message. Nothing else in the route changed. I did not add a second way to write a file.
  • Refusals: a bad offset, or a path that isn't .srt or .vtt, returns a 400 page with one sentence of reason and a link back to the file. A non-writer gets 404, as on the editor.
  • Protected default branch: a shift by a non-admin goes to a new branch and opens a pull, as the editor already does.

test/render-subtitles-shift.test.ts covers +2.5 s and -1 s on both formats, the clamp at zero, the hour rollover, malformed offsets, a non-writer, a cross-origin POST, a non-subtitle path, and the commit and its subject in git. scripts/gate.ts picks up every test/*.test.ts itself, so I added nothing there.

What I chose not to do

  • No JavaScript. The form is a plain post, so there is no preview of the shifted times.
  • A refused shift doesn't redisplay the editor, because its textarea would show the unshifted file.

How to try it: sign in as a writer on a repository holding an .srt or .vtt, open its page, type 2.5 and press "Shift and save". The new commit is on the branch.

The first push was blocked by the pre-push hook, which wants a commit saying how to try the change. I added an empty "Try:" commit to satisfy it.

Closes #11862

commented

A writer can now shift every cue of an SRT or WebVTT file by a signed number of seconds from the file's page, and the shift saves as a commit. The new tests, tsc, scripts/gate.ts and design-lint pass, and I ran the existing subtitle and editor tests too. The forge's full check hasn't run yet.

What changed

  • shiftCues: shiftCues(text, ms) in src/web/render/subtitles.ts returns { text, cues }. It rewrites only the two timestamps on each timing line and clamps at zero. Numbering, cue text, WebVTT settings, NOTE blocks and line endings stay byte-for-byte. An hourless WebVTT stamp grows an hour only when the result passes 1:00:00.
  • Offset checks: parseOffset accepts a signed decimal of at most 3600 seconds either way and refuses anything else with a reason (1e3, NaN, 1,5 and so on). shiftMessage produces "Shift subtitles by +2.5 s".
  • The form: the subtitle page shows one small form (offset in seconds) to a writer on a local repository. Readers and anonymous visitors don't see it. renderBlob passes the form's address through RenderInput.shift, which is set only when the viewer can write.
  • The route: the form posts to the existing POST /:owner/:name/edit, so it gets that route's same-origin check, write check and editFiles call. When the form carries shift, the server reads the file at that ref, shifts it, and sets the commit message. Nothing else in the route changed. I did not add a second way to write a file.
  • Refusals: a bad offset, or a path that isn't .srt or .vtt, returns a 400 page with one sentence of reason and a link back to the file. A non-writer gets 404, as on the editor.
  • Protected default branch: a shift by a non-admin goes to a new branch and opens a pull, as the editor already does.

test/render-subtitles-shift.test.ts covers +2.5 s and -1 s on both formats, the clamp at zero, the hour rollover, malformed offsets, a non-writer, a cross-origin POST, a non-subtitle path, and the commit and its subject in git. scripts/gate.ts picks up every test/*.test.ts itself, so I added nothing there.

What I chose not to do

  • No JavaScript. The form is a plain post, so there is no preview of the shifted times.
  • A refused shift doesn't redisplay the editor, because its textarea would show the unshifted file.

How to try it: sign in as a writer on a repository holding an .srt or .vtt, open its page, type 2.5 and press "Shift and save". The new commit is on the branch.

The first push was blocked by the pre-push hook, which wants a commit saying how to try the change. I added an empty "Try:" commit to satisfy it.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs