Make mobile Update decisions transaction-safe #771

Closed
opened 2026-08-13 20:50:17 +00:00 by timmy · 0 comments
Owner

Problem

The swipe adapter currently calls DOM .click(), which returns undefined, so its promise-aware busy lock releases before the asynchronous mark-read request settles. Only the Mark read button is disabled by the real handler; Keep unread, Reply, More, and additional swipes remain active. On a slow mobile connection this can double-advance or change the selected update while an acknowledgement is pending.

Scope

Coordinate swipe and button decisions through one asynchronous transaction. Keep the current update selected while pending; disable all decision controls and gestures; advance exactly once on success; restore the same item, controls, status, and originating focus on failure. Preserve Undo.

Acceptance tests

  • Swipe and button actions use the same promise-returning coordinator.
  • A pending decision rejects additional swipes and button actions.
  • Pending state disables Keep unread, Mark read, Reply, and More and exposes an accessible status.
  • Mark-read success advances exactly once and retains Undo.
  • Failure leaves the current update selected/unread, restores controls, announces retry guidance, and returns focus to the originating action.
  • Focused tests and the full suite pass.

Non-duplication

All 388 historical issue titles and recent commits were checked. #769 added swipe gestures, but no issue or commit addresses the real .click() promise loss or a shared cross-action transaction lock.

## Problem The swipe adapter currently calls DOM `.click()`, which returns `undefined`, so its promise-aware busy lock releases before the asynchronous mark-read request settles. Only the Mark read button is disabled by the real handler; Keep unread, Reply, More, and additional swipes remain active. On a slow mobile connection this can double-advance or change the selected update while an acknowledgement is pending. ## Scope Coordinate swipe and button decisions through one asynchronous transaction. Keep the current update selected while pending; disable all decision controls and gestures; advance exactly once on success; restore the same item, controls, status, and originating focus on failure. Preserve Undo. ## Acceptance tests - Swipe and button actions use the same promise-returning coordinator. - A pending decision rejects additional swipes and button actions. - Pending state disables Keep unread, Mark read, Reply, and More and exposes an accessible status. - Mark-read success advances exactly once and retains Undo. - Failure leaves the current update selected/unread, restores controls, announces retry guidance, and returns focus to the originating action. - Focused tests and the full suite pass. ## Non-duplication All 388 historical issue titles and recent commits were checked. #769 added swipe gestures, but no issue or commit addresses the real `.click()` promise loss or a shared cross-action transaction lock.
timmy self-assigned this 2026-08-13 20:50:17 +00:00
timmy closed this issue 2026-08-13 21:01:01 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
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: stackchain/stackchain-dashboard#771
No description provided.