Skip to content

refactor(mobile): queued-overlay parity with web — shared applyQueuedOp, live steer overlay#629

Merged
gbasin merged 1 commit into
masterfrom
refactor/mobile-overlay-gaps
Jul 21, 2026
Merged

refactor(mobile): queued-overlay parity with web — shared applyQueuedOp, live steer overlay#629
gbasin merged 1 commit into
masterfrom
refactor/mobile-overlay-gaps

Conversation

@gbasin

@gbasin gbasin commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Closes the two mobile gaps flagged in #616.

Gap 1 — live send(): now derives its optimistic message from the shared pendingMessageFromSendPayload instead of a third inline copy. Only drift found: the waveform key is now omitted when empty — verified renderer-identical in #616.

Gap 2 — queued steer overlay: applyQueuedOp delegates wholesale to the shared queuedOverlayAction (~75-line if-chain → small wrapper; mobile already uses the shared appReducer and dispatched identical action shapes), picking up web's session.steer thread-overlay branch. The audit's deeper finding: mobile never enqueued thread provenance, so that branch alone would have been dead codesteerSession now builds the full QueuedThreadSteerPayload (channelId/threadRootEventId/clientMsgId=opId/createdAt) and dispatches the optimistic thread row in onStored, exactly mirroring web's useSessionActions (verified side-by-side; the op executor already tolerates the fields, and session.steer.onRejected already routes send-failed by channelId+clientMsgId). Mobile's MessageRow already renders steeredSessionId (the → agent chip).

New mobile/test/chatOverlays.test.ts (6 tests): voice/plain send construction, steer-overlay recovery, provenance-less rejection guard, reducer land/reconcile by clientMsgId, and first-ever delegation coverage for the edit/delete/reaction/mute/read overlay ops.

Validation: pnpm check fully green (mobile 233 tests), full local e2e 120/120 exit 0.

…Op, live steer overlay

Closes the two gaps flagged in #616:

- live send() derives its optimistic message from the shared
  pendingMessageFromSendPayload instead of a third inline copy (only
  drift: waveform key now omitted when empty — renderer-identical per
  the #616 verification)
- applyQueuedOp delegates wholesale to the shared queuedOverlayAction
  (mobile already used the shared appReducer and dispatched the same
  action shapes), which adds the previously-missing session.steer
  thread-overlay branch. Crucially, mobile never enqueued thread
  provenance, so the branch would have been dead: steerSession now
  carries the full QueuedThreadSteerPayload shape (channelId,
  threadRootEventId, clientMsgId=opId, createdAt) and dispatches the
  optimistic thread row in onStored, mirroring web's useSessionActions;
  the thread composer passes the provenance. MessageRow already renders
  steeredSessionId.

New mobile/test/chatOverlays.test.ts (6 tests): voice/plain send
construction, steer overlay recovery + provenance-less rejection guard,
reducer land/reconcile by clientMsgId, and delegation coverage for
edit/delete/reaction/mute/read overlays.

Validation: pnpm check green (mobile 233), e2e 120/120.
@gbasin
gbasin enabled auto-merge July 21, 2026 15:27
@gbasin
gbasin added this pull request to the merge queue Jul 21, 2026
Merged via the queue into master with commit 0a1984e Jul 21, 2026
19 checks passed
@gbasin
gbasin deleted the refactor/mobile-overlay-gaps branch July 21, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant