Skip to content

feat(profile): favorite public groups on profiles - #996

Merged
bmc08gt merged 9 commits into
mainfrom
feat/profile-favorite-groups
Oct 6, 2026
Merged

bmc08gt merged 9 commits into
mainfrom
feat/profile-favorite-groups

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator

Adds the Favorite Public Groups picker to Edit Profile and the matching section on your own profile and other people's (Figma nodes 10961:185, 10961:314, 10990:494). It uses the GetFeaturedGroups/SetFeaturedGroups RPCs that main picked up with flipcash2 0.18.0.

This replaces #991, which was stacked on the profile-refresh branches. These are the same commits, cherry-picked onto main now that the stack has merged.

  • Edit Profile: a new card opens a picker of your public groups. It saves an ordered list of up to 10. The contract rejects an 11th as a validation error, not a result code, so the picker stops you at 10.
  • Picker candidates: the groups you already feature, plus the public groups you've joined. A group you've left is still listed, so you can still remove it.
  • Picker order: groups keep the server's order, and new picks go on the end.
  • Picker loading: the list fills in once both the featured groups and the group feed have loaded, instead of showing the featured ones first. The search field is pinned and stays put through the load.
  • Picker chrome: Figma (node 10961:188) has Cancel/Done in the bar. The picker uses the bottom Save button the other Edit Profile editors use instead. Save is pinned with scrollEdgeBar(.bottom), and it gets a backgroundMain backing in its own shape, because the disabled filled style is a 10% tint that rows would show through.
  • Save errors: a denied save (one of the groups went private) shows its own dialog.
  • Profile section: on your own profile and on other people's profiles, the groups appear under the stats card behind a divider. Tapping one opens the chat. The section is hidden when there are none.
  • State: your own featured groups live in one FeaturedGroups unit on SessionContainer, shared by the You tab, the Edit Profile card and the picker. Featured groups stay out of ConversationStore. They come back list-shaped (no members, viewer state or last message) and can be chats the viewer isn't in.
  • Tests: EditFeaturedGroupsModelTests covers candidates, order, the cap and error mapping. SettingsRoutingTests covers the new destination.

Edit Profile gets a "Favorite Public Groups" card that opens a picker of
the user's public groups, saved with SetFeaturedGroups. The You tab and
other users' profiles list those groups under the stats card and open the
chat on tap; the section hides when there are none.

The picker's candidates are the currently featured groups plus joined
public groups, so a group the user has since left can still be removed.
Selection keeps the server's order, appends new picks, and caps at 10,
which the contract enforces as a validation error rather than a result
code. A denied save (a group went private) gets its own dialog.

Own-profile state lives in a FeaturedGroups unit on SessionContainer,
shared by the You tab, the Edit Profile card and the picker. Featured
groups stay out of ConversationStore: they are list-shaped and may belong
to chats the viewer is not in.
The section now sits under a divider with a heading-weight title, and its
rows drop the card and separators for a 48pt rounded-square picture beside
the title and description (node 10961:111). ContactAvatarView takes an
optional corner radius for that; every existing caller stays a circle.

Another person's featured groups now report a failed load instead of
dropping it silently, matching the own-profile path.
Titles the screen "Favorite Groups", drops the row separators, and adds
the footer line from node 10961:188. The search prompt now reads "Search
your public groups".
Group descriptions use appTextSmall, the subtitle token RecipientRow uses,
instead of the smaller appTextCaption, and wrap to two lines. Rows drop the
66pt minimum height that stacked on the list's own insets.

The picker shows a spinner until the group feed is read, so the list
appears whole instead of growing from the featured groups. Save sits below
the list, as in the other Edit Profile editors, rather than over it.
…rite groups

The picker swapped a spinner for the List while loading, which rebuilt the
List and dropped the search field attached to it. The List now stays, with
the spinner drawn over it, and the field is pinned with
navigationBarDrawer(displayMode: .always) so it shows before any scroll.

Profile rows get 16pt between them (was 2pt) and 24pt under the heading
(was 12pt).
Save is pinned with scrollEdgeBar(.bottom), so rows scroll under it. A new
hardScrollEdge(for:) modifier in FlipcashUI swaps the app-wide soft edge for
the hard one on this list, which blurs the rows out instead of leaving them
readable. The disabled filled style is a 10% tint, so the button gets a
backgroundMain backing in its own shape to stop rows showing through it.
The hard edge drew a full-width blurred band with a line across it behind
the button. The picker goes back to the app-wide soft edge, and the
button's own backing keeps rows from showing through it. hardScrollEdge
had no other caller, so it goes too.
@bmc08gt bmc08gt self-assigned this Oct 6, 2026
…-groups

* origin/main:
  feat(chat): rebuild the group profile on the profile refresh (#995)
  refactor(profile): key the profile header and cover on what they render (#993)
#993 moved the profile inset to ProfileHeaderMetrics and gave
ProfileHeaderView a fourth generic parameter, so the old
ProfileHeaderView<EmptyView, EmptyView, EmptyView>.inset no longer compiles.
@bmc08gt
bmc08gt merged commit aa97e0d into main Oct 6, 2026
2 of 3 checks passed
bmc08gt added a commit that referenced this pull request Oct 6, 2026
* origin/main:
  feat(profile): favorite public groups on profiles (#996)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant