Always show all currencies, flagging ones the active source doesn't price
Previously a currency the active price source had no rate for was hidden entirely, so switching sources (e.g. to CoinGecko, which quotes far fewer fiat currencies than Coinbase) could silently drop it from the picker and even from the user's own selection. Every system currency is now always offered. ConverterUiState tracks which codes the latest fetch actually priced, and both UIs (Compose and the native SwiftUI screen, since iOS/macOS don't render Compose UI at all) show a "Not priced by <source>" indicator for the rest, with the amount field emptied and disabled rather than showing a stale or meaningless value. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QpjMKWGoiT5aJBzhxvXkwp
This commit is contained in:
@@ -129,6 +129,8 @@ struct ContentView: View {
|
||||
keyboardType: .decimalPad,
|
||||
sanitize: sanitizeDecimalInput,
|
||||
onChange: { viewModel.onFiatAmountChanged(code: row.code, value: $0) },
|
||||
isPriced: state.pricedCurrencyCodes.contains(row.code),
|
||||
sourceName: state.sourceName,
|
||||
onMoveUp: index > 0 ? {
|
||||
var codes = state.fiatRows.map(\.code)
|
||||
codes.move(fromOffsets: [index], toOffset: index - 1)
|
||||
@@ -164,6 +166,8 @@ struct ContentView: View {
|
||||
currentCurrency: state.currentCurrency,
|
||||
selectedOtherCurrencies: state.selectedOtherCurrencies,
|
||||
unselectedCurrencies: state.unselectedCurrencies,
|
||||
pricedCurrencyCodes: state.pricedCurrencyCodes,
|
||||
sourceName: state.sourceName,
|
||||
localeCurrencyCode: state.localeCurrencyCode,
|
||||
onToggle: { viewModel.onFiatCurrencyToggled($0) }
|
||||
)
|
||||
@@ -202,6 +206,8 @@ struct ContentView: View {
|
||||
keyboardType: NumericFieldKeyboard,
|
||||
sanitize: @escaping (String) -> String,
|
||||
onChange: @escaping (String) -> Void,
|
||||
isPriced: Bool = true,
|
||||
sourceName: String = "",
|
||||
onMoveUp: (() -> Void)? = nil,
|
||||
onMoveDown: (() -> Void)? = nil
|
||||
) -> some View {
|
||||
@@ -226,16 +232,27 @@ struct ContentView: View {
|
||||
.buttonStyle(.borderless)
|
||||
}
|
||||
#endif
|
||||
Text(label)
|
||||
VStack(alignment: .leading) {
|
||||
Text(label)
|
||||
if !isPriced {
|
||||
Text(IosLocalizationKt.localizedFormattedString(
|
||||
resource: MR.strings.shared.currency_not_priced,
|
||||
args: [sourceName]
|
||||
))
|
||||
.font(.caption2)
|
||||
.foregroundColor(.red)
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
NumericField(
|
||||
placeholder: "",
|
||||
value: value,
|
||||
value: isPriced ? value : "",
|
||||
keyboardType: keyboardType,
|
||||
sanitize: sanitize,
|
||||
onChange: onChange,
|
||||
alignment: .trailing
|
||||
)
|
||||
.disabled(!isPriced)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ struct CurrencyPickerSheet: View {
|
||||
let currentCurrency: CurrencyInfo
|
||||
let selectedOtherCurrencies: [CurrencyInfo]
|
||||
let unselectedCurrencies: [CurrencyInfo]
|
||||
let pricedCurrencyCodes: [String]
|
||||
let sourceName: String
|
||||
let localeCurrencyCode: String?
|
||||
let onToggle: (String) -> Void
|
||||
|
||||
@@ -51,9 +53,20 @@ struct CurrencyPickerSheet: View {
|
||||
|
||||
@ViewBuilder
|
||||
private func currencyRow(for info: CurrencyInfo, isSelected: Bool, onTap: (() -> Void)?) -> some View {
|
||||
let isPriced = pricedCurrencyCodes.contains(info.code)
|
||||
let content = HStack {
|
||||
Text(currencyLabel(for: info))
|
||||
.foregroundColor(.primary)
|
||||
VStack(alignment: .leading) {
|
||||
Text(currencyLabel(for: info))
|
||||
.foregroundColor(.primary)
|
||||
if !isPriced {
|
||||
Text(IosLocalizationKt.localizedFormattedString(
|
||||
resource: MR.strings.shared.currency_not_priced,
|
||||
args: [sourceName]
|
||||
))
|
||||
.font(.caption)
|
||||
.foregroundColor(.red)
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
if isSelected {
|
||||
Image(systemName: "checkmark")
|
||||
|
||||
Reference in New Issue
Block a user