A swipe onto a panel the app was already heading for is still a swipe #26

Closed
opened 2026-08-11 21:41:45 +00:00 by aiko · 1 comment
Owner

Parent

#1

What is wrong, with evidence

Two reports that turn out to be one bug: swiping the Cue strip is inconsistent, and turning on Swiping seeks the show changes nothing. The setting itself is fine — the header label and the diagnostics state both flip with it, confirmed on the phone. The swipe path never acts on it.

From #24's log, taken while the reader was swiping:

settle 61 reader
settle 63 app
settle 62 app
strip panel 64 live 64 following await 61,64

Those app verdicts are the reader's own swipes, misjudged.

Cause. #22 made the strip ignore settles it had queued itself, recorded in awaitingSettle, to stop its own auto-scroll reading as a swipe. With the Playhead advancing, the app queues scrolls constantly, so a swipe that lands on a panel the app had also queued is attributed to the app. readerMoved returns false, the scrollend handler returns early, and followsSettle is never reached — no seek, no freeze, nothing.

It is a race, so it is intermittent, which is exactly how it feels in the hand.

#22 named this blind spot and judged it harmless: "a swipe onto the panel a scroll is already travelling to — nothing distinguishes the two inside that window and nothing needs to: the strip was going there either way." That reasoning holds for the frozen state, where the outcome is the same either way. It does not hold for follow mode, where the app's scroll must not seek and the reader's must.

What to build

A discriminator that does not depend on where the strip lands.

#22 rejected a pointer flag on the grounds that tapping a word puts a finger on the strip without scrolling it, so a nearby auto-scroll settle would read as the reader's. That objection is answerable: a pointer down and the scroll position changing between that pointer going down and the settle is unambiguous — a tap alone moves nothing, and the app's own scroll happens with no pointer down at all.

Whatever you choose, it must satisfy both:

  • The app's auto-scroll never reads as the reader's, including when the Playhead crosses a Cue boundary mid-scroll — that is #22's bug and its regression test must keep passing.
  • The reader's swipe always reads as the reader's, including when it lands on a panel the app had queued — this bug.

awaitingSettle may stay, change, or go. It exists only to answer this question, and if a better answer makes it dead weight, remove it rather than keeping both.

Acceptance criteria

  • A swipe onto a panel the app had queued is judged the reader's
  • The app's own scroll is still never judged the reader's, and #22's boundary-crossing regression test still passes
  • With follow mode on, a swipe seeks the show — including one landing on a queued panel
  • With follow mode off, the same swipe freezes the strip
  • A tap that opens a Lookup does not read as a swipe
  • The diagnostics log's reader/app verdict reflects the new discriminator
  • Both directions are covered by tests: the app's scroll misread as the reader's, and the reader's misread as the app's

Blocked by

## Parent #1 ## What is wrong, with evidence Two reports that turn out to be one bug: swiping the Cue strip is inconsistent, and turning on `Swiping seeks the show` changes nothing. The setting itself is fine — the header label and the diagnostics state both flip with it, confirmed on the phone. The swipe path never acts on it. From #24's log, taken while the reader was swiping: ``` settle 61 reader settle 63 app settle 62 app strip panel 64 live 64 following await 61,64 ``` Those `app` verdicts are the reader's own swipes, misjudged. **Cause.** #22 made the strip ignore settles it had queued itself, recorded in `awaitingSettle`, to stop its own auto-scroll reading as a swipe. With the Playhead advancing, the app queues scrolls constantly, so a swipe that lands on a panel the app had also queued is attributed to the app. `readerMoved` returns false, the `scrollend` handler returns early, and `followsSettle` is never reached — no seek, no freeze, nothing. It is a race, so it is intermittent, which is exactly how it feels in the hand. #22 named this blind spot and judged it harmless: *"a swipe onto the panel a scroll is already travelling to — nothing distinguishes the two inside that window and nothing needs to: the strip was going there either way."* That reasoning holds for the frozen state, where the outcome is the same either way. It does not hold for follow mode, where the app's scroll must not seek and the reader's must. ## What to build A discriminator that does not depend on where the strip lands. #22 rejected a pointer flag on the grounds that tapping a word puts a finger on the strip without scrolling it, so a nearby auto-scroll settle would read as the reader's. That objection is answerable: a pointer down **and** the scroll position changing between that pointer going down and the settle is unambiguous — a tap alone moves nothing, and the app's own scroll happens with no pointer down at all. Whatever you choose, it must satisfy both: - The app's auto-scroll never reads as the reader's, including when the Playhead crosses a Cue boundary mid-scroll — that is #22's bug and its regression test must keep passing. - The reader's swipe always reads as the reader's, including when it lands on a panel the app had queued — this bug. `awaitingSettle` may stay, change, or go. It exists only to answer this question, and if a better answer makes it dead weight, remove it rather than keeping both. ## Acceptance criteria - [ ] A swipe onto a panel the app had queued is judged the reader's - [ ] The app's own scroll is still never judged the reader's, and #22's boundary-crossing regression test still passes - [ ] With follow mode on, a swipe seeks the show — including one landing on a queued panel - [ ] With follow mode off, the same swipe freezes the strip - [ ] A tap that opens a Lookup does not read as a swipe - [ ] The diagnostics log's `reader`/`app` verdict reflects the new discriminator - [ ] Both directions are covered by tests: the app's scroll misread as the reader's, and the reader's misread as the app's ## Blocked by - #18 - #22 - #24
Author
Owner

This was generated by AI during triage.

Merged to main. Suites: 79 C#, 371 phone.

The verdict no longer looks at where the strip landed. dragsTheStrip asks whether a pointer was down, travelled past a slop threshold, and the strip's scroll actually moved since that pointer went down — both halves required, each excluding a named false positive: a vertical drag down the tail of a long Cue, and a finger resting on a word while the app scrolls underneath it.

awaitingSettle and scrolledItselfTo are deleted. They existed only to answer this one question, and keeping them would have left two notions of "who moved the strip" that can disagree — the thing the last cross-seam review warned about.

#22's test and this one are now the same landing with opposite verdicts: the app arriving on panel 1 is the app's, the reader arriving on panel 1 is the reader's. That is the fix stated as plainly as it can be.

Known limit, in the safe direction: a drag that passes the slop while the strip cannot move (over-scrolled at either end) reads as the app's, so it does not seek.

> *This was generated by AI during triage.* Merged to `main`. Suites: 79 C#, 371 phone. The verdict no longer looks at where the strip landed. `dragsTheStrip` asks whether a pointer was down, travelled past a slop threshold, **and** the strip's scroll actually moved since that pointer went down — both halves required, each excluding a named false positive: a vertical drag down the tail of a long Cue, and a finger resting on a word while the app scrolls underneath it. `awaitingSettle` and `scrolledItselfTo` are deleted. They existed only to answer this one question, and keeping them would have left two notions of "who moved the strip" that can disagree — the thing the last cross-seam review warned about. #22's test and this one are now the same landing with opposite verdicts: the app arriving on panel 1 is the app's, the reader arriving on panel 1 is the reader's. That is the fix stated as plainly as it can be. Known limit, in the safe direction: a drag that passes the slop while the strip cannot move (over-scrolled at either end) reads as the app's, so it does not seek.
aiko closed this issue 2026-08-11 21:55:01 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
mobrule/kurageyomi#26
No description provided.