diff --git a/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/SystemCurrencies.kt b/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/SystemCurrencies.kt index 8182859..bf029a1 100644 --- a/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/SystemCurrencies.kt +++ b/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/SystemCurrencies.kt @@ -40,6 +40,21 @@ private fun localizedRegionName(regionCode: String): String? { /** The current platform's localized display name for ISO 3166-1 alpha-2 [regionCode], if known. */ expect fun regionDisplayName(regionCode: String): String? +/** + * Pre-populates [regionDisplayNameCache] for every region code [currencies] issue from, so the + * first character typed into currency search doesn't pay for all of them at once. Intended to be + * called once, asynchronously, before the user has a chance to reach the search field — e.g. from + * a coroutine launched at startup, not blocking that launch's other work. Not thread-safe: + * [regionDisplayNameCache] is a plain, unsynchronized map, so this (like [matchesCurrencySearch]) + * must only ever run on the single thread/dispatcher UI state changes are made from. + */ +fun warmRegionDisplayNameCache(currencies: List) { + currencies.asSequence() + .flatMap { issuingCountryCodes(it.code).asSequence() } + .distinct() + .forEach { regionCode -> localizedRegionName(regionCode) } +} + /** * ISO 4217 codes for the precious metals actively traded today. These aren't tied to any * country, so a currently-used-currency filter derived from country/locale data (as the diff --git a/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/ui/PriceViewModel.kt b/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/ui/PriceViewModel.kt index 039a1ba..1ec75ba 100644 --- a/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/ui/PriceViewModel.kt +++ b/shared/src/commonMain/kotlin/xyz/tyiu/satsprice/ui/PriceViewModel.kt @@ -33,6 +33,7 @@ import xyz.tyiu.satsprice.domain.sanitizeIntegerInput import xyz.tyiu.satsprice.domain.toBigDecimalOrNull import xyz.tyiu.satsprice.localeCurrencyCode import xyz.tyiu.satsprice.systemCurrencies +import xyz.tyiu.satsprice.warmRegionDisplayNameCache import kotlin.time.Instant private const val AUTO_REFRESH_INTERVAL_MILLIS = 60_000L @@ -106,6 +107,10 @@ class PriceViewModel( init { manualSource.currencyCode = defaultCurrencyCode + // Fired off separately (rather than folded into the launch below) so it doesn't delay + // that one's own startup work — this just needs to finish before the user reaches the + // currency picker's search field, not before anything else. + viewModelScope.launch { warmRegionDisplayNameCache(systemCurrencyList) } viewModelScope.launch { selectedCurrenciesStore.loadSelectedCurrencies().takeIf { it.isNotEmpty() }?.let { persisted -> lastPersistedSelection = persisted