Skip to content

fix(chat): group-chat sender runs — avatar on the last bubble, runs broken by sender id - #1481

Merged
bmc08gt merged 2 commits into
code/cashfrom
fix/group-chat-sender-runs
Sep 17, 2026
Merged

bmc08gt merged 2 commits into
code/cashfrom
fix/group-chat-sender-runs

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Two fixes to how a group transcript reads a run of messages.

The avatar sits on the run's last bubble

It was on the same bubble as the name, at the top. It now sits next to the newest thing that person said, level with the bottom bubble, and the name stays on the first — the two mark the run's ends instead of stacking on one bubble.

endsSenderRun is the mirror of startsSenderRun: newer is peek(index - 1) under reverseLayout where older is peek(index + 1).

Runs break by sender id, not by resolved profile

A group's incoming bubbles were cornered as one run until the member profiles landed — First at the top, Middle through the rest, whoever actually sent them.

isSameAuthorAs compared sender?.userId, and sender comes from the profile map ChatViewModel combines into the paging stream. That map starts null and arrives after the first page, so early on every member's bubble has a null sender and they all compare equal. bubblePositionOf and rowGapBelow both read that answer, so the merged run got one set of corners and the tight same-sender gap. A member whose profile never resolves stayed merged for good.

ContentBubble now carries senderId off the message, independent of the lookup, and authorId prefers it. The profile still draws the name and the picture; it no longer decides who said it. The run helpers key off authorId too, so a run holds its shape from the first frame rather than re-splitting when the names arrive.

Tests

BubblePositionTest is new: cornering across a sender change, with resolved profiles and without. SenderRunTest gained the endsSenderRun cases and the unresolved-profile case.

…ofile

A group's incoming bubbles are cornered as one run until the member profiles
land: First at the top, Middle through the rest, whoever actually sent them.

isSameAuthorAs compared sender?.userId, and `sender` is filled from the profile
map that ChatViewModel combines into the paging stream. That map starts null
and arrives after the first page, so early on every member's bubble has a null
sender and they all compare equal. bubblePositionOf and rowGapBelow both read
that answer, so the run gets one set of corners and the tight same-sender gap.
A member whose profile never resolves stays merged for good.

ContentBubble now carries senderId straight off the message, independent of the
lookup, and authorId prefers it. The profile is still what draws the name and
the picture; it is no longer what decides who said it.
The picture sat on the same bubble as the name, at the top of the run. It now
sits on the run's last message — the newest thing that person said, level with
the bottom bubble — while the name stays on the first, so the two mark the
run's ends instead of stacking.

endsSenderRun is the mirror of startsSenderRun: `newer` is peek(index - 1)
under reverseLayout, where `older` is peek(index + 1). Both key off authorId
rather than the resolved sender, so a run holds its shape from the first frame
instead of re-splitting when the profiles arrive.
@bmc08gt bmc08gt self-assigned this Sep 17, 2026
@github-actions github-actions Bot added the type: fix Bug fix label Sep 17, 2026
@bmc08gt
bmc08gt merged commit 46b5a06 into code/cash Sep 17, 2026
3 checks passed
@bmc08gt
bmc08gt deleted the fix/group-chat-sender-runs branch September 23, 2026 16:46
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