Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Flipcash/Core/Navigation/AppRouter+Destination.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ extension AppRouter {
/// Wallet's Recent section. `transactionHistory` is the per-token slice.
case activity
case give(PublicKey)
/// Pushes the buy flow (`BuyAmountScreen`) onto the current stack instead
/// of presenting it as a sheet — the new-UI currency-info "Convert"/"Get".
case buyCurrency(PublicKey)
/// Skips the picker step in the withdraw flow and lands the user on
/// `WithdrawIntroScreen` with the currency pre-selected. Pushed from
/// USDF Currency Info on the Wallet sheet.
Expand Down Expand Up @@ -74,7 +77,7 @@ extension AppRouter {
switch self {
case .currencyInfo, .currencyInfoForDeposit, .discoverCurrencies,
.currencyCreationSummary, .currencyCreationWizard,
.transactionHistory, .activity, .give, .withdrawCurrency,
.transactionHistory, .activity, .give, .buyCurrency, .withdrawCurrency,
.usdcDepositEducation, .usdcDepositAddress:
return .balance
case .settingsMyAccount, .settingsAdvancedFeatures, .settingsAdvancedBetaFeatures,
Expand Down Expand Up @@ -102,6 +105,7 @@ extension AppRouter {
case .transactionHistory: "transactionHistory"
case .activity: "activity"
case .give: "give"
case .buyCurrency: "buyCurrency"
case .withdrawCurrency: "withdrawCurrency"
case .usdcDepositEducation: "usdcDepositEducation"
case .usdcDepositAddress: "usdcDepositAddress"
Expand Down Expand Up @@ -133,6 +137,7 @@ extension AppRouter {
.currencyInfoForDeposit(let mint),
.transactionHistory(let mint),
.give(let mint),
.buyCurrency(let mint),
.withdrawCurrency(let mint):
return mint.base58
case .tipConversation(let conversationID),
Expand Down
3 changes: 3 additions & 0 deletions Flipcash/Core/Navigation/AppRouter+DestinationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ struct DestinationView: View {
GiveScreen(mint: mint)
.id(mint)

case .buyCurrency(let mint):
BuyAmountScreen(mint: mint)

// MARK: - Settings flow

case .settingsMyAccount:
Expand Down
18 changes: 6 additions & 12 deletions Flipcash/Core/Navigation/AppRouter+NestedSheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,23 +86,17 @@ private struct BuySheetRoot: View {

let mint: PublicKey

@Environment(SessionContainer.self) private var sessionContainer
@Environment(AppRouter.self) private var router

var body: some View {
@Bindable var router = router
NavigationStack(path: $router[.buy]) {
BuyAmountScreen(
mint: mint,
currencyName: sessionContainer.session.balance(for: mint)?.name ?? "this currency",
session: sessionContainer.session,
ratesController: sessionContainer.ratesController
)
.id(mint)
.environment(\.dismissParentContainer, { router.dismissSheet() })
// Registers the shared destinations, including the Add Money
// deposit steps, so a buy-shortfall deposit pushes onto this stack.
.appRouterDestinations()
BuyAmountScreen(mint: mint)
.environment(\.dismissParentContainer, { router.dismissSheet() })
.environment(\.presentedAsSheetRoot, true)
// Registers the shared destinations, including the Add Money
// deposit steps, so a buy-shortfall deposit pushes onto this stack.
.appRouterDestinations()
}
}
}
Expand Down
32 changes: 31 additions & 1 deletion Flipcash/Core/Screens/Main/Buy/BuyAmountScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,41 @@ import SwiftUI
import FlipcashCore
import FlipcashUI

/// Amount entry for buying a currency. The caller provides the surrounding
/// `NavigationStack` — the buy sheet wraps it, the pushed `.buyCurrency`
/// destination uses the active one.
///
/// Thin environment-reading wrapper that hands the DI containers to
/// ``BuyAmountScreenContent``, whose `init` seeds the `@State` view model
/// synchronously. `.id(mint)` rebuilds the content (and its view model) when the
/// mint changes.
struct BuyAmountScreen: View {

let mint: PublicKey

@Environment(SessionContainer.self) private var sessionContainer

var body: some View {
BuyAmountScreenContent(
mint: mint,
currencyName: sessionContainer.session.balance(for: mint)?.name ?? "this currency",
session: sessionContainer.session,
ratesController: sessionContainer.ratesController
)
.id(mint)
}
}

private struct BuyAmountScreenContent: View {

@State private var viewModel: BuyAmountViewModel
@State private var isShowingCurrencySelection: Bool = false

@Environment(AppRouter.self) private var router
@Environment(RatesController.self) private var ratesController
/// True when this is the root of a presented sheet; false when pushed onto a
/// host stack (new-UI Convert/Get) where the system back arrow replaces Close.
@Environment(\.presentedAsSheetRoot) private var presentedAsSheetRoot

init(mint: PublicKey, currencyName: String, session: Session, ratesController: RatesController) {
self._viewModel = State(initialValue: BuyAmountViewModel(
Expand Down Expand Up @@ -56,7 +84,9 @@ struct BuyAmountScreen: View {
.navigationTitle(viewModel.screenTitle)
.toolbarTitleDisplayMode(.inline)
.toolbar {
if !isDismissBlocked {
// Only the sheet-root presentation gets a Close button; a pushed
// instance relies on the system back arrow.
if presentedAsSheetRoot && !isDismissBlocked {
ToolbarItem(placement: .topBarTrailing) {
CloseButton(action: router.dismissSheet)
}
Expand Down