Skip to content

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

Closed
bmc08gt wants to merge 46 commits into
feat/profile-refresh-copyfrom
feat/profile-featured-groups
Closed

bmc08gt wants to merge 46 commits into
feat/profile-refresh-copyfrom
feat/profile-featured-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.

Stacked on #990, with main merged in. The RPC wrappers only exist on main, so this branch merges origin/main into the stack head. Until the stack takes main, this diff also shows main's 9 commits. The feature is the feat(profile) commit and the two fix(profile) commits after it.

  • 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 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 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.

bmc08gt added 30 commits October 5, 2026 23:00
The You tab becomes the profile in later slices, so the rows it held
move to a Settings screen reached from a gear on the tab: an interim
Profile section (the My Account editors until Edit Profile exists),
Security, Privacy, Advanced, and Account with a new Account Info screen
(phone, email, user ID, authority public key), then the version footer.

SettingsMyAccountScreen and SettingsAdvancedFeaturesScreen are removed,
and the UI smoke tests now reach Settings through the gear.

Base: origin/main 410bb5f.
…nfoDetails.Row

The UI tests' failure messages and doc comments still named My Account,
which this branch removed. Also rewraps a YouScreen doc comment that was
reflowed onto one 110-column line.
Rebuild the You tab as the user's own profile: cover banner, avatar,
name, handle and bio, a stats card (minimum to chat, date joined), and
an Edit Profile button. Share becomes a menu with "Share Profile" and
"Show Profile Card"; the card, link row, Share/Download and export move
to a full-screen ProfileCardScreen. A "Claim your username" row replaces
the username progress card. Add a cover subject to ProfileAvatarStore
and extract StartChattingFee from ConversationScreen. Remove
TipCardPresentation and the tab-bar expansion state. Exported card files
are now named "Chat with <name>".
Push the new chat when the DM record lands before the start-chatting sheet
dismisses, and only when the profile is still in front. Open Chat from a DM
returns to it instead of pushing a copy. Unmute from the menu reports errors
and analytics like the mute sheet, Start Chatting runs the give-cash gate in
both branches, and the toolbar buttons get accessibility labels.
The profile screens had the right controls in a centred, inset-card
layout that didn't follow the design. Follow nodes 10961:314 and
10990:494 instead: a full-bleed 214pt banner (flat #323234 when there is
no cover), a left-aligned 84pt avatar overlapping it, Edit Profile and
Share in the avatar row, left-aligned name, handle and bio, and a
two-column stats card with labels above values.

Share opens a sheet with Share Profile, Show Profile Card and Copy Link
in place of the menu. The other-user profile draws its back and overflow
buttons over the banner with no navigation bar, and the pinned button is
white over a fade. The Finish Your Profile card and the card-colour
cover fallback are gone, with their tests.
Move the You tab's gear and the other-user profile's back and overflow
controls into the navigation bar, so the app-wide soft scroll edge draws
the top fade. Drop the "You" title, the cover's dark overlay and the
pinned button's gradient; the pinned button now sits in a scroll edge bar.

Replace Mute/Unmute in the overflow menu with one "Mute Notifications"
entry that opens MuteChatSheet, whose "Never" option unmutes.

Top-align the stats card labels, and left-align the share sheet's
"Share User Profile" title with a shorter detent.
The profile screens matched Figma pixel values: ten font sizes, four RGB
colours and one-off radii and paddings that no other screen uses. Swap
them for the app* font tokens, the textMain/textSecondary/backgroundRow
colours, glass buttons, and the PartialSheet + ChatActionRow sheet that
Mute Notifications already uses.
… the bar

At rest the iOS 26 soft edge only darkened the cover banner and left a hard band where it stopped.
Under the handle they took the bio's spot. The action row's height comes
from the share button, so a badge appearing on mute or block no longer
moves the content below it. The stats card uses Metrics.boxRadius like the
app's other cards.
Share and Edit Profile now match the design (node 10961:323, 10961:335):
38pt tall, a 22pt share glyph, 18pt side padding on Edit Profile, and a
flat fill at 10% of the action colour. Over the #19191A background that
is the design's #303031. On glass the circle rendered at 34pt and the
capsule at 31pt.
appTextBody is Avenir Regular, a weight nothing else in the app uses, so
the bio read as a different typeface next to the header. Use
appTextMessage, the Medium weight chat bubbles use.
The profile hides the tab bar, so the toast host drew 12pt above the bottom
edge, over the pinned button. A screen can now mark a bottom bar with
toastClearance(_:); the host measures it and keeps the toast above it while
it is on screen.
The entrance moved the toast by its own padded height, so a toast raised
over the profile's pinned button travelled up from the screen edge past
the button. It now rises the 56pt a toast 12pt off the edge always did.
…rofile header

The You tab's Edit Profile button now pushes Edit Profile instead of
Settings, and Settings drops its interim Profile section.

Edit Profile draws its cover with ProfileCoverBanner and its avatar at
the You tab's 84pt with the same 5pt ring, so the two screens show the
same empty cover. The parked CoverBanner, with its 3:1 card-colour
fill, is removed; the cover editor previews a picked image through
ProfileCoverBanner's new preview parameter. Row insets match Settings
(25/20), values sit against the chevron, and the empty-cover plus uses
appDisplayMedium instead of a 40pt system font.
…ards

The cover sits in an inset card with a Change cover chip, the avatar
overlaps its edge with a camera badge, and Name, Username, Bio and
Minimum to Chat are label/value cards that open the existing editors.
A Medium-weight label reads as secondary next to the bold value.
iOS 18 keeps the opaque chip, since the row fill vanishes on a photo.
…tton

The glass takes a backgroundMain tint so the label holds on a bright
cover, and the chip is a button beside the cover card rather than a
label inside it, so the interactive glass responds to its own press.
Both open the cover editor.
…f the profile card

Drop the link row and Share button; the profile's Share menu already offers both.
The card springs in from 0.55 scale with the bill pop's timing while the backdrop fades in, and Close plays it in reverse. The cover is presented and dismissed without its slide so the reveal is the only motion.
…glass swaps to Download in place

The card was a full-screen cover with its own toolbar button laid over the
You tab's gear. The two glass buttons sampled different backdrops, so the
glass shifted and changed colour as the cover settled and cleared. The card
is now an overlay in the You tab, the tab's one toolbar button swaps its
glyph between Settings and Download, and the tab bar hides while it is up.
The keyboard and Save button rose while the screen was still sliding in, so Save animated in from off screen. Name, Username, Bio, username lookup and group name now focus after the push finishes.
bmc08gt added 10 commits October 6, 2026 13:05
Edit Profile read only the account's own fee and showed "Not set" when there was none, while the You tab showed the regional minimum others actually pay. Both now use StartChattingFee.
A scan always opens the person's profile after the card's 750ms hold. A
username search and a transaction's details open the DM when it exists
and the profile until then, through DMRoute. The profile is where the
paid chat starts, so nothing routes into a conversation by user ID any
more, and tipConversationForUser and tipConversationForUserSendingCash
are removed.
Every route to a person now lands on their profile until a DM exists, and
the profile owns the paid start-chatting flow. ConversationScreen only opens
an existing chat, so the tipDM context, the chatExists/startChattingFee
plumbing, the full-width Start Chatting bar, and the open-time Send Cash are
unreachable.
Scanning opens the profile now, so the old wait for the empty chat's
send-cash button timed out with the profile on screen.
Scan prompts, the tutorial step, the scan error alert, the setup card screen and the unnamed export file now say "Profile Card". Identifiers and analytics event names keep tip card; the code rename is a later chore.

Delete UsernameProgressCard: Edit Profile's Username card replaced it and nothing references it.
It has no callers after the You tab redesign, but it may come back.
…-groups

* origin/main:
  chore(deps): bump flipcash2-client-protocol to 0.18.0
  feat(chat): persist group cover picture
  feat(chat): adopt flipcash2 0.18.0 cover picture, membership and featured-group contract
  fix(chat): show the reply quote on a photo reply
  fix(chat): open the reactors sheet from a long press anywhere in the reaction row
  feat(chat): double-tap a photo to react
  fix(chat): keep a photo retryable when its chat can't be fetched offline
  fix(blob): stop waiting on finalization after three lost polls
  fix(chat): send a photo whose upload failed offline
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.
@bmc08gt bmc08gt self-assigned this Oct 6, 2026
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.
@bmc08gt
bmc08gt force-pushed the feat/profile-refresh-copy branch from b662c90 to 8d3cd64 Compare October 6, 2026 20:14
…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 commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator Author

Replaced by #996, which has the same seven favorite-groups commits on main and merged as aa97e0d.

@bmc08gt bmc08gt closed this Oct 6, 2026
@bmc08gt
bmc08gt deleted the feat/profile-featured-groups branch October 6, 2026 23:04
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