M2-03: Seek from the transcript #44
No reviewers
Labels
No labels
area/agent
area/capture
area/editor
area/geo
area/security
area/sync
area/transcription
area/ui
area/vault
area/voice-memos
blocked
milestone/M1
milestone/M2
milestone/M3
milestone/M4
needs-decision
needs-hardware
p0
p1
p2
type/bug
type/enhancement
type/feature
type/idea
type/infrastructure
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Stash/stash-ios!44
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "m2-03-transcript-seek"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #30.
Tapping a cue plays the memo from those words. The cue under the playhead is marked while it
plays, and the list follows it until somebody scrolls away — a button above the transport puts
following back, and so does tapping a cue.
The decisions worth reviewing
The cue path waits for its seek to land before it plays.
AVPlayer.seekis asynchronous, soplaying on the next line starts the audio at the position the memo was already at. For a feature
whose only job is to start the words somebody tapped, that is the bug and not an edge case. The
scrubber does not wait, because there the finger has already put the playhead where it belongs.
A tap that arrives before the file is ready is kept.
open()sets the base before it awaitsthe header, so a cue tapped while the screen is still opening arrives with no item to seek.
PendingSeekcarries the memo and the item it was asked for, and the status observer runs it whenthe file comes good — dropping it is a tap that does nothing on exactly the memos that take
longest to open.
Playback still yields to capture, at every suspension. The gate is asked before anything moves
(
open()tears down the loaded memo before it awaits, so refusing afterwards would throw away aplayhead), again at the commit, and a capture invalidates any request that was in flight across
it. That last one is a security finding: a recording that starts and fails quickly would otherwise
leave the gate clear again by the time a suspended tap resumed, and play a private memo out loud.
CueTimelinesorts for the lookup and never for the display. The reader keeps a foreign file'scues in file order on purpose; the timeline sorts a copy, off the main actor, and answers with the
last cue that started — its end is deliberately not consulted, so a silence does not blink the
marking off and stop the list following mid-memo.
Cue rows are
Buttons, so cue text is no longer selectable. A button consumes the long pressthat starts a selection. Both cannot have it, and playing from a tapped cue is what the timestamps
were built for.
Validated
On the device: tapping a cue plays from those words, and on a one-hour memo the audio landed
within about half a second of the words when seeking from cues near the end. That closes the
alignment question open since #8 and #9 — nothing was systematically off, so there is no follow-up
issue against transcription.
333 unit tests pass, lint clean. New:
CueTimelineTests,PendingSeekTests.Not validated
only on the pure rules underneath them. They are timing edge cases — a tap during a slow open, a
capture that starts and fails inside a tap.
clicks into it, the same Accessibility limitation recorded in M1-11. The device pass is the only
end-to-end evidence.
fixes, which did not touch them.
A decision file is written for
stash-docs; it is not in this PR because it is a differentrepository. See the note on the issue.