Browse Source

Minor settings cleanup

- Fix dark mode setting title
- Enforce usages of translated strings for screen titles
- Use LocalUriHandler where applicable instead of Android context
arkon 2 years ago
parent
commit
c2eaf1c86b
22 changed files with 384 additions and 333 deletions
  1. 1 1
      app/src/main/java/eu/kanade/presentation/browse/ExtensionsScreen.kt
  2. 1 1
      app/src/main/java/eu/kanade/presentation/components/EmptyScreen.kt
  3. 4 2
      app/src/main/java/eu/kanade/presentation/more/settings/PreferenceScaffold.kt
  4. 2 2
      app/src/main/java/eu/kanade/presentation/more/settings/screen/Commons.kt
  5. 5 2
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SearchableSettings.kt
  6. 49 43
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt
  7. 58 43
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAppearanceScreen.kt
  8. 29 26
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt
  9. 15 12
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBrowseScreen.kt
  10. 32 29
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDownloadScreen.kt
  11. 8 5
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsGeneralScreen.kt
  12. 41 39
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt
  13. 5 2
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsMainScreen.kt
  14. 85 82
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt
  15. 3 3
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt
  16. 11 9
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSecurityScreen.kt
  17. 27 24
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt
  18. 1 1
      app/src/main/java/eu/kanade/presentation/more/settings/widget/AppThemePreferenceWidget.kt
  19. 2 2
      app/src/main/java/eu/kanade/presentation/more/settings/widget/EditTextPreferenceWidget.kt
  20. 1 1
      app/src/main/java/eu/kanade/presentation/more/settings/widget/ListPreferenceWidget.kt
  21. 2 2
      app/src/main/java/eu/kanade/presentation/more/settings/widget/MultiSelectListPreferenceWidget.kt
  22. 2 2
      app/src/main/java/eu/kanade/presentation/more/settings/widget/TriStateListDialog.kt

+ 1 - 1
app/src/main/java/eu/kanade/presentation/browse/ExtensionsScreen.kt

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

+ 1 - 1
app/src/main/java/eu/kanade/presentation/components/EmptyScreen.kt

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

+ 4 - 2
app/src/main/java/eu/kanade/presentation/more/settings/PreferenceScaffold.kt

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

+ 2 - 2
app/src/main/java/eu/kanade/presentation/more/settings/screen/Commons.kt

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

+ 5 - 2
app/src/main/java/eu/kanade/presentation/more/settings/screen/SearchableSettings.kt

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

+ 49 - 43
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt

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

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

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

+ 29 - 26
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt

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

+ 15 - 12
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBrowseScreen.kt

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

+ 32 - 29
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDownloadScreen.kt

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

+ 8 - 5
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsGeneralScreen.kt

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

+ 41 - 39
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt

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

+ 5 - 2
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsMainScreen.kt

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

+ 85 - 82
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt

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

+ 3 - 3
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt

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

+ 11 - 9
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSecurityScreen.kt

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

+ 27 - 24
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt

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

+ 1 - 1
app/src/main/java/eu/kanade/presentation/more/settings/widget/AppThemePreferenceWidget.kt

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

+ 2 - 2
app/src/main/java/eu/kanade/presentation/more/settings/widget/EditTextPreferenceWidget.kt

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

+ 1 - 1
app/src/main/java/eu/kanade/presentation/more/settings/widget/ListPreferenceWidget.kt

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

+ 2 - 2
app/src/main/java/eu/kanade/presentation/more/settings/widget/MultiSelectListPreferenceWidget.kt

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

+ 2 - 2
app/src/main/java/eu/kanade/presentation/more/settings/widget/TriStateListDialog.kt

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