Skip to content

feat(chat): render the share-profile widget bubble - #1628

Merged
bmc08gt merged 4 commits into
code/cashfrom
feat/share-profile-widget
Sep 30, 2026
Merged

bmc08gt merged 4 commits into
code/cashfrom
feat/share-profile-widget

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Renders the share-profile widget (messaging.v1.WidgetContent.share_profile) as a chat bubble, following Figma node 10588:1979. Builds on #1625 (merged), which brings in the 0.13.0 contract and the domain model this builds on.

Only the server sends widgets. The widget's username decides whose profile the card shows and shares:

  • Own username: the bubble uses the LocalUserManager profile, with no lookup.

  • Any other username: it resolves through the same by-handle lookup as @handle mentions (LinkCardResolver / UserLinkLookup). While that runs, the username stands in for the name with shimmer. If it fails or finds nobody, the username stays as the name.

  • Share: the new ChatAction.ShareProfile(userId, username, displayName) presents Shareable.TipCard, the same shape as rememberProfileShare. It is disabled until the user resolves, since there is no userId to share before that.

  • Unknown widget variants: these render the existing UndecryptableBubble with the update-app hint.

  • Chat list preview: "Shared a profile".

  • Chat rules: Reply and reactions on a widget follow the chat's speaker rules. The new canSpeak(rules, balances, isStaff) in GroupAccess.kt shares a per-requirement check with the listener gate, so MinimumBalance, Staff and Never mean the same thing in both. A viewer who can speak gets Reply and reactions. Anyone else, or anyone outside the group, gets neither. There is no Copy or Report, since the server sends widgets, and encoding one in LocalToProtobuf is an error(...). For now the speaker gate applies to widgets only: text and cash messages, and the composer, still ignore speaker rules.

  • Reply quote: quoting a widget reads "Shared a profile".

  • Styling: existing tokens and components throughout (bubbleShape, ContactAvatar, CodeButton). Where they differ from the Figma: the outline is 8% white instead of 7%, and the avatar gradient comes from the app's contactAvatar token.

  • Visibility: Bubble in MessageBubble.kt is now internal instead of private, so the widget can reuse it.

ShareProfileWidgetScreenshotTest renders the own, other-user and lookup-failed states with Robolectric, following UndecryptableBubbleScreenshotTest.

@bmc08gt bmc08gt self-assigned this Sep 30, 2026
@github-actions github-actions Bot added type: feature New functionality area: network gRPC, connectivity, API, exchange rates labels Sep 30, 2026
@bmc08gt
bmc08gt added this pull request to stack #1632 September 30, 2026 17:10
Draws WidgetContent.ShareProfile as a card with the sender's avatar, name and
handle, and a Share button that runs the same share-link flow as the You tab.
The name and picture come from the signed-in user's session profile, since the
widget only ever describes them. An unrecognised widget variant draws as the
existing unsupported-message bubble.

The chat list previews a shared profile as "Shared a profile" ("You shared a
profile" for the viewer's own).
Widgets are sent by the server, never by a client. Give them no message
actions or reactions (as with system notices), use one sender-independent
list preview, and make encoding a widget an error.
The widget carries only a username, which now decides whose profile the
card shows and shares. The signed-in user's own comes from the session;
anyone else's goes through the by-handle lookup that person link cards
use. Until it answers, or if it fails, the card shows the username and
its initials, and Share stays off because it needs the resolved id.
A widget stays free of Copy and Report, but Reply and reactions now
follow whether the viewer may speak. canSpeak evaluates the speaker
rules (never, minimum balance, staff) with the predicate the listener
gate already uses. A reply that quotes a widget reads 'Shared a profile'.
@bmc08gt
bmc08gt force-pushed the feat/share-profile-widget branch from 8c9d37d to dbb7a77 Compare September 30, 2026 17:15
@bmc08gt
bmc08gt removed this pull request from stack #1632 September 30, 2026 17:15
@bmc08gt
bmc08gt changed the base branch from chore/flipcash2-3d6de707 to code/cash September 30, 2026 17:15
@bmc08gt
bmc08gt added this pull request to stack #1633 September 30, 2026 17:15
@bmc08gt
bmc08gt merged commit 0f0ace9 into code/cash Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: network gRPC, connectivity, API, exchange rates type: feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant