Browse Source

Show non-localized language names too in app language selection

arkon 1 năm trước cách đây
mục cha
commit
89678ebb17

+ 6 - 55
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAppearanceScreen.kt

@@ -1,34 +1,26 @@
 package eu.kanade.presentation.more.settings.screen
 
 import android.app.Activity
-import android.content.Context
-import androidx.appcompat.app.AppCompatDelegate
 import androidx.compose.foundation.layout.Column
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.ReadOnlyComposable
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
 import androidx.compose.ui.platform.LocalContext
 import androidx.core.app.ActivityCompat
-import androidx.core.os.LocaleListCompat
+import cafe.adriel.voyager.navigator.LocalNavigator
+import cafe.adriel.voyager.navigator.currentOrThrow
 import eu.kanade.domain.ui.UiPreferences
 import eu.kanade.domain.ui.model.TabletUiMode
 import eu.kanade.domain.ui.model.ThemeMode
 import eu.kanade.domain.ui.model.setAppCompatDelegateThemeMode
 import eu.kanade.presentation.more.settings.Preference
+import eu.kanade.presentation.more.settings.screen.appearance.AppLanguageScreen
 import eu.kanade.presentation.more.settings.widget.AppThemeModePreferenceWidget
 import eu.kanade.presentation.more.settings.widget.AppThemePreferenceWidget
-import eu.kanade.tachiyomi.R
-import eu.kanade.tachiyomi.util.system.LocaleHelper
 import eu.kanade.tachiyomi.util.system.toast
-import kotlinx.collections.immutable.ImmutableMap
 import kotlinx.collections.immutable.persistentListOf
 import kotlinx.collections.immutable.toImmutableMap
-import org.xmlpull.v1.XmlPullParser
-import tachiyomi.core.i18n.stringResource
 import tachiyomi.i18n.MR
 import tachiyomi.presentation.core.i18n.stringResource
 import tachiyomi.presentation.core.util.collectAsState
