Skip to content

feat(routing): open the profile until a DM exists - #1694

Merged
bmc08gt merged 4 commits into
feat/profile-refresh-edit-profilefrom
feat/profile-refresh-routing
Oct 7, 2026
Merged

bmc08gt merged 4 commits into
feat/profile-refresh-edit-profilefrom
feat/profile-refresh-routing

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator

Fifth slice of the profile refresh, matching code-payments/code-ios-app#989: every way of reaching a person opens their profile until a DM with them exists, and the conversation screen no longer gates the first message on a payment. Paying to start a chat now happens only from the profile (#1692). Stacked on #1693.

Where each entry goes

  • DmDestinationResolver (shared/blocklist) returns the DM when the person's generated chat id has members and they aren't blocked, and the profile otherwise. Blocked is checked first, the same rule ChatProfileViewModel uses, because a block hides the DM without removing its members.
  • Scanning a profile card always opens the profile, even with a DM. The card reveal is 750ms (was 450ms) to match iOS.
  • Username search and transaction details go through the resolver. The transaction details button reads "View Profile" or "View in Chat", and follows the resolver if a block or a member sync changes the answer.
  • The resolver reads only the local members table. On a fresh install, before chats sync, a person you already have a DM with opens on their profile; its pinned button turns into Open Chat once members arrive. iOS has the same behaviour.

After a block

  • New ProfileOrigin values: Link, Scan, UsernameLookup and Transaction. Blocking from a profile opened by scan or username search resets to the chat list; from a link or transaction details it pops back one screen, as on iOS.

Paid-DM gate removed from the conversation

  • ChatViewModel loses the fee state, the minimum-amount hint, OnInitPaymentConfirmed and the tip-vs-send switch. ChatStep.InitPayment, SendCashOnOpen/StartSendCashOnceReady and the openSendCash route flag are deleted.
  • A tip DM is open for typing from its first message. A contact DM still needs a Cash message first.
  • Every send from the conversation is a plain send and is reported as "Sent Cash". The Scanned → Presented → Sent Tip funnel still completes, because the paid first message is sent by StartChattingPayer from the profile.
  • DeeplinkType.TipChat takes a ChatId, so nothing can build a by-user chat route any more. A saved Chat(ByUser) back stack entry opens the profile instead; ChatIdentifier.ByUser stays only so an old saved route still decodes.

Unknown fee

  • The profile's pinned button waits for the fee instead of falling back to opening the DM with Send Cash. startChattingFee falls back to the regional default and both of its inputs start with a value, so a missing fee only means it is still loading.

Tests

  • New: DmDestinationResolverTest, TransactionDetailsViewModelTest, FindByUsernameViewModelTest, ProfileOriginTest, ChatTypingGateTest.
  • ChatOpenTranscriptTest now opens by chat id. ChatSendFailureAnalyticsTest expects "Sent Cash" for a send inside a tip DM. Tests for the removed gate (ChatInitFeeReducerTest, StartSendCashOnceReadyTest) are deleted.
  • maestro/tip_deeplink.yaml now waits for the profile instead of the chat screen.

@bmc08gt bmc08gt self-assigned this Oct 6, 2026
@github-actions github-actions Bot added type: feature New functionality area: payments Payments, transfers, intents, billing area: scanner QR/Kikcode scanning, camera area: deeplinks Deep link handling, URL routing, and link parsing and removed type: feature New functionality labels Oct 6, 2026
@bmc08gt
bmc08gt added this pull request to stack #1696 October 7, 2026 01:28
@bmc08gt
bmc08gt force-pushed the feat/profile-refresh-routing branch from 581a5c5 to b377708 Compare October 7, 2026 01:51
@github-actions github-actions Bot added the type: feature New functionality label Oct 7, 2026
@bmc08gt
bmc08gt force-pushed the feat/profile-refresh-routing branch 2 times, most recently from e1f4af1 to e78b89e Compare October 7, 2026 02:19
@bmc08gt
bmc08gt force-pushed the feat/profile-refresh-routing branch from e78b89e to 133c2c1 Compare October 7, 2026 02:40
Scanning a profile card now always opens the profile after a 750ms hold,
matching iOS. Username search and transaction details resolve through
DmDestinationResolver: the DM when its chat has members and the person
isn't blocked, the profile otherwise. Transaction details labels the
button View Profile or View in Chat accordingly.

Profile routes carry a ProfileOrigin (Link, Scan, UsernameLookup,
Transaction); a block pops back for link and transaction, and resets to
the chat list for scan and search.
startChattingFee already falls back to the regional default, so a null fee
only means the presets have not loaded yet. The profile's pinned button now
waits for it instead of pushing the chat's keypad, and the OpenSendCash
fallback and its Start Chatting label are gone.
The conversation no longer takes the fee that opens a tip DM; the profile does.
Drops ChatViewModel's init-payment flow (fee state, minimum-amount hint,
OnInitPaymentConfirmed, the ChatInitPayment step), the open-with-Send-Cash
hand-off and the openSendCash route flag. A saved Chat route that still
carries a ByUser identifier opens the profile instead of a gated chat.
Sends from the conversation are all plain cash sends. The profile-card
deeplink Maestro flow now waits on the profile rather than chat_screen.
ChatViewModel never receives ChatIdentifier.ByUser now that the app redirects
it to the profile, so its three branches become an error. TipChat carries a
ChatId, since the router only ever builds it from one.

Adds tests for the typing gate (tip DM open, contact DM waits for Cash), the
transaction details counterpart action following DmDestinationResolver, the
username lookup's two destinations, and ProfileOrigin.resetsToChatsAfterBlock.
FindByUsernameViewModel takes a DispatcherProvider so its events are testable.

Removes the tip-minimum strings this branch orphaned, and fixes a stale
comment and the tip_deeplink entry in the Maestro README.
@bmc08gt
bmc08gt force-pushed the feat/profile-refresh-routing branch from 133c2c1 to 6aebb4a Compare October 7, 2026 03:04
@bmc08gt
bmc08gt merged commit ca52657 into code/cash Oct 7, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: deeplinks Deep link handling, URL routing, and link parsing area: payments Payments, transfers, intents, billing area: scanner QR/Kikcode scanning, camera type: feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant