Skip to content
Closed
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
4 changes: 4 additions & 0 deletions components/resources/library/api/desktop/library.api
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ public final class org/jetbrains/compose/resources/ResourceReaderKt {
public static final fun getLocalResourceReader ()Landroidx/compose/runtime/ProvidableCompositionLocal;
}

public final class org/jetbrains/compose/resources/ResourceState_blockingKt {
public static final fun awaitPendingResourceStateLoads (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public final class org/jetbrains/compose/resources/StringArrayResource : org/jetbrains/compose/resources/Resource {
public static final field $stable I
public final fun getKey ()Ljava/lang/String;
Expand Down
3 changes: 3 additions & 0 deletions components/resources/library/api/library.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageC
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Svg$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Svg$stableprop|#static{}org_jetbrains_compose_resources_ImageCache_Svg$stableprop[0]
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Vector$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Vector$stableprop|#static{}org_jetbrains_compose_resources_ImageCache_Vector$stableprop[0]
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_LanguageQualifier$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_LanguageQualifier$stableprop|#static{}org_jetbrains_compose_resources_LanguageQualifier$stableprop[0]
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_LocaleQualifiers$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_LocaleQualifiers$stableprop|#static{}org_jetbrains_compose_resources_LocaleQualifiers$stableprop[0]
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_MissingResourceException$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_MissingResourceException$stableprop|#static{}org_jetbrains_compose_resources_MissingResourceException$stableprop[0]
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_PluralStringResource$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_PluralStringResource$stableprop|#static{}org_jetbrains_compose_resources_PluralStringResource$stableprop[0]
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_RegionQualifier$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_RegionQualifier$stableprop|#static{}org_jetbrains_compose_resources_RegionQualifier$stableprop[0]
Expand Down Expand Up @@ -111,6 +112,7 @@ final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageC
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Svg$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Svg$stableprop_getter|org_jetbrains_compose_resources_ImageCache_Svg$stableprop_getter(){}[0]
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Vector$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Vector$stableprop_getter|org_jetbrains_compose_resources_ImageCache_Vector$stableprop_getter(){}[0]
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_LanguageQualifier$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_LanguageQualifier$stableprop_getter|org_jetbrains_compose_resources_LanguageQualifier$stableprop_getter(){}[0]
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_LocaleQualifiers$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_LocaleQualifiers$stableprop_getter|org_jetbrains_compose_resources_LocaleQualifiers$stableprop_getter(){}[0]
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_MissingResourceException$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_MissingResourceException$stableprop_getter|org_jetbrains_compose_resources_MissingResourceException$stableprop_getter(){}[0]
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_PluralStringResource$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_PluralStringResource$stableprop_getter|org_jetbrains_compose_resources_PluralStringResource$stableprop_getter(){}[0]
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_RegionQualifier$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_RegionQualifier$stableprop_getter|org_jetbrains_compose_resources_RegionQualifier$stableprop_getter(){}[0]
Expand All @@ -132,6 +134,7 @@ final fun org.jetbrains.compose.resources/stringArrayResource(org.jetbrains.comp
final fun org.jetbrains.compose.resources/stringResource(org.jetbrains.compose.resources/StringResource, androidx.compose.runtime/Composer?, kotlin/Int): kotlin/String // org.jetbrains.compose.resources/stringResource|stringResource(org.jetbrains.compose.resources.StringResource;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun org.jetbrains.compose.resources/stringResource(org.jetbrains.compose.resources/StringResource, kotlin/Array<out kotlin/Any>..., androidx.compose.runtime/Composer?, kotlin/Int): kotlin/String // org.jetbrains.compose.resources/stringResource|stringResource(org.jetbrains.compose.resources.StringResource;kotlin.Array<out|kotlin.Any>...;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final fun org.jetbrains.compose.resources/vectorResource(org.jetbrains.compose.resources/DrawableResource, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.ui.graphics.vector/ImageVector // org.jetbrains.compose.resources/vectorResource|vectorResource(org.jetbrains.compose.resources.DrawableResource;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
final suspend fun org.jetbrains.compose.resources/awaitPendingResourceStateLoads() // org.jetbrains.compose.resources/awaitPendingResourceStateLoads|awaitPendingResourceStateLoads(){}[0]
final suspend fun org.jetbrains.compose.resources/getDrawableResourceBytes(org.jetbrains.compose.resources/ResourceEnvironment, org.jetbrains.compose.resources/DrawableResource): kotlin/ByteArray // org.jetbrains.compose.resources/getDrawableResourceBytes|getDrawableResourceBytes(org.jetbrains.compose.resources.ResourceEnvironment;org.jetbrains.compose.resources.DrawableResource){}[0]
final suspend fun org.jetbrains.compose.resources/getFontResourceBytes(org.jetbrains.compose.resources/ResourceEnvironment, org.jetbrains.compose.resources/FontResource): kotlin/ByteArray // org.jetbrains.compose.resources/getFontResourceBytes|getFontResourceBytes(org.jetbrains.compose.resources.ResourceEnvironment;org.jetbrains.compose.resources.FontResource){}[0]
final suspend fun org.jetbrains.compose.resources/getPluralString(org.jetbrains.compose.resources/PluralStringResource, kotlin/Int): kotlin/String // org.jetbrains.compose.resources/getPluralString|getPluralString(org.jetbrains.compose.resources.PluralStringResource;kotlin.Int){}[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,36 @@ package org.jetbrains.compose.resources

import android.content.res.Configuration
import android.content.res.Resources
import android.os.Build
import android.os.LocaleList
import java.util.*

// LocaleList.getDefault() follows a per-app language, which Resources.getSystem() does not:
// that one stays on the device list. Compose reads the same list for LocaleList.current, so
// stringResource and getString cannot disagree.
internal actual fun systemPreferredLocales(): List<LocaleQualifiers> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val localeList = LocaleList.getDefault()
if (!localeList.isEmpty) {
return (0 until localeList.size()).map { i -> localeQualifiersOf(localeList.get(i)) }
}
}
return listOf(localeQualifiersOf(Locale.getDefault()))
}

internal actual fun getSystemEnvironment(): ResourceEnvironment {
val locale = Locale.getDefault()
val configuration = Resources.getSystem().configuration
val isDarkTheme = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
val dpi = configuration.densityDpi
return ResourceEnvironment(
language = LanguageQualifier(locale.language),
script = ScriptQualifier(locale.script),
region = RegionQualifier(locale.country),
locales = systemPreferredLocales(),
theme = ThemeQualifier.selectByValue(isDarkTheme),
density = DensityQualifier.selectByValue(dpi)
)
}
}

private fun localeQualifiersOf(locale: Locale) = LocaleQualifiers(
language = LanguageQualifier(locale.language.orEmpty()),
script = ScriptQualifier(locale.script.orEmpty()),
region = RegionQualifier(locale.country.orEmpty())
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.jetbrains.compose.resources

import platform.Foundation.NSLocale
import platform.Foundation.NSLocaleCountryCode
import platform.Foundation.NSLocaleLanguageCode
import platform.Foundation.NSLocaleScriptCode
import platform.Foundation.currentLocale
import platform.Foundation.preferredLanguages

// preferredLanguages is the ordered preferred-language list. Unlike
// Bundle.main.preferredLocalizations it is not filtered against Xcode .lproj bundles,
// and it keeps the region, so values-en-rIN still matches a user on en-IN.
internal actual fun systemPreferredLocales(): List<LocaleQualifiers> {
val tags = NSLocale.preferredLanguages.mapNotNull { it as? String }
if (tags.isEmpty()) return listOf(localeQualifiersOf(NSLocale.currentLocale))
return tags.map { localeQualifiersOf(NSLocale(it)) }
}

private fun localeQualifiersOf(loc: NSLocale): LocaleQualifiers {
val languageCode = (loc.objectForKey(NSLocaleLanguageCode) as? String).orEmpty()
val scriptCode = (loc.objectForKey(NSLocaleScriptCode) as? String).orEmpty()
val regionCode = (loc.objectForKey(NSLocaleCountryCode) as? String).orEmpty()
return LocaleQualifiers(
language = LanguageQualifier(languageCode),
script = ScriptQualifier(scriptCode),
region = RegionQualifier(regionCode)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,15 @@ private suspend fun loadPluralString(
): String {
val resourceItem = resource.getResourceItemByEnvironment(environment)
val item = getStringItem(resourceItem, resourceReader) as StringItem.Plurals
val itemLanguage = resourceItem.qualifiers.filterIsInstance<LanguageQualifier>().firstOrNull()
?: LanguageQualifier(DEFAULT_LANGUAGE)
val matchedLocale = environment.locales.firstOrNull { it.language == itemLanguage }
val itemRegion = resourceItem.qualifiers.filterIsInstance<RegionQualifier>().firstOrNull()
?: matchedLocale?.region
?: RegionQualifier("")
val pluralRuleList = PluralRuleList.getInstance(
environment.language,
environment.region,
itemLanguage,
itemRegion,
)
val pluralCategory = pluralRuleList.getCategory(quantity)
val str = item.items[pluralCategory]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,19 @@ enum class DensityQualifier(val dpi: Int) : Qualifier {
}
}
}

/**
* One locale in a preference list used for resource matching.
*/
@InternalResourceApi
data class LocaleQualifiers(
val language: LanguageQualifier,
val script: ScriptQualifier = ScriptQualifier(""),
val region: RegionQualifier = RegionQualifier("")
) {
constructor(language: String, script: String = "", region: String = "") : this(
LanguageQualifier(language),
ScriptQualifier(script),
RegionQualifier(region)
)
}
Loading