Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[resources] Select default resource if there are no exact language+region or default language match #4577

Merged
merged 1 commit into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ internal var getResourceEnvironment = ::getSystemEnvironment
internal fun Resource.getResourceItemByEnvironment(environment: ResourceEnvironment): ResourceItem {
//Priority of environments: https://developer.android.com/guide/topics/resources/providing-resources#table2
items.toList()
.filterBy(environment.language)
.also { if (it.size == 1) return it.first() }
.filterBy(environment.region)
.filterByLocale(environment.language, environment.region)
.also { if (it.size == 1) return it.first() }
.filterBy(environment.theme)
.also { if (it.size == 1) return it.first() }
Expand Down Expand Up @@ -84,4 +82,34 @@ private fun List<ResourceItem>.filterBy(qualifier: Qualifier): List<ResourceItem
return filter { item ->
item.qualifiers.none { it::class == qualifier::class }
}
}

// we need to filter by language and region together because there is slightly different logic:
// 1) if there is the exact match language+region then use it
// 2) if there is the language WITHOUT region match then use it
// 3) in other cases use items WITHOUT language and region qualifiers at all
// issue: https://github.com/JetBrains/compose-multiplatform/issues/4571
private fun List<ResourceItem>.filterByLocale(language: LanguageQualifier, region: RegionQualifier): List<ResourceItem> {
val withLanguage = filter { item ->
item.qualifiers.any { it == language }
}

val withExactLocale = withLanguage.filter { item ->
item.qualifiers.any { it == region }
}

//if there are the exact language + the region items
if (withExactLocale.isNotEmpty()) return withExactLocale

val withDefaultRegion = withLanguage.filter { item ->
item.qualifiers.none { it is RegionQualifier }
}

//if there are the language without a region items
if (withDefaultRegion.isNotEmpty()) return withDefaultRegion

//items without any locale qualifiers
return filter { item ->
item.qualifiers.none { it is LanguageQualifier || it is RegionQualifier }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class ResourceTest {
ResourceItem(setOf(), "default", -1, -1),
ResourceItem(setOf(LanguageQualifier("en")), "en", -1, -1),
ResourceItem(setOf(LanguageQualifier("en"), RegionQualifier("US"), XHDPI), "en-rUS-xhdpi", -1, -1),
ResourceItem(setOf(LanguageQualifier("de"), RegionQualifier("US")), "de-rUS", -1, -1),
ResourceItem(setOf(LanguageQualifier("fr"), LIGHT), "fr-light", -1, -1),
ResourceItem(setOf(DARK), "dark", -1, -1),
)
Expand All @@ -48,6 +49,18 @@ class ResourceTest {
"en",
resource.getResourceItemByEnvironment(env("en", "IN", LIGHT, LDPI)).path
)
assertEquals(
"de-rUS",
resource.getResourceItemByEnvironment(env("de", "US", LIGHT, LDPI)).path
)
assertEquals(
"default",
resource.getResourceItemByEnvironment(env("de", "", LIGHT, LDPI)).path
)
assertEquals(
"default",
resource.getResourceItemByEnvironment(env("de", "IN", LIGHT, LDPI)).path
)
assertEquals(
"default",
resource.getResourceItemByEnvironment(env("ch", "", LIGHT, MDPI)).path
Expand Down