@@ -107,11 +99,8 @@ object SettingsAppearanceScreen : SearchableSettings {
         uiPreferences: UiPreferences,
     ): Preference.PreferenceGroup {
         val context = LocalContext.current
+        val navigator = LocalNavigator.currentOrThrow
 
-        val langs = remember { getLangs(context) }
-        var currentLanguage by remember {
-            mutableStateOf(AppCompatDelegate.getApplicationLocales().get(0)?.toLanguageTag() ?: "")
-        }
         val now = remember { Instant.now().toEpochMilli() }
 
         val dateFormat by uiPreferences.dateFormat().collectAsState()
@@ -119,26 +108,12 @@ object SettingsAppearanceScreen : SearchableSettings {
             UiPreferences.dateFormat(dateFormat).format(now)
         }
 
-        LaunchedEffect(currentLanguage) {
-            val locale = if (currentLanguage.isEmpty()) {
-                LocaleListCompat.getEmptyLocaleList()
-            } else {
-                LocaleListCompat.forLanguageTags(currentLanguage)
-            }
-            AppCompatDelegate.setApplicationLocales(locale)
-        }
-
         return Preference.PreferenceGroup(
             title = stringResource(MR.strings.pref_category_display),
             preferenceItems = persistentListOf(
-                Preference.PreferenceItem.BasicListPreference(
-                    value = currentLanguage,
+                Preference.PreferenceItem.TextPreference(
                     title = stringResource(MR.strings.pref_app_language),
-                    entries = langs,
-                    onValueChanged = { newValue ->
-                        currentLanguage = newValue
-                        true
-                    },
+                    onClick = { navigator.push(AppLanguageScreen()) },
                 ),
                 Preference.PreferenceItem.ListPreference(
                     pref = uiPreferences.tabletUiMode(),
@@ -173,30 +148,6 @@ object SettingsAppearanceScreen : SearchableSettings {
             ),
         )
     }
-    private fun getLangs(context: Context): ImmutableMap<String, String> {
-        val langs = mutableListOf<Pair<String, String>>()
-        val parser = context.resources.getXml(R.xml.locales_config)
-        var eventType = parser.eventType
-        while (eventType != XmlPullParser.END_DOCUMENT) {
-            if (eventType == XmlPullParser.START_TAG && parser.name == "locale") {
-                for (i in 0..<parser.attributeCount) {
-                    if (parser.getAttributeName(i) == "name") {
-                        val langTag = parser.getAttributeValue(i)
-                        val displayName = LocaleHelper.getDisplayName(langTag)
-                        if (displayName.isNotEmpty()) {
-                            langs.add(Pair(langTag, displayName))
-                        }
-                    }
-                }
-            }
-            eventType = parser.next()
-        }
-
-        langs.sortBy { it.second }
-        langs.add(0, Pair("", context.stringResource(MR.strings.label_default)))
-
-        return langs.toMap().toImmutableMap()
-    }
 }
 
 private val DateFormats = listOf(

+ 128 - 0
app/src/main/java/eu/kanade/presentation/more/settings/screen/appearance/AppLanguageScreen.kt

@@ -0,0 +1,128 @@
+package eu.kanade.presentation.more.settings.screen.appearance
+
+import android.content.Context
+import androidx.appcompat.app.AppCompatDelegate
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Check
+import androidx.compose.material3.Icon
+import androidx.compose.material3.ListItem
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.core.os.LocaleListCompat
+import cafe.adriel.voyager.navigator.LocalNavigator
+import cafe.adriel.voyager.navigator.currentOrThrow
+import eu.kanade.presentation.components.AppBar
+import eu.kanade.presentation.util.Screen
+import eu.kanade.tachiyomi.R
+import eu.kanade.tachiyomi.util.system.LocaleHelper
+import kotlinx.collections.immutable.ImmutableList
+import kotlinx.collections.immutable.toImmutableList
+import org.xmlpull.v1.XmlPullParser
+import tachiyomi.core.i18n.stringResource
+import tachiyomi.i18n.MR
+import tachiyomi.presentation.core.components.material.Scaffold
+import tachiyomi.presentation.core.i18n.stringResource
+import java.util.Locale
+
+class AppLanguageScreen : Screen() {
+
+    @Composable
+    override fun Content() {
+        val context = LocalContext.current
+        val navigator = LocalNavigator.currentOrThrow
+
+        val langs = remember { getLangs(context) }
+        var currentLanguage by remember {
+            mutableStateOf(AppCompatDelegate.getApplicationLocales().get(0)?.toLanguageTag() ?: "")
+        }
+
+        LaunchedEffect(currentLanguage) {
+            val locale = if (currentLanguage.isEmpty()) {
+                LocaleListCompat.getEmptyLocaleList()
+            } else {
+                LocaleListCompat.forLanguageTags(currentLanguage)
+            }
+            AppCompatDelegate.setApplicationLocales(locale)
+        }
+
+        Scaffold(
+            topBar = { scrollBehavior ->
+                AppBar(
+                    title = stringResource(MR.strings.pref_app_language),
+                    navigateUp = navigator::pop,
+                    scrollBehavior = scrollBehavior,
+                )
+            },
+        ) { contentPadding ->
+            LazyColumn(
+                modifier = Modifier.padding(contentPadding),
+            ) {
+                items(langs) {
+                    ListItem(
+                        modifier = Modifier.clickable {
+                            currentLanguage = it.langTag
+                        },
+                        headlineContent = { Text(it.displayName) },
+                        supportingContent = {
+                            it.localizedDisplayName?.let {
+                                Text(it)
+                            }
+                        },
+                        trailingContent = {
+                            if (currentLanguage == it.langTag) {
+                                Icon(
+                                    imageVector = Icons.Default.Check,
+                                    contentDescription = null,
+                                    tint = MaterialTheme.colorScheme.primary,
+                                )
+                            }
+                        },
+                    )
+                }
+            }
+        }
+    }
+
+    private fun getLangs(context: Context): ImmutableList<Language> {
+        val langs = mutableListOf<Language>()
+        val parser = context.resources.getXml(R.xml.locales_config)
+        var eventType = parser.eventType
+        while (eventType != XmlPullParser.END_DOCUMENT) {
+            if (eventType == XmlPullParser.START_TAG && parser.name == "locale") {
+                for (i in 0..<parser.attributeCount) {
+                    if (parser.getAttributeName(i) == "name") {
+                        val langTag = parser.getAttributeValue(i)
+                        val displayName = LocaleHelper.getDisplayName(langTag)
+                        if (displayName.isNotEmpty()) {
+                            langs.add(Language(langTag, displayName, Locale.forLanguageTag(langTag).displayName))
+                        }
+                    }
+                }
+            }
+            eventType = parser.next()
+        }
+
+        langs.sortBy { it.displayName }
+        langs.add(0, Language("", context.stringResource(MR.strings.label_default), null))
+
+        return langs.toImmutableList()
+    }
+
+    private data class Language(
+        val langTag: String,
+        val displayName: String,
+        val localizedDisplayName: String?,
+    )
+}