Give each Monero account a swipeable card with its balance and QR

This commit is contained in:
2026-10-01 22:05:19 +08:00
parent e3846fe881
commit 994ba5ed6b
4 changed files with 189 additions and 50 deletions
+27 -13
View File
@@ -15,7 +15,7 @@ final class AppModel: ObservableObject {
@Published var moneroReady = false
@Published var moneroAddress: String?
@Published var moneroAccounts: [MoneroAccount] = []
@Published var prices = PriceService.Prices()
@Published var prices = PriceService.Prices(currency: "USD")
/// Whether the app is behind the biometric lock screen right now.
@Published var locked = false
@@ -57,24 +57,38 @@ final class AppModel: ObservableObject {
// MARK: - Fiat display
private static let fiatFormatter: NumberFormatter = {
/// The fiat currency the wallet shows; persisted, and changing it refetches
/// the price cache.
var fiatCurrency: String {
get { UserDefaults.standard.string(forKey: "koins.fiatCurrency") ?? "USD" }
set {
UserDefaults.standard.set(newValue, forKey: "koins.fiatCurrency")
objectWillChange.send()
Task { await refreshPrices() }
}
}
/// The current chain's balance in the chosen fiat currency, when a price is
/// known.
var fiatBalance: String? {
fiatValue(of: balance.total, chain: chain)
}
/// Converts a chain amount into the chosen fiat currency, when a price is
/// known.
func fiatValue(of amount: String, chain: Chain) -> String? {
let price = chain == .xrp ? prices.xrp : prices.xmr
guard let price, let value = Decimal(string: amount) else { return nil }
let fiat = value * Decimal(price)
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.currencyCode = "USD"
formatter.currencyCode = fiatCurrency
formatter.locale = Locale(identifier: "en_US")
return formatter
}()
/// The current chain's balance in USD, when a price is known.
var fiatBalance: String? {
let price = chain == .xrp ? prices.xrp : prices.xmr
guard let price, let amount = Decimal(string: balance.total) else { return nil }
let usd = amount * Decimal(price)
return Self.fiatFormatter.string(from: usd as NSDecimalNumber)
return formatter.string(from: fiat as NSDecimalNumber)
}
private func refreshPrices() async {
prices = await PriceService.shared.prices()
prices = await PriceService.shared.prices(currency: fiatCurrency)
}
// MARK: - Biometric lock