Skip to content

fix(chat): gate the message actions on the edit and delete windows - #1403

Merged
bmc08gt merged 4 commits into
code/cashfrom
fix/chat-message-action-windows
Sep 3, 2026
Merged

fix(chat): gate the message actions on the edit and delete windows#1403
bmc08gt merged 4 commits into
code/cashfrom
fix/chat-message-action-windows

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

The edit and delete windows arrived in ResolvedUserFlags in #1397 with nothing reading them. Four fixes on top of that, three of them user-visible.

The windows now gate the menu

MessagePolicy carries both windows and ChatViewModel maps the resolved flags into it, so the selection bar stops offering Edit or Delete on a message past its window instead of sending a request the server answers CANNOT_EDIT / CANNOT_DELETE.

Capabilities resolve once, when a transcript row is mapped, and the windows keep running under an open transcript. So the ToggleMessageSelection reducer re-applies them to the bubble it selects. Resolver and reducer share withinWindows, and a test pins that both give the same answer for the same instant.

A just-sent message would not long-press

Sending writes an optimistic row with event_sequence 0 — only the server can stamp it — and confirmPendingMessage updated the id, timestamp, unread sequence and status but not the sequence. The row stayed at 0 until some later fetch of the chat overwrote it, which is why leaving the chat and coming back appeared to fix it.

Anything keyed on that stamp read the message as unacknowledged in the meantime: resolveCapabilities returns nothing for sequence 0, so the row was not selectable, and expected_event_sequence is validated >= 1 on the wire, so an edit or delete built from the stale value could not have been valid either. The confirm now writes the sequence the send echo carries.

The bottom bar sat behind the keyboard

Screens are drawn edge to edge, so the window is not resized when the IME opens and the bottom-aligned bar slid up underneath it. An edit failure, raised while the composer still holds focus, showed an error the user could not see. imePadding on the animated content lifts the bar; the scrim still covers the whole window.

Both windows are overridable

Watching the menu narrow otherwise means waiting out whatever the server publishes. Both are now Fields on the User Flags screen, entered in seconds like the bill exchange timeout above them.

The windows landed in `ResolvedUserFlags` with nothing reading them, so the
selection bar offered Edit and Delete on any message the viewer sent, however
old. The server answers `CANNOT_EDIT` / `CANNOT_DELETE` for those, which is a
failed round-trip and an error bar where the action should not have been on
offer.

`MessagePolicy` now carries both windows, and `ChatViewModel` maps the resolved
flags into it and combines it into the transcript. Resolution happens once, when
a row is mapped, so the windows keep running under an open transcript: the
`ToggleMessageSelection` reducer re-applies them to the bubble it selects, which
`withinWindows` shares with the resolver so both give the same answer for the
same instant.
Watching the menu narrow means waiting out whatever the server publishes. Both
windows are now `Field`s on the User Flags screen, entered in seconds like the
bill exchange timeout above them, so a window short enough to observe is one
text field away.
Every screen is drawn edge to edge, so the window is not resized when the IME
opens. The bottom bar is bottom-aligned in that unresized window, which put it
behind the keyboard: a chat edit failure, raised while the composer still holds
focus, showed an error the user could not see.

`imePadding` on the animated content lifts the bar with the keyboard. The scrim
is left alone so it still covers the whole window.
Long-pressing a message just sent did nothing; leaving the chat and coming back
made it work. Sending writes an optimistic row with `event_sequence` 0, because
only the server can stamp it, and `confirmPendingMessage` then updated the id,
timestamp, unread sequence and status but not the sequence. The row stayed at 0
until some later fetch of the chat overwrote it.

Everything keyed on that stamp read the message as unacknowledged in the
meantime. `resolveCapabilities` returns nothing for sequence 0, so the row was
not selectable, and `expected_event_sequence` is validated `>= 1` on the wire,
so an edit or delete built from the stale value could not have been valid
either.

The confirm now writes the sequence from the send echo, which carries it.
@bmc08gt bmc08gt self-assigned this Sep 3, 2026
@github-actions github-actions Bot added type: fix Bug fix area: ui Compose UI, theme, components, resources labels Sep 3, 2026
@bmc08gt
bmc08gt merged commit 13e2c50 into code/cash Sep 3, 2026
2 of 3 checks passed
bmc08gt added a commit that referenced this pull request Sep 4, 2026
Gating the actions on the edit and delete windows (#1403) made the
ToggleMessageSelection reducer re-narrow the bubble it selects, so the selection
is a copy of the bubble the event carried. Three assertSame checks were pinning
the old identity and have failed on code/cash since that merge, taking down the
messenger module's test task on every PR.

The narrowing is a no-op under MessagePolicy.Default, whose windows are both
null, so the copy is value-equal and assertEquals asserts what the tests meant.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ui Compose UI, theme, components, resources type: fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant