Repository navigation
feat(chat): suggest @mentions from the server's pool - #942
Merged
Merged
Conversation
bmc08gt
force-pushed
the
feat/mention-picker
branch
from
October 1, 2026 18:34
48a3bdb to
28a4044
Compare
bmc08gt
marked this pull request as ready for review
October 1, 2026 18:35
Typing @ at the start of the text or after whitespace, with a collapsed cursor, opens a list of members above the reply strip. The fullwidth @ also triggers, matching Android. "a@b" never opens it. Whitespace, moving the cursor off the word, deleting the @, send, or a pick closes it. Groups only. The word after the @ goes to RosterSearchSource; a new word cancels the search in flight. Members without a username are left out, since a pick inserts "@username " as plain text. The first open per visit prepares the source and re-runs the query when it lands. The list shows 4 rows, 3 with a reply open, and 2 when the full count would leave under 120pt of transcript above the keyboard. Row metrics live in MentionListMetrics for the design pass. setBarHeight used to infer the reply strip's height from the delta after `replying` flipped and subtract that stored value on close. The list changes height while open, which would leave that value stale and put the clip below the bar. The bar now reports which cards are open and the height of any card still exiting; the clip subtracts the exiting height and travels only when the set of open cards changes. A row count change while open snaps.
RosterSearchSource.prepare now returns whether the source could ready itself. The picker searches again only on success, and a picker closed before prepare lands stays closed. Matches Android 345dde414.
Rows are 50pt with a 1pt white-10% divider inset to the name and none after the last, so 4/3/2 rows measure 203/152/101pt. The row cap now counts the dividers, through the same listHeight the frame uses. The handle takes #EBEBF5 at 60%, and a pressed row gets the dark tertiary fill. The card keeps the reply strip's glass, radius and inset rather than the spec's solid fill.
A pick mid-text inserted "@username " before the existing space, leaving "hi @maria there". When whitespace already follows the word, insert "@username" alone and put the cursor after that whitespace. At the end of the text or before a non-space, the trailing space stays.
Add the flipcash2 0.15.0 RPC to ChatService and FlipClient. A MentionSuggestion carries the user's profile and their last_sent_at; one without a readable user id or username is dropped, since a pick inserts the username. ErrorGetMentionSuggestions maps the result explicitly and classifies like ErrorGetRoster. Builds only against the local 0.15.0 checkout (FLIPCASH_PROTO_LOCAL) until that version is tagged and the pin moves.
ServerMentionSearch is the session's RosterSearchSource. It fetches Chat.GetMentionSuggestions once per composing session, when the picker first opens in a visit, and filters the held pool locally: every query word must prefix a display-name or username token, and matches keep the server's order. A new message moves its sender to the front of the pool; a sender the pool doesn't hold is not added, since the server decides who is suggested. Fetched profiles are written to the profile cache. A chat whose pool can't be fetched, or that the server answers DENIED or NOT_FOUND, matches nobody and shows no error; the user can still type a handle by hand. Text normalization lives in MentionSearchText, which follows Android's rules.
Picks up Chat.GetMentionSuggestions. Package.resolved moves from 0.14.1 to 0.15.0 (a86e91bd).
The mention rows drew the monogram placeholder for everyone. Load each member's thumbnail through the shared ProfileAvatarStore and pass it to the avatar, as the reactors sheet does.
Some palette hues are too dark to read as a name on the dark surface (#553ED9 is 2.2:1 against #262626). `ComplementaryPalette.nameColor` blends the `.middle` stop 15% toward white until it reaches 4.5:1, for at most ten steps, against a fixed #262626 so Android can apply the same rule and land on the same colour. Mention rows, the transcript's quote author and the composer's reply strip use it. The reply strip's rule takes the name colour too, so it keeps the same contrast as the name beside it.
…face The mention list and the reply strip now share a GlassEffectContainer, each with its own glass ID. With the list open, a reply peels out of the list's bottom edge, and closing it merges the strip back in. Typing `@` with a reply open splits the list out of the strip. The container's spacing equals the 12pt gap the cards rest at, so a neck joins the two shapes until the split lands. A card opening or closing on its own still slides out from behind the composer. This also fixes several jumps while the list resizes: - The composer slid down 219pt from the top of the bar when the list opened. The bar's host was resized inside SwiftUI's animated update, so the whole bar animated toward its new size. The host is now screen-tall and pinned to the bottom, and its height is reported after the update. - Filtering moved the list's bottom edge about a row off the composer and back. When results change, the list now resizes in a single animation, and the UIKit clip holds the taller of the old and new heights until the spring ends. - With both cards open, the transcript lost its bottom pin. The list's room included the list itself, so the bar flipped between 313.7 and 149.7pt within 17ms. The room now leaves the list out. - The transcript and the fade above the bar follow the glass edge during a held shrink, so they no longer wait out the hold and then snap. Rows are built eagerly. A lazy row created while the card grew slid in from the wrong place, along with its divider.
bmc08gt
force-pushed
the
feat/mention-picker
branch
from
October 2, 2026 21:20
28a4044 to
0e77a1e
Compare
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.
Adds the @-mention picker to the group-chat composer, backed by the server's ranked pool from
Chat.GetMentionSuggestions(flipcash2-client-protocol 0.15.0, code-payments/flipcash2-client-protocol#22).ChatService.getMentionSuggestionswraps the RPC.ErrorGetMentionSuggestionsmaps each result case by name, not byrawValue:.MentionSuggestionis its own type, not aMember.ServerMentionSearchfetches the pool once per picker visit, filters it locally in the server's order, excludes blocked users, and moves a new message's sender to the front.DENIEDorNOT_FOUNDshows no suggestions, with no fallback. The next picker visit retries.RosterSearchSourcestays as the seam, withServerMentionSearchas its only implementation.Package.resolvedpins 0.15.0 ata86e91bd.This no longer depends on roster sync.
Chat.GetRosteris kept private for now, so the roster-search stack (#915) is parked, and no store schema changes ship here.Bar motion
The mention list and the reply strip share a
GlassEffectContainer. With the list open, a reply peels out of the list's bottom edge and merges back in when it closes. Typing@with a reply open splits the list out of the strip. A card opening or closing on its own still slides out from behind the composer.Fixed along the way:
Name colours
ComplementaryPalette.nameColorlightens a person's.middlestop toward white until it reaches 4.5:1 against#262626, so names like#553ED9(2.2:1) can be read. Mention rows, quote authors and the reply strip use it.