Files
sats-price/Sources/SatsPrice/SatsViewModel.swift

213 lines
5.6 KiB
Swift

// This is free software: you can redistribute and/or modify it
// under the terms of the GNU General Public License 3.0
// as published by the Free Software Foundation https://fsf.org
//
//
// SatsViewModel.swift
// SatsPrice
//
// Created by Terry Yiu on 2/19/24.
//
import Foundation
import SwiftUI
class SatsViewModel: ObservableObject {
@Published var lastUpdated: Date?
@Published var btcToCurrencyStringInternal: String = ""
@Published var satsStringInternal: String = ""
@Published var btcStringInternal: String = ""
@Published var currencyValueStringInternal: String = ""
@Published var selectedCurrency: Locale.Currency = Locale.current.currency ?? Locale.Currency("USD")
var currencies: [Locale.Currency] {
let commonISOCurrencyCodes = Set(Locale.commonISOCurrencyCodes)
let currentCurrency = Locale.current.currency ?? Locale.Currency("USD")
if commonISOCurrencyCodes.contains(currentCurrency.identifier) {
return Locale.commonISOCurrencyCodes.map { Locale.Currency($0) }
} else {
var commonAndCurrentCurrencies = Locale.commonISOCurrencyCodes
commonAndCurrentCurrencies.append(currentCurrency.identifier)
commonAndCurrentCurrencies.sort()
return commonAndCurrentCurrencies.map { Locale.Currency($0) }
}
}
var btcToCurrencyString: String {
get {
btcToCurrencyStringInternal
}
set {
guard btcToCurrencyStringInternal != newValue else {
return
}
btcToCurrencyStringInternal = newValue
if let btc, let btcToCurrency {
currencyValueStringInternal = (btc * btcToCurrency).formatString()
} else {
currencyValueStringInternal = ""
}
}
}
var satsString: String {
get {
satsStringInternal
}
set {
guard satsStringInternal != newValue else {
return
}
satsStringInternal = newValue
if let sats {
#if !SKIP
let btc = sats / Decimal(100000000)
#else
let btc = sats.divide(Decimal(100000000), 20, java.math.RoundingMode.DOWN)
#endif
btcStringInternal = btc.formatString()
if let btcToCurrency {
currencyValueStringInternal = (btc * btcToCurrency).formatString()
} else {
currencyValueStringInternal = ""
}
} else {
btcStringInternal = ""
currencyValueStringInternal = ""
}
}
}
var btcString: String {
get {
btcStringInternal
}
set {
guard btcStringInternal != newValue else {
return
}
btcStringInternal = newValue
if let btc {
let sats = btc * Decimal(100000000)
satsStringInternal = sats.formatString()
if let btcToCurrency {
currencyValueStringInternal = (btc * btcToCurrency).formatString()
} else {
currencyValueStringInternal = ""
}
} else {
satsStringInternal = ""
currencyValueStringInternal = ""
}
}
}
var currencyValueString: String {
get {
currencyValueStringInternal
}
set {
guard currencyValueStringInternal != newValue else {
return
}
currencyValueStringInternal = newValue
if let currencyValue {
if let btcToCurrency {
#if !SKIP
let btc = currencyValue / btcToCurrency
#else
let btc = currencyValue.divide(btcToCurrency, 20, java.math.RoundingMode.DOWN)
#endif
btcStringInternal = btc.formatString()
let sats = btc * Decimal(100000000)
satsStringInternal = sats.formatString()
} else {
satsStringInternal = ""
btcStringInternal = ""
currencyValueStringInternal = ""
}
} else {
satsStringInternal = ""
btcStringInternal = ""
currencyValueStringInternal = ""
}
}
}
var btcToCurrency: Decimal? {
#if !SKIP
return Decimal(string: btcToCurrencyStringInternal)
#else
do {
return Decimal(btcToCurrencyStringInternal)
} catch {
return nil
}
#endif
}
var sats: Decimal? {
#if !SKIP
return Decimal(string: satsStringInternal)
#else
do {
return Decimal(satsStringInternal)
} catch {
return nil
}
#endif
}
var btc: Decimal? {
#if !SKIP
return Decimal(string: btcStringInternal)
#else
do {
return Decimal(btcStringInternal)
} catch {
return nil
}
#endif
}
var currencyValue: Decimal? {
#if !SKIP
return Decimal(string: currencyValueStringInternal)
#else
do {
return Decimal(currencyValueStringInternal)
} catch {
return nil
}
#endif
}
var exceedsMaximum: Bool {
if let btc, btc > Decimal(21000000) {
return true
}
return false
}
}
extension Decimal {
func formatString() -> String {
#if !SKIP
return String(describing: self)
#else
return stripTrailingZeros().toPlainString()
#endif
}
}