Add languages settings (#52)
This commit is contained in:
parent
a225513088
commit
dc2e18bcee
|
@ -77,6 +77,9 @@ class App : Application(), Configuration.Provider {
|
|||
}
|
||||
}
|
||||
|
||||
private fun dataStoreInit() {
|
||||
}
|
||||
|
||||
private suspend fun accountInit() {
|
||||
if (accountRepository.isNoAccount()) {
|
||||
val account = accountRepository.addDefaultAccount()
|
||||
|
@ -85,9 +88,6 @@ class App : Application(), Configuration.Provider {
|
|||
}
|
||||
}
|
||||
|
||||
private fun dataStoreInit() {
|
||||
}
|
||||
|
||||
private fun workerInit() {
|
||||
rssRepository.get().doSync()
|
||||
}
|
||||
|
|
|
@ -18,7 +18,9 @@ import coil.memory.MemoryCache
|
|||
import coil.request.*
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import me.ash.reader.data.preference.LanguagesPreference
|
||||
import me.ash.reader.data.preference.SettingsProvider
|
||||
import me.ash.reader.ui.ext.languages
|
||||
import me.ash.reader.ui.page.common.HomeEntry
|
||||
|
||||
@AndroidEntryPoint
|
||||
|
@ -28,6 +30,13 @@ class MainActivity : ComponentActivity(), ImageLoader {
|
|||
super.onCreate(savedInstanceState)
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
Log.i("RLog", "onCreate: ${ProfileInstallerInitializer().create(this)}")
|
||||
|
||||
// Set the language
|
||||
LanguagesPreference.fromValue(languages).let {
|
||||
if (it == LanguagesPreference.UseDeviceLanguages) return@let
|
||||
it.setLocale(this)
|
||||
}
|
||||
|
||||
setContent {
|
||||
SettingsProvider {
|
||||
HomeEntry()
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
package me.ash.reader.data.preference
|
||||
|
||||
import android.content.Context
|
||||
import android.os.LocaleList
|
||||
import android.util.Log
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import me.ash.reader.R
|
||||
import me.ash.reader.ui.ext.DataStoreKeys
|
||||
import me.ash.reader.ui.ext.dataStore
|
||||
import me.ash.reader.ui.ext.put
|
||||
import java.util.*
|
||||
|
||||
sealed class LanguagesPreference(val value: Int) : Preference() {
|
||||
object UseDeviceLanguages : LanguagesPreference(0)
|
||||
object English : LanguagesPreference(1)
|
||||
object ChineseSimplified : LanguagesPreference(2)
|
||||
|
||||
override fun put(context: Context, scope: CoroutineScope) {
|
||||
scope.launch {
|
||||
context.dataStore.put(
|
||||
DataStoreKeys.Languages,
|
||||
value
|
||||
)
|
||||
setLocale(context)
|
||||
}
|
||||
}
|
||||
|
||||
fun getDesc(context: Context): String =
|
||||
when (this) {
|
||||
UseDeviceLanguages -> context.getString(R.string.use_device_languages)
|
||||
English -> context.getString(R.string.english)
|
||||
ChineseSimplified -> context.getString(R.string.chinese_simplified)
|
||||
}
|
||||
|
||||
fun getLocale(): Locale =
|
||||
when (this) {
|
||||
UseDeviceLanguages -> LocaleList.getDefault().get(0)
|
||||
English -> Locale("en", "US")
|
||||
ChineseSimplified -> Locale("zh", "CN")
|
||||
}
|
||||
|
||||
fun setLocale(context: Context) {
|
||||
val locale = getLocale()
|
||||
|
||||
Log.i("Rlog", "setLocale: $locale, ${LocaleList.getDefault().get(0)}")
|
||||
|
||||
val resources = context.resources
|
||||
val metrics = resources.displayMetrics
|
||||
val configuration = resources.configuration
|
||||
configuration.setLocale(locale)
|
||||
configuration.setLocales(LocaleList(locale))
|
||||
context.createConfigurationContext(configuration)
|
||||
resources.updateConfiguration(configuration, metrics)
|
||||
|
||||
val appResources = context.applicationContext.resources
|
||||
val appMetrics = appResources.displayMetrics
|
||||
val appConfiguration = appResources.configuration
|
||||
appConfiguration.setLocale(locale)
|
||||
appConfiguration.setLocales(LocaleList(locale))
|
||||
context.applicationContext.createConfigurationContext(appConfiguration)
|
||||
appResources.updateConfiguration(appConfiguration, appMetrics)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val default = UseDeviceLanguages
|
||||
val values = listOf(UseDeviceLanguages, English, ChineseSimplified)
|
||||
|
||||
fun fromPreferences(preferences: Preferences): LanguagesPreference =
|
||||
when (preferences[DataStoreKeys.Languages.key]) {
|
||||
0 -> UseDeviceLanguages
|
||||
1 -> English
|
||||
2 -> ChineseSimplified
|
||||
else -> default
|
||||
}
|
||||
|
||||
fun fromValue(value: Int): LanguagesPreference =
|
||||
when (value) {
|
||||
0 -> UseDeviceLanguages
|
||||
1 -> English
|
||||
2 -> ChineseSimplified
|
||||
else -> default
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,6 +37,8 @@ data class Settings(
|
|||
val flowArticleListTime: FlowArticleListTimePreference = FlowArticleListTimePreference.default,
|
||||
val flowArticleListDateStickyHeader: FlowArticleListDateStickyHeaderPreference = FlowArticleListDateStickyHeaderPreference.default,
|
||||
val flowArticleListTonalElevation: FlowArticleListTonalElevationPreference = FlowArticleListTonalElevationPreference.default,
|
||||
|
||||
val languages: LanguagesPreference = LanguagesPreference.default,
|
||||
)
|
||||
|
||||
fun Preferences.toSettings(): Settings {
|
||||
|
@ -68,6 +70,8 @@ fun Preferences.toSettings(): Settings {
|
|||
this
|
||||
),
|
||||
flowArticleListTonalElevation = FlowArticleListTonalElevationPreference.fromPreferences(this),
|
||||
|
||||
languages = LanguagesPreference.fromPreferences(this),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -109,6 +113,8 @@ fun SettingsProvider(
|
|||
LocalFlowFilterBarFilled provides settings.flowFilterBarFilled,
|
||||
LocalFlowFilterBarPadding provides settings.flowFilterBarPadding,
|
||||
LocalFlowFilterBarTonalElevation provides settings.flowFilterBarTonalElevation,
|
||||
|
||||
LocalLanguages provides settings.languages,
|
||||
) {
|
||||
content()
|
||||
}
|
||||
|
@ -162,3 +168,6 @@ val LocalFlowArticleListDateStickyHeader =
|
|||
compositionLocalOf<FlowArticleListDateStickyHeaderPreference> { FlowArticleListDateStickyHeaderPreference.default }
|
||||
val LocalFlowArticleListTonalElevation =
|
||||
compositionLocalOf<FlowArticleListTonalElevationPreference> { FlowArticleListTonalElevationPreference.default }
|
||||
|
||||
val LocalLanguages =
|
||||
compositionLocalOf<LanguagesPreference> { LanguagesPreference.default }
|
||||
|
|
|
@ -24,6 +24,7 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import me.ash.reader.ui.theme.palette.alwaysLight
|
||||
|
@ -43,7 +44,7 @@ fun Banner(
|
|||
Surface(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.height(88.dp),
|
||||
.height(if (!desc.isNullOrBlank()) 88.dp else Dp.Unspecified),
|
||||
color = Color.Unspecified,
|
||||
) {
|
||||
Row(
|
||||
|
|
|
@ -39,6 +39,9 @@ val Context.initialPage: Int
|
|||
val Context.initialFilter: Int
|
||||
get() = this.dataStore.get(DataStoreKeys.InitialFilter) ?: 2
|
||||
|
||||
val Context.languages: Int
|
||||
get() = this.dataStore.get(DataStoreKeys.Languages) ?: 0
|
||||
|
||||
suspend fun <T> DataStore<Preferences>.put(dataStoreKeys: DataStoreKeys<T>, value: T) {
|
||||
this.edit {
|
||||
withContext(Dispatchers.IO) {
|
||||
|
@ -244,4 +247,9 @@ sealed class DataStoreKeys<T> {
|
|||
override val key: Preferences.Key<Int>
|
||||
get() = intPreferencesKey("initialFilter")
|
||||
}
|
||||
|
||||
object Languages : DataStoreKeys<Int>() {
|
||||
override val key: Preferences.Key<Int>
|
||||
get() = intPreferencesKey("languages")
|
||||
}
|
||||
}
|
|
@ -27,6 +27,7 @@ import me.ash.reader.ui.page.settings.color.DarkTheme
|
|||
import me.ash.reader.ui.page.settings.color.feeds.FeedsPageStyle
|
||||
import me.ash.reader.ui.page.settings.color.flow.FlowPageStyle
|
||||
import me.ash.reader.ui.page.settings.interaction.Interaction
|
||||
import me.ash.reader.ui.page.settings.languages.Languages
|
||||
import me.ash.reader.ui.page.settings.tips.TipsAndSupport
|
||||
import me.ash.reader.ui.page.startup.StartupPage
|
||||
import me.ash.reader.ui.theme.AppTheme
|
||||
|
@ -146,6 +147,11 @@ fun HomeEntry(
|
|||
Interaction(navController)
|
||||
}
|
||||
|
||||
// Languages
|
||||
animatedComposable(route = RouteName.LANGUAGES) {
|
||||
Languages(navController = navController)
|
||||
}
|
||||
|
||||
// Tips & Support
|
||||
animatedComposable(route = RouteName.TIPS_AND_SUPPORT) {
|
||||
TipsAndSupport(navController)
|
||||
|
|
|
@ -21,6 +21,9 @@ object RouteName {
|
|||
// Interaction
|
||||
const val INTERACTION = "interaction"
|
||||
|
||||
// Languages
|
||||
const val LANGUAGES = "languages"
|
||||
|
||||
// Tips & Support
|
||||
const val TIPS_AND_SUPPORT = "tips_and_support"
|
||||
}
|
|
@ -143,8 +143,11 @@ fun SettingsPage(
|
|||
title = stringResource(R.string.languages),
|
||||
desc = stringResource(R.string.languages_desc),
|
||||
icon = Icons.Outlined.Language,
|
||||
enable = false,
|
||||
) {}
|
||||
) {
|
||||
navController.navigate(RouteName.LANGUAGES) {
|
||||
launchSingleTop = true
|
||||
}
|
||||
}
|
||||
}
|
||||
item {
|
||||
SelectableSettingGroupItem(
|
||||
|
@ -156,6 +159,7 @@ fun SettingsPage(
|
|||
launchSingleTop = true
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ fun FlowPageStyle(
|
|||
text = stringResource(R.string.article_list)
|
||||
)
|
||||
SettingItem(
|
||||
title = stringResource(R.string.display_feed_favicon),
|
||||
title = stringResource(R.string.feed_favicons),
|
||||
onClick = {
|
||||
(!articleListFeedIcon).put(context, scope)
|
||||
},
|
||||
|
@ -163,7 +163,7 @@ fun FlowPageStyle(
|
|||
}
|
||||
}
|
||||
SettingItem(
|
||||
title = stringResource(R.string.display_feed_name),
|
||||
title = stringResource(R.string.feed_names),
|
||||
onClick = {
|
||||
(!articleListFeedName).put(context, scope)
|
||||
},
|
||||
|
@ -173,14 +173,14 @@ fun FlowPageStyle(
|
|||
}
|
||||
}
|
||||
SettingItem(
|
||||
title = stringResource(R.string.display_article_image),
|
||||
title = stringResource(R.string.article_images),
|
||||
enable = false,
|
||||
onClick = {},
|
||||
) {
|
||||
Switch(activated = false, enable = false)
|
||||
}
|
||||
SettingItem(
|
||||
title = stringResource(R.string.display_article_desc),
|
||||
title = stringResource(R.string.article_desc),
|
||||
onClick = {
|
||||
(!articleListDesc).put(context, scope)
|
||||
},
|
||||
|
@ -190,7 +190,7 @@ fun FlowPageStyle(
|
|||
}
|
||||
}
|
||||
SettingItem(
|
||||
title = stringResource(R.string.display_article_date),
|
||||
title = stringResource(R.string.article_date),
|
||||
onClick = {
|
||||
(!articleListTime).put(context, scope)
|
||||
},
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package me.ash.reader.ui.page.settings.languages
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.KeyboardArrowRight
|
||||
import androidx.compose.material.icons.outlined.Lightbulb
|
||||
import androidx.compose.material.icons.rounded.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavHostController
|
||||
import me.ash.reader.R
|
||||
import me.ash.reader.data.preference.LanguagesPreference
|
||||
import me.ash.reader.data.preference.LocalLanguages
|
||||
import me.ash.reader.ui.component.Banner
|
||||
import me.ash.reader.ui.component.DisplayText
|
||||
import me.ash.reader.ui.component.FeedbackIconButton
|
||||
import me.ash.reader.ui.page.settings.SettingItem
|
||||
import me.ash.reader.ui.theme.palette.onLight
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun Languages(
|
||||
navController: NavHostController,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val languages = LocalLanguages.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface)
|
||||
.statusBarsPadding()
|
||||
.navigationBarsPadding(),
|
||||
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface,
|
||||
topBar = {
|
||||
SmallTopAppBar(
|
||||
colors = TopAppBarDefaults.smallTopAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface
|
||||
),
|
||||
title = {},
|
||||
navigationIcon = {
|
||||
FeedbackIconButton(
|
||||
imageVector = Icons.Rounded.ArrowBack,
|
||||
contentDescription = stringResource(R.string.back),
|
||||
tint = MaterialTheme.colorScheme.onSurface
|
||||
) {
|
||||
navController.popBackStack()
|
||||
}
|
||||
},
|
||||
actions = {}
|
||||
)
|
||||
},
|
||||
content = {
|
||||
LazyColumn {
|
||||
item(key = languages.value) {
|
||||
DisplayText(text = stringResource(R.string.languages), desc = "")
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Banner(
|
||||
title = stringResource(R.string.help_translate),
|
||||
icon = Icons.Outlined.Lightbulb,
|
||||
action = {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.KeyboardArrowRight,
|
||||
contentDescription = stringResource(R.string.go_to),
|
||||
)
|
||||
},
|
||||
) {
|
||||
context.startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(context.getString(R.string.github_link))
|
||||
)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
}
|
||||
item {
|
||||
LanguagesPreference.values.map {
|
||||
SettingItem(
|
||||
title = it.getDesc(context),
|
||||
onClick = {
|
||||
it.put(context, scope)
|
||||
},
|
||||
) {
|
||||
RadioButton(selected = it == languages, onClick = {
|
||||
it.put(context, scope)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
<resources>
|
||||
<string name="read_you">Read You</string>
|
||||
<string name="all">全部</string>
|
||||
<string name="all_desc">%1$d 项已归档</string>
|
||||
<string name="unread">未读</string>
|
||||
|
@ -90,7 +89,9 @@
|
|||
<string name="interaction">交互</string>
|
||||
<string name="interaction_desc">启动时、触感反馈</string>
|
||||
<string name="languages">语言</string>
|
||||
<string name="languages_desc">英语、中文</string>
|
||||
<string name="languages_desc">English、简体中文</string>
|
||||
<string name="use_device_languages">跟随系统设置</string>
|
||||
<string name="help_translate">帮助我们翻译</string>
|
||||
<string name="tips_and_support">提示和支持</string>
|
||||
<string name="tips_and_support_desc">关于、开源</string>
|
||||
<string name="welcome">欢迎</string>
|
||||
|
@ -120,8 +121,6 @@
|
|||
<string name="reading_page">阅读页面</string>
|
||||
<string name="sponsor">捐赠</string>
|
||||
<string name="open_source_licenses">开放源代码许可</string>
|
||||
<string name="github_link">https://github.com/Ashinch/ReadYou</string>
|
||||
<string name="telegram_link">https://t.me/ReadYouApp</string>
|
||||
<string name="update_link">https://gitee.com/api/v5/repos/Ashinch/ReadYou/releases/latest</string>
|
||||
<string name="change_log">更新日志</string>
|
||||
<string name="update">更新</string>
|
||||
|
@ -140,11 +139,11 @@
|
|||
<string name="preview_feed_name">漩涡书院</string>
|
||||
<string name="value">值</string>
|
||||
<string name="padding_on_both_ends">两端边距</string>
|
||||
<string name="display_article_date">显示文章发布时间</string>
|
||||
<string name="display_article_desc">显示文章描述</string>
|
||||
<string name="display_article_image">显示文章插图</string>
|
||||
<string name="display_feed_name">显示订阅源名称</string>
|
||||
<string name="display_feed_favicon">显示订阅源图标</string>
|
||||
<string name="article_date">文章发布时间</string>
|
||||
<string name="article_desc">文章描述</string>
|
||||
<string name="article_images">文章插图</string>
|
||||
<string name="feed_names">订阅源名称</string>
|
||||
<string name="feed_favicons">订阅源图标</string>
|
||||
<string name="article_date_sticky_header">文章发布日期粘性标签(实验性)</string>
|
||||
<string name="article_list">文章列表</string>
|
||||
<string name="group_list">分组列表</string>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<resources>
|
||||
<string name="read_you">Read You</string>
|
||||
<string name="read_you" translatable="false">Read You</string>
|
||||
<string name="all">All</string>
|
||||
<string name="all_desc">%1$d Archived Items</string>
|
||||
<string name="unread">Unread</string>
|
||||
|
@ -91,7 +91,11 @@
|
|||
<string name="interaction">Interaction</string>
|
||||
<string name="interaction_desc">On start, haptic feedback</string>
|
||||
<string name="languages">Languages</string>
|
||||
<string name="languages_desc">English, Chinese</string>
|
||||
<string name="languages_desc">English, 简体中文</string>
|
||||
<string name="help_translate">Help us translate</string>
|
||||
<string name="use_device_languages">Use Device Languages</string>
|
||||
<string name="english" translatable="false">English</string>
|
||||
<string name="chinese_simplified" translatable="false">简体中文</string>
|
||||
<string name="tips_and_support">Tips & support</string>
|
||||
<string name="tips_and_support_desc">About, open source</string>
|
||||
<string name="welcome">Welcome</string>
|
||||
|
@ -121,8 +125,8 @@
|
|||
<string name="reading_page">Reading Page</string>
|
||||
<string name="sponsor">Sponsor</string>
|
||||
<string name="open_source_licenses">Open Source Licenses</string>
|
||||
<string name="github_link">https://github.com/Ashinch/ReadYou</string>
|
||||
<string name="telegram_link">https://t.me/ReadYouApp</string>
|
||||
<string name="github_link" translatable="false">https://github.com/Ashinch/ReadYou</string>
|
||||
<string name="telegram_link" translatable="false">https://t.me/ReadYouApp</string>
|
||||
<string name="update_link">https://api.github.com/repos/Ashinch/ReadYou/releases/latest</string>
|
||||
<string name="change_log">Change Log</string>
|
||||
<string name="update">Update</string>
|
||||
|
@ -141,12 +145,12 @@
|
|||
<string name="preview_feed_name">Reddit</string>
|
||||
<string name="value">value</string>
|
||||
<string name="padding_on_both_ends">Padding on Both Ends</string>
|
||||
<string name="display_article_date">Display Article Publish Time</string>
|
||||
<string name="display_article_desc">Display Article Descriptions</string>
|
||||
<string name="display_article_image">Display Article Images</string>
|
||||
<string name="display_feed_name">Display Feed Names</string>
|
||||
<string name="display_feed_favicon">Display Feed Favicons</string>
|
||||
<string name="article_date_sticky_header">Article Publish Date Sticky Header (Experimental)</string>
|
||||
<string name="article_date">Article Published Time</string>
|
||||
<string name="article_desc">Article Descriptions</string>
|
||||
<string name="article_images">Article Images</string>
|
||||
<string name="feed_names">Feed Names</string>
|
||||
<string name="feed_favicons">Feed Favicons</string>
|
||||
<string name="article_date_sticky_header">Article Published Date Sticky Header (Experimental)</string>
|
||||
<string name="article_list">Article List</string>
|
||||
<string name="group_list">Group List</string>
|
||||
<string name="always_expand">Always Expand</string>
|
||||
|
|
Loading…
Reference in New Issue
Block a user