Snap & Talk: added Snaps join in the order they were captured, and the Capture area stays chosen
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 35/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- swift
- Domain
- desktop, documentation
Research direction
Part 1 starts in ReadbackModel.importSnapSnapshots (ReadbackModel.swift:992-1006): sort by createdAt then id before the import, leaving SnapReadback itself alone, and confirm Tests/SnapChecks/main.swift:152 still passes. Part 2 moves the @State captureMode in ReadbackView.swift:20 into ReadbackModel so the picker survives leaving the page. Run bash scripts/test-snap.sh and the --check-snap-capture and --check-readback harnesses. Done when the added batch runs oldest to newest, the notice is singular-aware, and the Capture area stays chosen across a page round trip.
Written by the indexing model from the issue text.
Description
Outcome: selecting a captured sequence and adding it to Snap & Talk produces sections, and so a deck, in story order, opening on the first step. A Capture area of Region or Window stays chosen when you leave the page and come back.
1. Added Snaps keep capture order
Evidence (train head 14d06bc)
- Use selected › Add to Snap & Talk passes
Array(selectedIDs), built from a Set (SnapWorkspaceView.swift:186). WorkbenchHome.swift:196-197callssnap.handoffSnapshots, which filtersstore.load().items(SnapModel.swift:622-634). Those items are sorted newest first (SnapStore.swift:147).ReadbackModel.importSnapSnapshots(ReadbackModel.swift:992-1006) passes that order toSnapReadback.importSnapshots, which appends in the order it is given.- So five screenshots taken in order become a deck that runs backwards. A Desktop import, which selects what it added, lands reversed too.
- The only remedy is the Reorder sheet, one move at a time (
ReadbackOrdering.swift:63-90). :1000reviewsactiveSections.last. With today's order, that happens to be the earliest screenshot.- The notice says 'Added 1 Snaps.' and '1 already present were skipped.' (
:1003).
Change
- In
importSnapSnapshots, sort bycreatedAtascending, breaking ties byid.uuidString, before importing. Do the sort here, not in SnapReadback:Tests/SnapChecks/main.swift:152keeps SnapReadback's input order. - Review the first section of the new batch,
activeSections[activeSections.count - result.added], guarded for bounds, so the person still lands on the earliest screenshot. - Make the notice singular-aware:
- 'Added 1 Snap.' / 'Added N Snaps.'
- '1 already present was skipped.' / 'N already present were skipped.'
- Hand off's saved-history order (
docs/snap.md:45) is unchanged. - In
docs/snap.md, beside:49, add: 'Added Snaps join the end of the session in the order they were captured, and the first of them opens for narration.'
Acceptance (--check-snap-capture, near SnapCaptureChecks.swift:269)
- Insert three Snaps at T, T+60 and T+120.
handoffSnapshotsreturns them newest first, which pins the cause. - After the import:
- the last three sections run oldest to newest;
- the earlier section is still first;
- the oldest added section is the one under review;
- the notice begins 'Added 3 Snaps.'
- Adding one more gives 'Added 1 Snap.'
- Re-importing a set with one Snap already present says '1 already present was skipped.'
bash scripts/test-snap.shpasses unchanged.
2. The Capture area survives leaving the page
Evidence
- The choice is view state that defaults to Screen:
@State private var captureMode = .screen(ReadbackView.swift:20). - The page is one branch of
switch model.page(WorkbenchHome.swift:177-188), so leaving the page drops that state. - The most common round trip leaves the page on purpose. Add from Snap History… (
ReadbackView.swift:280) goes to Snap, and Add to narrated session comes back (WorkbenchHome.swift:193-195). - On return the picker shows Screen. Capture & narrate (
:272) then takes the whole display at once and starts the microphone. Replace screenshot… (:418) and Redo (:421) also follow the picker, since tonight's #345. docs/snap.md:5says Capture area governs all three actions, but not whether the choice is kept.
Change
- Add
@Published var captureArea: SnapCapture.Mode = .screenon ReadbackModel, in memory only. There is no defaults key, so a relaunch starts on Screen. Remembering it across relaunch is a behaviour decision, like the pack-skill row in the overnight ledger. - Bind the picker to it, and pass it to the three actions. The model functions keep their
mode:parameters. - Toolbar, ⌥C and panel captures pass their own mode and never write it.
- In
docs/snap.md:5, add: 'the page keeps that choice while Workbench runs, including after you leave the page.'
Acceptance (--check-readback, ReadbackCaptureChoiceChecks)
- A fresh model is on Screen.
- Set Region, host ReadbackView offscreen (as
ReadbackOrderingChecks.swift:127does), close it, then host it again on the same model. The Capture area segmented control shows Region. - A second model on the same defaults is on Screen.
replaceScreenshot(id, mode: model.captureArea)records[.region]and no screen capture.@State private var captureModeis gone, and the readback renders are unchanged.
Value before scope
- Outcome: the narrated deck follows the story, and a chosen capture area is not silently lost. Snap & Talk handoff is a repeated ask.
- Simpler route: sort before an existing append, and move one property from view to model.
- Owner: ReadbackModel.
- Complexity: a few lines, no new setting.
- Verified by:
--check-snap-captureand--check-readback.
Grammar: Quality.
Refs #63, #112
Build-ready record from the 15 Oct round-three pass (delight and code-base value), verified against the release train head 14d06bc by an independent skeptic per item. Closes only after native acceptance.
- Dominant language
- Swift
- Stars
- 0
- Forks
- 1
- Avg merge
- 8h 5m
- Merged PRs (30d)
- 215
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Ship-Work/workbench
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
-
documentation good first issue help wanted
Difficulty 2/5 Half a day Newbie friendliness 74/100
Ship-Work/workbench#29 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 55/100
Maintainers usually reply within 1 day
All issues in Ship-Work/workbench
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
raullenchai/Rapid-MLX#4889 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
iOS-2026
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
mozilla-mobile/firefox-ios#36150 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
-
HTMLFormatter applies the wrong column alignment to table cells that follow a spanned cellPossibly taken @auraseb claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
swiftlang/swift-markdown#296 ·