Skip to content

fix(chat): stop a group re-rendering as a DM with one of its members - #1531

Merged
bmc08gt merged 1 commit into
code/cashfrom
fix/group-chat-dm-flash
Sep 23, 2026
Merged

bmc08gt merged 1 commit into
code/cashfrom
fix/group-chat-dm-flash

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

When a group's roster changes, the chat screen redraws for about half a second as a tip DM with the first other member. The title bar shows that member, sender avatars disappear, and the composer goes $ + Message → Send a Tip → hidden before the group comes back.

Two paths in ChatViewModel read "no device contact" as "tip DM", and a group has no device contact either:

  • The tip counterparty collector took the first non-self member of any chat, and the OnTipUserResolved reducer replaced the Group subject with it. observeMetadata combines the members table, so a single roster change emits on both flows, and OnGroupResolved only restores the group after the DM frame has drawn.
  • Opening by chat id dispatched OnTipDmDetected, which set chatType = TIP_DM on a group.

Changes:

  • OnTipUserResolved and OnTipDmDetected leave a resolved ChatSubject.Group alone.
  • The collector combines the members with the chat's metadata type and skips GROUP.
  • The ByChatId open path reads the cached metadata before dispatching OnTipDmDetected.

A group opened before any metadata is cached still has no type to check against, so the collector can resolve a member until OnGroupResolved arrives. The reducer guard covers every emission after that.

ChatViewModelStateTest pins both reducer guards.

When a group's roster changed, the chat screen redrew for about half a
second as a tip DM with the first other member: their name in the title
bar, no sender avatars, and the "$" composer, then "Send a Tip", before
flipping back.

The tip counterparty collector took the first non-self member of any chat,
and OnTipUserResolved replaced the Group subject with it. observeMetadata
combines the members table too, so one roster change emitted on both
flows and OnGroupResolved only put the group back afterwards. Opening a
group by chat id also dispatched OnTipDmDetected, since a group has no
device contact either.

Both reducers now keep a resolved group, the collector skips chats whose
metadata says GROUP, and the open path checks the cached metadata before
marking a tip DM.
@bmc08gt bmc08gt self-assigned this Sep 23, 2026
@github-actions github-actions Bot added the type: fix Bug fix label Sep 23, 2026
@bmc08gt
bmc08gt merged commit 9a6d8bb into code/cash Sep 23, 2026
3 checks passed
@bmc08gt
bmc08gt deleted the fix/group-chat-dm-flash branch September 23, 2026 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant