Repository navigation
feat(chat): rebuild Edit Group in Edit Profile's shape - #994
Merged
Merged
Conversation
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>".
…n cover cache pool
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.
… from the You tab
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.
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.
EditChatRequest has carried cover_picture since flipcash2 0.18.0, but ChatService.editChat never set it. Build the request in ChatService.editChatRequest so it can be tested without a transport, and set cover_picture from an optional blob ID; nil leaves the field unset, like title and profile picture. GroupChatEditing.editChat now takes the description edit and the cover blob ID too, and EditGroupModel passes .unchanged and nil for both, so the existing name and picture edits send the same request as before. EditGroupPictureScreen shows the photo-rejection copy for coverPictureBlobNotAccepted.
ProfileCoverBanner and ProfileHeaderView took a UserID and derived the cover subject and the avatar from it, so a group profile could not use either. The banner now takes a ProfileCover (picture plus the subject it loads under), built with .user(_:picture:) or .group(_:picture:). The header takes that cover, an avatar view slot, and title/subtitle/bodyText, matching Android's ProfileHeader(cover, avatar, title, subtitle, body). The ring and overlap stay in the header. User callers pass a ProfileHeaderAvatar, which draws the same ContactAvatarView at 84pt. AvatarSubject gains groupCover(ConversationID): the original blob, authorized as .chatProfile, cached in the cover pool. Layout constants move to a non-generic ProfileHeaderMetrics so callers below the header don't spell out its generic parameters.
…to feat/edit-group-refresh * origin/feat/edit-chat-cover-picture: feat(chat): send cover_picture and description through editChat 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 Group now has the inset cover with a "Change cover" chip, the group photo overlapping it with a caption, and cards that push their own screens: Group name and Description. Balance Requirements is read-only, because `EditChatRequest` has no rules field. Chat shows the Join amount when the group sets no speaker minimum, and the card is hidden when neither side has one. The cover screen uploads through EditGroupModel's existing reservation path and sends only `cover_picture`. Description is modelled on Edit Bio, and an emptied field goes out as an explicit clear. Both confirm before saving, like name and picture, since the change reaches everyone in the group. `applyEdit` now seats the description from the EditChat response, so a cleared description lands as a clear without waiting for the stream. FieldCard and CoverChip move out of EditProfileScreen so both editors share them, and the picture screen's error mapping moves to a shared dialog the cover screen also uses.
bmc08gt
force-pushed
the
refactor/profile-header-render-inputs
branch
from
October 6, 2026 20:15
79ad9ef to
d1e5c5e
Compare
* origin/main: feat(profile): favorite public groups on profiles (#996)
bmc08gt
changed the base branch from
refactor/profile-header-render-inputs
to
main
October 6, 2026 23:02
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebuilds Edit Group in Edit Profile v2's shape, following the "Edit Group" section of the group profile refresh spec. Figma node 10918:265 was direction only.
Changes
canEditturns false is unchanged.EditGroupCoverScreen) reusesEditGroupModel's upload and reservation path through the newsaveCover, which sends onlycover_picture.EditGroupDescriptionModel/Screen) is modelled on Edit Bio, with the same 160-character limit as the contract. An emptied field is sent as.clear, anddescriptionModeratedshows under the field.EditChatRequesthas no rules field. It has Join and Chat rows, with Chat falling back to Join when the group sets no speaker minimum, plus the spec's footnote. The card is hidden when neither side has a minimum, the same rule the spec gives for the profile screen. The rows come from feat(chat): rebuild the group profile on the profile refresh #995'sGroupBalanceRequirements; amounts use the gate panel's format.applyEditnow seats the description from theEditChatresponse.Conversation(response.chat)carries the full post-edit description, so a cleared description lands as a clear and other edits leave it unchanged.FieldCardandCoverChipmove out ofEditProfileScreenintoProfileFieldCard.swift, unchanged, so both editors share them. The picture screen's error mapping moves toDialogItem+GroupImageEditso the cover screen can use it too.Cover and description edits aren't sent to analytics. Shared-core's
GroupFieldonly definesnameandpicture, and logging a cover or description edit as a picture edit would miscount.No UI smoke test touches Edit Group, so none needed updating.