Skip to content

fix(chat): keep group members a FullRefresh leaves out - #1587

Merged
bmc08gt merged 2 commits into
code/cashfrom
fix/group-preview-sender-name
Sep 28, 2026
Merged

bmc08gt merged 2 commits into
code/cashfrom
fix/group-preview-sender-name

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Group rows in the Chats list switched between "Name: text" and bare "text". formatPreview only prefixes when the sender is in the chat's cached members, and two things broke that.

FullRefresh deleted group members. EventStreamDelegate handled MetadataUpdate.FullRefresh with replaceMembers, which deletes every cached member not in metadata.members. For a group that list is a page of the roster (chat/v1/model.proto: "For large group chats, this is a subset of all members"), so each refresh dropped members the device had cached from roster changes, message loads and feed pages. If one of them sent the last message, the row lost the name until something cached them again. Groups now upsert on FullRefresh, the same as RosterStateHolder.refetch, and departures come through RosterChange.MemberLeft. DMs still use replaceMembers. replaceMembers on this path came in with #1365.

An empty name read as ": text". ChatEntityMapper.toMember maps a member with no profile row to UserProfile.Empty, whose displayName is "", and formatPreview treated that as a name. Group cash had the same problem. A blank name now counts as missing, matching iOS's ConversationController.groupSenderName.

The transcript drew a blank name line. The profile proto allows an empty display_name (min_len: 0), and the app stores it unchanged, so a group member with no name got an empty line above their run of messages. MessageRow now skips the name line when it is blank; the avatar is still drawn.

Tests:

  • FullRefreshMembersTest streams a FullRefresh through EventStreamDelegate against the real member table. A group with A, B and C cached keeps B and C (and C's name) after a refresh listing only A; a DM refresh still replaces. The group case fails without the fix.
  • ChatSummaryPreviewTest covers a blank-named sender for text and cash; both fail without the fix.
  • GroupTranscriptScreenshotTest.omitsNameLineForBlankDisplayName renders a run from a nameless sender and checks no blank text node is drawn; it fails without the fix.

A sender who was never in any page the device received still previews as bare text, as on iOS. Changing that needs a product or backend decision.

A FullRefresh replaced the chat's cached members with the metadata's
member list. For a group that list is only a page of the roster, so the
refresh deleted every other member the device held from roster changes,
message loads and feed pages. When one of them sent the last message,
the Chats list preview lost the "Name: " prefix until something cached
them again. Groups now merge on FullRefresh, as RosterStateHolder.refetch
already does, and departures come through MemberLeft. DMs still replace.

A member row with no profile row maps to UserProfile.Empty, whose name
is "", so the preview read ": text". formatPreview now treats a blank
name as missing, as iOS does.
@bmc08gt bmc08gt self-assigned this Sep 28, 2026
@github-actions github-actions Bot added the type: fix Bug fix label Sep 28, 2026
The profile proto allows an empty display_name, and the app stores it as-is,
so a group member with no name drew an empty textSmall line above their run.
The avatar still marks the run.
@bmc08gt
bmc08gt merged commit 9a79832 into code/cash Sep 28, 2026
3 checks passed
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