mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-26 17:10:34 +01:00
138 lines
4.5 KiB
Swift
138 lines
4.5 KiB
Swift
//
|
|
// PriceIntent.swift
|
|
// BlueWallet
|
|
//
|
|
|
|
import AppIntents
|
|
import SwiftUI
|
|
|
|
@available(iOS 16.0, *)
|
|
struct PriceIntent: AppIntent {
|
|
// MARK: - Intent Metadata
|
|
|
|
static var title: LocalizedStringResource = "Market Rate"
|
|
static var description = IntentDescription("View the current Bitcoin market rate in your preferred fiat currency.")
|
|
static var openAppWhenRun: Bool { false }
|
|
|
|
// MARK: - Parameters
|
|
|
|
@Parameter(
|
|
title: "Currency"
|
|
)
|
|
var fiatCurrency: FiatUnitEnum?
|
|
|
|
@MainActor
|
|
func perform() async throws -> some IntentResult & ReturnsValue<Double> & ProvidesDialog & ShowsSnippetView {
|
|
// Determine the fiat currency to use:
|
|
// 1. UserDefaults in Shared Group
|
|
// 2. Device's preferred currency
|
|
// 3. Default to USD
|
|
let selectedFiatCurrency: FiatUnitEnum
|
|
|
|
if let sharedCurrencyCode = getSharedCurrencyCode(),
|
|
let fiat = FiatUnitEnum(rawValue: sharedCurrencyCode.uppercased()) {
|
|
selectedFiatCurrency = fiat
|
|
} else if let preferredCurrencyCode = Locale.current.currencyCode,
|
|
let fiat = FiatUnitEnum(rawValue: preferredCurrencyCode.uppercased()) {
|
|
selectedFiatCurrency = fiat
|
|
} else {
|
|
selectedFiatCurrency = .USD
|
|
}
|
|
|
|
let dataSource = selectedFiatCurrency.source
|
|
|
|
var lastUpdated = "--"
|
|
var priceDouble: Double = 0.0
|
|
|
|
do {
|
|
guard let fetchedData = try await MarketAPI.fetchPrice(currency: selectedFiatCurrency.rawValue) else {
|
|
throw NSError(
|
|
domain: "PriceIntentErrorDomain",
|
|
code: -1,
|
|
userInfo: [NSLocalizedDescriptionKey: "Failed to fetch price data."]
|
|
)
|
|
}
|
|
|
|
priceDouble = fetchedData.rateDouble
|
|
lastUpdated = formattedDate(from: fetchedData.lastUpdate)
|
|
|
|
} catch {
|
|
let errorView = CompactPriceView(
|
|
price: "N/A",
|
|
lastUpdated: "--",
|
|
currencySymbol: getCurrencySymbol(for: selectedFiatCurrency.rawValue),
|
|
dataSource: "Error fetching data"
|
|
)
|
|
|
|
return .result(
|
|
value: 0.0,
|
|
dialog: "Failed to retrieve the Bitcoin market rate.",
|
|
view: errorView
|
|
)
|
|
}
|
|
|
|
let formattedPrice = formatPrice(priceDouble, currencyCode: selectedFiatCurrency.rawValue)
|
|
|
|
let currencySymbol = getCurrencySymbol(for: selectedFiatCurrency.rawValue)
|
|
|
|
let view = CompactPriceView(
|
|
price: formattedPrice,
|
|
lastUpdated: lastUpdated,
|
|
currencySymbol: currencySymbol,
|
|
dataSource: dataSource
|
|
)
|
|
|
|
return .result(
|
|
value: priceDouble,
|
|
dialog: "Current Bitcoin Market Rate",
|
|
view: view
|
|
)
|
|
}
|
|
|
|
// MARK: - Helper Methods
|
|
|
|
private func formattedDate(from isoString: String?) -> String {
|
|
guard let isoString = isoString else { return "--" }
|
|
let isoFormatter = ISO8601DateFormatter()
|
|
if let date = isoFormatter.date(from: isoString) {
|
|
let formatter = DateFormatter()
|
|
formatter.dateStyle = .medium
|
|
formatter.timeStyle = .short
|
|
return formatter.string(from: date)
|
|
}
|
|
return "--"
|
|
}
|
|
|
|
private func formatPrice(_ price: Double, currencyCode: String) -> String {
|
|
let formatter = NumberFormatter()
|
|
formatter.numberStyle = .currency
|
|
formatter.currencyCode = currencyCode
|
|
|
|
// Omit cents if price is a whole number
|
|
if price.truncatingRemainder(dividingBy: 1) == 0 {
|
|
formatter.maximumFractionDigits = 0
|
|
formatter.minimumFractionDigits = 0
|
|
} else {
|
|
formatter.maximumFractionDigits = 2
|
|
formatter.minimumFractionDigits = 2
|
|
}
|
|
|
|
guard let formattedNumber = formatter.string(from: NSNumber(value: price)) else {
|
|
return "\(price)"
|
|
}
|
|
|
|
return formattedNumber
|
|
}
|
|
|
|
private func getCurrencySymbol(for currencyCode: String) -> String {
|
|
let formatter = NumberFormatter()
|
|
formatter.numberStyle = .currency
|
|
formatter.currencyCode = currencyCode
|
|
return formatter.currencySymbol
|
|
}
|
|
|
|
private func getSharedCurrencyCode() -> String? {
|
|
let sharedDefaults = UserDefaults(suiteName: UserDefaultsGroupKey.GroupName.rawValue)
|
|
return sharedDefaults?.string(forKey: "selectedFiatCurrency")
|
|
}
|
|
}
|