Migrate to multiplatform string resources (#10147)

* Migrate to multiplatform string resources

* Move plurals translations into separate files

* Fix lint check on generated files
This commit is contained in:
arkon
2023-11-18 13:54:56 -05:00
committed by GitHub
parent c39ae21f4a
commit 46e734fc8e
340 changed files with 5741 additions and 6292 deletions
@@ -13,9 +13,7 @@ import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.automirrored.outlined.Label
import androidx.compose.material.icons.outlined.CloudOff
import androidx.compose.material.icons.outlined.GetApp
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Label
import androidx.compose.material.icons.outlined.QueryStats
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.Storage
@@ -24,8 +22,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import eu.kanade.presentation.components.WarningBanner
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
@@ -33,8 +29,11 @@ import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.more.DownloadQueueState
import tachiyomi.core.Constants
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.i18n.localizePlural
@Composable
fun MoreScreen(
@@ -62,7 +61,7 @@ fun MoreScreen(
) {
if (isFDroid) {
WarningBanner(
textRes = R.string.fdroid_warning,
textRes = MR.strings.fdroid_warning,
modifier = Modifier.clickable {
uriHandler.openUri(
"https://tachiyomi.org/docs/faq/general#how-do-i-update-from-the-f-droid-builds",
@@ -81,8 +80,8 @@ fun MoreScreen(
}
item {
SwitchPreferenceWidget(
title = stringResource(R.string.label_downloaded_only),
subtitle = stringResource(R.string.downloaded_only_summary),
title = localize(MR.strings.label_downloaded_only),
subtitle = localize(MR.strings.downloaded_only_summary),
icon = Icons.Outlined.CloudOff,
checked = downloadedOnly,
onCheckedChanged = onDownloadedOnlyChange,
@@ -90,8 +89,8 @@ fun MoreScreen(
}
item {
SwitchPreferenceWidget(
title = stringResource(R.string.pref_incognito_mode),
subtitle = stringResource(R.string.pref_incognito_mode_summary),
title = localize(MR.strings.pref_incognito_mode),
subtitle = localize(MR.strings.pref_incognito_mode_summary),
icon = ImageVector.vectorResource(R.drawable.ic_glasses_24dp),
checked = incognitoMode,
onCheckedChanged = onIncognitoModeChange,
@@ -103,17 +102,17 @@ fun MoreScreen(
item {
val downloadQueueState = downloadQueueStateProvider()
TextPreferenceWidget(
title = stringResource(R.string.label_download_queue),
title = localize(MR.strings.label_download_queue),
subtitle = when (downloadQueueState) {
DownloadQueueState.Stopped -> null
is DownloadQueueState.Paused -> {
val pending = downloadQueueState.pending
if (pending == 0) {
stringResource(R.string.paused)
localize(MR.strings.paused)
} else {
"${stringResource(R.string.paused)}${
pluralStringResource(
id = R.plurals.download_queue_summary,
"${localize(MR.strings.paused)}${
localizePlural(
MR.plurals.download_queue_summary,
count = pending,
pending,
)
@@ -122,7 +121,7 @@ fun MoreScreen(
}
is DownloadQueueState.Downloading -> {
val pending = downloadQueueState.pending
pluralStringResource(id = R.plurals.download_queue_summary, count = pending, pending)
localizePlural(MR.plurals.download_queue_summary, count = pending, pending)
}
},
icon = Icons.Outlined.GetApp,
@@ -131,21 +130,21 @@ fun MoreScreen(
}
item {
TextPreferenceWidget(
title = stringResource(R.string.categories),
title = localize(MR.strings.categories),
icon = Icons.AutoMirrored.Outlined.Label,
onPreferenceClick = onClickCategories,
)
}
item {
TextPreferenceWidget(
title = stringResource(R.string.label_stats),
title = localize(MR.strings.label_stats),
icon = Icons.Outlined.QueryStats,
onPreferenceClick = onClickStats,
)
}
item {
TextPreferenceWidget(
title = stringResource(R.string.label_data_storage),
title = localize(MR.strings.label_data_storage),
icon = Icons.Outlined.Storage,
onPreferenceClick = onClickDataAndStorage,
)
@@ -155,21 +154,21 @@ fun MoreScreen(
item {
TextPreferenceWidget(
title = stringResource(R.string.label_settings),
title = localize(MR.strings.label_settings),
icon = Icons.Outlined.Settings,
onPreferenceClick = onClickSettings,
)
}
item {
TextPreferenceWidget(
title = stringResource(R.string.pref_category_about),
title = localize(MR.strings.pref_category_about),
icon = Icons.Outlined.Info,
onPreferenceClick = onClickAbout,
)
}
item {
TextPreferenceWidget(
title = stringResource(R.string.label_help),
title = localize(MR.strings.label_help),
icon = Icons.AutoMirrored.Outlined.HelpOutline,
onPreferenceClick = { uriHandler.openUri(Constants.URL_HELP) },
)
@@ -14,7 +14,6 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.tooling.preview.PreviewLightDark
import com.halilibo.richtext.markdown.Markdown
@@ -22,8 +21,9 @@ import com.halilibo.richtext.ui.RichTextStyle
import com.halilibo.richtext.ui.material3.Material3RichText
import com.halilibo.richtext.ui.string.RichTextStringStyle
import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.screens.InfoScreen
@Composable
@@ -36,11 +36,11 @@ fun NewUpdateScreen(
) {
InfoScreen(
icon = Icons.Outlined.NewReleases,
headingText = stringResource(R.string.update_check_notification_update_available),
headingText = localize(MR.strings.update_check_notification_update_available),
subtitleText = versionName,
acceptText = stringResource(R.string.update_check_confirm),
acceptText = localize(MR.strings.update_check_confirm),
onAcceptClick = onAcceptUpdate,
rejectText = stringResource(R.string.action_not_now),
rejectText = localize(MR.strings.action_not_now),
onRejectClick = onRejectUpdate,
) {
Material3RichText(
@@ -59,7 +59,7 @@ fun NewUpdateScreen(
onClick = onOpenInBrowser,
modifier = Modifier.padding(top = MaterialTheme.padding.small),
) {
Text(text = stringResource(R.string.update_check_open))
Text(text = localize(MR.strings.update_check_open))
Spacer(modifier = Modifier.width(MaterialTheme.padding.tiny))
Icon(imageVector = Icons.AutoMirrored.Outlined.OpenInNew, contentDescription = null)
}
@@ -3,9 +3,9 @@ package eu.kanade.presentation.more.settings
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.Tracker
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.core.preference.Preference as PreferenceData
sealed class Preference {
@@ -109,7 +109,7 @@ sealed class Preference {
v.map { e[it] }
.takeIf { it.isNotEmpty() }
?.joinToString()
} ?: stringResource(R.string.none)
} ?: localize(MR.strings.none)
subtitle?.format(combined)
},
override val icon: ImageVector? = null,
@@ -1,15 +1,15 @@
package eu.kanade.presentation.more.settings
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.RowScope
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.components.AppBar
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.localize
@Composable
fun PreferenceScaffold(
@StringRes titleRes: Int,
titleRes: StringResource,
actions: @Composable RowScope.() -> Unit = {},
onBackPressed: (() -> Unit)? = null,
itemsProvider: @Composable () -> List<Preference>,
@@ -17,7 +17,7 @@ fun PreferenceScaffold(
Scaffold(
topBar = {
AppBar(
title = stringResource(titleRes),
title = localize(titleRes),
navigateUp = onBackPressed,
actions = actions,
scrollBehavior = it,
@@ -3,10 +3,10 @@ package eu.kanade.presentation.more.settings.screen
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.category.visualName
import eu.kanade.tachiyomi.R
import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
/**
* Returns a string of categories name for settings subtitle
@@ -34,15 +34,15 @@ fun getCategoriesLabel(
includedCategories.isNotEmpty() && includedCategories.size != allCategories.size ->
includedCategories.joinToString { it.visualName(context) }
// All explicitly selected
includedCategories.size == allCategories.size -> stringResource(R.string.all)
allExcluded -> stringResource(R.string.none)
else -> stringResource(R.string.all)
includedCategories.size == allCategories.size -> localize(MR.strings.all)
allExcluded -> localize(MR.strings.none)
else -> localize(MR.strings.all)
}
val excludedItemsText = when {
excludedCategories.isEmpty() -> stringResource(R.string.none)
allExcluded -> stringResource(R.string.all)
excludedCategories.isEmpty() -> localize(MR.strings.none)
allExcluded -> localize(MR.strings.all)
else -> excludedCategories.joinToString { it.visualName(context) }
}
return stringResource(R.string.include, includedItemsText) + "\n" +
stringResource(R.string.exclude, excludedItemsText)
return localize(MR.strings.include, includedItemsText) + "\n" +
localize(MR.strings.exclude, excludedItemsText)
}
@@ -1,10 +1,10 @@
package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.RowScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import cafe.adriel.voyager.core.screen.Screen
import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.PreferenceScaffold
import eu.kanade.presentation.util.LocalBackPress
@@ -13,8 +13,7 @@ interface SearchableSettings : Screen {
@Composable
@ReadOnlyComposable
@StringRes
fun getTitleRes(): Int
fun getTitleRes(): StringResource
@Composable
fun getPreferences(): List<Preference>
@@ -7,7 +7,6 @@ import android.os.Build
import android.provider.Settings
import android.webkit.WebStorage
import android.webkit.WebView
import androidx.annotation.StringRes
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
@@ -21,7 +20,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.core.net.toUri
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
@@ -29,9 +27,8 @@ import eu.kanade.domain.base.BasePreferences
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.screen.advanced.ClearDatabaseScreen
import eu.kanade.presentation.more.settings.screen.debug.DebugInfoScreen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.DownloadCache
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.data.library.MetadataUpdateJob
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.NetworkPreferences
import eu.kanade.tachiyomi.network.PREF_DOH_360
@@ -60,6 +57,8 @@ import tachiyomi.core.util.lang.launchNonCancellable
import tachiyomi.core.util.lang.withUIContext
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.manga.interactor.ResetViewerFlags
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -69,8 +68,7 @@ object SettingsAdvancedScreen : SearchableSettings {
@ReadOnlyComposable
@Composable
@StringRes
override fun getTitleRes() = R.string.pref_category_advanced
override fun getTitleRes() = MR.strings.pref_category_advanced
@Composable
override fun getPreferences(): List<Preference> {
@@ -86,13 +84,13 @@ object SettingsAdvancedScreen : SearchableSettings {
listOf(
Preference.PreferenceItem.SwitchPreference(
pref = basePreferences.acraEnabled(),
title = stringResource(R.string.pref_enable_acra),
subtitle = stringResource(R.string.pref_acra_summary),
title = localize(MR.strings.pref_enable_acra),
subtitle = localize(MR.strings.pref_acra_summary),
enabled = isPreviewBuildType || isReleaseBuildType,
),
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_dump_crash_logs),
subtitle = stringResource(R.string.pref_dump_crash_logs_summary),
title = localize(MR.strings.pref_dump_crash_logs),
subtitle = localize(MR.strings.pref_dump_crash_logs_summary),
onClick = {
scope.launch {
CrashLogUtil(context).dumpLogs()
@@ -101,15 +99,15 @@ object SettingsAdvancedScreen : SearchableSettings {
),
Preference.PreferenceItem.SwitchPreference(
pref = networkPreferences.verboseLogging(),
title = stringResource(R.string.pref_verbose_logging),
subtitle = stringResource(R.string.pref_verbose_logging_summary),
title = localize(MR.strings.pref_verbose_logging),
subtitle = localize(MR.strings.pref_verbose_logging_summary),
onValueChanged = {
context.toast(R.string.requires_app_restart)
context.toast(MR.strings.requires_app_restart)
true
},
),
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_debug_info),
title = localize(MR.strings.pref_debug_info),
onClick = { navigator.push(DebugInfoScreen()) },
),
),
@@ -117,7 +115,7 @@ object SettingsAdvancedScreen : SearchableSettings {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
add(
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_manage_notifications),
title = localize(MR.strings.pref_manage_notifications),
onClick = {
val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
@@ -145,11 +143,11 @@ object SettingsAdvancedScreen : SearchableSettings {
val uriHandler = LocalUriHandler.current
return Preference.PreferenceGroup(
title = stringResource(R.string.label_background_activity),
title = localize(MR.strings.label_background_activity),
preferenceItems = listOf(
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_disable_battery_optimization),
subtitle = stringResource(R.string.pref_disable_battery_optimization_summary),
title = localize(MR.strings.pref_disable_battery_optimization),
subtitle = localize(MR.strings.pref_disable_battery_optimization_summary),
onClick = {
val packageName: String = context.packageName
if (!context.powerManager.isIgnoringBatteryOptimizations(packageName)) {
@@ -162,16 +160,16 @@ object SettingsAdvancedScreen : SearchableSettings {
}
context.startActivity(intent)
} catch (e: ActivityNotFoundException) {
context.toast(R.string.battery_optimization_setting_activity_not_found)
context.toast(MR.strings.battery_optimization_setting_activity_not_found)
}
} else {
context.toast(R.string.battery_optimization_disabled)
context.toast(MR.strings.battery_optimization_disabled)
}
},
),
Preference.PreferenceItem.TextPreference(
title = "Don't kill my app!",
subtitle = stringResource(R.string.about_dont_kill_my_app),
subtitle = localize(MR.strings.about_dont_kill_my_app),
onClick = { uriHandler.openUri("https://dontkillmyapp.com/") },
),
),
@@ -184,19 +182,19 @@ object SettingsAdvancedScreen : SearchableSettings {
val navigator = LocalNavigator.currentOrThrow
return Preference.PreferenceGroup(
title = stringResource(R.string.label_data),
title = localize(MR.strings.label_data),
preferenceItems = listOf(
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_invalidate_download_cache),
subtitle = stringResource(R.string.pref_invalidate_download_cache_summary),
title = localize(MR.strings.pref_invalidate_download_cache),
subtitle = localize(MR.strings.pref_invalidate_download_cache_summary),
onClick = {
Injekt.get<DownloadCache>().invalidateCache()
context.toast(R.string.download_cache_invalidated)
context.toast(MR.strings.download_cache_invalidated)
},
),
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_clear_database),
subtitle = stringResource(R.string.pref_clear_database_summary),
title = localize(MR.strings.pref_clear_database),
subtitle = localize(MR.strings.pref_clear_database_summary),
onClick = { navigator.push(ClearDatabaseScreen()) },
),
),
@@ -214,17 +212,17 @@ object SettingsAdvancedScreen : SearchableSettings {
val userAgent by userAgentPref.collectAsState()
return Preference.PreferenceGroup(
title = stringResource(R.string.label_network),
title = localize(MR.strings.label_network),
preferenceItems = listOf(
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_clear_cookies),
title = localize(MR.strings.pref_clear_cookies),
onClick = {
networkHelper.cookieJar.removeAll()
context.toast(R.string.cookies_cleared)
context.toast(MR.strings.cookies_cleared)
},
),
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_clear_webview_data),
title = localize(MR.strings.pref_clear_webview_data),
onClick = {
try {
WebView(context).run {
@@ -236,18 +234,18 @@ object SettingsAdvancedScreen : SearchableSettings {
}
WebStorage.getInstance().deleteAllData()
context.applicationInfo?.dataDir?.let { File("$it/app_webview/").deleteRecursively() }
context.toast(R.string.webview_data_deleted)
context.toast(MR.strings.webview_data_deleted)
} catch (e: Throwable) {
logcat(LogPriority.ERROR, e)
context.toast(R.string.cache_delete_error)
context.toast(MR.strings.cache_delete_error)
}
},
),
Preference.PreferenceItem.ListPreference(
pref = networkPreferences.dohProvider(),
title = stringResource(R.string.pref_dns_over_https),
title = localize(MR.strings.pref_dns_over_https),
entries = mapOf(
-1 to stringResource(R.string.disabled),
-1 to localize(MR.strings.disabled),
PREF_DOH_CLOUDFLARE to "Cloudflare",
PREF_DOH_GOOGLE to "Google",
PREF_DOH_ADGUARD to "AdGuard",
@@ -262,30 +260,30 @@ object SettingsAdvancedScreen : SearchableSettings {
PREF_DOH_SHECAN to "Shecan",
),
onValueChanged = {
context.toast(R.string.requires_app_restart)
context.toast(MR.strings.requires_app_restart)
true
},
),
Preference.PreferenceItem.EditTextPreference(
pref = userAgentPref,
title = stringResource(R.string.pref_user_agent_string),
title = localize(MR.strings.pref_user_agent_string),
onValueChanged = {
try {
// OkHttp checks for valid values internally
Headers.Builder().add("User-Agent", it)
} catch (_: IllegalArgumentException) {
context.toast(R.string.error_user_agent_string_invalid)
context.toast(MR.strings.error_user_agent_string_invalid)
return@EditTextPreference false
}
true
},
),
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_reset_user_agent_string),
title = localize(MR.strings.pref_reset_user_agent_string),
enabled = remember(userAgent) { userAgent != userAgentPref.defaultValue() },
onClick = {
userAgentPref.delete()
context.toast(R.string.requires_app_restart)
context.toast(MR.strings.requires_app_restart)
},
),
),
@@ -298,23 +296,23 @@ object SettingsAdvancedScreen : SearchableSettings {
val context = LocalContext.current
return Preference.PreferenceGroup(
title = stringResource(R.string.label_library),
title = localize(MR.strings.label_library),
preferenceItems = listOf(
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_refresh_library_covers),
onClick = { LibraryUpdateJob.startNow(context, target = LibraryUpdateJob.Target.COVERS) },
title = localize(MR.strings.pref_refresh_library_covers),
onClick = { MetadataUpdateJob.startNow(context) },
),
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_reset_viewer_flags),
subtitle = stringResource(R.string.pref_reset_viewer_flags_summary),
title = localize(MR.strings.pref_reset_viewer_flags),
subtitle = localize(MR.strings.pref_reset_viewer_flags_summary),
onClick = {
scope.launchNonCancellable {
val success = Injekt.get<ResetViewerFlags>().await()
withUIContext {
val message = if (success) {
R.string.pref_reset_viewer_flags_success
MR.strings.pref_reset_viewer_flags_success
} else {
R.string.pref_reset_viewer_flags_error
MR.strings.pref_reset_viewer_flags_error
}
context.toast(message)
}
@@ -338,11 +336,11 @@ object SettingsAdvancedScreen : SearchableSettings {
val dismiss = { shizukuMissing = false }
AlertDialog(
onDismissRequest = dismiss,
title = { Text(text = stringResource(R.string.ext_installer_shizuku)) },
text = { Text(text = stringResource(R.string.ext_installer_shizuku_unavailable_dialog)) },
title = { Text(text = localize(MR.strings.ext_installer_shizuku)) },
text = { Text(text = localize(MR.strings.ext_installer_shizuku_unavailable_dialog)) },
dismissButton = {
TextButton(onClick = dismiss) {
Text(text = stringResource(R.string.action_cancel))
Text(text = localize(MR.strings.action_cancel))
}
},
confirmButton = {
@@ -352,19 +350,19 @@ object SettingsAdvancedScreen : SearchableSettings {
uriHandler.openUri("https://shizuku.rikka.app/download")
},
) {
Text(text = stringResource(R.string.action_ok))
Text(text = localize(MR.strings.action_ok))
}
},
)
}
return Preference.PreferenceGroup(
title = stringResource(R.string.label_extensions),
title = localize(MR.strings.label_extensions),
preferenceItems = listOf(
Preference.PreferenceItem.ListPreference(
pref = extensionInstallerPref,
title = stringResource(R.string.ext_installer_pref),
title = localize(MR.strings.ext_installer_pref),
entries = extensionInstallerPref.entries
.associateWith { stringResource(it.titleResId) },
.associateWith { localize(it.titleRes) },
onValueChanged = {
if (it == BasePreferences.ExtensionInstaller.SHIZUKU &&
!context.isShizukuInstalled
@@ -3,7 +3,6 @@ package eu.kanade.presentation.more.settings.screen
import android.app.Activity
import android.content.Context
import android.os.Build
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -13,7 +12,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.core.app.ActivityCompat
import androidx.core.os.LocaleListCompat
import eu.kanade.domain.ui.UiPreferences
@@ -29,6 +27,9 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.merge
import org.xmlpull.v1.XmlPullParser
import tachiyomi.core.i18n.localize
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -38,8 +39,7 @@ object SettingsAppearanceScreen : SearchableSettings {
@ReadOnlyComposable
@Composable
@StringRes
override fun getTitleRes() = R.string.pref_category_appearance
override fun getTitleRes() = MR.strings.pref_category_appearance
@Composable
override fun getPreferences(): List<Preference> {
@@ -76,26 +76,26 @@ object SettingsAppearanceScreen : SearchableSettings {
}
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_theme),
title = localize(MR.strings.pref_category_theme),
preferenceItems = listOf(
Preference.PreferenceItem.ListPreference(
pref = themeModePref,
title = stringResource(R.string.pref_theme_mode),
title = localize(MR.strings.pref_theme_mode),
entries = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mapOf(
ThemeMode.SYSTEM to stringResource(R.string.theme_system),
ThemeMode.LIGHT to stringResource(R.string.theme_light),
ThemeMode.DARK to stringResource(R.string.theme_dark),
ThemeMode.SYSTEM to localize(MR.strings.theme_system),
ThemeMode.LIGHT to localize(MR.strings.theme_light),
ThemeMode.DARK to localize(MR.strings.theme_dark),
)
} else {
mapOf(
ThemeMode.LIGHT to stringResource(R.string.theme_light),
ThemeMode.DARK to stringResource(R.string.theme_dark),
ThemeMode.LIGHT to localize(MR.strings.theme_light),
ThemeMode.DARK to localize(MR.strings.theme_dark),
)
},
),
Preference.PreferenceItem.CustomPreference(
title = stringResource(R.string.pref_app_theme),
title = localize(MR.strings.pref_app_theme),
) { item ->
val value by appThemePref.collectAsState()
AppThemePreferenceWidget(
@@ -107,7 +107,7 @@ object SettingsAppearanceScreen : SearchableSettings {
},
Preference.PreferenceItem.SwitchPreference(
pref = amoledPref,
title = stringResource(R.string.pref_dark_theme_pure_black),
title = localize(MR.strings.pref_dark_theme_pure_black),
enabled = themeMode != ThemeMode.LIGHT,
),
),
@@ -140,11 +140,11 @@ object SettingsAppearanceScreen : SearchableSettings {
}
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_display),
title = localize(MR.strings.pref_category_display),
preferenceItems = listOf(
Preference.PreferenceItem.BasicListPreference(
value = currentLanguage,
title = stringResource(R.string.pref_app_language),
title = localize(MR.strings.pref_app_language),
entries = langs,
onValueChanged = { newValue ->
currentLanguage = newValue
@@ -153,28 +153,28 @@ object SettingsAppearanceScreen : SearchableSettings {
),
Preference.PreferenceItem.ListPreference(
pref = uiPreferences.tabletUiMode(),
title = stringResource(R.string.pref_tablet_ui_mode),
entries = TabletUiMode.entries.associateWith { stringResource(it.titleResId) },
title = localize(MR.strings.pref_tablet_ui_mode),
entries = TabletUiMode.entries.associateWith { localize(it.titleRes) },
onValueChanged = {
context.toast(R.string.requires_app_restart)
context.toast(MR.strings.requires_app_restart)
true
},
),
Preference.PreferenceItem.ListPreference(
pref = uiPreferences.dateFormat(),
title = stringResource(R.string.pref_date_format),
title = localize(MR.strings.pref_date_format),
entries = DateFormats
.associateWith {
val formattedDate = UiPreferences.dateFormat(it).format(now)
"${it.ifEmpty { stringResource(R.string.label_default) }} ($formattedDate)"
"${it.ifEmpty { localize(MR.strings.label_default) }} ($formattedDate)"
},
),
Preference.PreferenceItem.SwitchPreference(
pref = uiPreferences.relativeTime(),
title = stringResource(R.string.pref_relative_format),
subtitle = stringResource(
R.string.pref_relative_format_summary,
stringResource(R.string.relative_time_today),
title = localize(MR.strings.pref_relative_format),
subtitle = localize(
MR.strings.pref_relative_format_summary,
localize(MR.strings.relative_time_today),
formattedNow,
),
),
@@ -201,7 +201,7 @@ object SettingsAppearanceScreen : SearchableSettings {
}
langs.sortBy { it.second }
langs.add(0, Pair("", context.getString(R.string.label_default)))
langs.add(0, Pair("", context.localize(MR.strings.label_default)))
return langs.toMap()
}
@@ -1,16 +1,16 @@
package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.fragment.app.FragmentActivity
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.authenticate
import tachiyomi.core.i18n.localize
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -18,8 +18,7 @@ object SettingsBrowseScreen : SearchableSettings {
@ReadOnlyComposable
@Composable
@StringRes
override fun getTitleRes() = R.string.browse
override fun getTitleRes() = MR.strings.browse
@Composable
override fun getPreferences(): List<Preference> {
@@ -27,28 +26,28 @@ object SettingsBrowseScreen : SearchableSettings {
val sourcePreferences = remember { Injekt.get<SourcePreferences>() }
return listOf(
Preference.PreferenceGroup(
title = stringResource(R.string.label_sources),
title = localize(MR.strings.label_sources),
preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference(
pref = sourcePreferences.hideInLibraryItems(),
title = stringResource(R.string.pref_hide_in_library_items),
title = localize(MR.strings.pref_hide_in_library_items),
),
),
),
Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_nsfw_content),
title = localize(MR.strings.pref_category_nsfw_content),
preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference(
pref = sourcePreferences.showNsfwSource(),
title = stringResource(R.string.pref_show_nsfw_source),
subtitle = stringResource(R.string.requires_app_restart),
title = localize(MR.strings.pref_show_nsfw_source),
subtitle = localize(MR.strings.requires_app_restart),
onValueChanged = {
(context as FragmentActivity).authenticate(
title = context.getString(R.string.pref_category_nsfw_content),
title = context.localize(MR.strings.pref_category_nsfw_content),
)
},
),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.parental_controls_info)),
Preference.PreferenceItem.InfoPreference(localize(MR.strings.parental_controls_info)),
),
),
)
@@ -8,7 +8,6 @@ import android.text.format.Formatter
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
@@ -27,7 +26,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.more.settings.Preference
@@ -36,7 +34,6 @@ import eu.kanade.presentation.more.settings.widget.BasePreferenceWidget
import eu.kanade.presentation.more.settings.widget.PrefsHorizontalPadding
import eu.kanade.presentation.permissions.PermissionRequestHelper
import eu.kanade.presentation.util.relativeTimeSpanString
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.BackupCreateJob
import eu.kanade.tachiyomi.data.backup.BackupFileValidator
import eu.kanade.tachiyomi.data.backup.BackupRestoreJob
@@ -46,11 +43,14 @@ import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.system.toast
import logcat.LogPriority
import tachiyomi.core.i18n.localize
import tachiyomi.core.util.lang.launchNonCancellable
import tachiyomi.core.util.lang.withUIContext
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -59,8 +59,7 @@ object SettingsDataScreen : SearchableSettings {
@ReadOnlyComposable
@Composable
@StringRes
override fun getTitleRes() = R.string.label_data_storage
override fun getTitleRes() = MR.strings.label_data_storage
@Composable
override fun getPreferences(): List<Preference> {
@@ -82,7 +81,7 @@ object SettingsDataScreen : SearchableSettings {
val lastAutoBackup by backupPreferences.lastAutoBackupTimestamp().collectAsState()
return Preference.PreferenceGroup(
title = stringResource(R.string.label_backup),
title = localize(MR.strings.label_backup),
preferenceItems = listOf(
// Manual actions
getCreateBackupPref(),
@@ -91,14 +90,14 @@ object SettingsDataScreen : SearchableSettings {
// Automatic backups
Preference.PreferenceItem.ListPreference(
pref = backupIntervalPref,
title = stringResource(R.string.pref_backup_interval),
title = localize(MR.strings.pref_backup_interval),
entries = mapOf(
0 to stringResource(R.string.off),
6 to stringResource(R.string.update_6hour),
12 to stringResource(R.string.update_12hour),
24 to stringResource(R.string.update_24hour),
48 to stringResource(R.string.update_48hour),
168 to stringResource(R.string.update_weekly),
0 to localize(MR.strings.off),
6 to localize(MR.strings.update_6hour),
12 to localize(MR.strings.update_12hour),
24 to localize(MR.strings.update_24hour),
48 to localize(MR.strings.update_48hour),
168 to localize(MR.strings.update_weekly),
),
onValueChanged = {
BackupCreateJob.setupTask(context, it)
@@ -108,12 +107,12 @@ object SettingsDataScreen : SearchableSettings {
Preference.PreferenceItem.ListPreference(
pref = backupPreferences.numberOfBackups(),
enabled = backupInterval != 0,
title = stringResource(R.string.pref_backup_slots),
title = localize(MR.strings.pref_backup_slots),
entries = listOf(2, 3, 4, 5).associateWith { it.toString() },
),
Preference.PreferenceItem.InfoPreference(
stringResource(R.string.backup_info) + "\n\n" +
stringResource(R.string.last_auto_backup_info, relativeTimeSpanString(lastAutoBackup)),
localize(MR.strings.backup_info) + "\n\n" +
localize(MR.strings.last_auto_backup_info, relativeTimeSpanString(lastAutoBackup)),
),
),
)
@@ -123,8 +122,8 @@ object SettingsDataScreen : SearchableSettings {
private fun getCreateBackupPref(): Preference.PreferenceItem.TextPreference {
val navigator = LocalNavigator.currentOrThrow
return Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_create_backup),
subtitle = stringResource(R.string.pref_create_backup_summ),
title = localize(MR.strings.pref_create_backup),
subtitle = localize(MR.strings.pref_create_backup_summ),
onClick = { navigator.push(CreateBackupScreen()) },
)
}
@@ -139,7 +138,7 @@ object SettingsDataScreen : SearchableSettings {
is InvalidRestore -> {
AlertDialog(
onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.invalid_backup_file)) },
title = { Text(text = localize(MR.strings.invalid_backup_file)) },
text = { Text(text = listOfNotNull(err.uri, err.message).joinToString("\n\n")) },
dismissButton = {
TextButton(
@@ -148,12 +147,12 @@ object SettingsDataScreen : SearchableSettings {
onDismissRequest()
},
) {
Text(text = stringResource(R.string.action_copy_to_clipboard))
Text(text = localize(MR.strings.action_copy_to_clipboard))
}
},
confirmButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_ok))
Text(text = localize(MR.strings.action_ok))
}
},
)
@@ -161,15 +160,15 @@ object SettingsDataScreen : SearchableSettings {
is MissingRestoreComponents -> {
AlertDialog(
onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.pref_restore_backup)) },
title = { Text(text = localize(MR.strings.pref_restore_backup)) },
text = {
Column(
modifier = Modifier.verticalScroll(rememberScrollState()),
) {
val msg = buildString {
append(stringResource(R.string.backup_restore_content_full))
append(localize(MR.strings.backup_restore_content_full))
if (err.sources.isNotEmpty()) {
append("\n\n").append(stringResource(R.string.backup_restore_missing_sources))
append("\n\n").append(localize(MR.strings.backup_restore_missing_sources))
err.sources.joinTo(
this,
separator = "\n- ",
@@ -177,7 +176,7 @@ object SettingsDataScreen : SearchableSettings {
)
}
if (err.trackers.isNotEmpty()) {
append("\n\n").append(stringResource(R.string.backup_restore_missing_trackers))
append("\n\n").append(localize(MR.strings.backup_restore_missing_trackers))
err.trackers.joinTo(
this,
separator = "\n- ",
@@ -195,7 +194,7 @@ object SettingsDataScreen : SearchableSettings {
onDismissRequest()
},
) {
Text(text = stringResource(R.string.action_restore))
Text(text = localize(MR.strings.action_restore))
}
},
)
@@ -208,12 +207,12 @@ object SettingsDataScreen : SearchableSettings {
object : ActivityResultContracts.GetContent() {
override fun createIntent(context: Context, input: String): Intent {
val intent = super.createIntent(context, input)
return Intent.createChooser(intent, context.getString(R.string.file_select_backup))
return Intent.createChooser(intent, context.localize(MR.strings.file_select_backup))
}
},
) {
if (it == null) {
context.toast(R.string.file_null_uri_error)
context.toast(MR.strings.file_null_uri_error)
return@rememberLauncherForActivityResult
}
@@ -233,17 +232,17 @@ object SettingsDataScreen : SearchableSettings {
}
return Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_restore_backup),
subtitle = stringResource(R.string.pref_restore_backup_summ),
title = localize(MR.strings.pref_restore_backup),
subtitle = localize(MR.strings.pref_restore_backup_summ),
onClick = {
if (!BackupRestoreJob.isRunning(context)) {
if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) {
context.toast(R.string.restore_miui_warning, Toast.LENGTH_LONG)
context.toast(MR.strings.restore_miui_warning, Toast.LENGTH_LONG)
}
// no need to catch because it's wrapped with a chooser
chooseBackup.launch("*/*")
} else {
context.toast(R.string.restore_in_progress)
context.toast(MR.strings.restore_in_progress)
}
},
)
@@ -260,31 +259,31 @@ object SettingsDataScreen : SearchableSettings {
val cacheReadableSize = remember(cacheReadableSizeSema) { chapterCache.readableSize }
return Preference.PreferenceGroup(
title = stringResource(R.string.label_data),
title = localize(MR.strings.label_data),
preferenceItems = listOf(
getStorageInfoPref(cacheReadableSize),
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_clear_chapter_cache),
subtitle = stringResource(R.string.used_cache, cacheReadableSize),
title = localize(MR.strings.pref_clear_chapter_cache),
subtitle = localize(MR.strings.used_cache, cacheReadableSize),
onClick = {
scope.launchNonCancellable {
try {
val deletedFiles = chapterCache.clear()
withUIContext {
context.toast(context.getString(R.string.cache_deleted, deletedFiles))
context.toast(context.localize(MR.strings.cache_deleted, deletedFiles))
cacheReadableSizeSema++
}
} catch (e: Throwable) {
logcat(LogPriority.ERROR, e)
withUIContext { context.toast(R.string.cache_delete_error) }
withUIContext { context.toast(MR.strings.cache_delete_error) }
}
}
},
),
Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.autoClearChapterCache(),
title = stringResource(R.string.pref_auto_clear_chapter_cache),
title = localize(MR.strings.pref_auto_clear_chapter_cache),
),
),
)
@@ -303,10 +302,10 @@ object SettingsDataScreen : SearchableSettings {
}
return Preference.PreferenceItem.CustomPreference(
title = stringResource(R.string.pref_storage_usage),
title = localize(MR.strings.pref_storage_usage),
) {
BasePreferenceWidget(
title = stringResource(R.string.pref_storage_usage),
title = localize(MR.strings.pref_storage_usage),
subcomponent = {
// TODO: downloads, SD cards, bar representation?, i18n
Box(modifier = Modifier.padding(horizontal = PrefsHorizontalPadding)) {
@@ -4,7 +4,6 @@ import android.content.Intent
import android.os.Environment
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.collectAsState
@@ -14,19 +13,19 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.util.fastMap
import androidx.core.net.toUri
import com.hippo.unifile.UniFile
import eu.kanade.presentation.category.visualName
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.widget.TriStateListDialog
import eu.kanade.tachiyomi.R
import kotlinx.coroutines.runBlocking
import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.model.Category
import tachiyomi.domain.download.service.DownloadPreferences
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.i18n.localizePlural
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -36,8 +35,7 @@ object SettingsDownloadScreen : SearchableSettings {
@ReadOnlyComposable
@Composable
@StringRes
override fun getTitleRes() = R.string.pref_category_downloads
override fun getTitleRes() = MR.strings.pref_category_downloads
@Composable
override fun getPreferences(): List<Preference> {
@@ -49,16 +47,16 @@ object SettingsDownloadScreen : SearchableSettings {
getDownloadLocationPreference(downloadPreferences = downloadPreferences),
Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.downloadOnlyOverWifi(),
title = stringResource(R.string.connected_to_wifi),
title = localize(MR.strings.connected_to_wifi),
),
Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.saveChaptersAsCBZ(),
title = stringResource(R.string.save_chapter_as_cbz),
title = localize(MR.strings.save_chapter_as_cbz),
),
Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.splitTallImages(),
title = stringResource(R.string.split_tall_images),
subtitle = stringResource(R.string.split_tall_images_summary),
title = localize(MR.strings.split_tall_images),
subtitle = localize(MR.strings.split_tall_images_summary),
),
getDeleteChaptersGroup(
downloadPreferences = downloadPreferences,
@@ -99,15 +97,15 @@ object SettingsDownloadScreen : SearchableSettings {
return Preference.PreferenceItem.ListPreference(
pref = currentDirPref,
title = stringResource(R.string.pref_download_directory),
title = localize(MR.strings.pref_download_directory),
subtitleProvider = { value, _ ->
remember(value) {
UniFile.fromUri(context, value.toUri())?.filePath
} ?: stringResource(R.string.invalid_location, value)
} ?: localize(MR.strings.invalid_location, value)
},
entries = mapOf(
defaultDirPair,
customDirEntryKey to stringResource(R.string.custom_dir),
customDirEntryKey to localize(MR.strings.custom_dir),
),
onValueChanged = {
val default = it == defaultDirPair.first
@@ -121,7 +119,7 @@ object SettingsDownloadScreen : SearchableSettings {
@Composable
private fun rememberDefaultDownloadDir(): Pair<String, String> {
val appName = stringResource(R.string.app_name)
val appName = localize(MR.strings.app_name)
return remember {
val file = UniFile.fromFile(
File(
@@ -139,27 +137,27 @@ object SettingsDownloadScreen : SearchableSettings {
categories: List<Category>,
): Preference.PreferenceGroup {
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_delete_chapters),
title = localize(MR.strings.pref_category_delete_chapters),
preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.removeAfterMarkedAsRead(),
title = stringResource(R.string.pref_remove_after_marked_as_read),
title = localize(MR.strings.pref_remove_after_marked_as_read),
),
Preference.PreferenceItem.ListPreference(
pref = downloadPreferences.removeAfterReadSlots(),
title = stringResource(R.string.pref_remove_after_read),
title = localize(MR.strings.pref_remove_after_read),
entries = mapOf(
-1 to stringResource(R.string.disabled),
0 to stringResource(R.string.last_read_chapter),
1 to stringResource(R.string.second_to_last),
2 to stringResource(R.string.third_to_last),
3 to stringResource(R.string.fourth_to_last),
4 to stringResource(R.string.fifth_to_last),
-1 to localize(MR.strings.disabled),
0 to localize(MR.strings.last_read_chapter),
1 to localize(MR.strings.second_to_last),
2 to localize(MR.strings.third_to_last),
3 to localize(MR.strings.fourth_to_last),
4 to localize(MR.strings.fifth_to_last),
),
),
Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.removeBookmarkedChapters(),
title = stringResource(R.string.pref_remove_bookmarked_chapters),
title = localize(MR.strings.pref_remove_bookmarked_chapters),
),
getExcludedCategoriesPreference(
downloadPreferences = downloadPreferences,
@@ -176,7 +174,7 @@ object SettingsDownloadScreen : SearchableSettings {
): Preference.PreferenceItem.MultiSelectListPreference {
return Preference.PreferenceItem.MultiSelectListPreference(
pref = downloadPreferences.removeExcludeCategories(),
title = stringResource(R.string.pref_remove_exclude_categories),
title = localize(MR.strings.pref_remove_exclude_categories),
entries = categories().associate { it.id.toString() to it.visualName },
)
}
@@ -197,8 +195,8 @@ object SettingsDownloadScreen : SearchableSettings {
var showDialog by rememberSaveable { mutableStateOf(false) }
if (showDialog) {
TriStateListDialog(
title = stringResource(R.string.categories),
message = stringResource(R.string.pref_download_new_categories_details),
title = localize(MR.strings.categories),
message = localize(MR.strings.pref_download_new_categories_details),
items = allCategories,
initialChecked = included.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
initialInversed = excluded.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
@@ -213,14 +211,14 @@ object SettingsDownloadScreen : SearchableSettings {
}
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_auto_download),
title = localize(MR.strings.pref_category_auto_download),
preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference(
pref = downloadNewChaptersPref,
title = stringResource(R.string.pref_download_new),
title = localize(MR.strings.pref_download_new),
),
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.categories),
title = localize(MR.strings.categories),
subtitle = getCategoriesLabel(
allCategories = allCategories,
included = included,
@@ -238,20 +236,20 @@ object SettingsDownloadScreen : SearchableSettings {
downloadPreferences: DownloadPreferences,
): Preference.PreferenceGroup {
return Preference.PreferenceGroup(
title = stringResource(R.string.download_ahead),
title = localize(MR.strings.download_ahead),
preferenceItems = listOf(
Preference.PreferenceItem.ListPreference(
pref = downloadPreferences.autoDownloadWhileReading(),
title = stringResource(R.string.auto_download_while_reading),
title = localize(MR.strings.auto_download_while_reading),
entries = listOf(0, 2, 3, 5, 10).associateWith {
if (it == 0) {
stringResource(R.string.disabled)
localize(MR.strings.disabled)
} else {
pluralStringResource(id = R.plurals.next_unread_chapters, count = it, it)
localizePlural(MR.plurals.next_unread_chapters, count = it, it)
}
},
),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.download_ahead_info)),
Preference.PreferenceItem.InfoPreference(localize(MR.strings.download_ahead_info)),
),
)
}
@@ -1,6 +1,5 @@
package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.collectAsState
@@ -11,8 +10,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.util.fastMap
import androidx.core.content.ContextCompat
import cafe.adriel.voyager.navigator.LocalNavigator
@@ -21,7 +18,6 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.category.visualName
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.widget.TriStateListDialog
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.ui.category.CategoryScreen
import kotlinx.coroutines.launch
@@ -37,6 +33,9 @@ import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_HAS_U
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_COMPLETED
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_READ
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_OUTSIDE_RELEASE_PERIOD
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.i18n.localizePlural
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -45,8 +44,7 @@ object SettingsLibraryScreen : SearchableSettings {
@Composable
@ReadOnlyComposable
@StringRes
override fun getTitleRes() = R.string.pref_category_library
override fun getTitleRes() = MR.strings.pref_category_library
@Composable
override fun getPreferences(): List<Preference> {
@@ -77,16 +75,16 @@ object SettingsLibraryScreen : SearchableSettings {
// For default category
val ids = listOf(libraryPreferences.defaultCategory().defaultValue()) +
allCategories.fastMap { it.id.toInt() }
val labels = listOf(stringResource(R.string.default_category_summary)) +
val labels = listOf(localize(MR.strings.default_category_summary)) +
allCategories.fastMap { it.visualName(context) }
return Preference.PreferenceGroup(
title = stringResource(R.string.categories),
title = localize(MR.strings.categories),
preferenceItems = listOf(
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.action_edit_categories),
subtitle = pluralStringResource(
id = R.plurals.num_categories,
title = localize(MR.strings.action_edit_categories),
subtitle = localizePlural(
MR.plurals.num_categories,
count = userCategoriesCount,
userCategoriesCount,
),
@@ -94,13 +92,13 @@ object SettingsLibraryScreen : SearchableSettings {
),
Preference.PreferenceItem.ListPreference(
pref = libraryPreferences.defaultCategory(),
title = stringResource(R.string.default_category),
subtitle = selectedCategory?.visualName ?: stringResource(R.string.default_category_summary),
title = localize(MR.strings.default_category),
subtitle = selectedCategory?.visualName ?: localize(MR.strings.default_category_summary),
entries = ids.zip(labels).toMap(),
),
Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.categorizedDisplaySettings(),
title = stringResource(R.string.categorized_display_settings),
title = localize(MR.strings.categorized_display_settings),
onValueChanged = {
if (!it) {
scope.launch {
@@ -132,8 +130,8 @@ object SettingsLibraryScreen : SearchableSettings {
var showCategoriesDialog by rememberSaveable { mutableStateOf(false) }
if (showCategoriesDialog) {
TriStateListDialog(
title = stringResource(R.string.categories),
message = stringResource(R.string.pref_library_update_categories_details),
title = localize(MR.strings.categories),
message = localize(MR.strings.pref_library_update_categories_details),
items = allCategories,
initialChecked = included.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
initialInversed = excluded.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
@@ -148,18 +146,18 @@ object SettingsLibraryScreen : SearchableSettings {
}
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_library_update),
title = localize(MR.strings.pref_category_library_update),
preferenceItems = listOf(
Preference.PreferenceItem.ListPreference(
pref = autoUpdateIntervalPref,
title = stringResource(R.string.pref_library_update_interval),
title = localize(MR.strings.pref_library_update_interval),
entries = mapOf(
0 to stringResource(R.string.update_never),
12 to stringResource(R.string.update_12hour),
24 to stringResource(R.string.update_24hour),
48 to stringResource(R.string.update_48hour),
72 to stringResource(R.string.update_72hour),
168 to stringResource(R.string.update_weekly),
0 to localize(MR.strings.update_never),
12 to localize(MR.strings.update_12hour),
24 to localize(MR.strings.update_24hour),
48 to localize(MR.strings.update_48hour),
72 to localize(MR.strings.update_72hour),
168 to localize(MR.strings.update_weekly),
),
onValueChanged = {
LibraryUpdateJob.setupTask(context, it)
@@ -169,12 +167,12 @@ object SettingsLibraryScreen : SearchableSettings {
Preference.PreferenceItem.MultiSelectListPreference(
pref = libraryPreferences.autoUpdateDeviceRestrictions(),
enabled = autoUpdateInterval > 0,
title = stringResource(R.string.pref_library_update_restriction),
subtitle = stringResource(R.string.restrictions),
title = localize(MR.strings.pref_library_update_restriction),
subtitle = localize(MR.strings.restrictions),
entries = mapOf(
DEVICE_ONLY_ON_WIFI to stringResource(R.string.connected_to_wifi),
DEVICE_NETWORK_NOT_METERED to stringResource(R.string.network_not_metered),
DEVICE_CHARGING to stringResource(R.string.charging),
DEVICE_ONLY_ON_WIFI to localize(MR.strings.connected_to_wifi),
DEVICE_NETWORK_NOT_METERED to localize(MR.strings.network_not_metered),
DEVICE_CHARGING to localize(MR.strings.charging),
),
onValueChanged = {
// Post to event looper to allow the preference to be updated.
@@ -183,7 +181,7 @@ object SettingsLibraryScreen : SearchableSettings {
},
),
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.categories),
title = localize(MR.strings.categories),
subtitle = getCategoriesLabel(
allCategories = allCategories,
included = included,
@@ -193,22 +191,22 @@ object SettingsLibraryScreen : SearchableSettings {
),
Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.autoUpdateMetadata(),
title = stringResource(R.string.pref_library_update_refresh_metadata),
subtitle = stringResource(R.string.pref_library_update_refresh_metadata_summary),
title = localize(MR.strings.pref_library_update_refresh_metadata),
subtitle = localize(MR.strings.pref_library_update_refresh_metadata_summary),
),
Preference.PreferenceItem.MultiSelectListPreference(
pref = libraryPreferences.autoUpdateMangaRestrictions(),
title = stringResource(R.string.pref_library_update_manga_restriction),
title = localize(MR.strings.pref_library_update_manga_restriction),
entries = mapOf(
MANGA_HAS_UNREAD to stringResource(R.string.pref_update_only_completely_read),
MANGA_NON_READ to stringResource(R.string.pref_update_only_started),
MANGA_NON_COMPLETED to stringResource(R.string.pref_update_only_non_completed),
MANGA_OUTSIDE_RELEASE_PERIOD to stringResource(R.string.pref_update_only_in_release_period),
MANGA_HAS_UNREAD to localize(MR.strings.pref_update_only_completely_read),
MANGA_NON_READ to localize(MR.strings.pref_update_only_started),
MANGA_NON_COMPLETED to localize(MR.strings.pref_update_only_non_completed),
MANGA_OUTSIDE_RELEASE_PERIOD to localize(MR.strings.pref_update_only_in_release_period),
),
),
Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.newShowUpdatesCount(),
title = stringResource(R.string.pref_library_update_show_tab_badge),
title = localize(MR.strings.pref_library_update_show_tab_badge),
),
),
)
@@ -219,34 +217,34 @@ object SettingsLibraryScreen : SearchableSettings {
libraryPreferences: LibraryPreferences,
): Preference.PreferenceGroup {
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_chapter_swipe),
title = localize(MR.strings.pref_chapter_swipe),
preferenceItems = listOf(
Preference.PreferenceItem.ListPreference(
pref = libraryPreferences.swipeToStartAction(),
title = stringResource(R.string.pref_chapter_swipe_start),
title = localize(MR.strings.pref_chapter_swipe_start),
entries = mapOf(
LibraryPreferences.ChapterSwipeAction.Disabled to
stringResource(R.string.disabled),
localize(MR.strings.disabled),
LibraryPreferences.ChapterSwipeAction.ToggleBookmark to
stringResource(R.string.action_bookmark),
localize(MR.strings.action_bookmark),
LibraryPreferences.ChapterSwipeAction.ToggleRead to
stringResource(R.string.action_mark_as_read),
localize(MR.strings.action_mark_as_read),
LibraryPreferences.ChapterSwipeAction.Download to
stringResource(R.string.action_download),
localize(MR.strings.action_download),
),
),
Preference.PreferenceItem.ListPreference(
pref = libraryPreferences.swipeToEndAction(),
title = stringResource(R.string.pref_chapter_swipe_end),
title = localize(MR.strings.pref_chapter_swipe_end),
entries = mapOf(
LibraryPreferences.ChapterSwipeAction.Disabled to
stringResource(R.string.disabled),
localize(MR.strings.disabled),
LibraryPreferences.ChapterSwipeAction.ToggleBookmark to
stringResource(R.string.action_bookmark),
localize(MR.strings.action_bookmark),
LibraryPreferences.ChapterSwipeAction.ToggleRead to
stringResource(R.string.action_mark_as_read),
localize(MR.strings.action_mark_as_read),
LibraryPreferences.ChapterSwipeAction.Download to
stringResource(R.string.action_download),
localize(MR.strings.action_download),
),
),
),
@@ -1,6 +1,5 @@
package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.padding
@@ -10,7 +9,6 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ChromeReaderMode
import androidx.compose.material.icons.outlined.ChromeReaderMode
import androidx.compose.material.icons.outlined.Code
import androidx.compose.material.icons.outlined.CollectionsBookmark
import androidx.compose.material.icons.outlined.Explore
@@ -34,21 +32,22 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.graphics.ColorUtils
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.currentOrThrow
import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.more.settings.screen.about.AboutScreen
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.presentation.util.LocalBackPress
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.localize
import cafe.adriel.voyager.core.screen.Screen as VoyagerScreen
object SettingsMainScreen : Screen() {
@@ -85,13 +84,13 @@ object SettingsMainScreen : Screen() {
topBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(topBarState),
topBar = { scrollBehavior ->
AppBar(
title = stringResource(R.string.label_settings),
title = localize(MR.strings.label_settings),
navigateUp = backPress::invoke,
actions = {
AppBarActions(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_search),
title = localize(MR.strings.action_search),
icon = Icons.Outlined.Search,
onClick = { navigator.navigate(SettingsSearchScreen(), twoPane) },
),
@@ -148,7 +147,7 @@ object SettingsMainScreen : Screen() {
CompositionLocalProvider(LocalContentColor provides contentColor) {
TextPreferenceWidget(
modifier = modifier,
title = stringResource(item.titleRes),
title = localize(item.titleRes),
subtitle = item.formatSubtitle(),
icon = item.icon,
onPreferenceClick = { navigator.navigate(item.screen, twoPane) },
@@ -165,73 +164,72 @@ object SettingsMainScreen : Screen() {
}
private data class Item(
@StringRes val titleRes: Int,
@StringRes val subtitleRes: Int,
val formatSubtitle: @Composable () -> String = { stringResource(subtitleRes) },
val titleRes: StringResource,
val subtitleRes: StringResource? = null,
val formatSubtitle: @Composable () -> String? = { subtitleRes?.let { localize(it) } },
val icon: ImageVector,
val screen: VoyagerScreen,
)
private val items = listOf(
Item(
titleRes = R.string.pref_category_appearance,
subtitleRes = R.string.pref_appearance_summary,
titleRes = MR.strings.pref_category_appearance,
subtitleRes = MR.strings.pref_appearance_summary,
icon = Icons.Outlined.Palette,
screen = SettingsAppearanceScreen,
),
Item(
titleRes = R.string.pref_category_library,
subtitleRes = R.string.pref_library_summary,
titleRes = MR.strings.pref_category_library,
subtitleRes = MR.strings.pref_library_summary,
icon = Icons.Outlined.CollectionsBookmark,
screen = SettingsLibraryScreen,
),
Item(
titleRes = R.string.pref_category_reader,
subtitleRes = R.string.pref_reader_summary,
titleRes = MR.strings.pref_category_reader,
subtitleRes = MR.strings.pref_reader_summary,
icon = Icons.AutoMirrored.Outlined.ChromeReaderMode,
screen = SettingsReaderScreen,
),
Item(
titleRes = R.string.pref_category_downloads,
subtitleRes = R.string.pref_downloads_summary,
titleRes = MR.strings.pref_category_downloads,
subtitleRes = MR.strings.pref_downloads_summary,
icon = Icons.Outlined.GetApp,
screen = SettingsDownloadScreen,
),
Item(
titleRes = R.string.pref_category_tracking,
subtitleRes = R.string.pref_tracking_summary,
titleRes = MR.strings.pref_category_tracking,
subtitleRes = MR.strings.pref_tracking_summary,
icon = Icons.Outlined.Sync,
screen = SettingsTrackingScreen,
),
Item(
titleRes = R.string.browse,
subtitleRes = R.string.pref_browse_summary,
titleRes = MR.strings.browse,
subtitleRes = MR.strings.pref_browse_summary,
icon = Icons.Outlined.Explore,
screen = SettingsBrowseScreen,
),
Item(
titleRes = R.string.label_data_storage,
subtitleRes = R.string.pref_backup_summary,
titleRes = MR.strings.label_data_storage,
subtitleRes = MR.strings.pref_backup_summary,
icon = Icons.Outlined.Storage,
screen = SettingsDataScreen,
),
Item(
titleRes = R.string.pref_category_security,
subtitleRes = R.string.pref_security_summary,
titleRes = MR.strings.pref_category_security,
subtitleRes = MR.strings.pref_security_summary,
icon = Icons.Outlined.Security,
screen = SettingsSecurityScreen,
),
Item(
titleRes = R.string.pref_category_advanced,
subtitleRes = R.string.pref_advanced_summary,
titleRes = MR.strings.pref_category_advanced,
subtitleRes = MR.strings.pref_advanced_summary,
icon = Icons.Outlined.Code,
screen = SettingsAdvancedScreen,
),
Item(
titleRes = R.string.pref_category_about,
subtitleRes = 0,
titleRes = MR.strings.pref_category_about,
formatSubtitle = {
"${stringResource(R.string.app_name)} ${AboutScreen.getVersionName(withBuildDate = false)}"
"${localize(MR.strings.app_name)} ${AboutScreen.getVersionName(withBuildDate = false)}"
},
icon = Icons.Outlined.Info,
screen = AboutScreen,
@@ -1,18 +1,17 @@
package eu.kanade.presentation.more.settings.screen
import android.os.Build
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -22,8 +21,7 @@ object SettingsReaderScreen : SearchableSettings {
@ReadOnlyComposable
@Composable
@StringRes
override fun getTitleRes() = R.string.pref_category_reader
override fun getTitleRes() = MR.strings.pref_category_reader
@Composable
override fun getPreferences(): List<Preference> {
@@ -31,43 +29,43 @@ object SettingsReaderScreen : SearchableSettings {
return listOf(
Preference.PreferenceItem.ListPreference(
pref = readerPref.defaultReadingMode(),
title = stringResource(R.string.pref_viewer_type),
title = localize(MR.strings.pref_viewer_type),
entries = ReadingMode.entries.drop(1)
.associate { it.flagValue to stringResource(it.stringRes) },
.associate { it.flagValue to localize(it.stringRes) },
),
Preference.PreferenceItem.ListPreference(
pref = readerPref.doubleTapAnimSpeed(),
title = stringResource(R.string.pref_double_tap_anim_speed),
title = localize(MR.strings.pref_double_tap_anim_speed),
entries = mapOf(
1 to stringResource(R.string.double_tap_anim_speed_0),
500 to stringResource(R.string.double_tap_anim_speed_normal),
250 to stringResource(R.string.double_tap_anim_speed_fast),
1 to localize(MR.strings.double_tap_anim_speed_0),
500 to localize(MR.strings.double_tap_anim_speed_normal),
250 to localize(MR.strings.double_tap_anim_speed_fast),
),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPref.showReadingMode(),
title = stringResource(R.string.pref_show_reading_mode),
subtitle = stringResource(R.string.pref_show_reading_mode_summary),
title = localize(MR.strings.pref_show_reading_mode),
subtitle = localize(MR.strings.pref_show_reading_mode_summary),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPref.showNavigationOverlayOnStart(),
title = stringResource(R.string.pref_show_navigation_mode),
subtitle = stringResource(R.string.pref_show_navigation_mode_summary),
title = localize(MR.strings.pref_show_navigation_mode),
subtitle = localize(MR.strings.pref_show_navigation_mode_summary),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPref.trueColor(),
title = stringResource(R.string.pref_true_color),
subtitle = stringResource(R.string.pref_true_color_summary),
title = localize(MR.strings.pref_true_color),
subtitle = localize(MR.strings.pref_true_color_summary),
enabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O,
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPref.pageTransitions(),
title = stringResource(R.string.pref_page_transitions),
title = localize(MR.strings.pref_page_transitions),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPref.flashOnPageChange(),
title = stringResource(R.string.pref_flash_page),
subtitle = stringResource(R.string.pref_flash_page_summ),
title = localize(MR.strings.pref_flash_page),
subtitle = localize(MR.strings.pref_flash_page_summ),
),
getDisplayGroup(readerPreferences = readerPref),
getReadingGroup(readerPreferences = readerPref),
@@ -83,42 +81,42 @@ object SettingsReaderScreen : SearchableSettings {
val fullscreenPref = readerPreferences.fullscreen()
val fullscreen by fullscreenPref.collectAsState()
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_display),
title = localize(MR.strings.pref_category_display),
preferenceItems = listOf(
Preference.PreferenceItem.ListPreference(
pref = readerPreferences.defaultOrientationType(),
title = stringResource(R.string.pref_rotation_type),
title = localize(MR.strings.pref_rotation_type),
entries = ReaderOrientation.entries.drop(1)
.associate { it.flagValue to stringResource(it.stringRes) },
.associate { it.flagValue to localize(it.stringRes) },
),
Preference.PreferenceItem.ListPreference(
pref = readerPreferences.readerTheme(),
title = stringResource(R.string.pref_reader_theme),
title = localize(MR.strings.pref_reader_theme),
entries = mapOf(
1 to stringResource(R.string.black_background),
2 to stringResource(R.string.gray_background),
0 to stringResource(R.string.white_background),
3 to stringResource(R.string.automatic_background),
1 to localize(MR.strings.black_background),
2 to localize(MR.strings.gray_background),
0 to localize(MR.strings.white_background),
3 to localize(MR.strings.automatic_background),
),
),
Preference.PreferenceItem.SwitchPreference(
pref = fullscreenPref,
title = stringResource(R.string.pref_fullscreen),
title = localize(MR.strings.pref_fullscreen),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.cutoutShort(),
title = stringResource(R.string.pref_cutout_short),
title = localize(MR.strings.pref_cutout_short),
enabled = fullscreen &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P &&
LocalView.current.rootWindowInsets?.displayCutout != null, // has cutout
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.keepScreenOn(),
title = stringResource(R.string.pref_keep_screen_on),
title = localize(MR.strings.pref_keep_screen_on),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.showPageNumber(),
title = stringResource(R.string.pref_show_page_number),
title = localize(MR.strings.pref_show_page_number),
),
),
)
@@ -127,23 +125,23 @@ object SettingsReaderScreen : SearchableSettings {
@Composable
private fun getReadingGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup {
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_reading),
title = localize(MR.strings.pref_category_reading),
preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.skipRead(),
title = stringResource(R.string.pref_skip_read_chapters),
title = localize(MR.strings.pref_skip_read_chapters),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.skipFiltered(),
title = stringResource(R.string.pref_skip_filtered_chapters),
title = localize(MR.strings.pref_skip_filtered_chapters),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.skipDupe(),
title = stringResource(R.string.pref_skip_dupe_chapters),
title = localize(MR.strings.pref_skip_dupe_chapters),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.alwaysShowChapterTransition(),
title = stringResource(R.string.pref_always_show_chapter_transition),
title = localize(MR.strings.pref_always_show_chapter_transition),
),
),
)
@@ -162,57 +160,57 @@ object SettingsReaderScreen : SearchableSettings {
val rotateToFit by rotateToFitPref.collectAsState()
return Preference.PreferenceGroup(
title = stringResource(R.string.pager_viewer),
title = localize(MR.strings.pager_viewer),
preferenceItems = listOf(
Preference.PreferenceItem.ListPreference(
pref = navModePref,
title = stringResource(R.string.pref_viewer_nav),
title = localize(MR.strings.pref_viewer_nav),
entries = ReaderPreferences.TapZones
.mapIndexed { index, it -> index to stringResource(it) }
.mapIndexed { index, it -> index to localize(it) }
.toMap(),
),
Preference.PreferenceItem.ListPreference(
pref = readerPreferences.pagerNavInverted(),
title = stringResource(R.string.pref_read_with_tapping_inverted),
title = localize(MR.strings.pref_read_with_tapping_inverted),
entries = listOf(
ReaderPreferences.TappingInvertMode.NONE,
ReaderPreferences.TappingInvertMode.HORIZONTAL,
ReaderPreferences.TappingInvertMode.VERTICAL,
ReaderPreferences.TappingInvertMode.BOTH,
).associateWith { stringResource(it.titleResId) },
).associateWith { localize(it.titleRes) },
enabled = navMode != 5,
),
Preference.PreferenceItem.ListPreference(
pref = imageScaleTypePref,
title = stringResource(R.string.pref_image_scale_type),
title = localize(MR.strings.pref_image_scale_type),
entries = ReaderPreferences.ImageScaleType
.mapIndexed { index, it -> index + 1 to stringResource(it) }
.mapIndexed { index, it -> index + 1 to localize(it) }
.toMap(),
),
Preference.PreferenceItem.ListPreference(
pref = readerPreferences.zoomStart(),
title = stringResource(R.string.pref_zoom_start),
title = localize(MR.strings.pref_zoom_start),
entries = ReaderPreferences.ZoomStart
.mapIndexed { index, it -> index + 1 to stringResource(it) }
.mapIndexed { index, it -> index + 1 to localize(it) }
.toMap(),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.cropBorders(),
title = stringResource(R.string.pref_crop_borders),
title = localize(MR.strings.pref_crop_borders),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.landscapeZoom(),
title = stringResource(R.string.pref_landscape_zoom),
title = localize(MR.strings.pref_landscape_zoom),
enabled = imageScaleType == 1,
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.navigateToPan(),
title = stringResource(R.string.pref_navigate_pan),
title = localize(MR.strings.pref_navigate_pan),
enabled = navMode != 5,
),
Preference.PreferenceItem.SwitchPreference(
pref = dualPageSplitPref,
title = stringResource(R.string.pref_dual_page_split),
title = localize(MR.strings.pref_dual_page_split),
onValueChanged = {
rotateToFitPref.set(false)
true
@@ -220,13 +218,13 @@ object SettingsReaderScreen : SearchableSettings {
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.dualPageInvertPaged(),
title = stringResource(R.string.pref_dual_page_invert),
subtitle = stringResource(R.string.pref_dual_page_invert_summary),
title = localize(MR.strings.pref_dual_page_invert),
subtitle = localize(MR.strings.pref_dual_page_invert_summary),
enabled = dualPageSplit,
),
Preference.PreferenceItem.SwitchPreference(
pref = rotateToFitPref,
title = stringResource(R.string.pref_page_rotate),
title = localize(MR.strings.pref_page_rotate),
onValueChanged = {
dualPageSplitPref.set(false)
true
@@ -234,7 +232,7 @@ object SettingsReaderScreen : SearchableSettings {
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.dualPageRotateToFitInvert(),
title = stringResource(R.string.pref_page_rotate_invert),
title = localize(MR.strings.pref_page_rotate_invert),
enabled = rotateToFit,
),
),
@@ -254,29 +252,29 @@ object SettingsReaderScreen : SearchableSettings {
val webtoonSidePadding by webtoonSidePaddingPref.collectAsState()
return Preference.PreferenceGroup(
title = stringResource(R.string.webtoon_viewer),
title = localize(MR.strings.webtoon_viewer),
preferenceItems = listOf(
Preference.PreferenceItem.ListPreference(
pref = navModePref,
title = stringResource(R.string.pref_viewer_nav),
title = localize(MR.strings.pref_viewer_nav),
entries = ReaderPreferences.TapZones
.mapIndexed { index, it -> index to stringResource(it) }
.mapIndexed { index, it -> index to localize(it) }
.toMap(),
),
Preference.PreferenceItem.ListPreference(
pref = readerPreferences.webtoonNavInverted(),
title = stringResource(R.string.pref_read_with_tapping_inverted),
title = localize(MR.strings.pref_read_with_tapping_inverted),
entries = listOf(
ReaderPreferences.TappingInvertMode.NONE,
ReaderPreferences.TappingInvertMode.HORIZONTAL,
ReaderPreferences.TappingInvertMode.VERTICAL,
ReaderPreferences.TappingInvertMode.BOTH,
).associateWith { stringResource(it.titleResId) },
).associateWith { localize(it.titleRes) },
enabled = navMode != 5,
),
Preference.PreferenceItem.SliderPreference(
value = webtoonSidePadding,
title = stringResource(R.string.pref_webtoon_side_padding),
title = localize(MR.strings.pref_webtoon_side_padding),
subtitle = numberFormat.format(webtoonSidePadding / 100f),
min = ReaderPreferences.WEBTOON_PADDING_MIN,
max = ReaderPreferences.WEBTOON_PADDING_MAX,
@@ -287,31 +285,31 @@ object SettingsReaderScreen : SearchableSettings {
),
Preference.PreferenceItem.ListPreference(
pref = readerPreferences.readerHideThreshold(),
title = stringResource(R.string.pref_hide_threshold),
title = localize(MR.strings.pref_hide_threshold),
entries = mapOf(
ReaderPreferences.ReaderHideThreshold.HIGHEST to stringResource(R.string.pref_highest),
ReaderPreferences.ReaderHideThreshold.HIGH to stringResource(R.string.pref_high),
ReaderPreferences.ReaderHideThreshold.LOW to stringResource(R.string.pref_low),
ReaderPreferences.ReaderHideThreshold.LOWEST to stringResource(R.string.pref_lowest),
ReaderPreferences.ReaderHideThreshold.HIGHEST to localize(MR.strings.pref_highest),
ReaderPreferences.ReaderHideThreshold.HIGH to localize(MR.strings.pref_high),
ReaderPreferences.ReaderHideThreshold.LOW to localize(MR.strings.pref_low),
ReaderPreferences.ReaderHideThreshold.LOWEST to localize(MR.strings.pref_lowest),
),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.cropBordersWebtoon(),
title = stringResource(R.string.pref_crop_borders),
title = localize(MR.strings.pref_crop_borders),
),
Preference.PreferenceItem.SwitchPreference(
pref = dualPageSplitPref,
title = stringResource(R.string.pref_dual_page_split),
title = localize(MR.strings.pref_dual_page_split),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.dualPageInvertWebtoon(),
title = stringResource(R.string.pref_dual_page_invert),
subtitle = stringResource(R.string.pref_dual_page_invert_summary),
title = localize(MR.strings.pref_dual_page_invert),
subtitle = localize(MR.strings.pref_dual_page_invert_summary),
enabled = dualPageSplit,
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.webtoonDoubleTapZoomEnabled(),
title = stringResource(R.string.pref_double_tap_zoom),
title = localize(MR.strings.pref_double_tap_zoom),
enabled = true,
),
),
@@ -323,15 +321,15 @@ object SettingsReaderScreen : SearchableSettings {
val readWithVolumeKeysPref = readerPreferences.readWithVolumeKeys()
val readWithVolumeKeys by readWithVolumeKeysPref.collectAsState()
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_reader_navigation),
title = localize(MR.strings.pref_reader_navigation),
preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference(
pref = readWithVolumeKeysPref,
title = stringResource(R.string.pref_read_with_volume_keys),
title = localize(MR.strings.pref_read_with_volume_keys),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.readWithVolumeKeysInverted(),
title = stringResource(R.string.pref_read_with_volume_keys_inverted),
title = localize(MR.strings.pref_read_with_volume_keys_inverted),
enabled = readWithVolumeKeys,
),
),
@@ -341,16 +339,16 @@ object SettingsReaderScreen : SearchableSettings {
@Composable
private fun getActionsGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup {
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_reader_actions),
title = localize(MR.strings.pref_reader_actions),
preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.readWithLongTap(),
title = stringResource(R.string.pref_read_with_long_tap),
title = localize(MR.strings.pref_read_with_long_tap),
),
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.folderPerManga(),
title = stringResource(R.string.pref_create_folder_per_manga),
subtitle = stringResource(R.string.pref_create_folder_per_manga_summary),
title = localize(MR.strings.pref_create_folder_per_manga),
subtitle = localize(MR.strings.pref_create_folder_per_manga_summary),
),
),
)
@@ -41,7 +41,6 @@ import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue
@@ -53,8 +52,9 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.components.UpIcon
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.util.runOnEnterKeyPressed
import cafe.adriel.voyager.core.screen.Screen as VoyagerScreen
@@ -118,7 +118,7 @@ class SettingsSearchScreen : Screen() {
decorationBox = {
if (textFieldValue.text.isEmpty()) {
Text(
text = stringResource(R.string.action_search_settings),
text = localize(MR.strings.action_search_settings),
color = MaterialTheme.colorScheme.onSurfaceVariant,
style = MaterialTheme.typography.bodyLarge,
)
@@ -222,7 +222,7 @@ private fun SearchResult(
when {
it == null -> {}
it.isEmpty() -> {
EmptyScreen(stringResource(R.string.no_results_found))
EmptyScreen(localize(MR.strings.no_results_found))
}
else -> {
LazyColumn(
@@ -268,7 +268,7 @@ private fun SearchResult(
private fun getIndex() = settingScreens
.map { screen ->
SettingsData(
title = stringResource(screen.getTitleRes()),
title = localize(screen.getTitleRes()),
route = screen,
contents = screen.getPreferences(),
)
@@ -1,19 +1,19 @@
package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.fragment.app.FragmentActivity
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.authenticate
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.isAuthenticationSupported
import tachiyomi.core.i18n.localize
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.i18n.localizePlural
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -22,8 +22,7 @@ object SettingsSecurityScreen : SearchableSettings {
@ReadOnlyComposable
@Composable
@StringRes
override fun getTitleRes() = R.string.pref_category_security
override fun getTitleRes() = MR.strings.pref_category_security
@Composable
override fun getPreferences(): List<Preference> {
@@ -37,43 +36,43 @@ object SettingsSecurityScreen : SearchableSettings {
return listOf(
Preference.PreferenceItem.SwitchPreference(
pref = useAuthPref,
title = stringResource(R.string.lock_with_biometrics),
title = localize(MR.strings.lock_with_biometrics),
enabled = authSupported,
onValueChanged = {
(context as FragmentActivity).authenticate(
title = context.getString(R.string.lock_with_biometrics),
title = context.localize(MR.strings.lock_with_biometrics),
)
},
),
Preference.PreferenceItem.ListPreference(
pref = securityPreferences.lockAppAfter(),
title = stringResource(R.string.lock_when_idle),
title = localize(MR.strings.lock_when_idle),
enabled = authSupported && useAuth,
entries = LockAfterValues
.associateWith {
when (it) {
-1 -> stringResource(R.string.lock_never)
0 -> stringResource(R.string.lock_always)
else -> pluralStringResource(id = R.plurals.lock_after_mins, count = it, it)
-1 -> localize(MR.strings.lock_never)
0 -> localize(MR.strings.lock_always)
else -> localizePlural(MR.plurals.lock_after_mins, count = it, it)
}
},
onValueChanged = {
(context as FragmentActivity).authenticate(
title = context.getString(R.string.lock_when_idle),
title = context.localize(MR.strings.lock_when_idle),
)
},
),
Preference.PreferenceItem.SwitchPreference(
pref = securityPreferences.hideNotificationContent(),
title = stringResource(R.string.hide_notification_content),
title = localize(MR.strings.hide_notification_content),
),
Preference.PreferenceItem.ListPreference(
pref = securityPreferences.secureScreen(),
title = stringResource(R.string.secure_screen),
title = localize(MR.strings.secure_screen),
entries = SecurityPreferences.SecureScreenMode.entries
.associateWith { stringResource(it.titleResId) },
.associateWith { localize(it.titleRes) },
),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.secure_screen_summary)),
Preference.PreferenceItem.InfoPreference(localize(MR.strings.secure_screen_summary)),
)
}
}
@@ -1,7 +1,6 @@
package eu.kanade.presentation.more.settings.screen
import android.content.Context
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -13,7 +12,6 @@ import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
@@ -34,7 +32,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
@@ -42,9 +39,9 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import dev.icerock.moko.resources.StringResource
import eu.kanade.domain.track.service.TrackPreferences
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.EnhancedTracker
import eu.kanade.tachiyomi.data.track.Tracker
import eu.kanade.tachiyomi.data.track.TrackerManager
@@ -57,7 +54,9 @@ import eu.kanade.tachiyomi.util.system.toast
import tachiyomi.core.util.lang.launchIO
import tachiyomi.core.util.lang.withUIContext
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.localize
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -65,8 +64,7 @@ object SettingsTrackingScreen : SearchableSettings {
@ReadOnlyComposable
@Composable
@StringRes
override fun getTitleRes() = R.string.pref_category_tracking
override fun getTitleRes() = MR.strings.pref_category_tracking
@Composable
override fun RowScope.AppBarAction() {
@@ -74,7 +72,7 @@ object SettingsTrackingScreen : SearchableSettings {
IconButton(onClick = { uriHandler.openUri("https://tachiyomi.org/docs/guides/tracking") }) {
Icon(
imageVector = Icons.AutoMirrored.Outlined.HelpOutline,
contentDescription = stringResource(R.string.tracking_guide),
contentDescription = localize(MR.strings.tracking_guide),
)
}
}
@@ -111,10 +109,10 @@ object SettingsTrackingScreen : SearchableSettings {
val acceptedSources = (service as EnhancedTracker).getAcceptedSources()
sourceManager.getCatalogueSources().any { it::class.qualifiedName in acceptedSources }
}
var enhancedTrackerInfo = stringResource(R.string.enhanced_tracking_info)
var enhancedTrackerInfo = localize(MR.strings.enhanced_tracking_info)
if (enhancedTrackers.second.isNotEmpty()) {
val missingSourcesInfo = stringResource(
R.string.enhanced_services_not_installed,
val missingSourcesInfo = localize(
MR.strings.enhanced_services_not_installed,
enhancedTrackers.second.joinToString { it.name },
)
enhancedTrackerInfo += "\n\n$missingSourcesInfo"
@@ -123,10 +121,10 @@ object SettingsTrackingScreen : SearchableSettings {
return listOf(
Preference.PreferenceItem.SwitchPreference(
pref = trackPreferences.autoUpdateTrack(),
title = stringResource(R.string.pref_auto_update_manga_sync),
title = localize(MR.strings.pref_auto_update_manga_sync),
),
Preference.PreferenceGroup(
title = stringResource(R.string.services),
title = localize(MR.strings.services),
preferenceItems = listOf(
Preference.PreferenceItem.TrackerPreference(
title = trackerManager.myAnimeList.name,
@@ -143,13 +141,13 @@ object SettingsTrackingScreen : SearchableSettings {
Preference.PreferenceItem.TrackerPreference(
title = trackerManager.kitsu.name,
tracker = trackerManager.kitsu,
login = { dialog = LoginDialog(trackerManager.kitsu, R.string.email) },
login = { dialog = LoginDialog(trackerManager.kitsu, MR.strings.email) },
logout = { dialog = LogoutDialog(trackerManager.kitsu) },
),
Preference.PreferenceItem.TrackerPreference(
title = trackerManager.mangaUpdates.name,
tracker = trackerManager.mangaUpdates,
login = { dialog = LoginDialog(trackerManager.mangaUpdates, R.string.username) },
login = { dialog = LoginDialog(trackerManager.mangaUpdates, MR.strings.username) },
logout = { dialog = LogoutDialog(trackerManager.mangaUpdates) },
),
Preference.PreferenceItem.TrackerPreference(
@@ -164,11 +162,11 @@ object SettingsTrackingScreen : SearchableSettings {
login = { context.openInBrowser(BangumiApi.authUrl(), forceDefaultBrowser = true) },
logout = { dialog = LogoutDialog(trackerManager.bangumi) },
),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.tracking_info)),
Preference.PreferenceItem.InfoPreference(localize(MR.strings.tracking_info)),
),
),
Preference.PreferenceGroup(
title = stringResource(R.string.enhanced_services),
title = localize(MR.strings.enhanced_services),
preferenceItems = enhancedTrackers.first
.map { service ->
Preference.PreferenceItem.TrackerPreference(
@@ -185,7 +183,7 @@ object SettingsTrackingScreen : SearchableSettings {
@Composable
private fun TrackingLoginDialog(
tracker: Tracker,
@StringRes uNameStringRes: Int,
uNameStringRes: StringResource,
onDismissRequest: () -> Unit,
) {
val context = LocalContext.current
@@ -201,13 +199,13 @@ object SettingsTrackingScreen : SearchableSettings {
title = {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = stringResource(R.string.login_title, tracker.name),
text = localize(MR.strings.login_title, tracker.name),
modifier = Modifier.weight(1f),
)
IconButton(onClick = onDismissRequest) {
Icon(
imageVector = Icons.Outlined.Close,
contentDescription = stringResource(R.string.action_close),
contentDescription = localize(MR.strings.action_close),
)
}
}
@@ -218,7 +216,7 @@ object SettingsTrackingScreen : SearchableSettings {
modifier = Modifier.fillMaxWidth(),
value = username,
onValueChange = { username = it },
label = { Text(text = stringResource(uNameStringRes)) },
label = { Text(text = localize(uNameStringRes)) },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
singleLine = true,
isError = inputError && !processing,
@@ -229,7 +227,7 @@ object SettingsTrackingScreen : SearchableSettings {
modifier = Modifier.fillMaxWidth(),
value = password,
onValueChange = { password = it },
label = { Text(text = stringResource(R.string.password)) },
label = { Text(text = localize(MR.strings.password)) },
trailingIcon = {
IconButton(onClick = { hidePassword = !hidePassword }) {
Icon(
@@ -275,8 +273,8 @@ object SettingsTrackingScreen : SearchableSettings {
}
},
) {
val id = if (processing) R.string.loading else R.string.login
Text(text = stringResource(id))
val id = if (processing) MR.strings.loading else MR.strings.login
Text(text = localize(id))
}
},
)
@@ -290,7 +288,7 @@ object SettingsTrackingScreen : SearchableSettings {
): Boolean {
return try {
tracker.login(username, password)
withUIContext { context.toast(R.string.login_success) }
withUIContext { context.toast(MR.strings.login_success) }
true
} catch (e: Throwable) {
tracker.logout()
@@ -309,7 +307,7 @@ object SettingsTrackingScreen : SearchableSettings {
onDismissRequest = onDismissRequest,
title = {
Text(
text = stringResource(R.string.logout_title, tracker.name),
text = localize(MR.strings.logout_title, tracker.name),
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth(),
)
@@ -320,21 +318,21 @@ object SettingsTrackingScreen : SearchableSettings {
modifier = Modifier.weight(1f),
onClick = onDismissRequest,
) {
Text(text = stringResource(R.string.action_cancel))
Text(text = localize(MR.strings.action_cancel))
}
Button(
modifier = Modifier.weight(1f),
onClick = {
tracker.logout()
onDismissRequest()
context.toast(R.string.logout_success)
context.toast(MR.strings.logout_success)
},
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.error,
contentColor = MaterialTheme.colorScheme.onError,
),
) {
Text(text = stringResource(R.string.logout))
Text(text = localize(MR.strings.logout))
}
}
},
@@ -344,7 +342,7 @@ object SettingsTrackingScreen : SearchableSettings {
private data class LoginDialog(
val tracker: Tracker,
@StringRes val uNameStringRes: Int,
val uNameStringRes: StringResource,
)
private data class LogoutDialog(
@@ -19,7 +19,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
@@ -30,7 +29,6 @@ import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.presentation.util.LocalBackPress
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.updater.AppUpdateChecker
import eu.kanade.tachiyomi.data.updater.RELEASE_URL
import eu.kanade.tachiyomi.ui.more.NewUpdateScreen
@@ -44,9 +42,11 @@ import tachiyomi.core.util.lang.withIOContext
import tachiyomi.core.util.lang.withUIContext
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.release.interactor.GetApplicationRelease
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LinkIcon
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.icons.CustomIcons
import tachiyomi.presentation.core.icons.Discord
import tachiyomi.presentation.core.icons.Facebook
@@ -74,7 +74,7 @@ object AboutScreen : Screen() {
Scaffold(
topBar = { scrollBehavior ->
AppBar(
title = stringResource(R.string.pref_category_about),
title = localize(MR.strings.pref_category_about),
navigateUp = if (handleBack != null) handleBack::invoke else null,
scrollBehavior = scrollBehavior,
)
@@ -89,7 +89,7 @@ object AboutScreen : Screen() {
item {
TextPreferenceWidget(
title = stringResource(R.string.version),
title = localize(MR.strings.version),
subtitle = getVersionName(withBuildDate = true),
onPreferenceClick = {
val deviceInfo = CrashLogUtil(context).getDebugInfo()
@@ -101,7 +101,7 @@ object AboutScreen : Screen() {
if (BuildConfig.INCLUDE_UPDATER) {
item {
TextPreferenceWidget(
title = stringResource(R.string.check_for_updates),
title = localize(MR.strings.check_for_updates),
widget = {
AnimatedVisibility(visible = isCheckingUpdates) {
CircularProgressIndicator(
@@ -140,7 +140,7 @@ object AboutScreen : Screen() {
if (!BuildConfig.DEBUG) {
item {
TextPreferenceWidget(
title = stringResource(R.string.whats_new),
title = localize(MR.strings.whats_new),
onPreferenceClick = { uriHandler.openUri(RELEASE_URL) },
)
}
@@ -148,21 +148,21 @@ object AboutScreen : Screen() {
item {
TextPreferenceWidget(
title = stringResource(R.string.help_translate),
title = localize(MR.strings.help_translate),
onPreferenceClick = { uriHandler.openUri("https://tachiyomi.org/docs/contribute#translation") },
)
}
item {
TextPreferenceWidget(
title = stringResource(R.string.licenses),
title = localize(MR.strings.licenses),
onPreferenceClick = { navigator.push(OpenSourceLicensesScreen()) },
)
}
item {
TextPreferenceWidget(
title = stringResource(R.string.privacy_policy),
title = localize(MR.strings.privacy_policy),
onPreferenceClick = { uriHandler.openUri("https://tachiyomi.org/privacy/") },
)
}
@@ -175,7 +175,7 @@ object AboutScreen : Screen() {
horizontalArrangement = Arrangement.Center,
) {
LinkIcon(
label = stringResource(R.string.website),
label = localize(MR.strings.website),
icon = Icons.Outlined.Public,
url = "https://tachiyomi.org",
)
@@ -226,10 +226,10 @@ object AboutScreen : Screen() {
onAvailableUpdate(result)
}
is GetApplicationRelease.Result.NoNewUpdate -> {
context.toast(R.string.update_check_no_new_updates)
context.toast(MR.strings.update_check_no_new_updates)
}
is GetApplicationRelease.Result.OsTooOld -> {
context.toast(R.string.update_check_eol)
context.toast(MR.strings.update_check_eol)
}
else -> {}
}
@@ -9,7 +9,6 @@ import androidx.compose.material.icons.filled.Public
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.text.HtmlCompat
@@ -19,9 +18,10 @@ import com.google.android.material.textview.MaterialTextView
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.localize
class OpenSourceLibraryLicenseScreen(
private val name: String,
@@ -44,7 +44,7 @@ class OpenSourceLibraryLicenseScreen(
AppBarActions(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.website),
title = localize(MR.strings.website),
icon = Icons.Default.Public,
onClick = { uriHandler.openUri(website) },
),
@@ -4,7 +4,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import com.mikepenz.aboutlibraries.ui.compose.LibrariesContainer
@@ -12,8 +11,9 @@ import com.mikepenz.aboutlibraries.ui.compose.LibraryDefaults
import com.mikepenz.aboutlibraries.ui.compose.util.htmlReadyLicenseContent
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.localize
class OpenSourceLicensesScreen : Screen() {
@@ -23,7 +23,7 @@ class OpenSourceLicensesScreen : Screen() {
Scaffold(
topBar = { scrollBehavior ->
AppBar(
title = stringResource(R.string.licenses),
title = localize(MR.strings.licenses),
navigateUp = navigator::pop,
scrollBehavior = scrollBehavior,
)
@@ -27,7 +27,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
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.compose.ui.util.fastMap
import cafe.adriel.voyager.core.model.StateScreenModel
@@ -39,7 +38,6 @@ import eu.kanade.presentation.browse.components.SourceIcon
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.collectLatest
@@ -51,7 +49,9 @@ import tachiyomi.data.Database
import tachiyomi.domain.source.interactor.GetSourcesWithNonLibraryManga
import tachiyomi.domain.source.model.Source
import tachiyomi.domain.source.model.SourceWithCount
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.LoadingScreen
import tachiyomi.presentation.core.util.selectedBackground
@@ -81,20 +81,20 @@ class ClearDatabaseScreen : Screen() {
model.removeMangaBySourceId()
model.clearSelection()
model.hideConfirmation()
context.toast(R.string.clear_database_completed)
context.toast(MR.strings.clear_database_completed)
}
},
) {
Text(text = stringResource(R.string.action_ok))
Text(text = localize(MR.strings.action_ok))
}
},
dismissButton = {
TextButton(onClick = model::hideConfirmation) {
Text(text = stringResource(R.string.action_cancel))
Text(text = localize(MR.strings.action_cancel))
}
},
text = {
Text(text = stringResource(R.string.clear_database_confirmation))
Text(text = localize(MR.strings.clear_database_confirmation))
},
)
}
@@ -102,19 +102,19 @@ class ClearDatabaseScreen : Screen() {
Scaffold(
topBar = { scrollBehavior ->
AppBar(
title = stringResource(R.string.pref_clear_database),
title = localize(MR.strings.pref_clear_database),
navigateUp = navigator::pop,
actions = {
if (s.items.isNotEmpty()) {
AppBarActions(
actions = persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_select_all),
title = localize(MR.strings.action_select_all),
icon = Icons.Outlined.SelectAll,
onClick = model::selectAll,
),
AppBar.Action(
title = stringResource(R.string.action_select_all),
title = localize(MR.strings.action_select_all),
icon = Icons.Outlined.FlipToBack,
onClick = model::invertSelection,
),
@@ -128,7 +128,7 @@ class ClearDatabaseScreen : Screen() {
) { contentPadding ->
if (s.items.isEmpty()) {
EmptyScreen(
message = stringResource(R.string.database_clean),
message = localize(MR.strings.database_clean),
modifier = Modifier.padding(contentPadding),
)
} else {
@@ -160,7 +160,7 @@ class ClearDatabaseScreen : Screen() {
enabled = s.selection.isNotEmpty(),
) {
Text(
text = stringResource(R.string.action_delete),
text = localize(MR.strings.action_delete),
color = MaterialTheme.colorScheme.onPrimary,
)
}
@@ -196,7 +196,7 @@ class ClearDatabaseScreen : Screen() {
text = source.visualName,
style = MaterialTheme.typography.bodyMedium,
)
Text(text = stringResource(R.string.clear_database_source_item_count, count))
Text(text = localize(MR.strings.clear_database_source_item_count, count))
}
Checkbox(
checked = isSelected,
@@ -22,7 +22,6 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.rememberScreenModel
@@ -30,7 +29,6 @@ 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.data.backup.BackupCreateFlags
import eu.kanade.tachiyomi.data.backup.BackupCreateJob
import eu.kanade.tachiyomi.data.backup.models.Backup
@@ -41,9 +39,11 @@ import kotlinx.collections.immutable.minus
import kotlinx.collections.immutable.plus
import kotlinx.collections.immutable.toPersistentSet
import kotlinx.coroutines.flow.update
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.localize
class CreateBackupScreen : Screen() {
@@ -71,7 +71,7 @@ class CreateBackupScreen : Screen() {
Scaffold(
topBar = {
AppBar(
title = stringResource(R.string.pref_create_backup),
title = localize(MR.strings.pref_create_backup),
navigateUp = navigator::pop,
scrollBehavior = it,
)
@@ -89,7 +89,7 @@ class CreateBackupScreen : Screen() {
) {
item {
LabeledCheckbox(
label = stringResource(R.string.manga),
label = localize(MR.strings.manga),
checked = true,
onCheckedChange = {},
enabled = false,
@@ -98,7 +98,7 @@ class CreateBackupScreen : Screen() {
BackupChoices.forEach { (k, v) ->
item {
LabeledCheckbox(
label = stringResource(v),
label = localize(v),
checked = state.flags.contains(k),
onCheckedChange = {
model.toggleFlag(k)
@@ -117,20 +117,20 @@ class CreateBackupScreen : Screen() {
onClick = {
if (!BackupCreateJob.isManualJobRunning(context)) {
if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) {
context.toast(R.string.restore_miui_warning, Toast.LENGTH_LONG)
context.toast(MR.strings.restore_miui_warning, Toast.LENGTH_LONG)
}
try {
chooseBackupDir.launch(Backup.getFilename())
} catch (e: ActivityNotFoundException) {
context.toast(R.string.file_picker_error)
context.toast(MR.strings.file_picker_error)
}
} else {
context.toast(R.string.backup_in_progress)
context.toast(MR.strings.backup_in_progress)
}
},
) {
Text(
text = stringResource(R.string.action_create),
text = localize(MR.strings.action_create),
color = MaterialTheme.colorScheme.onPrimary,
)
}
@@ -163,10 +163,10 @@ private class CreateBackupScreenModel : StateScreenModel<CreateBackupScreenModel
}
private val BackupChoices = mapOf(
BackupCreateFlags.BACKUP_CATEGORY to R.string.categories,
BackupCreateFlags.BACKUP_CHAPTER to R.string.chapters,
BackupCreateFlags.BACKUP_TRACK to R.string.track,
BackupCreateFlags.BACKUP_HISTORY to R.string.history,
BackupCreateFlags.BACKUP_APP_PREFS to R.string.app_settings,
BackupCreateFlags.BACKUP_SOURCE_PREFS to R.string.source_settings,
BackupCreateFlags.BACKUP_CATEGORY to MR.strings.categories,
BackupCreateFlags.BACKUP_CHAPTER to MR.strings.chapters,
BackupCreateFlags.BACKUP_TRACK to MR.strings.track,
BackupCreateFlags.BACKUP_HISTORY to MR.strings.history,
BackupCreateFlags.BACKUP_APP_PREFS to MR.strings.app_settings,
BackupCreateFlags.BACKUP_SOURCE_PREFS to MR.strings.source_settings,
)
@@ -10,7 +10,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.navigator.LocalNavigator
@@ -18,12 +17,13 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.models.Backup
import eu.kanade.tachiyomi.util.system.copyToClipboard
import kotlinx.collections.immutable.persistentListOf
import kotlinx.serialization.protobuf.schema.ProtoBufSchemaGenerator
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.localize
class BackupSchemaScreen : Screen() {
@@ -47,7 +47,7 @@ class BackupSchemaScreen : Screen() {
AppBarActions(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_copy_to_clipboard),
title = localize(MR.strings.action_copy_to_clipboard),
icon = Icons.Default.ContentCopy,
onClick = {
context.copyToClipboard(title, schema)
@@ -17,6 +17,7 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.WebViewUtil
import kotlinx.coroutines.guava.await
import tachiyomi.i18n.MR
class DebugInfoScreen : Screen() {
@@ -24,7 +25,7 @@ class DebugInfoScreen : Screen() {
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
PreferenceScaffold(
titleRes = R.string.pref_debug_info,
titleRes = MR.strings.pref_debug_info,
onBackPressed = navigator::pop,
itemsProvider = {
listOf(
@@ -15,7 +15,6 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEach
@@ -30,14 +29,15 @@ import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.Screen
import eu.kanade.presentation.util.ioCoroutineScope
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.system.workManager
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.util.plus
class WorkerInfoScreen : Screen() {
@@ -65,7 +65,7 @@ class WorkerInfoScreen : Screen() {
AppBarActions(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_copy_to_clipboard),
title = localize(MR.strings.action_copy_to_clipboard),
icon = Icons.Default.ContentCopy,
onClick = {
context.copyToClipboard(title, enqueued + finished + running)
@@ -36,17 +36,17 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import eu.kanade.domain.ui.model.AppTheme
import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.util.secondaryItemAlpha
@Composable
@@ -76,7 +76,7 @@ private fun AppThemesList(
) {
val appThemes = remember {
AppTheme.entries
.filterNot { it.titleResId == null || (it == AppTheme.MONET && !DeviceUtil.isDynamicColorAvailable) }
.filterNot { it.titleRes == null || (it == AppTheme.MONET && !DeviceUtil.isDynamicColorAvailable) }
}
LazyRow(
contentPadding = PaddingValues(horizontal = PrefsHorizontalPadding),
@@ -104,7 +104,7 @@ private fun AppThemesList(
Spacer(modifier = Modifier.height(8.dp))
Text(
text = stringResource(appTheme.titleResId!!),
text = localize(appTheme.titleRes!!),
modifier = Modifier
.fillMaxWidth()
.secondaryItemAlpha(),
@@ -167,7 +167,7 @@ fun AppThemePreviewItem(
if (selected) {
Icon(
imageVector = Icons.Filled.CheckCircle,
contentDescription = stringResource(R.string.selected),
contentDescription = localize(MR.strings.selected),
tint = MaterialTheme.colorScheme.primary,
)
}
@@ -19,11 +19,11 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.window.DialogProperties
import eu.kanade.tachiyomi.R
import kotlinx.coroutines.launch
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
@Composable
fun EditTextPreferenceWidget(
@@ -83,12 +83,12 @@ fun EditTextPreferenceWidget(
}
},
) {
Text(text = stringResource(R.string.action_ok))
Text(text = localize(MR.strings.action_ok))
}
},
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel))
Text(text = localize(MR.strings.action_cancel))
}
},
)
@@ -11,11 +11,11 @@ import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark
import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.util.secondaryItemAlpha
@Composable
@@ -45,7 +45,7 @@ internal fun InfoWidget(text: String) {
private fun InfoWidgetPreview() {
TachiyomiTheme {
Surface {
InfoWidget(text = stringResource(R.string.download_ahead_info))
InfoWidget(text = localize(MR.strings.download_ahead_info))
}
}
}
@@ -22,10 +22,10 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart
@@ -75,7 +75,7 @@ fun <T> ListPreferenceWidget(
},
confirmButton = {
TextButton(onClick = { isDialogShown = false }) {
Text(text = stringResource(R.string.action_cancel))
Text(text = localize(MR.strings.action_cancel))
}
},
)
@@ -10,11 +10,11 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.window.DialogProperties
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.R
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.i18n.localize
@Composable
fun MultiSelectListPreferenceWidget(
@@ -70,12 +70,12 @@ fun MultiSelectListPreferenceWidget(
isDialogShown = false
},
) {
Text(text = stringResource(R.string.action_ok))
Text(text = localize(MR.strings.action_ok))
}
},
dismissButton = {
TextButton(onClick = { isDialogShown = false }) {
Text(text = stringResource(R.string.action_cancel))
Text(text = localize(MR.strings.action_cancel))
}
},
)
@@ -15,12 +15,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.more.settings.LocalPreferenceHighlighted
import eu.kanade.presentation.track.components.TrackLogoIcon
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.Tracker
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
@Composable
fun TrackingPreferenceWidget(
@@ -55,7 +55,7 @@ fun TrackingPreferenceWidget(
.padding(4.dp)
.size(32.dp),
tint = Color(0xFF4CAF50),
contentDescription = stringResource(R.string.login_success),
contentDescription = localize(MR.strings.login_success),
)
}
}
@@ -27,9 +27,9 @@ import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.localize
import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart
@@ -102,11 +102,11 @@ fun <T> TriStateListDialog(
} else {
MaterialTheme.colorScheme.primary
},
contentDescription = stringResource(
contentDescription = localize(
when (state) {
State.UNCHECKED -> R.string.not_selected
State.CHECKED -> R.string.selected
State.INVERSED -> R.string.disabled
State.UNCHECKED -> MR.strings.not_selected
State.CHECKED -> MR.strings.selected
State.INVERSED -> MR.strings.disabled
},
),
)
@@ -130,7 +130,7 @@ fun <T> TriStateListDialog(
},
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel))
Text(text = localize(MR.strings.action_cancel))
}
},
confirmButton = {
@@ -145,7 +145,7 @@ fun <T> TriStateListDialog(
onValueChanged(included, excluded)
},
) {
Text(text = stringResource(R.string.action_ok))
Text(text = localize(MR.strings.action_ok))
}
},
)
@@ -13,14 +13,14 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.more.stats.components.StatsItem
import eu.kanade.presentation.more.stats.components.StatsOverviewItem
import eu.kanade.presentation.more.stats.components.StatsSection
import eu.kanade.presentation.more.stats.data.StatsData
import eu.kanade.presentation.util.toDurationString
import eu.kanade.tachiyomi.R
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.localize
import java.util.Locale
import kotlin.time.DurationUnit
import kotlin.time.toDuration
@@ -55,28 +55,28 @@ fun StatsScreenContent(
private fun OverviewSection(
data: StatsData.Overview,
) {
val none = stringResource(R.string.none)
val none = localize(MR.strings.none)
val context = LocalContext.current
val readDurationString = remember(data.totalReadDuration) {
data.totalReadDuration
.toDuration(DurationUnit.MILLISECONDS)
.toDurationString(context, fallback = none)
}
StatsSection(R.string.label_overview_section) {
StatsSection(MR.strings.label_overview_section) {
Row {
StatsOverviewItem(
title = data.libraryMangaCount.toString(),
subtitle = stringResource(R.string.in_library),
subtitle = localize(MR.strings.in_library),
icon = Icons.Outlined.CollectionsBookmark,
)
StatsOverviewItem(
title = data.completedMangaCount.toString(),
subtitle = stringResource(R.string.label_completed_titles),
subtitle = localize(MR.strings.label_completed_titles),
icon = Icons.Outlined.LocalLibrary,
)
StatsOverviewItem(
title = readDurationString,
subtitle = stringResource(R.string.label_read_duration),
subtitle = localize(MR.strings.label_read_duration),
icon = Icons.Outlined.Schedule,
)
}
@@ -87,19 +87,19 @@ private fun OverviewSection(
private fun TitlesStats(
data: StatsData.Titles,
) {
StatsSection(R.string.label_titles_section) {
StatsSection(MR.strings.label_titles_section) {
Row {
StatsItem(
data.globalUpdateItemCount.toString(),
stringResource(R.string.label_titles_in_global_update),
localize(MR.strings.label_titles_in_global_update),
)
StatsItem(
data.startedMangaCount.toString(),
stringResource(R.string.label_started),
localize(MR.strings.label_started),
)
StatsItem(
data.localMangaCount.toString(),
stringResource(R.string.label_local),
localize(MR.strings.label_local),
)
}
}
@@ -109,19 +109,19 @@ private fun TitlesStats(
private fun ChapterStats(
data: StatsData.Chapters,
) {
StatsSection(R.string.chapters) {
StatsSection(MR.strings.chapters) {
Row {
StatsItem(
data.totalChapterCount.toString(),
stringResource(R.string.label_total_chapters),
localize(MR.strings.label_total_chapters),
)
StatsItem(
data.readChapterCount.toString(),
stringResource(R.string.label_read_chapters),
localize(MR.strings.label_read_chapters),
)
StatsItem(
data.downloadCount.toString(),
stringResource(R.string.label_downloaded),
localize(MR.strings.label_downloaded),
)
}
}
@@ -131,7 +131,7 @@ private fun ChapterStats(
private fun TrackerStats(
data: StatsData.Trackers,
) {
val notApplicable = stringResource(R.string.not_applicable)
val notApplicable = localize(MR.strings.not_applicable)
val meanScoreStr = remember(data.trackedTitleCount, data.meanScore) {
if (data.trackedTitleCount > 0 && !data.meanScore.isNaN()) {
// All other numbers are localized in English
@@ -140,19 +140,19 @@ private fun TrackerStats(
notApplicable
}
}
StatsSection(R.string.label_tracker_section) {
StatsSection(MR.strings.label_tracker_section) {
Row {
StatsItem(
data.trackedTitleCount.toString(),
stringResource(R.string.label_tracked_titles),
localize(MR.strings.label_tracked_titles),
)
StatsItem(
meanScoreStr,
stringResource(R.string.label_mean_score),
localize(MR.strings.label_mean_score),
)
StatsItem(
data.trackerCount.toString(),
stringResource(R.string.label_used),
localize(MR.strings.label_used),
)
}
}
@@ -1,6 +1,5 @@
package eu.kanade.presentation.more.stats.components
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
@@ -9,17 +8,18 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import dev.icerock.moko.resources.StringResource
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.localize
@Composable
fun StatsSection(
@StringRes titleRes: Int,
titleRes: StringResource,
content: @Composable () -> Unit,
) {
Text(
modifier = Modifier.padding(horizontal = MaterialTheme.padding.extraLarge),
text = stringResource(titleRes),
text = localize(titleRes),
style = MaterialTheme.typography.titleSmall,
)
ElevatedCard(