Minor settings cleanup

- Fix dark mode setting title
- Enforce usages of translated strings for screen titles
- Use LocalUriHandler where applicable instead of Android context
This commit is contained in:
arkon 2022-10-15 11:58:24 -04:00
parent 890f1a3c7b
commit c2eaf1c86b
22 changed files with 384 additions and 333 deletions

View File

@ -369,7 +369,7 @@ private fun ExtensionItemActions(
IconButton(onClick = { onClickItemCancel(extension) }) { IconButton(onClick = { onClickItemCancel(extension) }) {
Icon( Icon(
imageVector = Icons.Default.Close, imageVector = Icons.Default.Close,
contentDescription = stringResource(id = R.string.action_cancel), contentDescription = stringResource(R.string.action_cancel),
) )
} }
} }

View File

@ -88,7 +88,7 @@ fun EmptyScreen(
actions.forEach { actions.forEach {
ActionButton( ActionButton(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
title = stringResource(id = it.stringResId), title = stringResource(it.stringResId),
icon = it.icon, icon = it.icon,
onClick = it.onClick, onClick = it.onClick,
) )

View File

@ -1,13 +1,15 @@
package eu.kanade.presentation.more.settings package eu.kanade.presentation.more.settings
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.Scaffold import eu.kanade.presentation.components.Scaffold
@Composable @Composable
fun PreferenceScaffold( fun PreferenceScaffold(
title: String, @StringRes titleRes: Int,
actions: @Composable RowScope.() -> Unit = {}, actions: @Composable RowScope.() -> Unit = {},
onBackPressed: () -> Unit = {}, onBackPressed: () -> Unit = {},
itemsProvider: @Composable () -> List<Preference>, itemsProvider: @Composable () -> List<Preference>,
@ -15,7 +17,7 @@ fun PreferenceScaffold(
Scaffold( Scaffold(
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
AppBar( AppBar(
title = title, title = stringResource(titleRes),
navigateUp = onBackPressed, navigateUp = onBackPressed,
actions = actions, actions = actions,
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,

View File

@ -42,6 +42,6 @@ fun getCategoriesLabel(
allExcluded -> stringResource(R.string.all) allExcluded -> stringResource(R.string.all)
else -> excludedCategories.joinToString { it.visualName(context) } else -> excludedCategories.joinToString { it.visualName(context) }
} }
return stringResource(id = R.string.include, includedItemsText) + "\n" + return stringResource(R.string.include, includedItemsText) + "\n" +
stringResource(id = R.string.exclude, excludedItemsText) stringResource(R.string.exclude, excludedItemsText)
} }

View File

@ -1,5 +1,6 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
@ -10,9 +11,11 @@ import eu.kanade.presentation.more.settings.PreferenceScaffold
import eu.kanade.presentation.util.LocalBackPress import eu.kanade.presentation.util.LocalBackPress
interface SearchableSettings : Screen { interface SearchableSettings : Screen {
@Composable @Composable
@ReadOnlyComposable @ReadOnlyComposable
fun getTitle(): String @StringRes
fun getTitleRes(): Int
@Composable @Composable
fun getPreferences(): List<Preference> fun getPreferences(): List<Preference>
@ -25,7 +28,7 @@ interface SearchableSettings : Screen {
override fun Content() { override fun Content() {
val handleBack = LocalBackPress.currentOrThrow val handleBack = LocalBackPress.currentOrThrow
PreferenceScaffold( PreferenceScaffold(
title = getTitle(), titleRes = getTitleRes(),
onBackPressed = handleBack::invoke, onBackPressed = handleBack::invoke,
actions = { AppBarAction() }, actions = { AppBarAction() },
itemsProvider = { getPreferences() }, itemsProvider = { getPreferences() },

View File

@ -6,6 +6,7 @@ import android.content.Intent
import android.provider.Settings import android.provider.Settings
import android.webkit.WebStorage import android.webkit.WebStorage
import android.webkit.WebView import android.webkit.WebView
import androidx.annotation.StringRes
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
@ -18,6 +19,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.core.net.toUri import androidx.core.net.toUri
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
@ -54,7 +56,6 @@ import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.isDevFlavor import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.util.system.isPackageInstalled import eu.kanade.tachiyomi.util.system.isPackageInstalled
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.openInBrowser
import eu.kanade.tachiyomi.util.system.powerManager import eu.kanade.tachiyomi.util.system.powerManager
import eu.kanade.tachiyomi.util.system.setDefaultSettings import eu.kanade.tachiyomi.util.system.setDefaultSettings
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
@ -67,7 +68,8 @@ import java.io.File
class SettingsAdvancedScreen : SearchableSettings { class SettingsAdvancedScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
override fun getTitle(): String = stringResource(id = R.string.pref_category_advanced) @StringRes
override fun getTitleRes() = R.string.pref_category_advanced
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -79,13 +81,13 @@ class SettingsAdvancedScreen : SearchableSettings {
return listOf( return listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = basePreferences.acraEnabled(), pref = basePreferences.acraEnabled(),
title = stringResource(id = R.string.pref_enable_acra), title = stringResource(R.string.pref_enable_acra),
subtitle = stringResource(id = R.string.pref_acra_summary), subtitle = stringResource(R.string.pref_acra_summary),
enabled = !isDevFlavor, enabled = !isDevFlavor,
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_dump_crash_logs), title = stringResource(R.string.pref_dump_crash_logs),
subtitle = stringResource(id = R.string.pref_dump_crash_logs_summary), subtitle = stringResource(R.string.pref_dump_crash_logs_summary),
onClick = { onClick = {
scope.launchNonCancellable { scope.launchNonCancellable {
CrashLogUtil(context).dumpLogs() CrashLogUtil(context).dumpLogs()
@ -94,8 +96,8 @@ class SettingsAdvancedScreen : SearchableSettings {
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = networkPreferences.verboseLogging(), pref = networkPreferences.verboseLogging(),
title = stringResource(id = R.string.pref_verbose_logging), title = stringResource(R.string.pref_verbose_logging),
subtitle = stringResource(id = R.string.pref_verbose_logging_summary), subtitle = stringResource(R.string.pref_verbose_logging_summary),
onValueChanged = { onValueChanged = {
context.toast(R.string.requires_app_restart) context.toast(R.string.requires_app_restart)
true true
@ -113,12 +115,14 @@ class SettingsAdvancedScreen : SearchableSettings {
@Composable @Composable
private fun getBackgroundActivityGroup(): Preference.PreferenceGroup { private fun getBackgroundActivityGroup(): Preference.PreferenceGroup {
val context = LocalContext.current val context = LocalContext.current
val uriHandler = LocalUriHandler.current
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.label_background_activity), title = stringResource(R.string.label_background_activity),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_disable_battery_optimization), title = stringResource(R.string.pref_disable_battery_optimization),
subtitle = stringResource(id = R.string.pref_disable_battery_optimization_summary), subtitle = stringResource(R.string.pref_disable_battery_optimization_summary),
onClick = { onClick = {
val packageName: String = context.packageName val packageName: String = context.packageName
if (!context.powerManager.isIgnoringBatteryOptimizations(packageName)) { if (!context.powerManager.isIgnoringBatteryOptimizations(packageName)) {
@ -140,8 +144,8 @@ class SettingsAdvancedScreen : SearchableSettings {
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = "Don't kill my app!", title = "Don't kill my app!",
subtitle = stringResource(id = R.string.about_dont_kill_my_app), subtitle = stringResource(R.string.about_dont_kill_my_app),
onClick = { context.openInBrowser("https://dontkillmyapp.com/") }, onClick = { uriHandler.openUri("https://dontkillmyapp.com/") },
), ),
), ),
) )
@ -159,11 +163,11 @@ class SettingsAdvancedScreen : SearchableSettings {
val readableSize = remember(readableSizeSema) { chapterCache.readableSize } val readableSize = remember(readableSizeSema) { chapterCache.readableSize }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.label_data), title = stringResource(R.string.label_data),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_clear_chapter_cache), title = stringResource(R.string.pref_clear_chapter_cache),
subtitle = stringResource(id = R.string.used_cache, readableSize), subtitle = stringResource(R.string.used_cache, readableSize),
onClick = { onClick = {
scope.launchNonCancellable { scope.launchNonCancellable {
try { try {
@ -181,11 +185,11 @@ class SettingsAdvancedScreen : SearchableSettings {
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.autoClearChapterCache(), pref = libraryPreferences.autoClearChapterCache(),
title = stringResource(id = R.string.pref_auto_clear_chapter_cache), title = stringResource(R.string.pref_auto_clear_chapter_cache),
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_clear_database), title = stringResource(R.string.pref_clear_database),
subtitle = stringResource(id = R.string.pref_clear_database_summary), subtitle = stringResource(R.string.pref_clear_database_summary),
onClick = { navigator.push(ClearDatabaseScreen()) }, onClick = { navigator.push(ClearDatabaseScreen()) },
), ),
), ),
@ -203,17 +207,17 @@ class SettingsAdvancedScreen : SearchableSettings {
val userAgent by userAgentPref.collectAsState() val userAgent by userAgentPref.collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.label_network), title = stringResource(R.string.label_network),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_clear_cookies), title = stringResource(R.string.pref_clear_cookies),
onClick = { onClick = {
networkHelper.cookieManager.removeAll() networkHelper.cookieManager.removeAll()
context.toast(R.string.cookies_cleared) context.toast(R.string.cookies_cleared)
}, },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_clear_webview_data), title = stringResource(R.string.pref_clear_webview_data),
onClick = { onClick = {
try { try {
WebView(context).run { WebView(context).run {
@ -234,9 +238,9 @@ class SettingsAdvancedScreen : SearchableSettings {
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = networkPreferences.dohProvider(), pref = networkPreferences.dohProvider(),
title = stringResource(id = R.string.pref_dns_over_https), title = stringResource(R.string.pref_dns_over_https),
entries = mapOf( entries = mapOf(
-1 to stringResource(id = R.string.disabled), -1 to stringResource(R.string.disabled),
PREF_DOH_CLOUDFLARE to "Cloudflare", PREF_DOH_CLOUDFLARE to "Cloudflare",
PREF_DOH_GOOGLE to "Google", PREF_DOH_GOOGLE to "Google",
PREF_DOH_ADGUARD to "AdGuard", PREF_DOH_ADGUARD to "AdGuard",
@ -256,7 +260,7 @@ class SettingsAdvancedScreen : SearchableSettings {
), ),
Preference.PreferenceItem.EditTextPreference( Preference.PreferenceItem.EditTextPreference(
pref = userAgentPref, pref = userAgentPref,
title = stringResource(id = R.string.pref_user_agent_string), title = stringResource(R.string.pref_user_agent_string),
onValueChanged = { onValueChanged = {
if (it.isBlank()) { if (it.isBlank()) {
context.toast(R.string.error_user_agent_string_blank) context.toast(R.string.error_user_agent_string_blank)
@ -267,7 +271,7 @@ class SettingsAdvancedScreen : SearchableSettings {
}, },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_reset_user_agent_string), title = stringResource(R.string.pref_reset_user_agent_string),
enabled = remember(userAgent) { userAgent != userAgentPref.defaultValue() }, enabled = remember(userAgent) { userAgent != userAgentPref.defaultValue() },
onClick = { onClick = {
userAgentPref.delete() userAgentPref.delete()
@ -285,21 +289,21 @@ class SettingsAdvancedScreen : SearchableSettings {
val trackManager = remember { Injekt.get<TrackManager>() } val trackManager = remember { Injekt.get<TrackManager>() }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.label_library), title = stringResource(R.string.label_library),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_refresh_library_covers), title = stringResource(R.string.pref_refresh_library_covers),
onClick = { LibraryUpdateService.start(context, target = LibraryUpdateService.Target.COVERS) }, onClick = { LibraryUpdateService.start(context, target = LibraryUpdateService.Target.COVERS) },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_refresh_library_tracking), title = stringResource(R.string.pref_refresh_library_tracking),
subtitle = stringResource(id = R.string.pref_refresh_library_tracking_summary), subtitle = stringResource(R.string.pref_refresh_library_tracking_summary),
enabled = trackManager.hasLoggedServices(), enabled = trackManager.hasLoggedServices(),
onClick = { LibraryUpdateService.start(context, target = LibraryUpdateService.Target.TRACKING) }, onClick = { LibraryUpdateService.start(context, target = LibraryUpdateService.Target.TRACKING) },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_reset_viewer_flags), title = stringResource(R.string.pref_reset_viewer_flags),
subtitle = stringResource(id = R.string.pref_reset_viewer_flags_summary), subtitle = stringResource(R.string.pref_reset_viewer_flags_summary),
onClick = { onClick = {
scope.launchNonCancellable { scope.launchNonCancellable {
val success = Injekt.get<MangaRepository>().resetViewerFlags() val success = Injekt.get<MangaRepository>().resetViewerFlags()
@ -323,36 +327,38 @@ class SettingsAdvancedScreen : SearchableSettings {
basePreferences: BasePreferences, basePreferences: BasePreferences,
): Preference.PreferenceGroup { ): Preference.PreferenceGroup {
val context = LocalContext.current val context = LocalContext.current
val uriHandler = LocalUriHandler.current
var shizukuMissing by rememberSaveable { mutableStateOf(false) } var shizukuMissing by rememberSaveable { mutableStateOf(false) }
if (shizukuMissing) { if (shizukuMissing) {
val dismiss = { shizukuMissing = false } val dismiss = { shizukuMissing = false }
AlertDialog( AlertDialog(
onDismissRequest = dismiss, onDismissRequest = dismiss,
title = { Text(text = stringResource(id = R.string.ext_installer_shizuku)) }, title = { Text(text = stringResource(R.string.ext_installer_shizuku)) },
text = { Text(text = stringResource(id = R.string.ext_installer_shizuku_unavailable_dialog)) }, text = { Text(text = stringResource(R.string.ext_installer_shizuku_unavailable_dialog)) },
dismissButton = { dismissButton = {
TextButton(onClick = dismiss) { TextButton(onClick = dismiss) {
Text(text = stringResource(id = android.R.string.cancel)) Text(text = stringResource(android.R.string.cancel))
} }
}, },
confirmButton = { confirmButton = {
TextButton( TextButton(
onClick = { onClick = {
dismiss() dismiss()
context.openInBrowser("https://shizuku.rikka.app/download") uriHandler.openUri("https://shizuku.rikka.app/download")
}, },
) { ) {
Text(text = stringResource(id = android.R.string.ok)) Text(text = stringResource(android.R.string.ok))
} }
}, },
) )
} }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.label_extensions), title = stringResource(R.string.label_extensions),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = basePreferences.extensionInstaller(), pref = basePreferences.extensionInstaller(),
title = stringResource(id = R.string.ext_installer_pref), title = stringResource(R.string.ext_installer_pref),
entries = PreferenceValues.ExtensionInstaller.values() entries = PreferenceValues.ExtensionInstaller.values()
.run { .run {
if (DeviceUtil.isMiui) { if (DeviceUtil.isMiui) {
@ -360,7 +366,7 @@ class SettingsAdvancedScreen : SearchableSettings {
} else { } else {
toList() toList()
} }
}.associateWith { stringResource(id = it.titleResId) }, }.associateWith { stringResource(it.titleResId) },
onValueChanged = { onValueChanged = {
if (it == PreferenceValues.ExtensionInstaller.SHIZUKU && if (it == PreferenceValues.ExtensionInstaller.SHIZUKU &&
!(context.isPackageInstalled("moe.shizuku.privileged.api") || Sui.isSui()) !(context.isPackageInstalled("moe.shizuku.privileged.api") || Sui.isSui())
@ -381,12 +387,12 @@ class SettingsAdvancedScreen : SearchableSettings {
val context = LocalContext.current val context = LocalContext.current
val uiPreferences = remember { Injekt.get<UiPreferences>() } val uiPreferences = remember { Injekt.get<UiPreferences>() }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.pref_category_display), title = stringResource(R.string.pref_category_display),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = uiPreferences.tabletUiMode(), pref = uiPreferences.tabletUiMode(),
title = stringResource(id = R.string.pref_tablet_ui_mode), title = stringResource(R.string.pref_tablet_ui_mode),
entries = TabletUiMode.values().associateWith { stringResource(id = it.titleResId) }, entries = TabletUiMode.values().associateWith { stringResource(it.titleResId) },
onValueChanged = { onValueChanged = {
context.toast(R.string.requires_app_restart) context.toast(R.string.requires_app_restart)
true true

View File

@ -3,6 +3,7 @@ package eu.kanade.presentation.more.settings.screen
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
@ -28,53 +29,67 @@ class SettingsAppearanceScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
override fun getTitle(): String = stringResource(id = R.string.pref_category_appearance) @StringRes
override fun getTitleRes() = R.string.pref_category_appearance
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
val context = LocalContext.current val context = LocalContext.current
val uiPreferences = remember { Injekt.get<UiPreferences>() } val uiPreferences = remember { Injekt.get<UiPreferences>() }
return listOf(
getThemeGroup(context = context, uiPreferences = uiPreferences),
getNavigationGroup(context = context, uiPreferences = uiPreferences),
getTimestampGroup(uiPreferences = uiPreferences),
)
}
@Composable
private fun getThemeGroup(
context: Context,
uiPreferences: UiPreferences,
): Preference.PreferenceGroup {
val themeModePref = uiPreferences.themeMode() val themeModePref = uiPreferences.themeMode()
val themeMode by themeModePref.collectAsState()
val appThemePref = uiPreferences.appTheme() val appThemePref = uiPreferences.appTheme()
val amoledPref = uiPreferences.themeDarkAmoled() val amoledPref = uiPreferences.themeDarkAmoled()
val themeMode by themeModePref.collectAsState()
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
merge(appThemePref.changes(), amoledPref.changes()) merge(appThemePref.changes(), amoledPref.changes())
.drop(2) .drop(2)
.collectLatest { (context as? Activity)?.let { ActivityCompat.recreate(it) } } .collectLatest { (context as? Activity)?.let { ActivityCompat.recreate(it) } }
} }
return listOf( return Preference.PreferenceGroup(
Preference.PreferenceItem.ListPreference( title = stringResource(R.string.pref_category_theme),
pref = themeModePref, preferenceItems = listOf(
title = stringResource(id = R.string.pref_category_theme), Preference.PreferenceItem.ListPreference(
subtitle = "%s", pref = themeModePref,
entries = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { title = stringResource(R.string.pref_theme_mode),
mapOf( subtitle = "%s",
ThemeMode.SYSTEM to stringResource(id = R.string.theme_system), entries = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ThemeMode.LIGHT to stringResource(id = R.string.theme_light), mapOf(
ThemeMode.DARK to stringResource(id = R.string.theme_dark), ThemeMode.SYSTEM to stringResource(R.string.theme_system),
) ThemeMode.LIGHT to stringResource(R.string.theme_light),
} else { ThemeMode.DARK to stringResource(R.string.theme_dark),
mapOf( )
ThemeMode.LIGHT to stringResource(id = R.string.theme_light), } else {
ThemeMode.DARK to stringResource(id = R.string.theme_dark), mapOf(
) ThemeMode.LIGHT to stringResource(R.string.theme_light),
}, ThemeMode.DARK to stringResource(R.string.theme_dark),
)
},
),
Preference.PreferenceItem.AppThemePreference(
title = stringResource(R.string.pref_app_theme),
pref = appThemePref,
),
Preference.PreferenceItem.SwitchPreference(
pref = amoledPref,
title = stringResource(R.string.pref_dark_theme_pure_black),
enabled = themeMode != ThemeMode.LIGHT,
),
), ),
Preference.PreferenceItem.AppThemePreference(
title = stringResource(id = R.string.pref_app_theme),
pref = appThemePref,
),
Preference.PreferenceItem.SwitchPreference(
pref = amoledPref,
title = stringResource(id = R.string.pref_dark_theme_pure_black),
enabled = themeMode != ThemeMode.LIGHT,
),
getNavigationGroup(context = context, uiPreferences = uiPreferences),
getTimestampGroup(uiPreferences = uiPreferences),
) )
} }
@ -84,17 +99,17 @@ class SettingsAppearanceScreen : SearchableSettings {
uiPreferences: UiPreferences, uiPreferences: UiPreferences,
): Preference.PreferenceGroup { ): Preference.PreferenceGroup {
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.pref_category_navigation), title = stringResource(R.string.pref_category_navigation),
enabled = remember(context) { context.isTablet() }, enabled = remember(context) { context.isTablet() },
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = uiPreferences.sideNavIconAlignment(), pref = uiPreferences.sideNavIconAlignment(),
title = stringResource(id = R.string.pref_side_nav_icon_alignment), title = stringResource(R.string.pref_side_nav_icon_alignment),
subtitle = "%s", subtitle = "%s",
entries = mapOf( entries = mapOf(
0 to stringResource(id = R.string.alignment_top), 0 to stringResource(R.string.alignment_top),
1 to stringResource(id = R.string.alignment_center), 1 to stringResource(R.string.alignment_center),
2 to stringResource(id = R.string.alignment_bottom), 2 to stringResource(R.string.alignment_bottom),
), ),
), ),
), ),
@ -105,26 +120,26 @@ class SettingsAppearanceScreen : SearchableSettings {
private fun getTimestampGroup(uiPreferences: UiPreferences): Preference.PreferenceGroup { private fun getTimestampGroup(uiPreferences: UiPreferences): Preference.PreferenceGroup {
val now = remember { Date().time } val now = remember { Date().time }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.pref_category_timestamps), title = stringResource(R.string.pref_category_timestamps),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = uiPreferences.relativeTime(), pref = uiPreferences.relativeTime(),
title = stringResource(id = R.string.pref_relative_format), title = stringResource(R.string.pref_relative_format),
subtitle = "%s", subtitle = "%s",
entries = mapOf( entries = mapOf(
0 to stringResource(id = R.string.off), 0 to stringResource(R.string.off),
2 to stringResource(id = R.string.pref_relative_time_short), 2 to stringResource(R.string.pref_relative_time_short),
7 to stringResource(id = R.string.pref_relative_time_long), 7 to stringResource(R.string.pref_relative_time_long),
), ),
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = uiPreferences.dateFormat(), pref = uiPreferences.dateFormat(),
title = stringResource(id = R.string.pref_date_format), title = stringResource(R.string.pref_date_format),
subtitle = "%s", subtitle = "%s",
entries = DateFormats entries = DateFormats
.associateWith { .associateWith {
val formattedDate = UiPreferences.dateFormat(it).format(now) val formattedDate = UiPreferences.dateFormat(it).format(now)
"${it.ifEmpty { stringResource(id = R.string.label_default) }} ($formattedDate)" "${it.ifEmpty { stringResource(R.string.label_default) }} ($formattedDate)"
}, },
), ),
), ),

View File

@ -6,6 +6,7 @@ import android.net.Uri
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@ -53,9 +54,11 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class SettingsBackupScreen : SearchableSettings { class SettingsBackupScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
override fun getTitle(): String = stringResource(id = R.string.label_backup) @StringRes
override fun getTitleRes() = R.string.label_backup
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -110,8 +113,8 @@ class SettingsBackupScreen : SearchableSettings {
} }
return Preference.PreferenceItem.TextPreference( return Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_create_backup), title = stringResource(R.string.pref_create_backup),
subtitle = stringResource(id = R.string.pref_create_backup_summ), subtitle = stringResource(R.string.pref_create_backup_summ),
onClick = { onClick = {
scope.launch { scope.launch {
if (!BackupCreatorJob.isManualJobRunning(context)) { if (!BackupCreatorJob.isManualJobRunning(context)) {
@ -135,7 +138,7 @@ class SettingsBackupScreen : SearchableSettings {
val flags = remember { mutableStateListOf<Int>() } val flags = remember { mutableStateListOf<Int>() }
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(id = R.string.backup_choice)) }, title = { Text(text = stringResource(R.string.backup_choice)) },
text = { text = {
val choices = remember { val choices = remember {
mapOf( mapOf(
@ -148,13 +151,13 @@ class SettingsBackupScreen : SearchableSettings {
Column { Column {
CreateBackupDialogItem( CreateBackupDialogItem(
isSelected = true, isSelected = true,
title = stringResource(id = R.string.manga), title = stringResource(R.string.manga),
) )
choices.forEach { (k, v) -> choices.forEach { (k, v) ->
val isSelected = flags.contains(k) val isSelected = flags.contains(k)
CreateBackupDialogItem( CreateBackupDialogItem(
isSelected = isSelected, isSelected = isSelected,
title = stringResource(id = v), title = stringResource(v),
modifier = Modifier.clickable { modifier = Modifier.clickable {
if (isSelected) { if (isSelected) {
flags.remove(k) flags.remove(k)
@ -168,7 +171,7 @@ class SettingsBackupScreen : SearchableSettings {
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = android.R.string.cancel)) Text(text = stringResource(android.R.string.cancel))
} }
}, },
confirmButton = { confirmButton = {
@ -178,7 +181,7 @@ class SettingsBackupScreen : SearchableSettings {
onConfirm(flag) onConfirm(flag)
}, },
) { ) {
Text(text = stringResource(id = android.R.string.ok)) Text(text = stringResource(android.R.string.ok))
} }
}, },
) )
@ -218,7 +221,7 @@ class SettingsBackupScreen : SearchableSettings {
val clipboard = LocalClipboardManager.current val clipboard = LocalClipboardManager.current
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(id = R.string.invalid_backup_file)) }, title = { Text(text = stringResource(R.string.invalid_backup_file)) },
text = { Text(text = err.message) }, text = { Text(text = err.message) },
dismissButton = { dismissButton = {
TextButton( TextButton(
@ -228,12 +231,12 @@ class SettingsBackupScreen : SearchableSettings {
onDismissRequest() onDismissRequest()
}, },
) { ) {
Text(text = stringResource(id = R.string.copy)) Text(text = stringResource(R.string.copy))
} }
}, },
confirmButton = { confirmButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = android.R.string.ok)) Text(text = stringResource(android.R.string.ok))
} }
}, },
) )
@ -241,9 +244,9 @@ class SettingsBackupScreen : SearchableSettings {
is MissingRestoreComponents -> { is MissingRestoreComponents -> {
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(id = R.string.pref_restore_backup)) }, title = { Text(text = stringResource(R.string.pref_restore_backup)) },
text = { text = {
var msg = stringResource(id = R.string.backup_restore_content_full) var msg = stringResource(R.string.backup_restore_content_full)
if (err.sources.isNotEmpty()) { if (err.sources.isNotEmpty()) {
msg += "\n\n${stringResource(R.string.backup_restore_missing_sources)}\n${err.sources.joinToString("\n") { "- $it" }}" msg += "\n\n${stringResource(R.string.backup_restore_missing_sources)}\n${err.sources.joinToString("\n") { "- $it" }}"
} }
@ -259,7 +262,7 @@ class SettingsBackupScreen : SearchableSettings {
onDismissRequest() onDismissRequest()
}, },
) { ) {
Text(text = stringResource(id = R.string.action_restore)) Text(text = stringResource(R.string.action_restore))
} }
}, },
) )
@ -287,8 +290,8 @@ class SettingsBackupScreen : SearchableSettings {
} }
return Preference.PreferenceItem.TextPreference( return Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_restore_backup), title = stringResource(R.string.pref_restore_backup),
subtitle = stringResource(id = R.string.pref_restore_backup_summ), subtitle = stringResource(R.string.pref_restore_backup_summ),
onClick = { onClick = {
if (!BackupRestoreService.isRunning(context)) { if (!BackupRestoreService.isRunning(context)) {
if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) { if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) {
@ -324,17 +327,17 @@ class SettingsBackupScreen : SearchableSettings {
} }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.pref_backup_service_category), title = stringResource(R.string.pref_backup_service_category),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = backupPreferences.backupInterval(), pref = backupPreferences.backupInterval(),
title = stringResource(id = R.string.pref_backup_interval), title = stringResource(R.string.pref_backup_interval),
entries = mapOf( entries = mapOf(
6 to stringResource(id = R.string.update_6hour), 6 to stringResource(R.string.update_6hour),
12 to stringResource(id = R.string.update_12hour), 12 to stringResource(R.string.update_12hour),
24 to stringResource(id = R.string.update_24hour), 24 to stringResource(R.string.update_24hour),
48 to stringResource(id = R.string.update_48hour), 48 to stringResource(R.string.update_48hour),
168 to stringResource(id = R.string.update_weekly), 168 to stringResource(R.string.update_weekly),
), ),
onValueChanged = { onValueChanged = {
BackupCreatorJob.setupTask(context, it) BackupCreatorJob.setupTask(context, it)
@ -342,7 +345,7 @@ class SettingsBackupScreen : SearchableSettings {
}, },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_backup_directory), title = stringResource(R.string.pref_backup_directory),
subtitle = remember(backupDir) { subtitle = remember(backupDir) {
UniFile.fromUri(context, backupDir.toUri()).filePath!! + "/automatic" UniFile.fromUri(context, backupDir.toUri()).filePath!! + "/automatic"
}, },
@ -350,10 +353,10 @@ class SettingsBackupScreen : SearchableSettings {
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = backupPreferences.numberOfBackups(), pref = backupPreferences.numberOfBackups(),
title = stringResource(id = R.string.pref_backup_slots), title = stringResource(R.string.pref_backup_slots),
entries = listOf(2, 3, 4, 5).associateWith { it.toString() }, entries = listOf(2, 3, 4, 5).associateWith { it.toString() },
), ),
Preference.infoPreference(stringResource(id = R.string.backup_info)), Preference.infoPreference(stringResource(R.string.backup_info)),
), ),
) )
} }

View File

@ -1,5 +1,6 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -16,9 +17,11 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class SettingsBrowseScreen : SearchableSettings { class SettingsBrowseScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
override fun getTitle(): String = stringResource(id = R.string.browse) @StringRes
override fun getTitleRes() = R.string.browse
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -27,21 +30,21 @@ class SettingsBrowseScreen : SearchableSettings {
val preferences = remember { Injekt.get<BasePreferences>() } val preferences = remember { Injekt.get<BasePreferences>() }
return listOf( return listOf(
Preference.PreferenceGroup( Preference.PreferenceGroup(
title = stringResource(id = R.string.label_sources), title = stringResource(R.string.label_sources),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = sourcePreferences.duplicatePinnedSources(), pref = sourcePreferences.duplicatePinnedSources(),
title = stringResource(id = R.string.pref_duplicate_pinned_sources), title = stringResource(R.string.pref_duplicate_pinned_sources),
subtitle = stringResource(id = R.string.pref_duplicate_pinned_sources_summary), subtitle = stringResource(R.string.pref_duplicate_pinned_sources_summary),
), ),
), ),
), ),
Preference.PreferenceGroup( Preference.PreferenceGroup(
title = stringResource(id = R.string.label_extensions), title = stringResource(R.string.label_extensions),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = preferences.automaticExtUpdates(), pref = preferences.automaticExtUpdates(),
title = stringResource(id = R.string.pref_enable_automatic_extension_updates), title = stringResource(R.string.pref_enable_automatic_extension_updates),
onValueChanged = { onValueChanged = {
ExtensionUpdateJob.setupTask(context, it) ExtensionUpdateJob.setupTask(context, it)
true true
@ -50,28 +53,28 @@ class SettingsBrowseScreen : SearchableSettings {
), ),
), ),
Preference.PreferenceGroup( Preference.PreferenceGroup(
title = stringResource(id = R.string.action_global_search), title = stringResource(R.string.action_global_search),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = sourcePreferences.searchPinnedSourcesOnly(), pref = sourcePreferences.searchPinnedSourcesOnly(),
title = stringResource(id = R.string.pref_search_pinned_sources_only), title = stringResource(R.string.pref_search_pinned_sources_only),
), ),
), ),
), ),
Preference.PreferenceGroup( Preference.PreferenceGroup(
title = stringResource(id = R.string.pref_category_nsfw_content), title = stringResource(R.string.pref_category_nsfw_content),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = sourcePreferences.showNsfwSource(), pref = sourcePreferences.showNsfwSource(),
title = stringResource(id = R.string.pref_show_nsfw_source), title = stringResource(R.string.pref_show_nsfw_source),
subtitle = stringResource(id = R.string.requires_app_restart), subtitle = stringResource(R.string.requires_app_restart),
onValueChanged = { onValueChanged = {
(context as FragmentActivity).authenticate( (context as FragmentActivity).authenticate(
title = context.getString(R.string.pref_category_nsfw_content), title = context.getString(R.string.pref_category_nsfw_content),
) )
}, },
), ),
Preference.infoPreference(stringResource(id = R.string.parental_controls_info)), Preference.infoPreference(stringResource(R.string.parental_controls_info)),
), ),
), ),
) )

View File

@ -4,6 +4,7 @@ import android.content.Intent
import android.os.Environment import android.os.Environment
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
@ -33,9 +34,11 @@ import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
class SettingsDownloadScreen : SearchableSettings { class SettingsDownloadScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
override fun getTitle(): String = stringResource(id = R.string.pref_category_downloads) @StringRes
override fun getTitleRes() = R.string.pref_category_downloads
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -47,16 +50,16 @@ class SettingsDownloadScreen : SearchableSettings {
getDownloadLocationPreference(downloadPreferences = downloadPreferences), getDownloadLocationPreference(downloadPreferences = downloadPreferences),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.downloadOnlyOverWifi(), pref = downloadPreferences.downloadOnlyOverWifi(),
title = stringResource(id = R.string.connected_to_wifi), title = stringResource(R.string.connected_to_wifi),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.saveChaptersAsCBZ(), pref = downloadPreferences.saveChaptersAsCBZ(),
title = stringResource(id = R.string.save_chapter_as_cbz), title = stringResource(R.string.save_chapter_as_cbz),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.splitTallImages(), pref = downloadPreferences.splitTallImages(),
title = stringResource(id = R.string.split_tall_images), title = stringResource(R.string.split_tall_images),
subtitle = stringResource(id = R.string.split_tall_images_summary), subtitle = stringResource(R.string.split_tall_images_summary),
), ),
getDeleteChaptersGroup( getDeleteChaptersGroup(
downloadPreferences = downloadPreferences, downloadPreferences = downloadPreferences,
@ -97,13 +100,13 @@ class SettingsDownloadScreen : SearchableSettings {
return Preference.PreferenceItem.ListPreference( return Preference.PreferenceItem.ListPreference(
pref = currentDirPref, pref = currentDirPref,
title = stringResource(id = R.string.pref_download_directory), title = stringResource(R.string.pref_download_directory),
subtitle = remember(currentDir) { subtitle = remember(currentDir) {
UniFile.fromUri(context, currentDir.toUri()).filePath!! UniFile.fromUri(context, currentDir.toUri()).filePath!!
}, },
entries = mapOf( entries = mapOf(
defaultDirPair, defaultDirPair,
customDirEntryKey to stringResource(id = R.string.custom_dir), customDirEntryKey to stringResource(R.string.custom_dir),
), ),
onValueChanged = { onValueChanged = {
val default = it == defaultDirPair.first val default = it == defaultDirPair.first
@ -117,7 +120,7 @@ class SettingsDownloadScreen : SearchableSettings {
@Composable @Composable
private fun rememberDefaultDownloadDir(): Pair<String, String> { private fun rememberDefaultDownloadDir(): Pair<String, String> {
val appName = stringResource(id = R.string.app_name) val appName = stringResource(R.string.app_name)
return remember { return remember {
val file = UniFile.fromFile( val file = UniFile.fromFile(
File( File(
@ -135,27 +138,27 @@ class SettingsDownloadScreen : SearchableSettings {
categories: List<Category>, categories: List<Category>,
): Preference.PreferenceGroup { ): Preference.PreferenceGroup {
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.pref_category_delete_chapters), title = stringResource(R.string.pref_category_delete_chapters),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.removeAfterMarkedAsRead(), pref = downloadPreferences.removeAfterMarkedAsRead(),
title = stringResource(id = R.string.pref_remove_after_marked_as_read), title = stringResource(R.string.pref_remove_after_marked_as_read),
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = downloadPreferences.removeAfterReadSlots(), pref = downloadPreferences.removeAfterReadSlots(),
title = stringResource(id = R.string.pref_remove_after_read), title = stringResource(R.string.pref_remove_after_read),
entries = mapOf( entries = mapOf(
-1 to stringResource(id = R.string.disabled), -1 to stringResource(R.string.disabled),
0 to stringResource(id = R.string.last_read_chapter), 0 to stringResource(R.string.last_read_chapter),
1 to stringResource(id = R.string.second_to_last), 1 to stringResource(R.string.second_to_last),
2 to stringResource(id = R.string.third_to_last), 2 to stringResource(R.string.third_to_last),
3 to stringResource(id = R.string.fourth_to_last), 3 to stringResource(R.string.fourth_to_last),
4 to stringResource(id = R.string.fifth_to_last), 4 to stringResource(R.string.fifth_to_last),
), ),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.removeBookmarkedChapters(), pref = downloadPreferences.removeBookmarkedChapters(),
title = stringResource(id = R.string.pref_remove_bookmarked_chapters), title = stringResource(R.string.pref_remove_bookmarked_chapters),
), ),
getExcludedCategoriesPreference( getExcludedCategoriesPreference(
downloadPreferences = downloadPreferences, downloadPreferences = downloadPreferences,
@ -170,7 +173,7 @@ class SettingsDownloadScreen : SearchableSettings {
downloadPreferences: DownloadPreferences, downloadPreferences: DownloadPreferences,
categories: () -> List<Category>, categories: () -> List<Category>,
): Preference.PreferenceItem.MultiSelectListPreference { ): Preference.PreferenceItem.MultiSelectListPreference {
val none = stringResource(id = R.string.none) val none = stringResource(R.string.none)
val pref = downloadPreferences.removeExcludeCategories() val pref = downloadPreferences.removeExcludeCategories()
val entries = categories().associate { it.id.toString() to it.visualName } val entries = categories().associate { it.id.toString() to it.visualName }
val subtitle by produceState(initialValue = "") { val subtitle by produceState(initialValue = "") {
@ -186,7 +189,7 @@ class SettingsDownloadScreen : SearchableSettings {
} }
return Preference.PreferenceItem.MultiSelectListPreference( return Preference.PreferenceItem.MultiSelectListPreference(
pref = pref, pref = pref,
title = stringResource(id = R.string.pref_remove_exclude_categories), title = stringResource(R.string.pref_remove_exclude_categories),
subtitle = subtitle, subtitle = subtitle,
entries = entries, entries = entries,
) )
@ -208,8 +211,8 @@ class SettingsDownloadScreen : SearchableSettings {
var showDialog by rememberSaveable { mutableStateOf(false) } var showDialog by rememberSaveable { mutableStateOf(false) }
if (showDialog) { if (showDialog) {
TriStateListDialog( TriStateListDialog(
title = stringResource(id = R.string.categories), title = stringResource(R.string.categories),
message = stringResource(id = R.string.pref_download_new_categories_details), message = stringResource(R.string.pref_download_new_categories_details),
items = allCategories, items = allCategories,
initialChecked = included.mapNotNull { id -> allCategories.find { it.id.toString() == id } }, initialChecked = included.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
initialInversed = excluded.mapNotNull { id -> allCategories.find { it.id.toString() == id } }, initialInversed = excluded.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
@ -224,14 +227,14 @@ class SettingsDownloadScreen : SearchableSettings {
} }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.pref_download_new), title = stringResource(R.string.pref_download_new),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadNewChaptersPref, pref = downloadNewChaptersPref,
title = stringResource(id = R.string.pref_download_new), title = stringResource(R.string.pref_download_new),
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.categories), title = stringResource(R.string.categories),
subtitle = getCategoriesLabel( subtitle = getCategoriesLabel(
allCategories = allCategories, allCategories = allCategories,
included = included, included = included,
@ -249,20 +252,20 @@ class SettingsDownloadScreen : SearchableSettings {
downloadPreferences: DownloadPreferences, downloadPreferences: DownloadPreferences,
): Preference.PreferenceGroup { ): Preference.PreferenceGroup {
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.download_ahead), title = stringResource(R.string.download_ahead),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = downloadPreferences.autoDownloadWhileReading(), pref = downloadPreferences.autoDownloadWhileReading(),
title = stringResource(id = R.string.auto_download_while_reading), title = stringResource(R.string.auto_download_while_reading),
entries = listOf(0, 2, 3, 5, 10).associateWith { entries = listOf(0, 2, 3, 5, 10).associateWith {
if (it == 0) { if (it == 0) {
stringResource(id = R.string.disabled) stringResource(R.string.disabled)
} else { } else {
pluralStringResource(id = R.plurals.next_unread_chapters, count = it, it) pluralStringResource(id = R.plurals.next_unread_chapters, count = it, it)
} }
}, },
), ),
Preference.infoPreference(stringResource(id = R.string.download_ahead_info)), Preference.infoPreference(stringResource(R.string.download_ahead_info)),
), ),
) )
} }

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import android.provider.Settings import android.provider.Settings
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
@ -21,9 +22,11 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class SettingsGeneralScreen : SearchableSettings { class SettingsGeneralScreen : SearchableSettings {
@Composable @Composable
@ReadOnlyComposable @ReadOnlyComposable
override fun getTitle(): String = stringResource(id = R.string.pref_category_general) @StringRes
override fun getTitleRes() = R.string.pref_category_general
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -33,14 +36,14 @@ class SettingsGeneralScreen : SearchableSettings {
add( add(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = libraryPrefs.showUpdatesNavBadge(), pref = libraryPrefs.showUpdatesNavBadge(),
title = stringResource(id = R.string.pref_library_update_show_tab_badge), title = stringResource(R.string.pref_library_update_show_tab_badge),
), ),
) )
add( add(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = prefs.confirmExit(), pref = prefs.confirmExit(),
title = stringResource(id = R.string.pref_confirm_exit), title = stringResource(R.string.pref_confirm_exit),
), ),
) )
@ -48,7 +51,7 @@ class SettingsGeneralScreen : SearchableSettings {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
add( add(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.pref_manage_notifications), title = stringResource(R.string.pref_manage_notifications),
onClick = { onClick = {
val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply { val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName) putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
@ -64,7 +67,7 @@ class SettingsGeneralScreen : SearchableSettings {
add( add(
Preference.PreferenceItem.BasicListPreference( Preference.PreferenceItem.BasicListPreference(
value = currentLanguage, value = currentLanguage,
title = stringResource(id = R.string.pref_app_language), title = stringResource(R.string.pref_app_language),
subtitle = "%s", subtitle = "%s",
entries = langs, entries = langs,
onValueChanged = { newValue -> onValueChanged = { newValue ->

View File

@ -1,6 +1,7 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import android.content.Context import android.content.Context
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@ -58,7 +59,8 @@ class SettingsLibraryScreen : SearchableSettings {
@Composable @Composable
@ReadOnlyComposable @ReadOnlyComposable
override fun getTitle(): String = stringResource(id = R.string.pref_category_library) @StringRes
override fun getTitleRes() = R.string.pref_category_library
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -123,14 +125,14 @@ class SettingsLibraryScreen : SearchableSettings {
// For default category // For default category
val ids = listOf(libraryPreferences.defaultCategory().defaultValue()) + val ids = listOf(libraryPreferences.defaultCategory().defaultValue()) +
allCategories.map { it.id.toInt() } allCategories.map { it.id.toInt() }
val labels = listOf(stringResource(id = R.string.default_category_summary)) + val labels = listOf(stringResource(R.string.default_category_summary)) +
allCategories.map { it.visualName(context) } allCategories.map { it.visualName(context) }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.categories), title = stringResource(R.string.categories),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.action_edit_categories), title = stringResource(R.string.action_edit_categories),
subtitle = pluralStringResource( subtitle = pluralStringResource(
id = R.plurals.num_categories, id = R.plurals.num_categories,
count = userCategoriesCount, count = userCategoriesCount,
@ -140,13 +142,13 @@ class SettingsLibraryScreen : SearchableSettings {
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = libraryPreferences.defaultCategory(), pref = libraryPreferences.defaultCategory(),
title = stringResource(id = R.string.default_category), title = stringResource(R.string.default_category),
subtitle = selectedCategory?.visualName ?: stringResource(id = R.string.default_category_summary), subtitle = selectedCategory?.visualName ?: stringResource(R.string.default_category_summary),
entries = ids.zip(labels).toMap(), entries = ids.zip(labels).toMap(),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.categorizedDisplaySettings(), pref = libraryPreferences.categorizedDisplaySettings(),
title = stringResource(id = R.string.categorized_display_settings), title = stringResource(R.string.categorized_display_settings),
onValueChanged = { onValueChanged = {
if (!it) { if (!it) {
scope.launch { scope.launch {
@ -176,34 +178,34 @@ class SettingsLibraryScreen : SearchableSettings {
val libraryUpdateInterval by libraryUpdateIntervalPref.collectAsState() val libraryUpdateInterval by libraryUpdateIntervalPref.collectAsState()
val deviceRestrictionEntries = mapOf( val deviceRestrictionEntries = mapOf(
DEVICE_ONLY_ON_WIFI to stringResource(id = R.string.connected_to_wifi), DEVICE_ONLY_ON_WIFI to stringResource(R.string.connected_to_wifi),
DEVICE_NETWORK_NOT_METERED to stringResource(id = R.string.network_not_metered), DEVICE_NETWORK_NOT_METERED to stringResource(R.string.network_not_metered),
DEVICE_CHARGING to stringResource(id = R.string.charging), DEVICE_CHARGING to stringResource(R.string.charging),
DEVICE_BATTERY_NOT_LOW to stringResource(id = R.string.battery_not_low), DEVICE_BATTERY_NOT_LOW to stringResource(R.string.battery_not_low),
) )
val deviceRestrictions = libraryUpdateDeviceRestrictionPref.collectAsState() val deviceRestrictions = libraryUpdateDeviceRestrictionPref.collectAsState()
.value .value
.sorted() .sorted()
.map { deviceRestrictionEntries.getOrElse(it) { it } } .map { deviceRestrictionEntries.getOrElse(it) { it } }
.let { if (it.isEmpty()) stringResource(id = R.string.none) else it.joinToString() } .let { if (it.isEmpty()) stringResource(R.string.none) else it.joinToString() }
val mangaRestrictionEntries = mapOf( val mangaRestrictionEntries = mapOf(
MANGA_HAS_UNREAD to stringResource(id = R.string.pref_update_only_completely_read), MANGA_HAS_UNREAD to stringResource(R.string.pref_update_only_completely_read),
MANGA_NON_READ to stringResource(id = R.string.pref_update_only_started), MANGA_NON_READ to stringResource(R.string.pref_update_only_started),
MANGA_NON_COMPLETED to stringResource(id = R.string.pref_update_only_non_completed), MANGA_NON_COMPLETED to stringResource(R.string.pref_update_only_non_completed),
) )
val mangaRestrictions = libraryUpdateMangaRestrictionPref.collectAsState() val mangaRestrictions = libraryUpdateMangaRestrictionPref.collectAsState()
.value .value
.map { mangaRestrictionEntries.getOrElse(it) { it } } .map { mangaRestrictionEntries.getOrElse(it) { it } }
.let { if (it.isEmpty()) stringResource(id = R.string.none) else it.joinToString() } .let { if (it.isEmpty()) stringResource(R.string.none) else it.joinToString() }
val included by libraryUpdateCategoriesPref.collectAsState() val included by libraryUpdateCategoriesPref.collectAsState()
val excluded by libraryUpdateCategoriesExcludePref.collectAsState() val excluded by libraryUpdateCategoriesExcludePref.collectAsState()
var showDialog by rememberSaveable { mutableStateOf(false) } var showDialog by rememberSaveable { mutableStateOf(false) }
if (showDialog) { if (showDialog) {
TriStateListDialog( TriStateListDialog(
title = stringResource(id = R.string.categories), title = stringResource(R.string.categories),
message = stringResource(id = R.string.pref_library_update_categories_details), message = stringResource(R.string.pref_library_update_categories_details),
items = allCategories, items = allCategories,
initialChecked = included.mapNotNull { id -> allCategories.find { it.id.toString() == id } }, initialChecked = included.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
initialInversed = excluded.mapNotNull { id -> allCategories.find { it.id.toString() == id } }, initialInversed = excluded.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
@ -217,19 +219,19 @@ class SettingsLibraryScreen : SearchableSettings {
) )
} }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.pref_category_library_update), title = stringResource(R.string.pref_category_library_update),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = libraryUpdateIntervalPref, pref = libraryUpdateIntervalPref,
title = stringResource(id = R.string.pref_library_update_interval), title = stringResource(R.string.pref_library_update_interval),
subtitle = "%s", subtitle = "%s",
entries = mapOf( entries = mapOf(
0 to stringResource(id = R.string.update_never), 0 to stringResource(R.string.update_never),
12 to stringResource(id = R.string.update_12hour), 12 to stringResource(R.string.update_12hour),
24 to stringResource(id = R.string.update_24hour), 24 to stringResource(R.string.update_24hour),
48 to stringResource(id = R.string.update_48hour), 48 to stringResource(R.string.update_48hour),
72 to stringResource(id = R.string.update_72hour), 72 to stringResource(R.string.update_72hour),
168 to stringResource(id = R.string.update_weekly), 168 to stringResource(R.string.update_weekly),
), ),
onValueChanged = { onValueChanged = {
LibraryUpdateJob.setupTask(context, it) LibraryUpdateJob.setupTask(context, it)
@ -239,8 +241,8 @@ class SettingsLibraryScreen : SearchableSettings {
Preference.PreferenceItem.MultiSelectListPreference( Preference.PreferenceItem.MultiSelectListPreference(
pref = libraryUpdateDeviceRestrictionPref, pref = libraryUpdateDeviceRestrictionPref,
enabled = libraryUpdateInterval > 0, enabled = libraryUpdateInterval > 0,
title = stringResource(id = R.string.pref_library_update_restriction), title = stringResource(R.string.pref_library_update_restriction),
subtitle = stringResource(id = R.string.restrictions, deviceRestrictions), subtitle = stringResource(R.string.restrictions, deviceRestrictions),
entries = deviceRestrictionEntries, entries = deviceRestrictionEntries,
onValueChanged = { onValueChanged = {
// Post to event looper to allow the preference to be updated. // Post to event looper to allow the preference to be updated.
@ -250,12 +252,12 @@ class SettingsLibraryScreen : SearchableSettings {
), ),
Preference.PreferenceItem.MultiSelectListPreference( Preference.PreferenceItem.MultiSelectListPreference(
pref = libraryUpdateMangaRestrictionPref, pref = libraryUpdateMangaRestrictionPref,
title = stringResource(id = R.string.pref_library_update_manga_restriction), title = stringResource(R.string.pref_library_update_manga_restriction),
subtitle = mangaRestrictions, subtitle = mangaRestrictions,
entries = mangaRestrictionEntries, entries = mangaRestrictionEntries,
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(id = R.string.categories), title = stringResource(R.string.categories),
subtitle = getCategoriesLabel( subtitle = getCategoriesLabel(
allCategories = allCategories, allCategories = allCategories,
included = included, included = included,
@ -265,14 +267,14 @@ class SettingsLibraryScreen : SearchableSettings {
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.autoUpdateMetadata(), pref = libraryPreferences.autoUpdateMetadata(),
title = stringResource(id = R.string.pref_library_update_refresh_metadata), title = stringResource(R.string.pref_library_update_refresh_metadata),
subtitle = stringResource(id = R.string.pref_library_update_refresh_metadata_summary), subtitle = stringResource(R.string.pref_library_update_refresh_metadata_summary),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.autoUpdateTrackers(), pref = libraryPreferences.autoUpdateTrackers(),
enabled = Injekt.get<TrackManager>().hasLoggedServices(), enabled = Injekt.get<TrackManager>().hasLoggedServices(),
title = stringResource(id = R.string.pref_library_update_refresh_trackers), title = stringResource(R.string.pref_library_update_refresh_trackers),
subtitle = stringResource(id = R.string.pref_library_update_refresh_trackers_summary), subtitle = stringResource(R.string.pref_library_update_refresh_trackers_summary),
), ),
), ),
) )
@ -291,7 +293,7 @@ class SettingsLibraryScreen : SearchableSettings {
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(id = R.string.pref_library_columns)) }, title = { Text(text = stringResource(R.string.pref_library_columns)) },
text = { text = {
Row { Row {
Column( Column(
@ -299,7 +301,7 @@ class SettingsLibraryScreen : SearchableSettings {
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Text( Text(
text = stringResource(id = R.string.portrait), text = stringResource(R.string.portrait),
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
) )
NumberPicker( NumberPicker(
@ -320,7 +322,7 @@ class SettingsLibraryScreen : SearchableSettings {
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Text( Text(
text = stringResource(id = R.string.landscape), text = stringResource(R.string.landscape),
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
) )
NumberPicker( NumberPicker(
@ -339,12 +341,12 @@ class SettingsLibraryScreen : SearchableSettings {
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = android.R.string.cancel)) Text(text = stringResource(android.R.string.cancel))
} }
}, },
confirmButton = { confirmButton = {
TextButton(onClick = { onValueChanged(portraitValue, landscapeValue) }) { TextButton(onClick = { onValueChanged(portraitValue, landscapeValue) }) {
Text(text = stringResource(id = android.R.string.ok)) Text(text = stringResource(android.R.string.ok))
} }
}, },
) )

View File

@ -1,5 +1,6 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ChromeReaderMode import androidx.compose.material.icons.outlined.ChromeReaderMode
import androidx.compose.material.icons.outlined.Code import androidx.compose.material.icons.outlined.Code
@ -26,9 +27,11 @@ import eu.kanade.presentation.util.LocalBackPress
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
object SettingsMainScreen : SearchableSettings { object SettingsMainScreen : SearchableSettings {
@Composable @Composable
@ReadOnlyComposable @ReadOnlyComposable
override fun getTitle(): String = stringResource(id = R.string.label_settings) @StringRes
override fun getTitleRes() = R.string.label_settings
@Composable @Composable
@NonRestartableComposable @NonRestartableComposable
@ -93,7 +96,7 @@ object SettingsMainScreen : SearchableSettings {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
val backPress = LocalBackPress.currentOrThrow val backPress = LocalBackPress.currentOrThrow
PreferenceScaffold( PreferenceScaffold(
title = getTitle(), titleRes = getTitleRes(),
actions = { actions = {
AppBarActions( AppBarActions(
listOf( listOf(

View File

@ -1,6 +1,7 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import android.os.Build import android.os.Build
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -20,9 +21,11 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class SettingsReaderScreen : SearchableSettings { class SettingsReaderScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
override fun getTitle(): String = stringResource(id = R.string.pref_category_reader) @StringRes
override fun getTitleRes() = R.string.pref_category_reader
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -30,38 +33,38 @@ class SettingsReaderScreen : SearchableSettings {
return listOf( return listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPref.defaultReadingMode(), pref = readerPref.defaultReadingMode(),
title = stringResource(id = R.string.pref_viewer_type), title = stringResource(R.string.pref_viewer_type),
entries = ReadingModeType.values().drop(1) entries = ReadingModeType.values().drop(1)
.associate { it.flagValue to stringResource(id = it.stringRes) }, .associate { it.flagValue to stringResource(it.stringRes) },
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPref.doubleTapAnimSpeed(), pref = readerPref.doubleTapAnimSpeed(),
title = stringResource(id = R.string.pref_double_tap_anim_speed), title = stringResource(R.string.pref_double_tap_anim_speed),
entries = mapOf( entries = mapOf(
1 to stringResource(id = R.string.double_tap_anim_speed_0), 1 to stringResource(R.string.double_tap_anim_speed_0),
500 to stringResource(id = R.string.double_tap_anim_speed_normal), 500 to stringResource(R.string.double_tap_anim_speed_normal),
250 to stringResource(id = R.string.double_tap_anim_speed_fast), 250 to stringResource(R.string.double_tap_anim_speed_fast),
), ),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPref.showReadingMode(), pref = readerPref.showReadingMode(),
title = stringResource(id = R.string.pref_show_reading_mode), title = stringResource(R.string.pref_show_reading_mode),
subtitle = stringResource(id = R.string.pref_show_reading_mode_summary), subtitle = stringResource(R.string.pref_show_reading_mode_summary),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPref.showNavigationOverlayOnStart(), pref = readerPref.showNavigationOverlayOnStart(),
title = stringResource(id = R.string.pref_show_navigation_mode), title = stringResource(R.string.pref_show_navigation_mode),
subtitle = stringResource(id = R.string.pref_show_navigation_mode_summary), subtitle = stringResource(R.string.pref_show_navigation_mode_summary),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPref.trueColor(), pref = readerPref.trueColor(),
title = stringResource(id = R.string.pref_true_color), title = stringResource(R.string.pref_true_color),
subtitle = stringResource(id = R.string.pref_true_color_summary), subtitle = stringResource(R.string.pref_true_color_summary),
enabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O, enabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O,
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPref.pageTransitions(), pref = readerPref.pageTransitions(),
title = stringResource(id = R.string.pref_page_transitions), title = stringResource(R.string.pref_page_transitions),
), ),
getDisplayGroup(readerPreferences = readerPref), getDisplayGroup(readerPreferences = readerPref),
getPagedGroup(readerPreferences = readerPref), getPagedGroup(readerPreferences = readerPref),
@ -76,42 +79,42 @@ class SettingsReaderScreen : SearchableSettings {
val fullscreenPref = readerPreferences.fullscreen() val fullscreenPref = readerPreferences.fullscreen()
val fullscreen by fullscreenPref.collectAsState() val fullscreen by fullscreenPref.collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.pref_category_display), title = stringResource(R.string.pref_category_display),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.defaultOrientationType(), pref = readerPreferences.defaultOrientationType(),
title = stringResource(id = R.string.pref_rotation_type), title = stringResource(R.string.pref_rotation_type),
entries = OrientationType.values().drop(1) entries = OrientationType.values().drop(1)
.associate { it.flagValue to stringResource(id = it.stringRes) }, .associate { it.flagValue to stringResource(it.stringRes) },
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.readerTheme(), pref = readerPreferences.readerTheme(),
title = stringResource(id = R.string.pref_reader_theme), title = stringResource(R.string.pref_reader_theme),
entries = mapOf( entries = mapOf(
1 to stringResource(id = R.string.black_background), 1 to stringResource(R.string.black_background),
2 to stringResource(id = R.string.gray_background), 2 to stringResource(R.string.gray_background),
0 to stringResource(id = R.string.white_background), 0 to stringResource(R.string.white_background),
3 to stringResource(id = R.string.automatic_background), 3 to stringResource(R.string.automatic_background),
), ),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = fullscreenPref, pref = fullscreenPref,
title = stringResource(id = R.string.pref_fullscreen), title = stringResource(R.string.pref_fullscreen),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.cutoutShort(), pref = readerPreferences.cutoutShort(),
title = stringResource(id = R.string.pref_cutout_short), title = stringResource(R.string.pref_cutout_short),
enabled = fullscreen && enabled = fullscreen &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P &&
LocalView.current.rootWindowInsets?.displayCutout != null, // has cutout LocalView.current.rootWindowInsets?.displayCutout != null, // has cutout
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.keepScreenOn(), pref = readerPreferences.keepScreenOn(),
title = stringResource(id = R.string.pref_keep_screen_on), title = stringResource(R.string.pref_keep_screen_on),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.showPageNumber(), pref = readerPreferences.showPageNumber(),
title = stringResource(id = R.string.pref_show_page_number), title = stringResource(R.string.pref_show_page_number),
), ),
), ),
) )
@ -128,71 +131,71 @@ class SettingsReaderScreen : SearchableSettings {
val dualPageSplit by dualPageSplitPref.collectAsState() val dualPageSplit by dualPageSplitPref.collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.pager_viewer), title = stringResource(R.string.pager_viewer),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = navModePref, pref = navModePref,
title = stringResource(id = R.string.pref_viewer_nav), title = stringResource(R.string.pref_viewer_nav),
entries = stringArrayResource(id = R.array.pager_nav).let { entries = stringArrayResource(id = R.array.pager_nav).let {
it.indices.zip(it).toMap() it.indices.zip(it).toMap()
}, },
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.pagerNavInverted(), pref = readerPreferences.pagerNavInverted(),
title = stringResource(id = R.string.pref_read_with_tapping_inverted), title = stringResource(R.string.pref_read_with_tapping_inverted),
entries = mapOf( entries = mapOf(
TappingInvertMode.NONE to stringResource(id = R.string.none), TappingInvertMode.NONE to stringResource(R.string.none),
TappingInvertMode.HORIZONTAL to stringResource(id = R.string.tapping_inverted_horizontal), TappingInvertMode.HORIZONTAL to stringResource(R.string.tapping_inverted_horizontal),
TappingInvertMode.VERTICAL to stringResource(id = R.string.tapping_inverted_vertical), TappingInvertMode.VERTICAL to stringResource(R.string.tapping_inverted_vertical),
TappingInvertMode.BOTH to stringResource(id = R.string.tapping_inverted_both), TappingInvertMode.BOTH to stringResource(R.string.tapping_inverted_both),
), ),
enabled = navMode != 5, enabled = navMode != 5,
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.navigateToPan(), pref = readerPreferences.navigateToPan(),
title = stringResource(id = R.string.pref_navigate_pan), title = stringResource(R.string.pref_navigate_pan),
enabled = navMode != 5, enabled = navMode != 5,
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = imageScaleTypePref, pref = imageScaleTypePref,
title = stringResource(id = R.string.pref_image_scale_type), title = stringResource(R.string.pref_image_scale_type),
entries = mapOf( entries = mapOf(
1 to stringResource(id = R.string.scale_type_fit_screen), 1 to stringResource(R.string.scale_type_fit_screen),
2 to stringResource(id = R.string.scale_type_stretch), 2 to stringResource(R.string.scale_type_stretch),
3 to stringResource(id = R.string.scale_type_fit_width), 3 to stringResource(R.string.scale_type_fit_width),
4 to stringResource(id = R.string.scale_type_fit_height), 4 to stringResource(R.string.scale_type_fit_height),
5 to stringResource(id = R.string.scale_type_original_size), 5 to stringResource(R.string.scale_type_original_size),
6 to stringResource(id = R.string.scale_type_smart_fit), 6 to stringResource(R.string.scale_type_smart_fit),
), ),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.landscapeZoom(), pref = readerPreferences.landscapeZoom(),
title = stringResource(id = R.string.pref_landscape_zoom), title = stringResource(R.string.pref_landscape_zoom),
enabled = imageScaleType == 1, enabled = imageScaleType == 1,
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.zoomStart(), pref = readerPreferences.zoomStart(),
title = stringResource(id = R.string.pref_zoom_start), title = stringResource(R.string.pref_zoom_start),
entries = mapOf( entries = mapOf(
1 to stringResource(id = R.string.zoom_start_automatic), 1 to stringResource(R.string.zoom_start_automatic),
2 to stringResource(id = R.string.zoom_start_left), 2 to stringResource(R.string.zoom_start_left),
3 to stringResource(id = R.string.zoom_start_right), 3 to stringResource(R.string.zoom_start_right),
4 to stringResource(id = R.string.zoom_start_center), 4 to stringResource(R.string.zoom_start_center),
), ),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.cropBorders(), pref = readerPreferences.cropBorders(),
title = stringResource(id = R.string.pref_crop_borders), title = stringResource(R.string.pref_crop_borders),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = dualPageSplitPref, pref = dualPageSplitPref,
title = stringResource(id = R.string.pref_dual_page_split), title = stringResource(R.string.pref_dual_page_split),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.dualPageInvertPaged(), pref = readerPreferences.dualPageInvertPaged(),
title = stringResource(id = R.string.pref_dual_page_invert), title = stringResource(R.string.pref_dual_page_invert),
subtitle = stringResource(id = R.string.pref_dual_page_invert_summary), subtitle = stringResource(R.string.pref_dual_page_invert_summary),
enabled = dualPageSplit, enabled = dualPageSplit,
), ),
), ),
@ -208,66 +211,66 @@ class SettingsReaderScreen : SearchableSettings {
val dualPageSplit by dualPageSplitPref.collectAsState() val dualPageSplit by dualPageSplitPref.collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.webtoon_viewer), title = stringResource(R.string.webtoon_viewer),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = navModePref, pref = navModePref,
title = stringResource(id = R.string.pref_viewer_nav), title = stringResource(R.string.pref_viewer_nav),
entries = stringArrayResource(id = R.array.webtoon_nav).let { entries = stringArrayResource(id = R.array.webtoon_nav).let {
it.indices.zip(it).toMap() it.indices.zip(it).toMap()
}, },
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.webtoonNavInverted(), pref = readerPreferences.webtoonNavInverted(),
title = stringResource(id = R.string.pref_read_with_tapping_inverted), title = stringResource(R.string.pref_read_with_tapping_inverted),
entries = mapOf( entries = mapOf(
TappingInvertMode.NONE to stringResource(id = R.string.none), TappingInvertMode.NONE to stringResource(R.string.none),
TappingInvertMode.HORIZONTAL to stringResource(id = R.string.tapping_inverted_horizontal), TappingInvertMode.HORIZONTAL to stringResource(R.string.tapping_inverted_horizontal),
TappingInvertMode.VERTICAL to stringResource(id = R.string.tapping_inverted_vertical), TappingInvertMode.VERTICAL to stringResource(R.string.tapping_inverted_vertical),
TappingInvertMode.BOTH to stringResource(id = R.string.tapping_inverted_both), TappingInvertMode.BOTH to stringResource(R.string.tapping_inverted_both),
), ),
enabled = navMode != 5, enabled = navMode != 5,
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.webtoonSidePadding(), pref = readerPreferences.webtoonSidePadding(),
title = stringResource(id = R.string.pref_webtoon_side_padding), title = stringResource(R.string.pref_webtoon_side_padding),
entries = mapOf( entries = mapOf(
0 to stringResource(id = R.string.webtoon_side_padding_0), 0 to stringResource(R.string.webtoon_side_padding_0),
5 to stringResource(id = R.string.webtoon_side_padding_5), 5 to stringResource(R.string.webtoon_side_padding_5),
10 to stringResource(id = R.string.webtoon_side_padding_10), 10 to stringResource(R.string.webtoon_side_padding_10),
15 to stringResource(id = R.string.webtoon_side_padding_15), 15 to stringResource(R.string.webtoon_side_padding_15),
20 to stringResource(id = R.string.webtoon_side_padding_20), 20 to stringResource(R.string.webtoon_side_padding_20),
25 to stringResource(id = R.string.webtoon_side_padding_25), 25 to stringResource(R.string.webtoon_side_padding_25),
), ),
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.readerHideThreshold(), pref = readerPreferences.readerHideThreshold(),
title = stringResource(id = R.string.pref_hide_threshold), title = stringResource(R.string.pref_hide_threshold),
entries = mapOf( entries = mapOf(
ReaderHideThreshold.HIGHEST to stringResource(id = R.string.pref_highest), ReaderHideThreshold.HIGHEST to stringResource(R.string.pref_highest),
ReaderHideThreshold.HIGH to stringResource(id = R.string.pref_high), ReaderHideThreshold.HIGH to stringResource(R.string.pref_high),
ReaderHideThreshold.LOW to stringResource(id = R.string.pref_low), ReaderHideThreshold.LOW to stringResource(R.string.pref_low),
ReaderHideThreshold.LOWEST to stringResource(id = R.string.pref_lowest), ReaderHideThreshold.LOWEST to stringResource(R.string.pref_lowest),
), ),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.cropBordersWebtoon(), pref = readerPreferences.cropBordersWebtoon(),
title = stringResource(id = R.string.pref_crop_borders), title = stringResource(R.string.pref_crop_borders),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = dualPageSplitPref, pref = dualPageSplitPref,
title = stringResource(id = R.string.pref_dual_page_split), title = stringResource(R.string.pref_dual_page_split),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.dualPageInvertWebtoon(), pref = readerPreferences.dualPageInvertWebtoon(),
title = stringResource(id = R.string.pref_dual_page_invert), title = stringResource(R.string.pref_dual_page_invert),
subtitle = stringResource(id = R.string.pref_dual_page_invert_summary), subtitle = stringResource(R.string.pref_dual_page_invert_summary),
enabled = dualPageSplit, enabled = dualPageSplit,
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.longStripSplitWebtoon(), pref = readerPreferences.longStripSplitWebtoon(),
title = stringResource(id = R.string.pref_long_strip_split), title = stringResource(R.string.pref_long_strip_split),
subtitle = stringResource(id = R.string.split_tall_images_summary), subtitle = stringResource(R.string.split_tall_images_summary),
), ),
), ),
) )
@ -278,15 +281,15 @@ class SettingsReaderScreen : SearchableSettings {
val readWithVolumeKeysPref = readerPreferences.readWithVolumeKeys() val readWithVolumeKeysPref = readerPreferences.readWithVolumeKeys()
val readWithVolumeKeys by readWithVolumeKeysPref.collectAsState() val readWithVolumeKeys by readWithVolumeKeysPref.collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.pref_reader_navigation), title = stringResource(R.string.pref_reader_navigation),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readWithVolumeKeysPref, pref = readWithVolumeKeysPref,
title = stringResource(id = R.string.pref_read_with_volume_keys), title = stringResource(R.string.pref_read_with_volume_keys),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.readWithVolumeKeysInverted(), pref = readerPreferences.readWithVolumeKeysInverted(),
title = stringResource(id = R.string.pref_read_with_volume_keys_inverted), title = stringResource(R.string.pref_read_with_volume_keys_inverted),
enabled = readWithVolumeKeys, enabled = readWithVolumeKeys,
), ),
), ),
@ -296,15 +299,15 @@ class SettingsReaderScreen : SearchableSettings {
@Composable @Composable
private fun getActionsGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup { private fun getActionsGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup {
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(id = R.string.pref_reader_actions), title = stringResource(R.string.pref_reader_actions),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.readWithLongTap(), pref = readerPreferences.readWithLongTap(),
title = stringResource(id = R.string.pref_read_with_long_tap), title = stringResource(R.string.pref_read_with_long_tap),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.folderPerManga(), pref = readerPreferences.folderPerManga(),
title = stringResource(id = R.string.pref_create_folder_per_manga), title = stringResource(R.string.pref_create_folder_per_manga),
), ),
), ),
) )

View File

@ -115,7 +115,7 @@ class SettingsSearchScreen : Screen {
decorationBox = { decorationBox = {
if (textFieldValue.text.isEmpty()) { if (textFieldValue.text.isEmpty()) {
Text( Text(
text = stringResource(id = R.string.action_search_settings), text = stringResource(R.string.action_search_settings),
color = MaterialTheme.colorScheme.onSurfaceVariant, color = MaterialTheme.colorScheme.onSurfaceVariant,
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
) )
@ -218,7 +218,7 @@ private fun SearchResult(
/* Don't show anything just yet */ /* Don't show anything just yet */
} }
// No result // No result
it.isEmpty() -> item { EmptyScreen(stringResource(id = R.string.no_results_found)) } it.isEmpty() -> item { EmptyScreen(stringResource(R.string.no_results_found)) }
// Show result list // Show result list
else -> items( else -> items(
items = it, items = it,
@ -256,7 +256,7 @@ private fun SearchResult(
private fun getIndex() = settingScreens private fun getIndex() = settingScreens
.map { screen -> .map { screen ->
SettingsData( SettingsData(
title = screen.getTitle(), title = stringResource(screen.getTitleRes()),
route = screen, route = screen,
contents = screen.getPreferences(), contents = screen.getPreferences(),
) )

View File

@ -1,5 +1,6 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -21,7 +22,8 @@ class SettingsSecurityScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
override fun getTitle(): String = stringResource(id = R.string.pref_category_security) @StringRes
override fun getTitleRes() = R.string.pref_category_security
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -36,7 +38,7 @@ class SettingsSecurityScreen : SearchableSettings {
return listOf( return listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = useAuthPref, pref = useAuthPref,
title = stringResource(id = R.string.lock_with_biometrics), title = stringResource(R.string.lock_with_biometrics),
enabled = authSupported, enabled = authSupported,
onValueChanged = { onValueChanged = {
(context as FragmentActivity).authenticate( (context as FragmentActivity).authenticate(
@ -46,14 +48,14 @@ class SettingsSecurityScreen : SearchableSettings {
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = securityPreferences.lockAppAfter(), pref = securityPreferences.lockAppAfter(),
title = stringResource(id = R.string.lock_when_idle), title = stringResource(R.string.lock_when_idle),
subtitle = "%s", subtitle = "%s",
enabled = authSupported && useAuth, enabled = authSupported && useAuth,
entries = LockAfterValues entries = LockAfterValues
.associateWith { .associateWith {
when (it) { when (it) {
-1 -> stringResource(id = R.string.lock_never) -1 -> stringResource(R.string.lock_never)
0 -> stringResource(id = R.string.lock_always) 0 -> stringResource(R.string.lock_always)
else -> pluralStringResource(id = R.plurals.lock_after_mins, count = it, it) else -> pluralStringResource(id = R.plurals.lock_after_mins, count = it, it)
} }
}, },
@ -65,16 +67,16 @@ class SettingsSecurityScreen : SearchableSettings {
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = securityPreferences.hideNotificationContent(), pref = securityPreferences.hideNotificationContent(),
title = stringResource(id = R.string.hide_notification_content), title = stringResource(R.string.hide_notification_content),
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = securityPreferences.secureScreen(), pref = securityPreferences.secureScreen(),
title = stringResource(id = R.string.secure_screen), title = stringResource(R.string.secure_screen),
subtitle = "%s", subtitle = "%s",
entries = SecurityPreferences.SecureScreenMode.values() entries = SecurityPreferences.SecureScreenMode.values()
.associateWith { stringResource(id = it.titleResId) }, .associateWith { stringResource(it.titleResId) },
), ),
Preference.infoPreference(stringResource(id = R.string.secure_screen_summary)), Preference.infoPreference(stringResource(R.string.secure_screen_summary)),
) )
} }
} }

View File

@ -32,6 +32,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.PasswordVisualTransformation
@ -57,17 +58,19 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class SettingsTrackingScreen : SearchableSettings { class SettingsTrackingScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
override fun getTitle(): String = stringResource(id = R.string.pref_category_tracking) @StringRes
override fun getTitleRes() = R.string.pref_category_tracking
@Composable @Composable
override fun RowScope.AppBarAction() { override fun RowScope.AppBarAction() {
val context = LocalContext.current val uriHandler = LocalUriHandler.current
IconButton(onClick = { context.openInBrowser("https://tachiyomi.org/help/guides/tracking/") }) { IconButton(onClick = { uriHandler.openUri("https://tachiyomi.org/help/guides/tracking/") }) {
Icon( Icon(
imageVector = Icons.Default.HelpOutline, imageVector = Icons.Default.HelpOutline,
contentDescription = stringResource(id = R.string.tracking_guide), contentDescription = stringResource(R.string.tracking_guide),
) )
} }
} }
@ -100,55 +103,55 @@ class SettingsTrackingScreen : SearchableSettings {
return listOf( return listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = trackPreferences.autoUpdateTrack(), pref = trackPreferences.autoUpdateTrack(),
title = stringResource(id = R.string.pref_auto_update_manga_sync), title = stringResource(R.string.pref_auto_update_manga_sync),
), ),
Preference.PreferenceGroup( Preference.PreferenceGroup(
title = stringResource(id = R.string.services), title = stringResource(R.string.services),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TrackingPreference( Preference.PreferenceItem.TrackingPreference(
title = stringResource(id = trackManager.myAnimeList.nameRes()), title = stringResource(trackManager.myAnimeList.nameRes()),
service = trackManager.myAnimeList, service = trackManager.myAnimeList,
login = { context.openInBrowser(MyAnimeListApi.authUrl(), forceDefaultBrowser = true) }, login = { context.openInBrowser(MyAnimeListApi.authUrl(), forceDefaultBrowser = true) },
logout = { dialog = LogoutDialog(trackManager.myAnimeList) }, logout = { dialog = LogoutDialog(trackManager.myAnimeList) },
), ),
Preference.PreferenceItem.TrackingPreference( Preference.PreferenceItem.TrackingPreference(
title = stringResource(id = trackManager.aniList.nameRes()), title = stringResource(trackManager.aniList.nameRes()),
service = trackManager.aniList, service = trackManager.aniList,
login = { context.openInBrowser(AnilistApi.authUrl(), forceDefaultBrowser = true) }, login = { context.openInBrowser(AnilistApi.authUrl(), forceDefaultBrowser = true) },
logout = { dialog = LogoutDialog(trackManager.aniList) }, logout = { dialog = LogoutDialog(trackManager.aniList) },
), ),
Preference.PreferenceItem.TrackingPreference( Preference.PreferenceItem.TrackingPreference(
title = stringResource(id = trackManager.kitsu.nameRes()), title = stringResource(trackManager.kitsu.nameRes()),
service = trackManager.kitsu, service = trackManager.kitsu,
login = { dialog = LoginDialog(trackManager.kitsu, R.string.email) }, login = { dialog = LoginDialog(trackManager.kitsu, R.string.email) },
logout = { dialog = LogoutDialog(trackManager.kitsu) }, logout = { dialog = LogoutDialog(trackManager.kitsu) },
), ),
Preference.PreferenceItem.TrackingPreference( Preference.PreferenceItem.TrackingPreference(
title = stringResource(id = trackManager.mangaUpdates.nameRes()), title = stringResource(trackManager.mangaUpdates.nameRes()),
service = trackManager.mangaUpdates, service = trackManager.mangaUpdates,
login = { dialog = LoginDialog(trackManager.mangaUpdates, R.string.username) }, login = { dialog = LoginDialog(trackManager.mangaUpdates, R.string.username) },
logout = { dialog = LogoutDialog(trackManager.mangaUpdates) }, logout = { dialog = LogoutDialog(trackManager.mangaUpdates) },
), ),
Preference.PreferenceItem.TrackingPreference( Preference.PreferenceItem.TrackingPreference(
title = stringResource(id = trackManager.shikimori.nameRes()), title = stringResource(trackManager.shikimori.nameRes()),
service = trackManager.shikimori, service = trackManager.shikimori,
login = { context.openInBrowser(ShikimoriApi.authUrl(), forceDefaultBrowser = true) }, login = { context.openInBrowser(ShikimoriApi.authUrl(), forceDefaultBrowser = true) },
logout = { dialog = LogoutDialog(trackManager.shikimori) }, logout = { dialog = LogoutDialog(trackManager.shikimori) },
), ),
Preference.PreferenceItem.TrackingPreference( Preference.PreferenceItem.TrackingPreference(
title = stringResource(id = trackManager.bangumi.nameRes()), title = stringResource(trackManager.bangumi.nameRes()),
service = trackManager.bangumi, service = trackManager.bangumi,
login = { context.openInBrowser(BangumiApi.authUrl(), forceDefaultBrowser = true) }, login = { context.openInBrowser(BangumiApi.authUrl(), forceDefaultBrowser = true) },
logout = { dialog = LogoutDialog(trackManager.bangumi) }, logout = { dialog = LogoutDialog(trackManager.bangumi) },
), ),
Preference.infoPreference(stringResource(id = R.string.tracking_info)), Preference.infoPreference(stringResource(R.string.tracking_info)),
), ),
), ),
Preference.PreferenceGroup( Preference.PreferenceGroup(
title = stringResource(id = R.string.enhanced_services), title = stringResource(R.string.enhanced_services),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TrackingPreference( Preference.PreferenceItem.TrackingPreference(
title = stringResource(id = trackManager.komga.nameRes()), title = stringResource(trackManager.komga.nameRes()),
service = trackManager.komga, service = trackManager.komga,
login = { login = {
val sourceManager = Injekt.get<SourceManager>() val sourceManager = Injekt.get<SourceManager>()
@ -164,7 +167,7 @@ class SettingsTrackingScreen : SearchableSettings {
}, },
logout = trackManager.komga::logout, logout = trackManager.komga::logout,
), ),
Preference.infoPreference(stringResource(id = R.string.enhanced_tracking_info)), Preference.infoPreference(stringResource(R.string.enhanced_tracking_info)),
), ),
), ),
) )
@ -186,14 +189,14 @@ class SettingsTrackingScreen : SearchableSettings {
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(id = R.string.login_title, stringResource(id = service.nameRes()))) }, title = { Text(text = stringResource(R.string.login_title, stringResource(service.nameRes()))) },
text = { text = {
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
OutlinedTextField( OutlinedTextField(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
value = username, value = username,
onValueChange = { username = it }, onValueChange = { username = it },
label = { Text(text = stringResource(id = uNameStringRes)) }, label = { Text(text = stringResource(uNameStringRes)) },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
singleLine = true, singleLine = true,
isError = inputError && username.text.isEmpty(), isError = inputError && username.text.isEmpty(),
@ -204,7 +207,7 @@ class SettingsTrackingScreen : SearchableSettings {
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
value = password, value = password,
onValueChange = { password = it }, onValueChange = { password = it },
label = { Text(text = stringResource(id = R.string.password)) }, label = { Text(text = stringResource(R.string.password)) },
trailingIcon = { trailingIcon = {
IconButton(onClick = { hidePassword = !hidePassword }) { IconButton(onClick = { hidePassword = !hidePassword }) {
Icon( Icon(
@ -253,13 +256,13 @@ class SettingsTrackingScreen : SearchableSettings {
}, },
) { ) {
val id = if (processing) R.string.loading else R.string.login val id = if (processing) R.string.loading else R.string.login
Text(text = stringResource(id = id)) Text(text = stringResource(id))
} }
TextButton( TextButton(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
onClick = onDismissRequest, onClick = onDismissRequest,
) { ) {
Text(text = stringResource(id = android.R.string.cancel)) Text(text = stringResource(android.R.string.cancel))
} }
} }
}, },
@ -293,7 +296,7 @@ class SettingsTrackingScreen : SearchableSettings {
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { title = {
Text( Text(
text = stringResource(id = R.string.logout_title, stringResource(id = service.nameRes())), text = stringResource(R.string.logout_title, stringResource(service.nameRes())),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
) )
@ -304,7 +307,7 @@ class SettingsTrackingScreen : SearchableSettings {
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
onClick = onDismissRequest, onClick = onDismissRequest,
) { ) {
Text(text = stringResource(id = android.R.string.cancel)) Text(text = stringResource(android.R.string.cancel))
} }
Button( Button(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
@ -318,7 +321,7 @@ class SettingsTrackingScreen : SearchableSettings {
contentColor = MaterialTheme.colorScheme.onError, contentColor = MaterialTheme.colorScheme.onError,
), ),
) { ) {
Text(text = stringResource(id = R.string.logout)) Text(text = stringResource(R.string.logout))
} }
} }
}, },

View File

@ -101,7 +101,7 @@ private fun AppThemesList(
} }
Text( Text(
text = stringResource(id = appTheme.titleResId!!), text = stringResource(appTheme.titleResId!!),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 8.dp) .padding(top = 8.dp)

View File

@ -66,12 +66,12 @@ fun EditTextPreferenceWidget(
} }
}, },
) { ) {
Text(text = stringResource(id = android.R.string.ok)) Text(text = stringResource(android.R.string.ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = android.R.string.cancel)) Text(text = stringResource(android.R.string.cancel))
} }
}, },
) )

View File

@ -70,7 +70,7 @@ fun <T> ListPreferenceWidget(
}, },
confirmButton = { confirmButton = {
TextButton(onClick = { showDialog(false) }) { TextButton(onClick = { showDialog(false) }) {
Text(text = stringResource(id = android.R.string.cancel)) Text(text = stringResource(android.R.string.cancel))
} }
}, },
) )

View File

@ -86,12 +86,12 @@ fun MultiSelectListPreferenceWidget(
showDialog(false) showDialog(false)
}, },
) { ) {
Text(text = stringResource(id = android.R.string.ok)) Text(text = stringResource(android.R.string.ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = { showDialog(false) }) { TextButton(onClick = { showDialog(false) }) {
Text(text = stringResource(id = android.R.string.cancel)) Text(text = stringResource(android.R.string.cancel))
} }
}, },
) )

View File

@ -117,7 +117,7 @@ fun <T> TriStateListDialog(
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = android.R.string.cancel)) Text(text = stringResource(android.R.string.cancel))
} }
}, },
confirmButton = { confirmButton = {
@ -132,7 +132,7 @@ fun <T> TriStateListDialog(
onValueChanged(included, excluded) onValueChanged(included, excluded)
}, },
) { ) {
Text(text = stringResource(id = android.R.string.ok)) Text(text = stringResource(android.R.string.ok))
} }
}, },
) )