fix: upstream conflict.

Signed-off-by: KaiserBh <kaiserbh@proton.me>
This commit is contained in:
KaiserBh 2023-11-19 19:34:37 +11:00
commit be363807e6
No known key found for this signature in database
GPG Key ID: 14D73B142042BBA9
340 changed files with 5963 additions and 6352 deletions

View File

@ -1,12 +1,12 @@
package eu.kanade.domain.base package eu.kanade.domain.base
import android.content.Context import android.content.Context
import androidx.annotation.StringRes import dev.icerock.moko.resources.StringResource
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.isPreviewBuildType import eu.kanade.tachiyomi.util.system.isPreviewBuildType
import eu.kanade.tachiyomi.util.system.isReleaseBuildType import eu.kanade.tachiyomi.util.system.isReleaseBuildType
import tachiyomi.core.preference.Preference import tachiyomi.core.preference.Preference
import tachiyomi.core.preference.PreferenceStore import tachiyomi.core.preference.PreferenceStore
import tachiyomi.i18n.MR
class BasePreferences( class BasePreferences(
val context: Context, val context: Context,
@ -24,10 +24,10 @@ class BasePreferences(
fun acraEnabled() = preferenceStore.getBoolean("acra.enable", isPreviewBuildType || isReleaseBuildType) fun acraEnabled() = preferenceStore.getBoolean("acra.enable", isPreviewBuildType || isReleaseBuildType)
enum class ExtensionInstaller(@StringRes val titleResId: Int) { enum class ExtensionInstaller(val titleRes: StringResource) {
LEGACY(R.string.ext_installer_legacy), LEGACY(MR.strings.ext_installer_legacy),
PACKAGEINSTALLER(R.string.ext_installer_packageinstaller), PACKAGEINSTALLER(MR.strings.ext_installer_packageinstaller),
SHIZUKU(R.string.ext_installer_shizuku), SHIZUKU(MR.strings.ext_installer_shizuku),
PRIVATE(R.string.ext_installer_private), PRIVATE(MR.strings.ext_installer_private),
} }
} }

View File

@ -1,19 +1,20 @@
package eu.kanade.domain.ui.model package eu.kanade.domain.ui.model
import eu.kanade.tachiyomi.R import dev.icerock.moko.resources.StringResource
import tachiyomi.i18n.MR
enum class AppTheme(val titleResId: Int?) { enum class AppTheme(val titleRes: StringResource?) {
DEFAULT(R.string.label_default), DEFAULT(MR.strings.label_default),
MONET(R.string.theme_monet), MONET(MR.strings.theme_monet),
GREEN_APPLE(R.string.theme_greenapple), GREEN_APPLE(MR.strings.theme_greenapple),
LAVENDER(R.string.theme_lavender), LAVENDER(MR.strings.theme_lavender),
MIDNIGHT_DUSK(R.string.theme_midnightdusk), MIDNIGHT_DUSK(MR.strings.theme_midnightdusk),
STRAWBERRY_DAIQUIRI(R.string.theme_strawberrydaiquiri), STRAWBERRY_DAIQUIRI(MR.strings.theme_strawberrydaiquiri),
TAKO(R.string.theme_tako), TAKO(MR.strings.theme_tako),
TEALTURQUOISE(R.string.theme_tealturquoise), TEALTURQUOISE(MR.strings.theme_tealturquoise),
TIDAL_WAVE(R.string.theme_tidalwave), TIDAL_WAVE(MR.strings.theme_tidalwave),
YINYANG(R.string.theme_yinyang), YINYANG(MR.strings.theme_yinyang),
YOTSUBA(R.string.theme_yotsuba), YOTSUBA(MR.strings.theme_yotsuba),
// Deprecated // Deprecated
DARK_BLUE(null), DARK_BLUE(null),

View File

@ -1,10 +1,11 @@
package eu.kanade.domain.ui.model package eu.kanade.domain.ui.model
import eu.kanade.tachiyomi.R import dev.icerock.moko.resources.StringResource
import tachiyomi.i18n.MR
enum class TabletUiMode(val titleResId: Int) { enum class TabletUiMode(val titleRes: StringResource) {
AUTOMATIC(R.string.automatic_background), AUTOMATIC(MR.strings.automatic_background),
ALWAYS(R.string.lock_always), ALWAYS(MR.strings.lock_always),
LANDSCAPE(R.string.landscape), LANDSCAPE(MR.strings.landscape),
NEVER(R.string.lock_never), NEVER(MR.strings.lock_never),
} }

View File

@ -14,7 +14,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.paging.LoadState import androidx.paging.LoadState
import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.LazyPagingItems
import eu.kanade.presentation.browse.components.BrowseSourceComfortableGrid import eu.kanade.presentation.browse.components.BrowseSourceComfortableGrid
@ -22,14 +21,16 @@ import eu.kanade.presentation.browse.components.BrowseSourceCompactGrid
import eu.kanade.presentation.browse.components.BrowseSourceList import eu.kanade.presentation.browse.components.BrowseSourceList
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.util.formattedMessage import eu.kanade.presentation.util.formattedMessage
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import tachiyomi.core.i18n.stringResource
import tachiyomi.domain.library.model.LibraryDisplayMode import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.model.StubSource import tachiyomi.domain.source.model.StubSource
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.EmptyScreenAction import tachiyomi.presentation.core.screens.EmptyScreenAction
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
@ -62,7 +63,7 @@ fun BrowseSourceContent(
if (mangaList.itemCount > 0 && errorState != null && errorState is LoadState.Error) { if (mangaList.itemCount > 0 && errorState != null && errorState is LoadState.Error) {
val result = snackbarHostState.showSnackbar( val result = snackbarHostState.showSnackbar(
message = getErrorMessage(errorState), message = getErrorMessage(errorState),
actionLabel = context.getString(R.string.action_retry), actionLabel = context.stringResource(MR.strings.action_retry),
duration = SnackbarDuration.Indefinite, duration = SnackbarDuration.Indefinite,
) )
when (result) { when (result) {
@ -79,7 +80,7 @@ fun BrowseSourceContent(
actions = if (source is LocalSource) { actions = if (source is LocalSource) {
persistentListOf( persistentListOf(
EmptyScreenAction( EmptyScreenAction(
stringResId = R.string.local_source_help_guide, stringRes = MR.strings.local_source_help_guide,
icon = Icons.AutoMirrored.Outlined.HelpOutline, icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = onLocalSourceHelpClick, onClick = onLocalSourceHelpClick,
), ),
@ -87,17 +88,17 @@ fun BrowseSourceContent(
} else { } else {
persistentListOf( persistentListOf(
EmptyScreenAction( EmptyScreenAction(
stringResId = R.string.action_retry, stringRes = MR.strings.action_retry,
icon = Icons.Outlined.Refresh, icon = Icons.Outlined.Refresh,
onClick = mangaList::refresh, onClick = mangaList::refresh,
), ),
EmptyScreenAction( EmptyScreenAction(
stringResId = R.string.action_open_in_web_view, stringRes = MR.strings.action_open_in_web_view,
icon = Icons.Outlined.Public, icon = Icons.Outlined.Public,
onClick = onWebViewClick, onClick = onWebViewClick,
), ),
EmptyScreenAction( EmptyScreenAction(
stringResId = R.string.label_help, stringRes = MR.strings.label_help,
icon = Icons.AutoMirrored.Outlined.HelpOutline, icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = onHelpClick, onClick = onHelpClick,
), ),
@ -160,7 +161,7 @@ internal fun MissingSourceScreen(
}, },
) { paddingValues -> ) { paddingValues ->
EmptyScreen( EmptyScreen(
message = stringResource(R.string.source_not_installed, source.toString()), message = stringResource(MR.strings.source_not_installed, source.toString()),
modifier = Modifier.padding(paddingValues), modifier = Modifier.padding(paddingValues),
) )
} }

View File

@ -38,7 +38,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
@ -50,15 +49,16 @@ import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.WarningBanner import eu.kanade.presentation.components.WarningBanner
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.presentation.more.settings.widget.TrailingWidgetBuffer import eu.kanade.presentation.more.settings.widget.TrailingWidgetBuffer
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.ui.browse.extension.details.ExtensionDetailsScreenModel import eu.kanade.tachiyomi.ui.browse.extension.details.ExtensionDetailsScreenModel
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
@Composable @Composable
@ -77,7 +77,7 @@ fun ExtensionDetailsScreen(
Scaffold( Scaffold(
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
AppBar( AppBar(
title = stringResource(R.string.label_extension_info), title = stringResource(MR.strings.label_extension_info),
navigateUp = navigateUp, navigateUp = navigateUp,
actions = { actions = {
AppBarActions( AppBarActions(
@ -86,14 +86,14 @@ fun ExtensionDetailsScreen(
if (state.extension?.isUnofficial == false) { if (state.extension?.isUnofficial == false) {
add( add(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.whats_new), title = stringResource(MR.strings.whats_new),
icon = Icons.Outlined.History, icon = Icons.Outlined.History,
onClick = onClickWhatsNew, onClick = onClickWhatsNew,
), ),
) )
add( add(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_faq_and_guides), title = stringResource(MR.strings.action_faq_and_guides),
icon = Icons.AutoMirrored.Outlined.HelpOutline, icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = onClickReadme, onClick = onClickReadme,
), ),
@ -102,15 +102,15 @@ fun ExtensionDetailsScreen(
addAll( addAll(
listOf( listOf(
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_enable_all), title = stringResource(MR.strings.action_enable_all),
onClick = onClickEnableAll, onClick = onClickEnableAll,
), ),
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_disable_all), title = stringResource(MR.strings.action_disable_all),
onClick = onClickDisableAll, onClick = onClickDisableAll,
), ),
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.pref_clear_cookies), title = stringResource(MR.strings.pref_clear_cookies),
onClick = onClickClearCookies, onClick = onClickClearCookies,
), ),
), ),
@ -125,7 +125,7 @@ fun ExtensionDetailsScreen(
) { paddingValues -> ) { paddingValues ->
if (state.extension == null) { if (state.extension == null) {
EmptyScreen( EmptyScreen(
textResource = R.string.empty_screen, stringRes = MR.strings.empty_screen,
modifier = Modifier.padding(paddingValues), modifier = Modifier.padding(paddingValues),
) )
return@Scaffold return@Scaffold
@ -160,11 +160,11 @@ private fun ExtensionDetails(
when { when {
extension.isUnofficial -> extension.isUnofficial ->
item { item {
WarningBanner(R.string.unofficial_extension_message) WarningBanner(MR.strings.unofficial_extension_message)
} }
extension.isObsolete -> extension.isObsolete ->
item { item {
WarningBanner(R.string.obsolete_extension_message) WarningBanner(MR.strings.obsolete_extension_message)
} }
} }
@ -190,7 +190,6 @@ private fun ExtensionDetails(
key = { it.source.id }, key = { it.source.id },
) { source -> ) { source ->
SourceSwitchPreference( SourceSwitchPreference(
modifier = Modifier.animateItemPlacement(),
source = source, source = source,
onClickSourcePreferences = onClickSourcePreferences, onClickSourcePreferences = onClickSourcePreferences,
onClickSource = onClickSource, onClickSource = onClickSource,
@ -261,7 +260,7 @@ private fun DetailsHeader(
InfoText( InfoText(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
primaryText = extension.versionName, primaryText = extension.versionName,
secondaryText = stringResource(R.string.ext_info_version), secondaryText = stringResource(MR.strings.ext_info_version),
) )
InfoDivider() InfoDivider()
@ -269,7 +268,7 @@ private fun DetailsHeader(
InfoText( InfoText(
modifier = Modifier.weight(if (extension.isNsfw) 1.5f else 1f), modifier = Modifier.weight(if (extension.isNsfw) 1.5f else 1f),
primaryText = LocaleHelper.getSourceDisplayName(extension.lang, context), primaryText = LocaleHelper.getSourceDisplayName(extension.lang, context),
secondaryText = stringResource(R.string.ext_info_language), secondaryText = stringResource(MR.strings.ext_info_language),
) )
if (extension.isNsfw) { if (extension.isNsfw) {
@ -277,12 +276,12 @@ private fun DetailsHeader(
InfoText( InfoText(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
primaryText = stringResource(R.string.ext_nsfw_short), primaryText = stringResource(MR.strings.ext_nsfw_short),
primaryTextStyle = MaterialTheme.typography.bodyLarge.copy( primaryTextStyle = MaterialTheme.typography.bodyLarge.copy(
color = MaterialTheme.colorScheme.error, color = MaterialTheme.colorScheme.error,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
), ),
secondaryText = stringResource(R.string.ext_info_age_rating), secondaryText = stringResource(MR.strings.ext_info_age_rating),
onClick = onClickAgeRating, onClick = onClickAgeRating,
) )
} }
@ -301,7 +300,7 @@ private fun DetailsHeader(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
onClick = onClickUninstall, onClick = onClickUninstall,
) { ) {
Text(stringResource(R.string.ext_uninstall)) Text(stringResource(MR.strings.ext_uninstall))
} }
if (onClickAppInfo != null) { if (onClickAppInfo != null) {
@ -310,7 +309,7 @@ private fun DetailsHeader(
onClick = onClickAppInfo, onClick = onClickAppInfo,
) { ) {
Text( Text(
text = stringResource(R.string.ext_app_info), text = stringResource(MR.strings.ext_app_info),
color = MaterialTheme.colorScheme.onPrimary, color = MaterialTheme.colorScheme.onPrimary,
) )
} }
@ -388,7 +387,7 @@ private fun SourceSwitchPreference(
IconButton(onClick = { onClickSourcePreferences(source.source.id) }) { IconButton(onClick = { onClickSourcePreferences(source.source.id) }) {
Icon( Icon(
imageVector = Icons.Outlined.Settings, imageVector = Icons.Outlined.Settings,
contentDescription = stringResource(R.string.label_settings), contentDescription = stringResource(MR.strings.label_settings),
tint = MaterialTheme.colorScheme.onSurface, tint = MaterialTheme.colorScheme.onSurface,
) )
} }
@ -411,11 +410,11 @@ private fun NsfwWarningDialog(
) { ) {
AlertDialog( AlertDialog(
text = { text = {
Text(text = stringResource(R.string.ext_nsfw_warning)) Text(text = stringResource(MR.strings.ext_nsfw_warning))
}, },
confirmButton = { confirmButton = {
TextButton(onClick = onClickConfirm) { TextButton(onClick = onClickConfirm) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
onDismissRequest = onClickConfirm, onDismissRequest = onClickConfirm,

View File

@ -7,13 +7,13 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionFilterState import eu.kanade.tachiyomi.ui.browse.extension.ExtensionFilterState
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
@Composable @Composable
@ -25,7 +25,7 @@ fun ExtensionFilterScreen(
Scaffold( Scaffold(
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
AppBar( AppBar(
title = stringResource(R.string.label_extensions), title = stringResource(MR.strings.label_extensions),
navigateUp = navigateUp, navigateUp = navigateUp,
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
) )
@ -33,7 +33,7 @@ fun ExtensionFilterScreen(
) { contentPadding -> ) { contentPadding ->
if (state.isEmpty) { if (state.isEmpty) {
EmptyScreen( EmptyScreen(
textResource = R.string.empty_screen, stringRes = MR.strings.empty_screen,
modifier = Modifier.padding(contentPadding), modifier = Modifier.padding(contentPadding),
) )
return@Scaffold return@Scaffold
@ -58,7 +58,6 @@ private fun ExtensionFilterContent(
) { ) {
items(state.languages) { language -> items(state.languages) { language ->
SwitchPreferenceWidget( SwitchPreferenceWidget(
modifier = Modifier.animateItemPlacement(),
title = LocaleHelper.getSourceDisplayName(language, context), title = LocaleHelper.getSourceDisplayName(language, context),
checked = language in state.enabledLanguages, checked = language in state.enabledLanguages,
onCheckedChanged = { onClickLang(language) }, onCheckedChanged = { onClickLang(language) },

View File

@ -1,6 +1,5 @@
package eu.kanade.presentation.browse package eu.kanade.presentation.browse
import androidx.annotation.StringRes
import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -33,22 +32,23 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.browse.components.BaseBrowseItem import eu.kanade.presentation.browse.components.BaseBrowseItem
import eu.kanade.presentation.browse.components.ExtensionIcon import eu.kanade.presentation.browse.components.ExtensionIcon
import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.extension.model.InstallStep import eu.kanade.tachiyomi.extension.model.InstallStep
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionUiModel import eu.kanade.tachiyomi.ui.browse.extension.ExtensionUiModel
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionsScreenModel import eu.kanade.tachiyomi.ui.browse.extension.ExtensionsScreenModel
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.FastScrollLazyColumn import tachiyomi.presentation.core.components.FastScrollLazyColumn
import tachiyomi.presentation.core.components.material.PullRefresh import tachiyomi.presentation.core.components.material.PullRefresh
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.components.material.topSmallPaddingValues import tachiyomi.presentation.core.components.material.topSmallPaddingValues
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
import tachiyomi.presentation.core.theme.header import tachiyomi.presentation.core.theme.header
@ -79,12 +79,12 @@ fun ExtensionScreen(
state.isLoading -> LoadingScreen(Modifier.padding(contentPadding)) state.isLoading -> LoadingScreen(Modifier.padding(contentPadding))
state.isEmpty -> { state.isEmpty -> {
val msg = if (!searchQuery.isNullOrEmpty()) { val msg = if (!searchQuery.isNullOrEmpty()) {
R.string.no_results_found MR.strings.no_results_found
} else { } else {
R.string.empty_screen MR.strings.empty_screen
} }
EmptyScreen( EmptyScreen(
textResource = msg, stringRes = msg,
modifier = Modifier.padding(contentPadding), modifier = Modifier.padding(contentPadding),
) )
} }
@ -132,11 +132,11 @@ private fun ExtensionContent(
when (header) { when (header) {
is ExtensionUiModel.Header.Resource -> { is ExtensionUiModel.Header.Resource -> {
val action: @Composable RowScope.() -> Unit = val action: @Composable RowScope.() -> Unit =
if (header.textRes == R.string.ext_updates_pending) { if (header.textRes == MR.strings.ext_updates_pending) {
{ {
Button(onClick = { onClickUpdateAll() }) { Button(onClick = { onClickUpdateAll() }) {
Text( Text(
text = stringResource(R.string.ext_update_all), text = stringResource(MR.strings.ext_update_all),
style = LocalTextStyle.current.copy( style = LocalTextStyle.current.copy(
color = MaterialTheme.colorScheme.onPrimary, color = MaterialTheme.colorScheme.onPrimary,
), ),
@ -148,14 +148,12 @@ private fun ExtensionContent(
} }
ExtensionHeader( ExtensionHeader(
textRes = header.textRes, textRes = header.textRes,
modifier = Modifier.animateItemPlacement(),
action = action, action = action,
) )
} }
is ExtensionUiModel.Header.Text -> { is ExtensionUiModel.Header.Text -> {
ExtensionHeader( ExtensionHeader(
text = header.text, text = header.text,
modifier = Modifier.animateItemPlacement(),
) )
} }
} }
@ -167,7 +165,6 @@ private fun ExtensionContent(
key = { "extension-${it.hashCode()}" }, key = { "extension-${it.hashCode()}" },
) { item -> ) { item ->
ExtensionItem( ExtensionItem(
modifier = Modifier.animateItemPlacement(),
item = item, item = item,
onClickItem = { onClickItem = {
when (it) { when (it) {
@ -307,10 +304,10 @@ private fun ExtensionItemContent(
} }
val warning = when { val warning = when {
extension is Extension.Untrusted -> R.string.ext_untrusted extension is Extension.Untrusted -> MR.strings.ext_untrusted
extension is Extension.Installed && extension.isUnofficial -> R.string.ext_unofficial extension is Extension.Installed && extension.isUnofficial -> MR.strings.ext_unofficial
extension is Extension.Installed && extension.isObsolete -> R.string.ext_obsolete extension is Extension.Installed && extension.isObsolete -> MR.strings.ext_obsolete
extension.isNsfw -> R.string.ext_nsfw_short extension.isNsfw -> MR.strings.ext_nsfw_short
else -> null else -> null
} }
if (warning != null) { if (warning != null) {
@ -326,9 +323,9 @@ private fun ExtensionItemContent(
DotSeparatorNoSpaceText() DotSeparatorNoSpaceText()
Text( Text(
text = when (installStep) { text = when (installStep) {
InstallStep.Pending -> stringResource(R.string.ext_pending) InstallStep.Pending -> stringResource(MR.strings.ext_pending)
InstallStep.Downloading -> stringResource(R.string.ext_downloading) InstallStep.Downloading -> stringResource(MR.strings.ext_downloading)
InstallStep.Installing -> stringResource(R.string.ext_installing) InstallStep.Installing -> stringResource(MR.strings.ext_installing)
else -> error("Must not show non-install process text") else -> error("Must not show non-install process text")
}, },
) )
@ -354,19 +351,19 @@ private fun ExtensionItemActions(
) { ) {
Text( Text(
text = when (installStep) { text = when (installStep) {
InstallStep.Installed -> stringResource(R.string.ext_installed) InstallStep.Installed -> stringResource(MR.strings.ext_installed)
InstallStep.Error -> stringResource(R.string.action_retry) InstallStep.Error -> stringResource(MR.strings.action_retry)
InstallStep.Idle -> { InstallStep.Idle -> {
when (extension) { when (extension) {
is Extension.Installed -> { is Extension.Installed -> {
if (extension.hasUpdate) { if (extension.hasUpdate) {
stringResource(R.string.ext_update) stringResource(MR.strings.ext_update)
} else { } else {
stringResource(R.string.action_settings) stringResource(MR.strings.action_settings)
} }
} }
is Extension.Untrusted -> stringResource(R.string.ext_trust) is Extension.Untrusted -> stringResource(MR.strings.ext_trust)
is Extension.Available -> stringResource(R.string.ext_install) is Extension.Available -> stringResource(MR.strings.ext_install)
} }
} }
else -> error("Must not show install process text") else -> error("Must not show install process text")
@ -377,7 +374,7 @@ private fun ExtensionItemActions(
IconButton(onClick = { onClickItemCancel(extension) }) { IconButton(onClick = { onClickItemCancel(extension) }) {
Icon( Icon(
imageVector = Icons.Outlined.Close, imageVector = Icons.Outlined.Close,
contentDescription = stringResource(R.string.action_cancel), contentDescription = stringResource(MR.strings.action_cancel),
) )
} }
} }
@ -386,7 +383,7 @@ private fun ExtensionItemActions(
@Composable @Composable
private fun ExtensionHeader( private fun ExtensionHeader(
@StringRes textRes: Int, textRes: StringResource,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
action: @Composable RowScope.() -> Unit = {}, action: @Composable RowScope.() -> Unit = {},
) { ) {
@ -426,19 +423,19 @@ private fun ExtensionTrustDialog(
) { ) {
AlertDialog( AlertDialog(
title = { title = {
Text(text = stringResource(R.string.untrusted_extension)) Text(text = stringResource(MR.strings.untrusted_extension))
}, },
text = { text = {
Text(text = stringResource(R.string.untrusted_extension_message)) Text(text = stringResource(MR.strings.untrusted_extension_message))
}, },
confirmButton = { confirmButton = {
TextButton(onClick = onClickConfirm) { TextButton(onClick = onClickConfirm) {
Text(text = stringResource(R.string.ext_trust)) Text(text = stringResource(MR.strings.ext_trust))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onClickDismiss) { TextButton(onClick = onClickDismiss) {
Text(text = stringResource(R.string.ext_uninstall)) Text(text = stringResource(MR.strings.ext_uninstall))
} }
}, },
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,

View File

@ -7,9 +7,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.manga.components.BaseMangaListItem import eu.kanade.presentation.manga.components.BaseMangaListItem
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrateMangaScreenModel import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrateMangaScreenModel
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.FastScrollLazyColumn import tachiyomi.presentation.core.components.FastScrollLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
@ -33,7 +33,7 @@ fun MigrateMangaScreen(
) { contentPadding -> ) { contentPadding ->
if (state.isEmpty) { if (state.isEmpty) {
EmptyScreen( EmptyScreen(
textResource = R.string.empty_screen, stringRes = MR.strings.empty_screen,
modifier = Modifier.padding(contentPadding), modifier = Modifier.padding(contentPadding),
) )
return@Scaffold return@Scaffold

View File

@ -20,21 +20,21 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import eu.kanade.domain.source.interactor.SetMigrateSorting import eu.kanade.domain.source.interactor.SetMigrateSorting
import eu.kanade.presentation.browse.components.BaseSourceItem import eu.kanade.presentation.browse.components.BaseSourceItem
import eu.kanade.presentation.browse.components.SourceIcon import eu.kanade.presentation.browse.components.SourceIcon
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrateSourceScreenModel import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrateSourceScreenModel
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.Source
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.Badge import tachiyomi.presentation.core.components.Badge
import tachiyomi.presentation.core.components.BadgeGroup import tachiyomi.presentation.core.components.BadgeGroup
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.Scroller.STICKY_HEADER_KEY_PREFIX import tachiyomi.presentation.core.components.Scroller.STICKY_HEADER_KEY_PREFIX
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.components.material.topSmallPaddingValues import tachiyomi.presentation.core.components.material.topSmallPaddingValues
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
import tachiyomi.presentation.core.theme.header import tachiyomi.presentation.core.theme.header
@ -53,7 +53,7 @@ fun MigrateSourceScreen(
when { when {
state.isLoading -> LoadingScreen(Modifier.padding(contentPadding)) state.isLoading -> LoadingScreen(Modifier.padding(contentPadding))
state.isEmpty -> EmptyScreen( state.isEmpty -> EmptyScreen(
textResource = R.string.information_empty_library, stringRes = MR.strings.information_empty_library,
modifier = Modifier.padding(contentPadding), modifier = Modifier.padding(contentPadding),
) )
else -> else ->
@ -95,7 +95,7 @@ private fun MigrateSourceList(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
Text( Text(
text = stringResource(R.string.migration_selection_prompt), text = stringResource(MR.strings.migration_selection_prompt),
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
style = MaterialTheme.typography.header, style = MaterialTheme.typography.header,
) )
@ -104,11 +104,11 @@ private fun MigrateSourceList(
when (sortingMode) { when (sortingMode) {
SetMigrateSorting.Mode.ALPHABETICAL -> Icon( SetMigrateSorting.Mode.ALPHABETICAL -> Icon(
Icons.Outlined.SortByAlpha, Icons.Outlined.SortByAlpha,
contentDescription = stringResource(R.string.action_sort_alpha), contentDescription = stringResource(MR.strings.action_sort_alpha),
) )
SetMigrateSorting.Mode.TOTAL -> Icon( SetMigrateSorting.Mode.TOTAL -> Icon(
Icons.Outlined.Numbers, Icons.Outlined.Numbers,
contentDescription = stringResource(R.string.action_sort_count), contentDescription = stringResource(MR.strings.action_sort_count),
) )
} }
} }
@ -116,11 +116,11 @@ private fun MigrateSourceList(
when (sortingDirection) { when (sortingDirection) {
SetMigrateSorting.Direction.ASCENDING -> Icon( SetMigrateSorting.Direction.ASCENDING -> Icon(
Icons.Outlined.ArrowUpward, Icons.Outlined.ArrowUpward,
contentDescription = stringResource(R.string.action_asc), contentDescription = stringResource(MR.strings.action_asc),
) )
SetMigrateSorting.Direction.DESCENDING -> Icon( SetMigrateSorting.Direction.DESCENDING -> Icon(
Icons.Outlined.ArrowDownward, Icons.Outlined.ArrowDownward,
contentDescription = stringResource(R.string.action_desc), contentDescription = stringResource(MR.strings.action_desc),
) )
} }
} }
@ -132,7 +132,6 @@ private fun MigrateSourceList(
key = { (source, _) -> "migrate-${source.id}" }, key = { (source, _) -> "migrate-${source.id}" },
) { (source, count) -> ) { (source, count) ->
MigrateSourceItem( MigrateSourceItem(
modifier = Modifier.animateItemPlacement(),
source = source, source = source,
count = count, count = count,
onClickItem = { onClickItem(source) }, onClickItem = { onClickItem(source) },
@ -190,7 +189,7 @@ private fun MigrateSourceItem(
if (source.isStub) { if (source.isStub) {
Text( Text(
modifier = Modifier.secondaryItemAlpha(), modifier = Modifier.secondaryItemAlpha(),
text = stringResource(R.string.not_installed), text = stringResource(MR.strings.not_installed),
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,

View File

@ -7,16 +7,16 @@ import androidx.compose.material3.Checkbox
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.browse.components.BaseSourceItem import eu.kanade.presentation.browse.components.BaseSourceItem
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.browse.source.SourcesFilterScreenModel import eu.kanade.tachiyomi.ui.browse.source.SourcesFilterScreenModel
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.Source
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.FastScrollLazyColumn import tachiyomi.presentation.core.components.FastScrollLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
@Composable @Composable
@ -29,7 +29,7 @@ fun SourcesFilterScreen(
Scaffold( Scaffold(
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
AppBar( AppBar(
title = stringResource(R.string.label_sources), title = stringResource(MR.strings.label_sources),
navigateUp = navigateUp, navigateUp = navigateUp,
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
) )
@ -37,7 +37,7 @@ fun SourcesFilterScreen(
) { contentPadding -> ) { contentPadding ->
if (state.isEmpty) { if (state.isEmpty) {
EmptyScreen( EmptyScreen(
textResource = R.string.source_filter_empty_screen, stringRes = MR.strings.source_filter_empty_screen,
modifier = Modifier.padding(contentPadding), modifier = Modifier.padding(contentPadding),
) )
return@Scaffold return@Scaffold
@ -68,7 +68,6 @@ private fun SourcesFilterContent(
contentType = "source-filter-header", contentType = "source-filter-header",
) { ) {
SourcesFilterHeader( SourcesFilterHeader(
modifier = Modifier.animateItemPlacement(),
language = language, language = language,
enabled = enabled, enabled = enabled,
onClickItem = onClickLanguage, onClickItem = onClickLanguage,
@ -81,7 +80,6 @@ private fun SourcesFilterContent(
contentType = { "source-filter-item" }, contentType = { "source-filter-item" },
) { source -> ) { source ->
SourcesFilterItem( SourcesFilterItem(
modifier = Modifier.animateItemPlacement(),
source = source, source = source,
enabled = "${source.id}" !in state.disabledSources, enabled = "${source.id}" !in state.disabledSources,
onClickItem = onClickSource, onClickItem = onClickSource,

View File

@ -19,19 +19,19 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.browse.components.BaseSourceItem import eu.kanade.presentation.browse.components.BaseSourceItem
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.browse.source.SourcesScreenModel import eu.kanade.tachiyomi.ui.browse.source.SourcesScreenModel
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
import tachiyomi.domain.source.model.Pin import tachiyomi.domain.source.model.Pin
import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.Source
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.components.material.topSmallPaddingValues import tachiyomi.presentation.core.components.material.topSmallPaddingValues
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
import tachiyomi.presentation.core.theme.header import tachiyomi.presentation.core.theme.header
@ -49,7 +49,7 @@ fun SourcesScreen(
when { when {
state.isLoading -> LoadingScreen(Modifier.padding(contentPadding)) state.isLoading -> LoadingScreen(Modifier.padding(contentPadding))
state.isEmpty -> EmptyScreen( state.isEmpty -> EmptyScreen(
textResource = R.string.source_empty_screen, stringRes = MR.strings.source_empty_screen,
modifier = Modifier.padding(contentPadding), modifier = Modifier.padding(contentPadding),
) )
else -> { else -> {
@ -74,12 +74,10 @@ fun SourcesScreen(
when (model) { when (model) {
is SourceUiModel.Header -> { is SourceUiModel.Header -> {
SourceHeader( SourceHeader(
modifier = Modifier.animateItemPlacement(),
language = model.language, language = model.language,
) )
} }
is SourceUiModel.Item -> SourceItem( is SourceUiModel.Item -> SourceItem(
modifier = Modifier.animateItemPlacement(),
source = model.source, source = model.source,
onClickItem = onClickItem, onClickItem = onClickItem,
onLongClickItem = onLongClickItem, onLongClickItem = onLongClickItem,
@ -123,7 +121,7 @@ private fun SourceItem(
if (source.supportsLatest) { if (source.supportsLatest) {
TextButton(onClick = { onClickItem(source, Listing.Latest) }) { TextButton(onClick = { onClickItem(source, Listing.Latest) }) {
Text( Text(
text = stringResource(R.string.latest), text = stringResource(MR.strings.latest),
style = LocalTextStyle.current.copy( style = LocalTextStyle.current.copy(
color = MaterialTheme.colorScheme.primary, color = MaterialTheme.colorScheme.primary,
), ),
@ -151,7 +149,7 @@ private fun SourcePinButton(
alpha = SecondaryItemAlpha, alpha = SecondaryItemAlpha,
) )
} }
val description = if (isPinned) R.string.action_unpin else R.string.action_pin val description = if (isPinned) MR.strings.action_unpin else MR.strings.action_pin
IconButton(onClick = onClick) { IconButton(onClick = onClick) {
Icon( Icon(
imageVector = icon, imageVector = icon,
@ -174,7 +172,7 @@ fun SourceOptionsDialog(
}, },
text = { text = {
Column { Column {
val textId = if (Pin.Pinned in source.pin) R.string.action_unpin else R.string.action_pin val textId = if (Pin.Pinned in source.pin) MR.strings.action_unpin else MR.strings.action_pin
Text( Text(
text = stringResource(textId), text = stringResource(textId),
modifier = Modifier modifier = Modifier
@ -184,7 +182,7 @@ fun SourceOptionsDialog(
) )
if (!source.isLocal()) { if (!source.isLocal()) {
Text( Text(
text = stringResource(R.string.action_disable), text = stringResource(MR.strings.action_disable),
modifier = Modifier modifier = Modifier
.clickable(onClick = onClickDisable) .clickable(onClick = onClickDisable)
.fillMaxWidth() .fillMaxWidth()

View File

@ -4,11 +4,9 @@ import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource
import eu.kanade.tachiyomi.R
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun RemoveMangaDialog( fun RemoveMangaDialog(
@ -20,7 +18,7 @@ fun RemoveMangaDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
confirmButton = { confirmButton = {
@ -30,14 +28,14 @@ fun RemoveMangaDialog(
onConfirm() onConfirm()
}, },
) { ) {
Text(text = stringResource(R.string.action_remove)) Text(text = stringResource(MR.strings.action_remove))
} }
}, },
title = { title = {
Text(text = stringResource(R.string.are_you_sure)) Text(text = stringResource(MR.strings.are_you_sure))
}, },
text = { text = {
Text(text = stringResource(R.string.remove_manga, mangaToRemove.title)) Text(text = stringResource(MR.strings.remove_manga, mangaToRemove.title))
}, },
) )
} }

View File

@ -10,18 +10,18 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.AppBarTitle import eu.kanade.presentation.components.AppBarTitle
import eu.kanade.presentation.components.DropdownMenu import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.components.RadioMenuItem import eu.kanade.presentation.components.RadioMenuItem
import eu.kanade.presentation.components.SearchToolbar import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.library.model.LibraryDisplayMode import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.source.local.LocalSource import tachiyomi.source.local.LocalSource
@Composable @Composable
@ -58,7 +58,7 @@ fun BrowseSourceToolbar(
.apply { .apply {
add( add(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_display_mode), title = stringResource(MR.strings.action_display_mode),
icon = if (displayMode == LibraryDisplayMode.List) { icon = if (displayMode == LibraryDisplayMode.List) {
Icons.AutoMirrored.Filled.ViewList Icons.AutoMirrored.Filled.ViewList
} else { } else {
@ -70,14 +70,14 @@ fun BrowseSourceToolbar(
if (isLocalSource) { if (isLocalSource) {
add( add(
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.label_help), title = stringResource(MR.strings.label_help),
onClick = onHelpClick, onClick = onHelpClick,
), ),
) )
} else { } else {
add( add(
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_open_in_web_view), title = stringResource(MR.strings.action_open_in_web_view),
onClick = onWebViewClick, onClick = onWebViewClick,
), ),
) )
@ -85,7 +85,7 @@ fun BrowseSourceToolbar(
if (isConfigurableSource) { if (isConfigurableSource) {
add( add(
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_settings), title = stringResource(MR.strings.action_settings),
onClick = onSettingsClick, onClick = onSettingsClick,
), ),
) )
@ -99,21 +99,21 @@ fun BrowseSourceToolbar(
onDismissRequest = { selectingDisplayMode = false }, onDismissRequest = { selectingDisplayMode = false },
) { ) {
RadioMenuItem( RadioMenuItem(
text = { Text(text = stringResource(R.string.action_display_comfortable_grid)) }, text = { Text(text = stringResource(MR.strings.action_display_comfortable_grid)) },
isChecked = displayMode == LibraryDisplayMode.ComfortableGrid, isChecked = displayMode == LibraryDisplayMode.ComfortableGrid,
) { ) {
selectingDisplayMode = false selectingDisplayMode = false
onDisplayModeChange(LibraryDisplayMode.ComfortableGrid) onDisplayModeChange(LibraryDisplayMode.ComfortableGrid)
} }
RadioMenuItem( RadioMenuItem(
text = { Text(text = stringResource(R.string.action_display_grid)) }, text = { Text(text = stringResource(MR.strings.action_display_grid)) },
isChecked = displayMode == LibraryDisplayMode.CompactGrid, isChecked = displayMode == LibraryDisplayMode.CompactGrid,
) { ) {
selectingDisplayMode = false selectingDisplayMode = false
onDisplayModeChange(LibraryDisplayMode.CompactGrid) onDisplayModeChange(LibraryDisplayMode.CompactGrid)
} }
RadioMenuItem( RadioMenuItem(
text = { Text(text = stringResource(R.string.action_display_list)) }, text = { Text(text = stringResource(MR.strings.action_display_list)) },
isChecked = displayMode == LibraryDisplayMode.List, isChecked = displayMode == LibraryDisplayMode.List,
) { ) {
selectingDisplayMode = false selectingDisplayMode = false

View File

@ -13,15 +13,15 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.library.components.CommonMangaItemDefaults import eu.kanade.presentation.library.components.CommonMangaItemDefaults
import eu.kanade.presentation.library.components.MangaComfortableGridItem import eu.kanade.presentation.library.components.MangaComfortableGridItem
import eu.kanade.tachiyomi.R
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.MangaCover import tachiyomi.domain.manga.model.MangaCover
import tachiyomi.domain.manga.model.asMangaCover import tachiyomi.domain.manga.model.asMangaCover
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun GlobalSearchCardRow( fun GlobalSearchCardRow(
@ -78,7 +78,7 @@ private fun MangaItem(
@Composable @Composable
private fun EmptyResultItem() { private fun EmptyResultItem() {
Text( Text(
text = stringResource(R.string.no_results_found), text = stringResource(MR.strings.no_results_found),
modifier = Modifier modifier = Modifier
.padding( .padding(
horizontal = MaterialTheme.padding.medium, horizontal = MaterialTheme.padding.medium,

View File

@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowForward import androidx.compose.material.icons.automirrored.outlined.ArrowForward
import androidx.compose.material.icons.outlined.ArrowForward
import androidx.compose.material.icons.outlined.Error import androidx.compose.material.icons.outlined.Error
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -22,11 +21,11 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun GlobalSearchResultItem( fun GlobalSearchResultItem(
@ -93,7 +92,7 @@ fun GlobalSearchErrorResultItem(message: String?) {
Icon(imageVector = Icons.Outlined.Error, contentDescription = null) Icon(imageVector = Icons.Outlined.Error, contentDescription = null)
Spacer(Modifier.height(4.dp)) Spacer(Modifier.height(4.dp))
Text( Text(
text = message ?: stringResource(R.string.unknown_error), text = message ?: stringResource(MR.strings.unknown_error),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
) )
} }

View File

@ -26,11 +26,11 @@ import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.SearchToolbar import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SourceFilter import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SourceFilter
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun GlobalSearchToolbar( fun GlobalSearchToolbar(
@ -85,7 +85,7 @@ fun GlobalSearchToolbar(
) )
}, },
label = { label = {
Text(text = stringResource(id = R.string.pinned_sources)) Text(text = stringResource(MR.strings.pinned_sources))
}, },
) )
FilterChip( FilterChip(
@ -100,7 +100,7 @@ fun GlobalSearchToolbar(
) )
}, },
label = { label = {
Text(text = stringResource(id = R.string.all)) Text(text = stringResource(MR.strings.all))
}, },
) )
@ -118,7 +118,7 @@ fun GlobalSearchToolbar(
) )
}, },
label = { label = {
Text(text = stringResource(id = R.string.has_results)) Text(text = stringResource(MR.strings.has_results))
}, },
) )
} }

View File

@ -2,19 +2,20 @@ package eu.kanade.presentation.category
import android.content.Context import android.content.Context
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource import tachiyomi.core.i18n.stringResource
import eu.kanade.tachiyomi.R
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
val Category.visualName: String val Category.visualName: String
@Composable @Composable
get() = when { get() = when {
isSystemCategory -> stringResource(R.string.label_default) isSystemCategory -> stringResource(MR.strings.label_default)
else -> name else -> name
} }
fun Category.visualName(context: Context): String = fun Category.visualName(context: Context): String =
when { when {
isSystemCategory -> context.getString(R.string.label_default) isSystemCategory -> context.stringResource(MR.strings.label_default)
else -> name else -> name
} }

View File

@ -12,18 +12,18 @@ import androidx.compose.material.icons.outlined.SortByAlpha
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.category.components.CategoryFloatingActionButton import eu.kanade.presentation.category.components.CategoryFloatingActionButton
import eu.kanade.presentation.category.components.CategoryListItem import eu.kanade.presentation.category.components.CategoryListItem
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.category.CategoryScreenState import eu.kanade.tachiyomi.ui.category.CategoryScreenState
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.components.material.topSmallPaddingValues import tachiyomi.presentation.core.components.material.topSmallPaddingValues
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.util.plus import tachiyomi.presentation.core.util.plus
@ -42,13 +42,13 @@ fun CategoryScreen(
Scaffold( Scaffold(
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
AppBar( AppBar(
title = stringResource(R.string.action_edit_categories), title = stringResource(MR.strings.action_edit_categories),
navigateUp = navigateUp, navigateUp = navigateUp,
actions = { actions = {
AppBarActions( AppBarActions(
persistentListOf( persistentListOf(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_sort), title = stringResource(MR.strings.action_sort),
icon = Icons.Outlined.SortByAlpha, icon = Icons.Outlined.SortByAlpha,
onClick = onClickSortAlphabetically, onClick = onClickSortAlphabetically,
), ),
@ -67,7 +67,7 @@ fun CategoryScreen(
) { paddingValues -> ) { paddingValues ->
if (state.isEmpty) { if (state.isEmpty) {
EmptyScreen( EmptyScreen(
textResource = R.string.information_empty_category, stringRes = MR.strings.information_empty_category,
modifier = Modifier.padding(paddingValues), modifier = Modifier.padding(paddingValues),
) )
return@Scaffold return@Scaffold
@ -107,7 +107,6 @@ private fun CategoryContent(
key = { _, category -> "category-${category.id}" }, key = { _, category -> "category-${category.id}" },
) { index, category -> ) { index, category ->
CategoryListItem( CategoryListItem(
modifier = Modifier.animateItemPlacement(),
category = category, category = category,
canMoveUp = index != 0, canMoveUp = index != 0,
canMoveDown = index != categories.lastIndex, canMoveDown = index != categories.lastIndex,

View File

@ -25,14 +25,14 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.res.stringResource
import eu.kanade.core.preference.asToggleableState import eu.kanade.core.preference.asToggleableState
import eu.kanade.presentation.category.visualName import eu.kanade.presentation.category.visualName
import eu.kanade.tachiyomi.R
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import tachiyomi.core.preference.CheckboxState import tachiyomi.core.preference.CheckboxState
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
@Composable @Composable
@ -56,28 +56,28 @@ fun CategoryCreateDialog(
onDismissRequest() onDismissRequest()
}, },
) { ) {
Text(text = stringResource(R.string.action_add)) Text(text = stringResource(MR.strings.action_add))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
title = { title = {
Text(text = stringResource(R.string.action_add_category)) Text(text = stringResource(MR.strings.action_add_category))
}, },
text = { text = {
OutlinedTextField( OutlinedTextField(
modifier = Modifier.focusRequester(focusRequester), modifier = Modifier.focusRequester(focusRequester),
value = name, value = name,
onValueChange = { name = it }, onValueChange = { name = it },
label = { Text(text = stringResource(R.string.name)) }, label = { Text(text = stringResource(MR.strings.name)) },
supportingText = { supportingText = {
val msgRes = if (name.isNotEmpty() && nameAlreadyExists) { val msgRes = if (name.isNotEmpty() && nameAlreadyExists) {
R.string.error_category_exists MR.strings.error_category_exists
} else { } else {
R.string.information_required_plain MR.strings.information_required_plain
} }
Text(text = stringResource(msgRes)) Text(text = stringResource(msgRes))
}, },
@ -117,16 +117,16 @@ fun CategoryRenameDialog(
onDismissRequest() onDismissRequest()
}, },
) { ) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
title = { title = {
Text(text = stringResource(R.string.action_rename_category)) Text(text = stringResource(MR.strings.action_rename_category))
}, },
text = { text = {
OutlinedTextField( OutlinedTextField(
@ -136,12 +136,12 @@ fun CategoryRenameDialog(
valueHasChanged = name != it valueHasChanged = name != it
name = it name = it
}, },
label = { Text(text = stringResource(R.string.name)) }, label = { Text(text = stringResource(MR.strings.name)) },
supportingText = { supportingText = {
val msgRes = if (valueHasChanged && nameAlreadyExists) { val msgRes = if (valueHasChanged && nameAlreadyExists) {
R.string.error_category_exists MR.strings.error_category_exists
} else { } else {
R.string.information_required_plain MR.strings.information_required_plain
} }
Text(text = stringResource(msgRes)) Text(text = stringResource(msgRes))
}, },
@ -171,19 +171,19 @@ fun CategoryDeleteDialog(
onDelete() onDelete()
onDismissRequest() onDismissRequest()
}) { }) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
title = { title = {
Text(text = stringResource(R.string.delete_category)) Text(text = stringResource(MR.strings.delete_category))
}, },
text = { text = {
Text(text = stringResource(R.string.delete_category_confirmation, category.name)) Text(text = stringResource(MR.strings.delete_category_confirmation, category.name))
}, },
) )
} }
@ -200,19 +200,19 @@ fun CategorySortAlphabeticallyDialog(
onSort() onSort()
onDismissRequest() onDismissRequest()
}) { }) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
title = { title = {
Text(text = stringResource(R.string.action_sort_category)) Text(text = stringResource(MR.strings.action_sort_category))
}, },
text = { text = {
Text(text = stringResource(R.string.sort_category_confirmation)) Text(text = stringResource(MR.strings.sort_category_confirmation))
}, },
) )
} }
@ -234,14 +234,14 @@ fun ChangeCategoryDialog(
onEditCategories() onEditCategories()
}, },
) { ) {
Text(text = stringResource(R.string.action_edit_categories)) Text(text = stringResource(MR.strings.action_edit_categories))
} }
}, },
title = { title = {
Text(text = stringResource(R.string.action_move_category)) Text(text = stringResource(MR.strings.action_move_category))
}, },
text = { text = {
Text(text = stringResource(R.string.information_empty_category_dialog)) Text(text = stringResource(MR.strings.information_empty_category_dialog))
}, },
) )
return return
@ -255,11 +255,11 @@ fun ChangeCategoryDialog(
onDismissRequest() onDismissRequest()
onEditCategories() onEditCategories()
}) { }) {
Text(text = stringResource(R.string.action_edit)) Text(text = stringResource(MR.strings.action_edit))
} }
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
tachiyomi.presentation.core.components.material.TextButton(onClick = onDismissRequest) { tachiyomi.presentation.core.components.material.TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
tachiyomi.presentation.core.components.material.TextButton( tachiyomi.presentation.core.components.material.TextButton(
onClick = { onClick = {
@ -274,12 +274,12 @@ fun ChangeCategoryDialog(
) )
}, },
) { ) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
} }
}, },
title = { title = {
Text(text = stringResource(R.string.action_move_category)) Text(text = stringResource(MR.strings.action_move_category))
}, },
text = { text = {
Column( Column(

View File

@ -6,9 +6,9 @@ import androidx.compose.material.icons.outlined.Add
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource import tachiyomi.i18n.MR
import eu.kanade.tachiyomi.R
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrollingUp import tachiyomi.presentation.core.util.isScrollingUp
@ -18,7 +18,7 @@ fun CategoryFloatingActionButton(
onCreate: () -> Unit, onCreate: () -> Unit,
) { ) {
ExtendedFloatingActionButton( ExtendedFloatingActionButton(
text = { Text(text = stringResource(R.string.action_add)) }, text = { Text(text = stringResource(MR.strings.action_add)) },
icon = { Icon(imageVector = Icons.Outlined.Add, contentDescription = null) }, icon = { Icon(imageVector = Icons.Outlined.Add, contentDescription = null) },
onClick = onCreate, onClick = onCreate,
expanded = lazyListState.isScrollingUp() || lazyListState.isScrolledToEnd(), expanded = lazyListState.isScrollingUp() || lazyListState.isScrolledToEnd(),

View File

@ -11,7 +11,6 @@ import androidx.compose.material.icons.outlined.ArrowDropDown
import androidx.compose.material.icons.outlined.ArrowDropUp import androidx.compose.material.icons.outlined.ArrowDropUp
import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Edit import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material.icons.outlined.Label
import androidx.compose.material3.ElevatedCard import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
@ -20,10 +19,10 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import eu.kanade.tachiyomi.R
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun CategoryListItem( fun CategoryListItem(
@ -74,11 +73,11 @@ fun CategoryListItem(
IconButton(onClick = onRename) { IconButton(onClick = onRename) {
Icon( Icon(
imageVector = Icons.Outlined.Edit, imageVector = Icons.Outlined.Edit,
contentDescription = stringResource(R.string.action_rename_category), contentDescription = stringResource(MR.strings.action_rename_category),
) )
} }
IconButton(onClick = onDelete) { IconButton(onClick = onDelete) {
Icon(imageVector = Icons.Outlined.Delete, contentDescription = stringResource(R.string.action_delete)) Icon(imageVector = Icons.Outlined.Delete, contentDescription = stringResource(MR.strings.action_delete))
} }
} }
} }

View File

@ -50,8 +50,9 @@ import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.clearFocusOnSoftKeyboardHide import tachiyomi.presentation.core.util.clearFocusOnSoftKeyboardHide
import tachiyomi.presentation.core.util.runOnEnterKeyPressed import tachiyomi.presentation.core.util.runOnEnterKeyPressed
import tachiyomi.presentation.core.util.secondaryItemAlpha import tachiyomi.presentation.core.util.secondaryItemAlpha
@ -133,7 +134,7 @@ fun AppBar(
IconButton(onClick = onCancelActionMode) { IconButton(onClick = onCancelActionMode) {
Icon( Icon(
imageVector = Icons.Outlined.Close, imageVector = Icons.Outlined.Close,
contentDescription = stringResource(R.string.action_cancel), contentDescription = stringResource(MR.strings.action_cancel),
) )
} }
} else { } else {
@ -218,7 +219,7 @@ fun AppBarActions(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(), positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
tooltip = { tooltip = {
PlainTooltip { PlainTooltip {
Text(stringResource(R.string.abc_action_menu_overflow_description)) Text(stringResource(MR.strings.action_menu_overflow_description))
} }
}, },
state = rememberTooltipState(), state = rememberTooltipState(),
@ -228,7 +229,7 @@ fun AppBarActions(
) { ) {
Icon( Icon(
Icons.Outlined.MoreVert, Icons.Outlined.MoreVert,
contentDescription = stringResource(R.string.abc_action_menu_overflow_description), contentDescription = stringResource(MR.strings.action_menu_overflow_description),
) )
} }
} }
@ -253,7 +254,7 @@ fun AppBarActions(
/** /**
* @param searchEnabled Set to false if you don't want to show search action. * @param searchEnabled Set to false if you don't want to show search action.
* @param searchQuery If null, use normal toolbar. * @param searchQuery If null, use normal toolbar.
* @param placeholderText If null, [R.string.action_search_hint] is used. * @param placeholderText If null, [MR.strings.action_search_hint] is used.
*/ */
@Composable @Composable
fun SearchToolbar( fun SearchToolbar(
@ -317,7 +318,7 @@ fun SearchToolbar(
placeholder = { placeholder = {
Text( Text(
modifier = Modifier.secondaryItemAlpha(), modifier = Modifier.secondaryItemAlpha(),
text = (placeholderText ?: stringResource(R.string.action_search_hint)), text = (placeholderText ?: stringResource(MR.strings.action_search_hint)),
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.titleMedium.copy( style = MaterialTheme.typography.titleMedium.copy(
@ -342,7 +343,7 @@ fun SearchToolbar(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(), positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
tooltip = { tooltip = {
PlainTooltip { PlainTooltip {
Text(stringResource(R.string.action_search)) Text(stringResource(MR.strings.action_search))
} }
}, },
state = rememberTooltipState(), state = rememberTooltipState(),
@ -352,7 +353,7 @@ fun SearchToolbar(
) { ) {
Icon( Icon(
Icons.Outlined.Search, Icons.Outlined.Search,
contentDescription = stringResource(R.string.action_search), contentDescription = stringResource(MR.strings.action_search),
) )
} }
} }
@ -361,7 +362,7 @@ fun SearchToolbar(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(), positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
tooltip = { tooltip = {
PlainTooltip { PlainTooltip {
Text(stringResource(R.string.action_reset)) Text(stringResource(MR.strings.action_reset))
} }
}, },
state = rememberTooltipState(), state = rememberTooltipState(),
@ -374,7 +375,7 @@ fun SearchToolbar(
) { ) {
Icon( Icon(
Icons.Outlined.Close, Icons.Outlined.Close,
contentDescription = stringResource(R.string.action_reset), contentDescription = stringResource(MR.strings.action_reset),
) )
} }
} }
@ -394,7 +395,7 @@ fun UpIcon(navigationIcon: ImageVector? = null) {
?: Icons.AutoMirrored.Outlined.ArrowBack ?: Icons.AutoMirrored.Outlined.ArrowBack
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = stringResource(R.string.abc_action_bar_up_description), contentDescription = stringResource(MR.strings.action_bar_up_description),
) )
} }

View File

@ -1,6 +1,5 @@
package eu.kanade.presentation.components package eu.kanade.presentation.components
import androidx.annotation.StringRes
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically import androidx.compose.animation.expandVertically
import androidx.compose.animation.shrinkVertically import androidx.compose.animation.shrinkVertically
@ -26,13 +25,14 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.SubcomposeLayout import androidx.compose.ui.layout.SubcomposeLayout
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEach import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastMap import androidx.compose.ui.util.fastMap
import androidx.compose.ui.util.fastMaxBy import androidx.compose.ui.util.fastMaxBy
import eu.kanade.tachiyomi.R import dev.icerock.moko.resources.StringResource
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
val DownloadedOnlyBannerBackgroundColor val DownloadedOnlyBannerBackgroundColor
@Composable get() = MaterialTheme.colorScheme.tertiary @Composable get() = MaterialTheme.colorScheme.tertiary
@ -43,7 +43,7 @@ val IndexingBannerBackgroundColor
@Composable @Composable
fun WarningBanner( fun WarningBanner(
@StringRes textRes: Int, textRes: StringResource,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Text( Text(
@ -127,7 +127,7 @@ fun AppStateBanners(
@Composable @Composable
private fun DownloadedOnlyModeBanner(modifier: Modifier = Modifier) { private fun DownloadedOnlyModeBanner(modifier: Modifier = Modifier) {
Text( Text(
text = stringResource(R.string.label_downloaded_only), text = stringResource(MR.strings.label_downloaded_only),
modifier = Modifier modifier = Modifier
.background(DownloadedOnlyBannerBackgroundColor) .background(DownloadedOnlyBannerBackgroundColor)
.fillMaxWidth() .fillMaxWidth()
@ -142,7 +142,7 @@ private fun DownloadedOnlyModeBanner(modifier: Modifier = Modifier) {
@Composable @Composable
private fun IncognitoModeBanner(modifier: Modifier = Modifier) { private fun IncognitoModeBanner(modifier: Modifier = Modifier) {
Text( Text(
text = stringResource(R.string.pref_incognito_mode), text = stringResource(MR.strings.pref_incognito_mode),
modifier = Modifier modifier = Modifier
.background(IncognitoModeBannerBackgroundColor) .background(IncognitoModeBannerBackgroundColor)
.fillMaxWidth() .fillMaxWidth()
@ -173,7 +173,7 @@ private fun IndexingDownloadBanner(modifier: Modifier = Modifier) {
) )
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(
text = stringResource(R.string.download_notifier_cache_renewal), text = stringResource(MR.strings.download_notifier_cache_renewal),
color = MaterialTheme.colorScheme.onSecondary, color = MaterialTheme.colorScheme.onSecondary,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,

View File

@ -3,10 +3,10 @@ package eu.kanade.presentation.components
import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.manga.DownloadAction import eu.kanade.presentation.manga.DownloadAction
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun DownloadDropdownMenu( fun DownloadDropdownMenu(
@ -19,11 +19,11 @@ fun DownloadDropdownMenu(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
) { ) {
listOfNotNull( listOfNotNull(
DownloadAction.NEXT_1_CHAPTER to pluralStringResource(R.plurals.download_amount, 1, 1), DownloadAction.NEXT_1_CHAPTER to pluralStringResource(MR.plurals.download_amount, 1, 1),
DownloadAction.NEXT_5_CHAPTERS to pluralStringResource(R.plurals.download_amount, 5, 5), DownloadAction.NEXT_5_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 5, 5),
DownloadAction.NEXT_10_CHAPTERS to pluralStringResource(R.plurals.download_amount, 10, 10), DownloadAction.NEXT_10_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 10, 10),
DownloadAction.NEXT_25_CHAPTERS to pluralStringResource(R.plurals.download_amount, 25, 25), DownloadAction.NEXT_25_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 25, 25),
DownloadAction.UNREAD_CHAPTERS to stringResource(R.string.download_unread), DownloadAction.UNREAD_CHAPTERS to stringResource(MR.strings.download_unread),
).map { (downloadAction, string) -> ).map { (downloadAction, string) ->
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = string) }, text = { Text(text = string) },

View File

@ -15,11 +15,11 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.PopupProperties import androidx.compose.ui.window.PopupProperties
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import androidx.compose.material3.DropdownMenu as ComposeDropdownMenu import androidx.compose.material3.DropdownMenu as ComposeDropdownMenu
@Composable @Composable
@ -54,13 +54,13 @@ fun RadioMenuItem(
if (isChecked) { if (isChecked) {
Icon( Icon(
imageVector = Icons.Outlined.RadioButtonChecked, imageVector = Icons.Outlined.RadioButtonChecked,
contentDescription = stringResource(R.string.selected), contentDescription = stringResource(MR.strings.selected),
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
) )
} else { } else {
Icon( Icon(
imageVector = Icons.Outlined.RadioButtonUnchecked, imageVector = Icons.Outlined.RadioButtonUnchecked,
contentDescription = stringResource(R.string.not_selected), contentDescription = stringResource(MR.strings.not_selected),
) )
} }
}, },

View File

@ -2,14 +2,13 @@ package eu.kanade.presentation.components
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material.icons.outlined.Refresh import androidx.compose.material.icons.outlined.Refresh
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.EmptyScreenAction import tachiyomi.presentation.core.screens.EmptyScreenAction
@ -19,7 +18,7 @@ private fun NoActionPreview() {
TachiyomiTheme { TachiyomiTheme {
Surface { Surface {
EmptyScreen( EmptyScreen(
textResource = R.string.empty_screen, stringRes = MR.strings.empty_screen,
) )
} }
} }
@ -31,15 +30,15 @@ private fun WithActionPreview() {
TachiyomiTheme { TachiyomiTheme {
Surface { Surface {
EmptyScreen( EmptyScreen(
textResource = R.string.empty_screen, stringRes = MR.strings.empty_screen,
actions = persistentListOf( actions = persistentListOf(
EmptyScreenAction( EmptyScreenAction(
stringResId = R.string.action_retry, stringRes = MR.strings.action_retry,
icon = Icons.Outlined.Refresh, icon = Icons.Outlined.Refresh,
onClick = {}, onClick = {},
), ),
EmptyScreenAction( EmptyScreenAction(
stringResId = R.string.getting_started_guide, stringRes = MR.strings.getting_started_guide,
icon = Icons.AutoMirrored.Outlined.HelpOutline, icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = {}, onClick = {},
), ),

View File

@ -24,14 +24,14 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEachIndexed import androidx.compose.ui.util.fastForEachIndexed
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.HorizontalPager import tachiyomi.presentation.core.components.HorizontalPager
import tachiyomi.presentation.core.components.material.TabText import tachiyomi.presentation.core.components.material.TabText
import tachiyomi.presentation.core.i18n.stringResource
object TabbedDialogPaddings { object TabbedDialogPaddings {
val Horizontal = 24.dp val Horizontal = 24.dp
@ -94,7 +94,7 @@ private fun MoreMenu(
IconButton(onClick = { expanded = true }) { IconButton(onClick = { expanded = true }) {
Icon( Icon(
imageVector = Icons.Default.MoreVert, imageVector = Icons.Default.MoreVert,
contentDescription = stringResource(R.string.label_more), contentDescription = stringResource(MR.strings.label_more),
) )
} }
DropdownMenu( DropdownMenu(

View File

@ -1,6 +1,5 @@
package eu.kanade.presentation.components package eu.kanade.presentation.components
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.calculateEndPadding import androidx.compose.foundation.layout.calculateEndPadding
@ -20,17 +19,18 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource import dev.icerock.moko.resources.StringResource
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import tachiyomi.presentation.core.components.HorizontalPager import tachiyomi.presentation.core.components.HorizontalPager
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.TabText import tachiyomi.presentation.core.components.material.TabText
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun TabbedScreen( fun TabbedScreen(
@StringRes titleRes: Int, titleRes: StringResource,
tabs: ImmutableList<TabContent>, tabs: ImmutableList<TabContent>,
startIndex: Int? = null, startIndex: Int? = null,
searchQuery: String? = null, searchQuery: String? = null,
@ -96,7 +96,7 @@ fun TabbedScreen(
} }
data class TabContent( data class TabContent(
@StringRes val titleRes: Int, val titleRes: StringResource,
val badgeNumber: Int? = null, val badgeNumber: Int? = null,
val searchEnabled: Boolean = false, val searchEnabled: Boolean = false,
val actions: ImmutableList<AppBar.Action> = persistentListOf(), val actions: ImmutableList<AppBar.Action> = persistentListOf(),

View File

@ -13,13 +13,13 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.CrashLogUtil import eu.kanade.tachiyomi.util.CrashLogUtil
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.InfoScreen import tachiyomi.presentation.core.screens.InfoScreen
@Composable @Composable
@ -32,15 +32,15 @@ fun CrashScreen(
InfoScreen( InfoScreen(
icon = Icons.Outlined.BugReport, icon = Icons.Outlined.BugReport,
headingText = stringResource(R.string.crash_screen_title), headingText = stringResource(MR.strings.crash_screen_title),
subtitleText = stringResource(R.string.crash_screen_description, stringResource(R.string.app_name)), subtitleText = stringResource(MR.strings.crash_screen_description, stringResource(MR.strings.app_name)),
acceptText = stringResource(R.string.pref_dump_crash_logs), acceptText = stringResource(MR.strings.pref_dump_crash_logs),
onAcceptClick = { onAcceptClick = {
scope.launch { scope.launch {
CrashLogUtil(context).dumpLogs() CrashLogUtil(context).dumpLogs()
} }
}, },
rejectText = stringResource(R.string.crash_screen_restart_application), rejectText = stringResource(MR.strings.crash_screen_restart_application),
onRejectClick = onRestartClick, onRejectClick = onRestartClick,
) { ) {
Box( Box(

View File

@ -10,7 +10,6 @@ import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import eu.kanade.domain.ui.UiPreferences import eu.kanade.domain.ui.UiPreferences
@ -21,13 +20,14 @@ import eu.kanade.presentation.components.RelativeDateHeader
import eu.kanade.presentation.components.SearchToolbar import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.history.components.HistoryItem import eu.kanade.presentation.history.components.HistoryItem
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.history.HistoryScreenModel import eu.kanade.tachiyomi.ui.history.HistoryScreenModel
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.core.preference.InMemoryPreferenceStore import tachiyomi.core.preference.InMemoryPreferenceStore
import tachiyomi.domain.history.model.HistoryWithRelations import tachiyomi.domain.history.model.HistoryWithRelations
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.FastScrollLazyColumn import tachiyomi.presentation.core.components.FastScrollLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -47,14 +47,14 @@ fun HistoryScreen(
Scaffold( Scaffold(
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
SearchToolbar( SearchToolbar(
titleContent = { AppBarTitle(stringResource(R.string.history)) }, titleContent = { AppBarTitle(stringResource(MR.strings.history)) },
searchQuery = state.searchQuery, searchQuery = state.searchQuery,
onChangeSearchQuery = onSearchQueryChange, onChangeSearchQuery = onSearchQueryChange,
actions = { actions = {
AppBarActions( AppBarActions(
persistentListOf( persistentListOf(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.pref_clear_history), title = stringResource(MR.strings.pref_clear_history),
icon = Icons.Outlined.DeleteSweep, icon = Icons.Outlined.DeleteSweep,
onClick = { onClick = {
onDialogChange(HistoryScreenModel.Dialog.DeleteAll) onDialogChange(HistoryScreenModel.Dialog.DeleteAll)
@ -73,12 +73,12 @@ fun HistoryScreen(
LoadingScreen(Modifier.padding(contentPadding)) LoadingScreen(Modifier.padding(contentPadding))
} else if (it.isEmpty()) { } else if (it.isEmpty()) {
val msg = if (!state.searchQuery.isNullOrEmpty()) { val msg = if (!state.searchQuery.isNullOrEmpty()) {
R.string.no_results_found MR.strings.no_results_found
} else { } else {
R.string.information_no_recent_manga MR.strings.information_no_recent_manga
} }
EmptyScreen( EmptyScreen(
textResource = msg, stringRes = msg,
modifier = Modifier.padding(contentPadding), modifier = Modifier.padding(contentPadding),
) )
} else { } else {
@ -123,7 +123,6 @@ private fun HistoryScreenContent(
when (item) { when (item) {
is HistoryUiModel.Header -> { is HistoryUiModel.Header -> {
RelativeDateHeader( RelativeDateHeader(
modifier = Modifier.animateItemPlacement(),
date = item.date, date = item.date,
relativeTime = relativeTime, relativeTime = relativeTime,
dateFormat = dateFormat, dateFormat = dateFormat,
@ -132,7 +131,6 @@ private fun HistoryScreenContent(
is HistoryUiModel.Item -> { is HistoryUiModel.Item -> {
val value = item.item val value = item.item
HistoryItem( HistoryItem(
modifier = Modifier.animateItemPlacement(),
history = value, history = value,
onClickCover = { onClickCover(value) }, onClickCover = { onClickCover(value) },
onClickResume = { onClickResume(value) }, onClickResume = { onClickResume(value) },

View File

@ -10,12 +10,12 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LabeledCheckbox import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun HistoryDeleteDialog( fun HistoryDeleteDialog(
@ -26,16 +26,16 @@ fun HistoryDeleteDialog(
AlertDialog( AlertDialog(
title = { title = {
Text(text = stringResource(R.string.action_remove)) Text(text = stringResource(MR.strings.action_remove))
}, },
text = { text = {
Column( Column(
verticalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp),
) { ) {
Text(text = stringResource(R.string.dialog_with_checkbox_remove_description)) Text(text = stringResource(MR.strings.dialog_with_checkbox_remove_description))
LabeledCheckbox( LabeledCheckbox(
label = stringResource(R.string.dialog_with_checkbox_reset), label = stringResource(MR.strings.dialog_with_checkbox_reset),
checked = removeEverything, checked = removeEverything,
onCheckedChange = { removeEverything = it }, onCheckedChange = { removeEverything = it },
) )
@ -47,12 +47,12 @@ fun HistoryDeleteDialog(
onDelete(removeEverything) onDelete(removeEverything)
onDismissRequest() onDismissRequest()
}) { }) {
Text(text = stringResource(R.string.action_remove)) Text(text = stringResource(MR.strings.action_remove))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
) )
@ -65,10 +65,10 @@ fun HistoryDeleteAllDialog(
) { ) {
AlertDialog( AlertDialog(
title = { title = {
Text(text = stringResource(R.string.action_remove_everything)) Text(text = stringResource(MR.strings.action_remove_everything))
}, },
text = { text = {
Text(text = stringResource(R.string.clear_history_confirmation)) Text(text = stringResource(MR.strings.clear_history_confirmation))
}, },
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
confirmButton = { confirmButton = {
@ -76,12 +76,12 @@ fun HistoryDeleteAllDialog(
onDelete() onDelete()
onDismissRequest() onDismissRequest()
}) { }) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
) )

View File

@ -17,7 +17,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
@ -26,10 +25,11 @@ import androidx.compose.ui.unit.dp
import eu.kanade.presentation.manga.components.MangaCover import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.presentation.util.formatChapterNumber import eu.kanade.presentation.util.formatChapterNumber
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.lang.toTimestampString import eu.kanade.tachiyomi.util.lang.toTimestampString
import tachiyomi.domain.history.model.HistoryWithRelations import tachiyomi.domain.history.model.HistoryWithRelations
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
private val HistoryItemHeight = 96.dp private val HistoryItemHeight = 96.dp
@ -70,7 +70,7 @@ fun HistoryItem(
Text( Text(
text = if (history.chapterNumber > -1) { text = if (history.chapterNumber > -1) {
stringResource( stringResource(
R.string.recent_manga_time, MR.strings.recent_manga_time,
formatChapterNumber(history.chapterNumber), formatChapterNumber(history.chapterNumber),
readAt, readAt,
) )
@ -85,7 +85,7 @@ fun HistoryItem(
IconButton(onClick = onClickDelete) { IconButton(onClick = onClickDelete) {
Icon( Icon(
imageVector = Icons.Outlined.Delete, imageVector = Icons.Outlined.Delete,
contentDescription = stringResource(R.string.action_delete), contentDescription = stringResource(MR.strings.action_delete),
tint = MaterialTheme.colorScheme.onSurface, tint = MaterialTheme.colorScheme.onSurface,
) )
} }

View File

@ -9,10 +9,11 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource import dev.icerock.moko.resources.StringResource
import eu.kanade.tachiyomi.R
import tachiyomi.core.preference.CheckboxState import tachiyomi.core.preference.CheckboxState
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LabeledCheckbox import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun DeleteLibraryMangaDialog( fun DeleteLibraryMangaDialog(
@ -22,10 +23,10 @@ fun DeleteLibraryMangaDialog(
) { ) {
var list by remember { var list by remember {
mutableStateOf( mutableStateOf(
buildList<CheckboxState.State<Int>> { buildList<CheckboxState.State<StringResource>> {
add(CheckboxState.State.None(R.string.manga_from_library)) add(CheckboxState.State.None(MR.strings.manga_from_library))
if (!containsLocalManga) { if (!containsLocalManga) {
add(CheckboxState.State.None(R.string.downloaded_chapters)) add(CheckboxState.State.None(MR.strings.downloaded_chapters))
} }
}, },
) )
@ -34,7 +35,7 @@ fun DeleteLibraryMangaDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
confirmButton = { confirmButton = {
@ -48,11 +49,11 @@ fun DeleteLibraryMangaDialog(
) )
}, },
) { ) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
title = { title = {
Text(text = stringResource(R.string.action_remove)) Text(text = stringResource(MR.strings.action_remove))
}, },
text = { text = {
Column { Column {
@ -64,7 +65,7 @@ fun DeleteLibraryMangaDialog(
val index = list.indexOf(state) val index = list.indexOf(state)
if (index != -1) { if (index != -1) {
val mutableList = list.toMutableList() val mutableList = list.toMutableList()
mutableList[index] = state.next() as CheckboxState.State<Int> mutableList[index] = state.next() as CheckboxState.State<StringResource>
list = mutableList.toList() list = mutableList.toList()
} }
}, },

View File

@ -13,10 +13,8 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.TabbedDialog import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.LibrarySettingsScreenModel import eu.kanade.tachiyomi.ui.library.LibrarySettingsScreenModel
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.core.preference.TriState import tachiyomi.core.preference.TriState
@ -25,12 +23,14 @@ import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.domain.library.model.LibrarySort import tachiyomi.domain.library.model.LibrarySort
import tachiyomi.domain.library.model.sort import tachiyomi.domain.library.model.sort
import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.CheckboxItem import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.HeadingItem import tachiyomi.presentation.core.components.HeadingItem
import tachiyomi.presentation.core.components.SettingsChipRow import tachiyomi.presentation.core.components.SettingsChipRow
import tachiyomi.presentation.core.components.SliderItem import tachiyomi.presentation.core.components.SliderItem
import tachiyomi.presentation.core.components.SortItem import tachiyomi.presentation.core.components.SortItem
import tachiyomi.presentation.core.components.TriStateItem import tachiyomi.presentation.core.components.TriStateItem
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
@Composable @Composable
@ -42,9 +42,9 @@ fun LibrarySettingsDialog(
TabbedDialog( TabbedDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
tabTitles = persistentListOf( tabTitles = persistentListOf(
stringResource(R.string.action_filter), stringResource(MR.strings.action_filter),
stringResource(R.string.action_sort), stringResource(MR.strings.action_sort),
stringResource(R.string.action_display), stringResource(MR.strings.action_display),
), ),
) { page -> ) { page ->
Column( Column(
@ -75,7 +75,7 @@ private fun ColumnScope.FilterPage(
val filterDownloaded by screenModel.libraryPreferences.filterDownloaded().collectAsState() val filterDownloaded by screenModel.libraryPreferences.filterDownloaded().collectAsState()
val downloadedOnly by screenModel.preferences.downloadedOnly().collectAsState() val downloadedOnly by screenModel.preferences.downloadedOnly().collectAsState()
TriStateItem( TriStateItem(
label = stringResource(R.string.label_downloaded), label = stringResource(MR.strings.label_downloaded),
state = if (downloadedOnly) { state = if (downloadedOnly) {
TriState.ENABLED_IS TriState.ENABLED_IS
} else { } else {
@ -86,25 +86,25 @@ private fun ColumnScope.FilterPage(
) )
val filterUnread by screenModel.libraryPreferences.filterUnread().collectAsState() val filterUnread by screenModel.libraryPreferences.filterUnread().collectAsState()
TriStateItem( TriStateItem(
label = stringResource(R.string.action_filter_unread), label = stringResource(MR.strings.action_filter_unread),
state = filterUnread, state = filterUnread,
onClick = { screenModel.toggleFilter(LibraryPreferences::filterUnread) }, onClick = { screenModel.toggleFilter(LibraryPreferences::filterUnread) },
) )
val filterStarted by screenModel.libraryPreferences.filterStarted().collectAsState() val filterStarted by screenModel.libraryPreferences.filterStarted().collectAsState()
TriStateItem( TriStateItem(
label = stringResource(R.string.label_started), label = stringResource(MR.strings.label_started),
state = filterStarted, state = filterStarted,
onClick = { screenModel.toggleFilter(LibraryPreferences::filterStarted) }, onClick = { screenModel.toggleFilter(LibraryPreferences::filterStarted) },
) )
val filterBookmarked by screenModel.libraryPreferences.filterBookmarked().collectAsState() val filterBookmarked by screenModel.libraryPreferences.filterBookmarked().collectAsState()
TriStateItem( TriStateItem(
label = stringResource(R.string.action_filter_bookmarked), label = stringResource(MR.strings.action_filter_bookmarked),
state = filterBookmarked, state = filterBookmarked,
onClick = { screenModel.toggleFilter(LibraryPreferences::filterBookmarked) }, onClick = { screenModel.toggleFilter(LibraryPreferences::filterBookmarked) },
) )
val filterCompleted by screenModel.libraryPreferences.filterCompleted().collectAsState() val filterCompleted by screenModel.libraryPreferences.filterCompleted().collectAsState()
TriStateItem( TriStateItem(
label = stringResource(R.string.completed), label = stringResource(MR.strings.completed),
state = filterCompleted, state = filterCompleted,
onClick = { screenModel.toggleFilter(LibraryPreferences::filterCompleted) }, onClick = { screenModel.toggleFilter(LibraryPreferences::filterCompleted) },
) )
@ -118,13 +118,13 @@ private fun ColumnScope.FilterPage(
val service = trackers[0] val service = trackers[0]
val filterTracker by screenModel.libraryPreferences.filterTracking(service.id.toInt()).collectAsState() val filterTracker by screenModel.libraryPreferences.filterTracking(service.id.toInt()).collectAsState()
TriStateItem( TriStateItem(
label = stringResource(R.string.action_filter_tracked), label = stringResource(MR.strings.action_filter_tracked),
state = filterTracker, state = filterTracker,
onClick = { screenModel.toggleTracker(service.id.toInt()) }, onClick = { screenModel.toggleTracker(service.id.toInt()) },
) )
} }
else -> { else -> {
HeadingItem(R.string.action_filter_tracked) HeadingItem(MR.strings.action_filter_tracked)
trackers.map { service -> trackers.map { service ->
val filterTracker by screenModel.libraryPreferences.filterTracking(service.id.toInt()).collectAsState() val filterTracker by screenModel.libraryPreferences.filterTracking(service.id.toInt()).collectAsState()
TriStateItem( TriStateItem(
@ -149,18 +149,18 @@ private fun ColumnScope.SortPage(
if (screenModel.trackers.isEmpty()) { if (screenModel.trackers.isEmpty()) {
emptyList() emptyList()
} else { } else {
listOf(R.string.action_sort_tracker_score to LibrarySort.Type.TrackerMean) listOf(MR.strings.action_sort_tracker_score to LibrarySort.Type.TrackerMean)
} }
listOf( listOf(
R.string.action_sort_alpha to LibrarySort.Type.Alphabetical, MR.strings.action_sort_alpha to LibrarySort.Type.Alphabetical,
R.string.action_sort_total to LibrarySort.Type.TotalChapters, MR.strings.action_sort_total to LibrarySort.Type.TotalChapters,
R.string.action_sort_last_read to LibrarySort.Type.LastRead, MR.strings.action_sort_last_read to LibrarySort.Type.LastRead,
R.string.action_sort_last_manga_update to LibrarySort.Type.LastUpdate, MR.strings.action_sort_last_manga_update to LibrarySort.Type.LastUpdate,
R.string.action_sort_unread_count to LibrarySort.Type.UnreadCount, MR.strings.action_sort_unread_count to LibrarySort.Type.UnreadCount,
R.string.action_sort_latest_chapter to LibrarySort.Type.LatestChapter, MR.strings.action_sort_latest_chapter to LibrarySort.Type.LatestChapter,
R.string.action_sort_chapter_fetch_date to LibrarySort.Type.ChapterFetchDate, MR.strings.action_sort_chapter_fetch_date to LibrarySort.Type.ChapterFetchDate,
R.string.action_sort_date_added to LibrarySort.Type.DateAdded, MR.strings.action_sort_date_added to LibrarySort.Type.DateAdded,
).plus(trackerSortOption).map { (titleRes, mode) -> ).plus(trackerSortOption).map { (titleRes, mode) ->
SortItem( SortItem(
label = stringResource(titleRes), label = stringResource(titleRes),
@ -186,10 +186,10 @@ private fun ColumnScope.SortPage(
} }
private val displayModes = listOf( private val displayModes = listOf(
R.string.action_display_grid to LibraryDisplayMode.CompactGrid, MR.strings.action_display_grid to LibraryDisplayMode.CompactGrid,
R.string.action_display_comfortable_grid to LibraryDisplayMode.ComfortableGrid, MR.strings.action_display_comfortable_grid to LibraryDisplayMode.ComfortableGrid,
R.string.action_display_cover_only_grid to LibraryDisplayMode.CoverOnlyGrid, MR.strings.action_display_cover_only_grid to LibraryDisplayMode.CoverOnlyGrid,
R.string.action_display_list to LibraryDisplayMode.List, MR.strings.action_display_list to LibraryDisplayMode.List,
) )
@Composable @Composable
@ -197,7 +197,7 @@ private fun ColumnScope.DisplayPage(
screenModel: LibrarySettingsScreenModel, screenModel: LibrarySettingsScreenModel,
) { ) {
val displayMode by screenModel.libraryPreferences.displayMode().collectAsState() val displayMode by screenModel.libraryPreferences.displayMode().collectAsState()
SettingsChipRow(R.string.action_display_mode) { SettingsChipRow(MR.strings.action_display_mode) {
displayModes.map { (titleRes, mode) -> displayModes.map { (titleRes, mode) ->
FilterChip( FilterChip(
selected = displayMode == mode, selected = displayMode == mode,
@ -219,43 +219,43 @@ private fun ColumnScope.DisplayPage(
val columns by columnPreference.collectAsState() val columns by columnPreference.collectAsState()
SliderItem( SliderItem(
label = stringResource(R.string.pref_library_columns), label = stringResource(MR.strings.pref_library_columns),
max = 10, max = 10,
value = columns, value = columns,
valueText = if (columns > 0) { valueText = if (columns > 0) {
stringResource(R.string.pref_library_columns_per_row, columns) stringResource(MR.strings.pref_library_columns_per_row, columns)
} else { } else {
stringResource(R.string.label_default) stringResource(MR.strings.label_default)
}, },
onChange = columnPreference::set, onChange = columnPreference::set,
) )
} }
HeadingItem(R.string.overlay_header) HeadingItem(MR.strings.overlay_header)
CheckboxItem( CheckboxItem(
label = stringResource(R.string.action_display_download_badge), label = stringResource(MR.strings.action_display_download_badge),
pref = screenModel.libraryPreferences.downloadBadge(), pref = screenModel.libraryPreferences.downloadBadge(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.action_display_local_badge), label = stringResource(MR.strings.action_display_local_badge),
pref = screenModel.libraryPreferences.localBadge(), pref = screenModel.libraryPreferences.localBadge(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.action_display_language_badge), label = stringResource(MR.strings.action_display_language_badge),
pref = screenModel.libraryPreferences.languageBadge(), pref = screenModel.libraryPreferences.languageBadge(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.action_display_show_continue_reading_button), label = stringResource(MR.strings.action_display_show_continue_reading_button),
pref = screenModel.libraryPreferences.showContinueReadingButton(), pref = screenModel.libraryPreferences.showContinueReadingButton(),
) )
HeadingItem(R.string.tabs_header) HeadingItem(MR.strings.tabs_header)
CheckboxItem( CheckboxItem(
label = stringResource(R.string.action_display_show_tabs), label = stringResource(MR.strings.action_display_show_tabs),
pref = screenModel.libraryPreferences.categoryTabs(), pref = screenModel.libraryPreferences.categoryTabs(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.action_display_show_number_of_items), label = stringResource(MR.strings.action_display_show_number_of_items),
pref = screenModel.libraryPreferences.categoryNumberOfItems(), pref = screenModel.libraryPreferences.categoryNumberOfItems(),
) )
} }

View File

@ -33,14 +33,14 @@ import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shadow import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import eu.kanade.presentation.manga.components.MangaCover import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.BadgeGroup import tachiyomi.presentation.core.components.BadgeGroup
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.selectedBackground import tachiyomi.presentation.core.util.selectedBackground
object CommonMangaItemDefaults { object CommonMangaItemDefaults {
@ -378,7 +378,7 @@ private fun ContinueReadingButton(
) { ) {
Icon( Icon(
imageVector = Icons.Filled.PlayArrow, imageVector = Icons.Filled.PlayArrow,
contentDescription = stringResource(R.string.action_resume), contentDescription = stringResource(MR.strings.action_resume),
modifier = Modifier.size(16.dp), modifier = Modifier.size(16.dp),
) )
} }

View File

@ -4,9 +4,9 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.zIndex import androidx.compose.ui.zIndex
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
internal fun GlobalSearchItem( internal fun GlobalSearchItem(
@ -19,7 +19,7 @@ internal fun GlobalSearchItem(
onClick = onClick, onClick = onClick,
) { ) {
Text( Text(
text = stringResource(R.string.action_global_search_query, searchQuery), text = stringResource(MR.strings.action_global_search_query, searchQuery),
modifier = Modifier.zIndex(99f), modifier = Modifier.zIndex(99f),
) )
} }

View File

@ -18,10 +18,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.core.preference.PreferenceMutableState import eu.kanade.core.preference.PreferenceMutableState
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.LibraryItem import eu.kanade.tachiyomi.ui.library.LibraryItem
import tachiyomi.domain.library.model.LibraryDisplayMode import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.domain.library.model.LibraryManga import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.HorizontalPager import tachiyomi.presentation.core.components.HorizontalPager
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.util.plus import tachiyomi.presentation.core.util.plus
@ -124,9 +124,9 @@ private fun LibraryPagerEmptyScreen(
onGlobalSearchClicked: () -> Unit, onGlobalSearchClicked: () -> Unit,
) { ) {
val msg = when { val msg = when {
!searchQuery.isNullOrEmpty() -> R.string.no_results_found !searchQuery.isNullOrEmpty() -> MR.strings.no_results_found
hasActiveFilters -> R.string.error_no_match hasActiveFilters -> MR.strings.error_no_match
else -> R.string.information_no_manga_category else -> MR.strings.information_no_manga_category
} }
Column( Column(
@ -146,7 +146,7 @@ private fun LibraryPagerEmptyScreen(
} }
EmptyScreen( EmptyScreen(
textResource = msg, stringRes = msg,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
) )
} }

View File

@ -14,15 +14,15 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.SearchToolbar import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.Pill import tachiyomi.presentation.core.components.Pill
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.theme.active import tachiyomi.presentation.core.theme.active
@Composable @Composable
@ -98,21 +98,21 @@ private fun LibraryRegularToolbar(
AppBarActions( AppBarActions(
persistentListOf( persistentListOf(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_filter), title = stringResource(MR.strings.action_filter),
icon = Icons.Outlined.FilterList, icon = Icons.Outlined.FilterList,
iconTint = filterTint, iconTint = filterTint,
onClick = onClickFilter, onClick = onClickFilter,
), ),
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_update_library), title = stringResource(MR.strings.action_update_library),
onClick = onClickGlobalUpdate, onClick = onClickGlobalUpdate,
), ),
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_update_category), title = stringResource(MR.strings.action_update_category),
onClick = onClickRefresh, onClick = onClickRefresh,
), ),
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_open_random_manga), title = stringResource(MR.strings.action_open_random_manga),
onClick = onClickOpenRandomManga, onClick = onClickOpenRandomManga,
), ),
), ),
@ -135,12 +135,12 @@ private fun LibrarySelectionToolbar(
AppBarActions( AppBarActions(
persistentListOf( persistentListOf(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_select_all), title = stringResource(MR.strings.action_select_all),
icon = Icons.Outlined.SelectAll, icon = Icons.Outlined.SelectAll,
onClick = onClickSelectAll, onClick = onClickSelectAll,
), ),
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_select_inverse), title = stringResource(MR.strings.action_select_inverse),
icon = Icons.Outlined.FlipToBack, icon = Icons.Outlined.FlipToBack,
onClick = onClickInvertSelection, onClick = onClickInvertSelection,
), ),

View File

@ -25,20 +25,20 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.domain.manga.model.downloadedFilter import eu.kanade.domain.manga.model.downloadedFilter
import eu.kanade.domain.manga.model.forceDownloaded import eu.kanade.domain.manga.model.forceDownloaded
import eu.kanade.presentation.components.TabbedDialog import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.core.preference.TriState import tachiyomi.core.preference.TriState
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LabeledCheckbox import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.components.RadioItem import tachiyomi.presentation.core.components.RadioItem
import tachiyomi.presentation.core.components.SortItem import tachiyomi.presentation.core.components.SortItem
import tachiyomi.presentation.core.components.TriStateItem import tachiyomi.presentation.core.components.TriStateItem
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.theme.active import tachiyomi.presentation.core.theme.active
@Composable @Composable
@ -66,20 +66,20 @@ fun ChapterSettingsDialog(
TabbedDialog( TabbedDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
tabTitles = persistentListOf( tabTitles = persistentListOf(
stringResource(R.string.action_filter), stringResource(MR.strings.action_filter),
stringResource(R.string.action_sort), stringResource(MR.strings.action_sort),
stringResource(R.string.action_display), stringResource(MR.strings.action_display),
), ),
tabOverflowMenuContent = { closeMenu -> tabOverflowMenuContent = { closeMenu ->
DropdownMenuItem( DropdownMenuItem(
text = { Text(stringResource(R.string.set_chapter_settings_as_default)) }, text = { Text(stringResource(MR.strings.set_chapter_settings_as_default)) },
onClick = { onClick = {
showSetAsDefaultDialog = true showSetAsDefaultDialog = true
closeMenu() closeMenu()
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(stringResource(R.string.action_reset)) }, text = { Text(stringResource(MR.strings.action_reset)) },
onClick = { onClick = {
onResetToDefault() onResetToDefault()
closeMenu() closeMenu()
@ -136,17 +136,17 @@ private fun ColumnScope.FilterPage(
onScanlatorFilterClicked: (() -> Unit), onScanlatorFilterClicked: (() -> Unit),
) { ) {
TriStateItem( TriStateItem(
label = stringResource(R.string.label_downloaded), label = stringResource(MR.strings.label_downloaded),
state = downloadFilter, state = downloadFilter,
onClick = onDownloadFilterChanged, onClick = onDownloadFilterChanged,
) )
TriStateItem( TriStateItem(
label = stringResource(R.string.action_filter_unread), label = stringResource(MR.strings.action_filter_unread),
state = unreadFilter, state = unreadFilter,
onClick = onUnreadFilterChanged, onClick = onUnreadFilterChanged,
) )
TriStateItem( TriStateItem(
label = stringResource(R.string.action_filter_bookmarked), label = stringResource(MR.strings.action_filter_bookmarked),
state = bookmarkedFilter, state = bookmarkedFilter,
onClick = onBookmarkedFilterChanged, onClick = onBookmarkedFilterChanged,
) )
@ -179,7 +179,7 @@ fun ScanlatorFilterItem(
}, },
) )
Text( Text(
text = stringResource(R.string.scanlator), text = stringResource(MR.strings.scanlator),
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
) )
} }
@ -192,10 +192,10 @@ private fun ColumnScope.SortPage(
onItemSelected: (Long) -> Unit, onItemSelected: (Long) -> Unit,
) { ) {
listOf( listOf(
R.string.sort_by_source to Manga.CHAPTER_SORTING_SOURCE, MR.strings.sort_by_source to Manga.CHAPTER_SORTING_SOURCE,
R.string.sort_by_number to Manga.CHAPTER_SORTING_NUMBER, MR.strings.sort_by_number to Manga.CHAPTER_SORTING_NUMBER,
R.string.sort_by_upload_date to Manga.CHAPTER_SORTING_UPLOAD_DATE, MR.strings.sort_by_upload_date to Manga.CHAPTER_SORTING_UPLOAD_DATE,
R.string.action_sort_alpha to Manga.CHAPTER_SORTING_ALPHABET, MR.strings.action_sort_alpha to Manga.CHAPTER_SORTING_ALPHABET,
).map { (titleRes, mode) -> ).map { (titleRes, mode) ->
SortItem( SortItem(
label = stringResource(titleRes), label = stringResource(titleRes),
@ -211,8 +211,8 @@ private fun ColumnScope.DisplayPage(
onItemSelected: (Long) -> Unit, onItemSelected: (Long) -> Unit,
) { ) {
listOf( listOf(
R.string.show_title to Manga.CHAPTER_DISPLAY_NAME, MR.strings.show_title to Manga.CHAPTER_DISPLAY_NAME,
R.string.show_chapter_number to Manga.CHAPTER_DISPLAY_NUMBER, MR.strings.show_chapter_number to Manga.CHAPTER_DISPLAY_NUMBER,
).map { (titleRes, mode) -> ).map { (titleRes, mode) ->
RadioItem( RadioItem(
label = stringResource(titleRes), label = stringResource(titleRes),
@ -231,15 +231,15 @@ private fun SetAsDefaultDialog(
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.chapter_settings)) }, title = { Text(text = stringResource(MR.strings.chapter_settings)) },
text = { text = {
Column( Column(
verticalArrangement = Arrangement.spacedBy(12.dp), verticalArrangement = Arrangement.spacedBy(12.dp),
) { ) {
Text(text = stringResource(R.string.confirm_set_chapter_settings)) Text(text = stringResource(MR.strings.confirm_set_chapter_settings))
LabeledCheckbox( LabeledCheckbox(
label = stringResource(R.string.also_set_chapter_settings_for_library), label = stringResource(MR.strings.also_set_chapter_settings_for_library),
checked = optionalChecked, checked = optionalChecked,
onCheckedChange = { optionalChecked = it }, onCheckedChange = { optionalChecked = it },
) )
@ -247,7 +247,7 @@ private fun SetAsDefaultDialog(
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
confirmButton = { confirmButton = {
@ -257,7 +257,7 @@ private fun SetAsDefaultDialog(
onDismissRequest() onDismissRequest()
}, },
) { ) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
) )

View File

@ -8,9 +8,9 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun DuplicateMangaDialog( fun DuplicateMangaDialog(
@ -21,10 +21,10 @@ fun DuplicateMangaDialog(
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { title = {
Text(text = stringResource(R.string.are_you_sure)) Text(text = stringResource(MR.strings.are_you_sure))
}, },
text = { text = {
Text(text = stringResource(R.string.confirm_add_duplicate_manga)) Text(text = stringResource(MR.strings.confirm_add_duplicate_manga))
}, },
confirmButton = { confirmButton = {
FlowRow( FlowRow(
@ -36,13 +36,13 @@ fun DuplicateMangaDialog(
onOpenManga() onOpenManga()
}, },
) { ) {
Text(text = stringResource(R.string.action_show_manga)) Text(text = stringResource(MR.strings.action_show_manga))
} }
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
TextButton( TextButton(
onClick = { onClick = {
@ -50,7 +50,7 @@ fun DuplicateMangaDialog(
onConfirm() onConfirm()
}, },
) { ) {
Text(text = stringResource(R.string.action_add)) Text(text = stringResource(MR.strings.action_add))
} }
} }
}, },

View File

@ -44,7 +44,6 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.util.fastAll import androidx.compose.ui.util.fastAll
import androidx.compose.ui.util.fastAny import androidx.compose.ui.util.fastAny
import androidx.compose.ui.util.fastMap import androidx.compose.ui.util.fastMap
@ -58,7 +57,6 @@ import eu.kanade.presentation.manga.components.MangaInfoBox
import eu.kanade.presentation.manga.components.MangaToolbar import eu.kanade.presentation.manga.components.MangaToolbar
import eu.kanade.presentation.manga.components.MissingChapterCountListItem import eu.kanade.presentation.manga.components.MissingChapterCountListItem
import eu.kanade.presentation.util.formatChapterNumber import eu.kanade.presentation.util.formatChapterNumber
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.source.getNameForMangaInfo import eu.kanade.tachiyomi.source.getNameForMangaInfo
import eu.kanade.tachiyomi.ui.manga.ChapterList import eu.kanade.tachiyomi.ui.manga.ChapterList
@ -70,11 +68,13 @@ import tachiyomi.domain.chapter.service.missingChaptersCount
import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.model.StubSource import tachiyomi.domain.source.model.StubSource
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.TwoPanelBox import tachiyomi.presentation.core.components.TwoPanelBox
import tachiyomi.presentation.core.components.VerticalFastScroller import tachiyomi.presentation.core.components.VerticalFastScroller
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
import tachiyomi.presentation.core.components.material.PullRefresh import tachiyomi.presentation.core.components.material.PullRefresh
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrollingUp import tachiyomi.presentation.core.util.isScrollingUp
import java.text.DateFormat import java.text.DateFormat
@ -349,7 +349,9 @@ private fun MangaScreenSmallImpl(
val isReading = remember(state.chapters) { val isReading = remember(state.chapters) {
state.chapters.fastAny { it.chapter.read } state.chapters.fastAny { it.chapter.read }
} }
Text(text = stringResource(if (isReading) R.string.action_resume else R.string.action_start)) Text(
text = stringResource(if (isReading) MR.strings.action_resume else MR.strings.action_start),
)
}, },
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) }, icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueReading, onClick = onContinueReading,
@ -608,7 +610,9 @@ fun MangaScreenLargeImpl(
state.chapters.fastAny { it.chapter.read } state.chapters.fastAny { it.chapter.read }
} }
Text( Text(
text = stringResource(if (isReading) R.string.action_resume else R.string.action_start), text = stringResource(
if (isReading) MR.strings.action_resume else MR.strings.action_start,
),
) )
}, },
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) }, icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
@ -788,7 +792,7 @@ private fun LazyListScope.sharedChapterItems(
MangaChapterListItem( MangaChapterListItem(
title = if (manga.displayMode == Manga.CHAPTER_DISPLAY_NUMBER) { title = if (manga.displayMode == Manga.CHAPTER_DISPLAY_NUMBER) {
stringResource( stringResource(
R.string.display_mode_chapter, MR.strings.display_mode_chapter,
formatChapterNumber(item.chapter.chapterNumber), formatChapterNumber(item.chapter.chapterNumber),
) )
} else { } else {
@ -807,7 +811,7 @@ private fun LazyListScope.sharedChapterItems(
.takeIf { !item.chapter.read && it > 0L } .takeIf { !item.chapter.read && it > 0L }
?.let { ?.let {
stringResource( stringResource(
R.string.chapter_progress, MR.strings.chapter_progress,
it + 1, it + 1,
) )
}, },

View File

@ -29,13 +29,14 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.DropdownMenu import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.IconButtonTokens import tachiyomi.presentation.core.components.material.IconButtonTokens
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.secondaryItemAlpha import tachiyomi.presentation.core.util.secondaryItemAlpha
enum class ChapterDownloadAction { enum class ChapterDownloadAction {
@ -98,7 +99,7 @@ private fun NotDownloadedIndicator(
) { ) {
Icon( Icon(
painter = painterResource(R.drawable.ic_download_chapter_24dp), painter = painterResource(R.drawable.ic_download_chapter_24dp),
contentDescription = stringResource(R.string.manga_download), contentDescription = stringResource(MR.strings.manga_download),
modifier = Modifier.size(IndicatorSize), modifier = Modifier.size(IndicatorSize),
tint = MaterialTheme.colorScheme.onSurfaceVariant, tint = MaterialTheme.colorScheme.onSurfaceVariant,
) )
@ -156,14 +157,14 @@ private fun DownloadingIndicator(
} }
DropdownMenu(expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false }) { DropdownMenu(expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false }) {
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(R.string.action_start_downloading_now)) }, text = { Text(text = stringResource(MR.strings.action_start_downloading_now)) },
onClick = { onClick = {
onClick(ChapterDownloadAction.START_NOW) onClick(ChapterDownloadAction.START_NOW)
isMenuExpanded = false isMenuExpanded = false
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(R.string.action_cancel)) }, text = { Text(text = stringResource(MR.strings.action_cancel)) },
onClick = { onClick = {
onClick(ChapterDownloadAction.CANCEL) onClick(ChapterDownloadAction.CANCEL)
isMenuExpanded = false isMenuExpanded = false
@ -204,7 +205,7 @@ private fun DownloadedIndicator(
) )
DropdownMenu(expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false }) { DropdownMenu(expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false }) {
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(R.string.action_delete)) }, text = { Text(text = stringResource(MR.strings.action_delete)) },
onClick = { onClick = {
onClick(ChapterDownloadAction.DELETE) onClick(ChapterDownloadAction.DELETE)
isMenuExpanded = false isMenuExpanded = false
@ -232,7 +233,7 @@ private fun ErrorIndicator(
) { ) {
Icon( Icon(
imageVector = Icons.Outlined.ErrorOutline, imageVector = Icons.Outlined.ErrorOutline,
contentDescription = stringResource(R.string.chapter_error), contentDescription = stringResource(MR.strings.chapter_error),
modifier = Modifier.size(IndicatorSize), modifier = Modifier.size(IndicatorSize),
tint = MaterialTheme.colorScheme.error, tint = MaterialTheme.colorScheme.error,
) )

View File

@ -9,12 +9,12 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun ChapterHeader( fun ChapterHeader(
@ -35,9 +35,9 @@ fun ChapterHeader(
) { ) {
Text( Text(
text = if (chapterCount == null) { text = if (chapterCount == null) {
stringResource(R.string.chapters) stringResource(MR.strings.chapters)
} else { } else {
pluralStringResource(id = R.plurals.manga_num_chapters, count = chapterCount, chapterCount) pluralStringResource(MR.plurals.manga_num_chapters, count = chapterCount, chapterCount)
}, },
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.onBackground, color = MaterialTheme.colorScheme.onBackground,
@ -54,7 +54,7 @@ private fun MissingChaptersWarning(count: Int) {
} }
Text( Text(
text = pluralStringResource(id = R.plurals.missing_chapters, count = count, count), text = pluralStringResource(MR.plurals.missing_chapters, count = count, count),
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,

View File

@ -29,7 +29,6 @@ import androidx.compose.material.icons.outlined.BookmarkRemove
import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.DoneAll import androidx.compose.material.icons.outlined.DoneAll
import androidx.compose.material.icons.outlined.Download import androidx.compose.material.icons.outlined.Download
import androidx.compose.material.icons.outlined.Label
import androidx.compose.material.icons.outlined.RemoveDone import androidx.compose.material.icons.outlined.RemoveDone
import androidx.compose.material.ripple.rememberRipple import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -48,7 +47,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -59,6 +57,8 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
@Composable @Composable
@ -107,7 +107,7 @@ fun MangaBottomActionMenu(
) { ) {
if (onBookmarkClicked != null) { if (onBookmarkClicked != null) {
Button( Button(
title = stringResource(R.string.action_bookmark), title = stringResource(MR.strings.action_bookmark),
icon = Icons.Outlined.BookmarkAdd, icon = Icons.Outlined.BookmarkAdd,
toConfirm = confirm[0], toConfirm = confirm[0],
onLongClick = { onLongClickItem(0) }, onLongClick = { onLongClickItem(0) },
@ -116,7 +116,7 @@ fun MangaBottomActionMenu(
} }
if (onRemoveBookmarkClicked != null) { if (onRemoveBookmarkClicked != null) {
Button( Button(
title = stringResource(R.string.action_remove_bookmark), title = stringResource(MR.strings.action_remove_bookmark),
icon = Icons.Outlined.BookmarkRemove, icon = Icons.Outlined.BookmarkRemove,
toConfirm = confirm[1], toConfirm = confirm[1],
onLongClick = { onLongClickItem(1) }, onLongClick = { onLongClickItem(1) },
@ -125,7 +125,7 @@ fun MangaBottomActionMenu(
} }
if (onMarkAsReadClicked != null) { if (onMarkAsReadClicked != null) {
Button( Button(
title = stringResource(R.string.action_mark_as_read), title = stringResource(MR.strings.action_mark_as_read),
icon = Icons.Outlined.DoneAll, icon = Icons.Outlined.DoneAll,
toConfirm = confirm[2], toConfirm = confirm[2],
onLongClick = { onLongClickItem(2) }, onLongClick = { onLongClickItem(2) },
@ -134,7 +134,7 @@ fun MangaBottomActionMenu(
} }
if (onMarkAsUnreadClicked != null) { if (onMarkAsUnreadClicked != null) {
Button( Button(
title = stringResource(R.string.action_mark_as_unread), title = stringResource(MR.strings.action_mark_as_unread),
icon = Icons.Outlined.RemoveDone, icon = Icons.Outlined.RemoveDone,
toConfirm = confirm[3], toConfirm = confirm[3],
onLongClick = { onLongClickItem(3) }, onLongClick = { onLongClickItem(3) },
@ -143,7 +143,7 @@ fun MangaBottomActionMenu(
} }
if (onMarkPreviousAsReadClicked != null) { if (onMarkPreviousAsReadClicked != null) {
Button( Button(
title = stringResource(R.string.action_mark_previous_as_read), title = stringResource(MR.strings.action_mark_previous_as_read),
icon = ImageVector.vectorResource(R.drawable.ic_done_prev_24dp), icon = ImageVector.vectorResource(R.drawable.ic_done_prev_24dp),
toConfirm = confirm[4], toConfirm = confirm[4],
onLongClick = { onLongClickItem(4) }, onLongClick = { onLongClickItem(4) },
@ -152,7 +152,7 @@ fun MangaBottomActionMenu(
} }
if (onDownloadClicked != null) { if (onDownloadClicked != null) {
Button( Button(
title = stringResource(R.string.action_download), title = stringResource(MR.strings.action_download),
icon = Icons.Outlined.Download, icon = Icons.Outlined.Download,
toConfirm = confirm[5], toConfirm = confirm[5],
onLongClick = { onLongClickItem(5) }, onLongClick = { onLongClickItem(5) },
@ -161,7 +161,7 @@ fun MangaBottomActionMenu(
} }
if (onDeleteClicked != null) { if (onDeleteClicked != null) {
Button( Button(
title = stringResource(R.string.action_delete), title = stringResource(MR.strings.action_delete),
icon = Icons.Outlined.Delete, icon = Icons.Outlined.Delete,
toConfirm = confirm[6], toConfirm = confirm[6],
onLongClick = { onLongClickItem(6) }, onLongClick = { onLongClickItem(6) },
@ -258,21 +258,21 @@ fun LibraryBottomActionMenu(
.padding(horizontal = 8.dp, vertical = 12.dp), .padding(horizontal = 8.dp, vertical = 12.dp),
) { ) {
Button( Button(
title = stringResource(R.string.action_move_category), title = stringResource(MR.strings.action_move_category),
icon = Icons.AutoMirrored.Outlined.Label, icon = Icons.AutoMirrored.Outlined.Label,
toConfirm = confirm[0], toConfirm = confirm[0],
onLongClick = { onLongClickItem(0) }, onLongClick = { onLongClickItem(0) },
onClick = onChangeCategoryClicked, onClick = onChangeCategoryClicked,
) )
Button( Button(
title = stringResource(R.string.action_mark_as_read), title = stringResource(MR.strings.action_mark_as_read),
icon = Icons.Outlined.DoneAll, icon = Icons.Outlined.DoneAll,
toConfirm = confirm[1], toConfirm = confirm[1],
onLongClick = { onLongClickItem(1) }, onLongClick = { onLongClickItem(1) },
onClick = onMarkAsReadClicked, onClick = onMarkAsReadClicked,
) )
Button( Button(
title = stringResource(R.string.action_mark_as_unread), title = stringResource(MR.strings.action_mark_as_unread),
icon = Icons.Outlined.RemoveDone, icon = Icons.Outlined.RemoveDone,
toConfirm = confirm[2], toConfirm = confirm[2],
onLongClick = { onLongClickItem(2) }, onLongClick = { onLongClickItem(2) },
@ -281,7 +281,7 @@ fun LibraryBottomActionMenu(
if (onDownloadClicked != null) { if (onDownloadClicked != null) {
var downloadExpanded by remember { mutableStateOf(false) } var downloadExpanded by remember { mutableStateOf(false) }
Button( Button(
title = stringResource(R.string.action_download), title = stringResource(MR.strings.action_download),
icon = Icons.Outlined.Download, icon = Icons.Outlined.Download,
toConfirm = confirm[3], toConfirm = confirm[3],
onLongClick = { onLongClickItem(3) }, onLongClick = { onLongClickItem(3) },
@ -296,7 +296,7 @@ fun LibraryBottomActionMenu(
} }
} }
Button( Button(
title = stringResource(R.string.action_delete), title = stringResource(MR.strings.action_delete),
icon = Icons.Outlined.Delete, icon = Icons.Outlined.Delete,
toConfirm = confirm[4], toConfirm = confirm[4],
onLongClick = { onLongClickItem(4) }, onLongClick = { onLongClickItem(4) },

View File

@ -42,23 +42,22 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.platform.ViewConfiguration import androidx.compose.ui.platform.ViewConfiguration
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import me.saket.swipe.SwipeableActionsBox import me.saket.swipe.SwipeableActionsBox
import me.saket.swipe.rememberSwipeableActionsState import me.saket.swipe.rememberSwipeableActionsState
import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.ReadItemAlpha import tachiyomi.presentation.core.components.material.ReadItemAlpha
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.selectedBackground import tachiyomi.presentation.core.util.selectedBackground
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
@Composable @Composable
fun MangaChapterListItem( fun MangaChapterListItem(
modifier: Modifier = Modifier,
title: String, title: String,
date: String?, date: String?,
readProgress: String?, readProgress: String?,
@ -75,6 +74,7 @@ fun MangaChapterListItem(
onClick: () -> Unit, onClick: () -> Unit,
onDownloadClick: ((ChapterDownloadAction) -> Unit)?, onDownloadClick: ((ChapterDownloadAction) -> Unit)?,
onChapterSwipe: (LibraryPreferences.ChapterSwipeAction) -> Unit, onChapterSwipe: (LibraryPreferences.ChapterSwipeAction) -> Unit,
modifier: Modifier = Modifier,
) { ) {
val haptic = LocalHapticFeedback.current val haptic = LocalHapticFeedback.current
val density = LocalDensity.current val density = LocalDensity.current
@ -143,7 +143,7 @@ fun MangaChapterListItem(
if (!read) { if (!read) {
Icon( Icon(
imageVector = Icons.Filled.Circle, imageVector = Icons.Filled.Circle,
contentDescription = stringResource(R.string.unread), contentDescription = stringResource(MR.strings.unread),
modifier = Modifier modifier = Modifier
.height(8.dp) .height(8.dp)
.padding(end = 4.dp), .padding(end = 4.dp),
@ -153,7 +153,7 @@ fun MangaChapterListItem(
if (bookmark) { if (bookmark) {
Icon( Icon(
imageVector = Icons.Filled.Bookmark, imageVector = Icons.Filled.Bookmark,
contentDescription = stringResource(R.string.action_filter_bookmarked), contentDescription = stringResource(MR.strings.action_filter_bookmarked),
modifier = Modifier modifier = Modifier
.sizeIn(maxHeight = with(LocalDensity.current) { textHeight.toDp() - 2.dp }), .sizeIn(maxHeight = with(LocalDensity.current) { textHeight.toDp() - 2.dp }),
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,

View File

@ -32,7 +32,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
@ -47,11 +46,12 @@ import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.DropdownMenu import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.manga.EditCoverAction import eu.kanade.presentation.manga.EditCoverAction
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderPageImageView import eu.kanade.tachiyomi.ui.reader.viewer.ReaderPageImageView
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.clickableNoIndication import tachiyomi.presentation.core.util.clickableNoIndication
@Composable @Composable
@ -85,7 +85,7 @@ fun MangaCoverDialog(
IconButton(onClick = onDismissRequest) { IconButton(onClick = onDismissRequest) {
Icon( Icon(
imageVector = Icons.Outlined.Close, imageVector = Icons.Outlined.Close,
contentDescription = stringResource(R.string.action_close), contentDescription = stringResource(MR.strings.action_close),
) )
} }
} }
@ -94,12 +94,12 @@ fun MangaCoverDialog(
AppBarActions( AppBarActions(
actions = persistentListOf( actions = persistentListOf(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_share), title = stringResource(MR.strings.action_share),
icon = Icons.Outlined.Share, icon = Icons.Outlined.Share,
onClick = onShareClick, onClick = onShareClick,
), ),
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_save), title = stringResource(MR.strings.action_save),
icon = Icons.Outlined.Save, icon = Icons.Outlined.Save,
onClick = onSaveClick, onClick = onSaveClick,
), ),
@ -119,7 +119,7 @@ fun MangaCoverDialog(
) { ) {
Icon( Icon(
imageVector = Icons.Outlined.Edit, imageVector = Icons.Outlined.Edit,
contentDescription = stringResource(R.string.action_edit_cover), contentDescription = stringResource(MR.strings.action_edit_cover),
) )
} }
DropdownMenu( DropdownMenu(
@ -128,14 +128,14 @@ fun MangaCoverDialog(
offset = DpOffset(8.dp, 0.dp), offset = DpOffset(8.dp, 0.dp),
) { ) {
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(R.string.action_edit)) }, text = { Text(text = stringResource(MR.strings.action_edit)) },
onClick = { onClick = {
onEditClick(EditCoverAction.EDIT) onEditClick(EditCoverAction.EDIT)
expanded = false expanded = false
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(R.string.action_delete)) }, text = { Text(text = stringResource(MR.strings.action_delete)) },
onClick = { onClick = {
onEditClick(EditCoverAction.DELETE) onEditClick(EditCoverAction.DELETE)
expanded = false expanded = false

View File

@ -12,13 +12,13 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import tachiyomi.domain.manga.interactor.FetchInterval import tachiyomi.domain.manga.interactor.FetchInterval
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.WheelTextPicker import tachiyomi.presentation.core.components.WheelTextPicker
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun DeleteChaptersDialog( fun DeleteChaptersDialog(
@ -29,7 +29,7 @@ fun DeleteChaptersDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
confirmButton = { confirmButton = {
@ -39,14 +39,14 @@ fun DeleteChaptersDialog(
onConfirm() onConfirm()
}, },
) { ) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
title = { title = {
Text(text = stringResource(R.string.are_you_sure)) Text(text = stringResource(MR.strings.are_you_sure))
}, },
text = { text = {
Text(text = stringResource(R.string.confirm_delete_chapters)) Text(text = stringResource(MR.strings.confirm_delete_chapters))
}, },
) )
} }
@ -61,7 +61,7 @@ fun SetIntervalDialog(
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.manga_modify_calculated_interval_title)) }, title = { Text(text = stringResource(MR.strings.manga_modify_calculated_interval_title)) },
text = { text = {
BoxWithConstraints( BoxWithConstraints(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@ -71,7 +71,7 @@ fun SetIntervalDialog(
val items = (0..FetchInterval.MAX_INTERVAL) val items = (0..FetchInterval.MAX_INTERVAL)
.map { .map {
if (it == 0) { if (it == 0) {
stringResource(R.string.label_default) stringResource(MR.strings.label_default)
} else { } else {
it.toString() it.toString()
} }
@ -87,7 +87,7 @@ fun SetIntervalDialog(
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
confirmButton = { confirmButton = {
@ -95,7 +95,7 @@ fun SetIntervalDialog(
onValueChanged(selectedInterval) onValueChanged(selectedInterval)
onDismissRequest() onDismissRequest()
}) { }) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
) )

View File

@ -66,8 +66,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.Layout import androidx.compose.ui.layout.Layout
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.Constraints
@ -80,8 +78,11 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.TextButton import tachiyomi.presentation.core.components.material.TextButton
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.clickableNoIndication import tachiyomi.presentation.core.util.clickableNoIndication
import tachiyomi.presentation.core.util.secondaryItemAlpha import tachiyomi.presentation.core.util.secondaryItemAlpha
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
@ -178,9 +179,9 @@ fun MangaActionRow(
Row(modifier = modifier.padding(start = 16.dp, top = 8.dp, end = 16.dp)) { Row(modifier = modifier.padding(start = 16.dp, top = 8.dp, end = 16.dp)) {
MangaActionButton( MangaActionButton(
title = if (favorite) { title = if (favorite) {
stringResource(R.string.in_library) stringResource(MR.strings.in_library)
} else { } else {
stringResource(R.string.add_to_library) stringResource(MR.strings.add_to_library)
}, },
icon = if (favorite) Icons.Filled.Favorite else Icons.Outlined.FavoriteBorder, icon = if (favorite) Icons.Filled.Favorite else Icons.Outlined.FavoriteBorder,
color = if (favorite) MaterialTheme.colorScheme.primary else defaultActionButtonColor, color = if (favorite) MaterialTheme.colorScheme.primary else defaultActionButtonColor,
@ -190,7 +191,7 @@ fun MangaActionRow(
if (onEditIntervalClicked != null && fetchInterval != null) { if (onEditIntervalClicked != null && fetchInterval != null) {
MangaActionButton( MangaActionButton(
title = pluralStringResource( title = pluralStringResource(
id = R.plurals.day, MR.plurals.day,
count = fetchInterval.absoluteValue, count = fetchInterval.absoluteValue,
fetchInterval.absoluteValue, fetchInterval.absoluteValue,
), ),
@ -202,9 +203,9 @@ fun MangaActionRow(
if (onTrackingClicked != null) { if (onTrackingClicked != null) {
MangaActionButton( MangaActionButton(
title = if (trackingCount == 0) { title = if (trackingCount == 0) {
stringResource(R.string.manga_tracking_tab) stringResource(MR.strings.manga_tracking_tab)
} else { } else {
pluralStringResource(id = R.plurals.num_trackers, count = trackingCount, trackingCount) pluralStringResource(MR.plurals.num_trackers, count = trackingCount, trackingCount)
}, },
icon = if (trackingCount == 0) Icons.Outlined.Sync else Icons.Outlined.Done, icon = if (trackingCount == 0) Icons.Outlined.Sync else Icons.Outlined.Done,
color = if (trackingCount == 0) defaultActionButtonColor else MaterialTheme.colorScheme.primary, color = if (trackingCount == 0) defaultActionButtonColor else MaterialTheme.colorScheme.primary,
@ -213,7 +214,7 @@ fun MangaActionRow(
} }
if (onWebViewClicked != null) { if (onWebViewClicked != null) {
MangaActionButton( MangaActionButton(
title = stringResource(R.string.action_web_view), title = stringResource(MR.strings.action_web_view),
icon = Icons.Outlined.Public, icon = Icons.Outlined.Public,
color = defaultActionButtonColor, color = defaultActionButtonColor,
onClick = onWebViewClicked, onClick = onWebViewClicked,
@ -237,7 +238,7 @@ fun ExpandableMangaDescription(
mutableStateOf(defaultExpandState) mutableStateOf(defaultExpandState)
} }
val desc = val desc =
description.takeIf { !it.isNullOrBlank() } ?: stringResource(R.string.description_placeholder) description.takeIf { !it.isNullOrBlank() } ?: stringResource(MR.strings.description_placeholder)
val trimmedDescription = remember(desc) { val trimmedDescription = remember(desc) {
desc desc
.replace(whitespaceLineRegex, "\n") .replace(whitespaceLineRegex, "\n")
@ -267,14 +268,14 @@ fun ExpandableMangaDescription(
onDismissRequest = { showMenu = false }, onDismissRequest = { showMenu = false },
) { ) {
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(R.string.action_search)) }, text = { Text(text = stringResource(MR.strings.action_search)) },
onClick = { onClick = {
onTagSearch(tagSelected) onTagSearch(tagSelected)
showMenu = false showMenu = false
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = stringResource(R.string.action_copy_to_clipboard)) }, text = { Text(text = stringResource(MR.strings.action_copy_to_clipboard)) },
onClick = { onClick = {
onCopyTagToClipboard(tagSelected) onCopyTagToClipboard(tagSelected)
showMenu = false showMenu = false
@ -341,7 +342,7 @@ private fun MangaAndSourceTitlesLarge(
MangaCover.Book( MangaCover.Book(
modifier = Modifier.fillMaxWidth(0.65f), modifier = Modifier.fillMaxWidth(0.65f),
data = coverDataProvider(), data = coverDataProvider(),
contentDescription = stringResource(R.string.manga_cover), contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick, onClick = onCoverClick,
) )
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
@ -383,7 +384,7 @@ private fun MangaAndSourceTitlesSmall(
.sizeIn(maxWidth = 100.dp) .sizeIn(maxWidth = 100.dp)
.align(Alignment.Top), .align(Alignment.Top),
data = coverDataProvider(), data = coverDataProvider(),
contentDescription = stringResource(R.string.manga_cover), contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick, onClick = onCoverClick,
) )
Column( Column(
@ -415,7 +416,7 @@ private fun MangaContentInfo(
) { ) {
val context = LocalContext.current val context = LocalContext.current
Text( Text(
text = title.ifBlank { stringResource(R.string.unknown_title) }, text = title.ifBlank { stringResource(MR.strings.unknown_title) },
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
modifier = Modifier.clickableNoIndication( modifier = Modifier.clickableNoIndication(
onLongClick = { onLongClick = {
@ -445,7 +446,7 @@ private fun MangaContentInfo(
) )
Text( Text(
text = author?.takeIf { it.isNotBlank() } text = author?.takeIf { it.isNotBlank() }
?: stringResource(R.string.unknown_author), ?: stringResource(MR.strings.unknown_author),
style = MaterialTheme.typography.titleSmall, style = MaterialTheme.typography.titleSmall,
modifier = Modifier modifier = Modifier
.clickableNoIndication( .clickableNoIndication(
@ -511,13 +512,13 @@ private fun MangaContentInfo(
ProvideTextStyle(MaterialTheme.typography.bodyMedium) { ProvideTextStyle(MaterialTheme.typography.bodyMedium) {
Text( Text(
text = when (status) { text = when (status) {
SManga.ONGOING.toLong() -> stringResource(R.string.ongoing) SManga.ONGOING.toLong() -> stringResource(MR.strings.ongoing)
SManga.COMPLETED.toLong() -> stringResource(R.string.completed) SManga.COMPLETED.toLong() -> stringResource(MR.strings.completed)
SManga.LICENSED.toLong() -> stringResource(R.string.licensed) SManga.LICENSED.toLong() -> stringResource(MR.strings.licensed)
SManga.PUBLISHING_FINISHED.toLong() -> stringResource(R.string.publishing_finished) SManga.PUBLISHING_FINISHED.toLong() -> stringResource(MR.strings.publishing_finished)
SManga.CANCELLED.toLong() -> stringResource(R.string.cancelled) SManga.CANCELLED.toLong() -> stringResource(MR.strings.cancelled)
SManga.ON_HIATUS.toLong() -> stringResource(R.string.on_hiatus) SManga.ON_HIATUS.toLong() -> stringResource(MR.strings.on_hiatus)
else -> stringResource(R.string.unknown) else -> stringResource(MR.strings.unknown)
}, },
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
maxLines = 1, maxLines = 1,
@ -592,7 +593,7 @@ private fun MangaSummary(
Icon( Icon(
painter = rememberAnimatedVectorPainter(image, !expanded), painter = rememberAnimatedVectorPainter(image, !expanded),
contentDescription = stringResource( contentDescription = stringResource(
if (expanded) R.string.manga_info_collapse else R.string.manga_info_expand, if (expanded) MR.strings.manga_info_collapse else MR.strings.manga_info_expand,
), ),
tint = MaterialTheme.colorScheme.onBackground, tint = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.background(Brush.radialGradient(colors = colors.asReversed())), modifier = Modifier.background(Brush.radialGradient(colors = colors.asReversed())),

View File

@ -21,7 +21,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
@ -29,8 +28,9 @@ import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.DownloadDropdownMenu import eu.kanade.presentation.components.DownloadDropdownMenu
import eu.kanade.presentation.components.UpIcon import eu.kanade.presentation.components.UpIcon
import eu.kanade.presentation.manga.DownloadAction import eu.kanade.presentation.manga.DownloadAction
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.theme.active import tachiyomi.presentation.core.theme.active
@Composable @Composable
@ -75,12 +75,12 @@ fun MangaToolbar(
AppBarActions( AppBarActions(
persistentListOf( persistentListOf(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_select_all), title = stringResource(MR.strings.action_select_all),
icon = Icons.Outlined.SelectAll, icon = Icons.Outlined.SelectAll,
onClick = onSelectAll, onClick = onSelectAll,
), ),
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_select_inverse), title = stringResource(MR.strings.action_select_inverse),
icon = Icons.Outlined.FlipToBack, icon = Icons.Outlined.FlipToBack,
onClick = onInvertSelection, onClick = onInvertSelection,
), ),
@ -104,7 +104,7 @@ fun MangaToolbar(
if (onClickDownload != null) { if (onClickDownload != null) {
add( add(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.manga_download), title = stringResource(MR.strings.manga_download),
icon = Icons.Outlined.Download, icon = Icons.Outlined.Download,
onClick = { downloadExpanded = !downloadExpanded }, onClick = { downloadExpanded = !downloadExpanded },
), ),
@ -112,7 +112,7 @@ fun MangaToolbar(
} }
add( add(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_filter), title = stringResource(MR.strings.action_filter),
icon = Icons.Outlined.FilterList, icon = Icons.Outlined.FilterList,
iconTint = filterTint, iconTint = filterTint,
onClick = onClickFilter, onClick = onClickFilter,
@ -120,14 +120,14 @@ fun MangaToolbar(
) )
add( add(
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_webview_refresh), title = stringResource(MR.strings.action_webview_refresh),
onClick = onClickRefresh, onClick = onClickRefresh,
), ),
) )
if (onClickEditCategory != null) { if (onClickEditCategory != null) {
add( add(
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_edit_categories), title = stringResource(MR.strings.action_edit_categories),
onClick = onClickEditCategory, onClick = onClickEditCategory,
), ),
) )
@ -135,7 +135,7 @@ fun MangaToolbar(
if (onClickMigrate != null) { if (onClickMigrate != null) {
add( add(
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_migrate), title = stringResource(MR.strings.action_migrate),
onClick = onClickMigrate, onClick = onClickMigrate,
), ),
) )
@ -143,7 +143,7 @@ fun MangaToolbar(
if (onClickShare != null) { if (onClickShare != null) {
add( add(
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_share), title = stringResource(MR.strings.action_share),
onClick = onClickShare, onClick = onClickShare,
), ),
) )

View File

@ -10,11 +10,11 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.util.secondaryItemAlpha import tachiyomi.presentation.core.util.secondaryItemAlpha
@Composable @Composable
@ -34,7 +34,7 @@ fun MissingChapterCountListItem(
) { ) {
HorizontalDivider(modifier = Modifier.weight(1f)) HorizontalDivider(modifier = Modifier.weight(1f))
Text( Text(
text = pluralStringResource(id = R.plurals.missing_chapters, count = count, count), text = pluralStringResource(MR.plurals.missing_chapters, count = count, count),
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
) )
HorizontalDivider(modifier = Modifier.weight(1f)) HorizontalDivider(modifier = Modifier.weight(1f))

View File

@ -20,19 +20,17 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.minimumInteractiveComponentSize import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.toMutableStateList import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.TextButton import tachiyomi.presentation.core.components.material.TextButton
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart import tachiyomi.presentation.core.util.isScrolledToStart
@ -49,10 +47,10 @@ fun ScanlatorFilterDialog(
val mutableExcludedScanlators = remember(excludedScanlators) { excludedScanlators.toMutableStateList() } val mutableExcludedScanlators = remember(excludedScanlators) { excludedScanlators.toMutableStateList() }
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.exclude_scanlators)) }, title = { Text(text = stringResource(MR.strings.exclude_scanlators)) },
text = textFunc@{ text = textFunc@{
if (sortedAvailableScanlators.isEmpty()) { if (sortedAvailableScanlators.isEmpty()) {
Text(text = stringResource(R.string.no_scanlators_found)) Text(text = stringResource(MR.strings.no_scanlators_found))
return@textFunc return@textFunc
} }
Box { Box {
@ -108,16 +106,16 @@ fun ScanlatorFilterDialog(
confirmButton = { confirmButton = {
if (sortedAvailableScanlators.isEmpty()) { if (sortedAvailableScanlators.isEmpty()) {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
} else { } else {
FlowRow { FlowRow {
TextButton(onClick = mutableExcludedScanlators::clear) { TextButton(onClick = mutableExcludedScanlators::clear) {
Text(text = stringResource(R.string.action_reset)) Text(text = stringResource(MR.strings.action_reset))
} }
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
TextButton( TextButton(
onClick = { onClick = {
@ -125,7 +123,7 @@ fun ScanlatorFilterDialog(
onDismissRequest() onDismissRequest()
}, },
) { ) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
} }
} }

View File

@ -13,9 +13,7 @@ import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.automirrored.outlined.Label import androidx.compose.material.icons.automirrored.outlined.Label
import androidx.compose.material.icons.outlined.CloudOff import androidx.compose.material.icons.outlined.CloudOff
import androidx.compose.material.icons.outlined.GetApp import androidx.compose.material.icons.outlined.GetApp
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material.icons.outlined.Info import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Label
import androidx.compose.material.icons.outlined.QueryStats import androidx.compose.material.icons.outlined.QueryStats
import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.Storage import androidx.compose.material.icons.outlined.Storage
@ -24,8 +22,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource import androidx.compose.ui.res.vectorResource
import eu.kanade.presentation.components.WarningBanner import eu.kanade.presentation.components.WarningBanner
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
@ -33,8 +29,11 @@ import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.more.DownloadQueueState import eu.kanade.tachiyomi.ui.more.DownloadQueueState
import tachiyomi.core.Constants import tachiyomi.core.Constants
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun MoreScreen( fun MoreScreen(
@ -62,7 +61,7 @@ fun MoreScreen(
) { ) {
if (isFDroid) { if (isFDroid) {
WarningBanner( WarningBanner(
textRes = R.string.fdroid_warning, textRes = MR.strings.fdroid_warning,
modifier = Modifier.clickable { modifier = Modifier.clickable {
uriHandler.openUri( uriHandler.openUri(
"https://tachiyomi.org/docs/faq/general#how-do-i-update-from-the-f-droid-builds", "https://tachiyomi.org/docs/faq/general#how-do-i-update-from-the-f-droid-builds",
@ -81,8 +80,8 @@ fun MoreScreen(
} }
item { item {
SwitchPreferenceWidget( SwitchPreferenceWidget(
title = stringResource(R.string.label_downloaded_only), title = stringResource(MR.strings.label_downloaded_only),
subtitle = stringResource(R.string.downloaded_only_summary), subtitle = stringResource(MR.strings.downloaded_only_summary),
icon = Icons.Outlined.CloudOff, icon = Icons.Outlined.CloudOff,
checked = downloadedOnly, checked = downloadedOnly,
onCheckedChanged = onDownloadedOnlyChange, onCheckedChanged = onDownloadedOnlyChange,
@ -90,8 +89,8 @@ fun MoreScreen(
} }
item { item {
SwitchPreferenceWidget( SwitchPreferenceWidget(
title = stringResource(R.string.pref_incognito_mode), title = stringResource(MR.strings.pref_incognito_mode),
subtitle = stringResource(R.string.pref_incognito_mode_summary), subtitle = stringResource(MR.strings.pref_incognito_mode_summary),
icon = ImageVector.vectorResource(R.drawable.ic_glasses_24dp), icon = ImageVector.vectorResource(R.drawable.ic_glasses_24dp),
checked = incognitoMode, checked = incognitoMode,
onCheckedChanged = onIncognitoModeChange, onCheckedChanged = onIncognitoModeChange,
@ -103,17 +102,17 @@ fun MoreScreen(
item { item {
val downloadQueueState = downloadQueueStateProvider() val downloadQueueState = downloadQueueStateProvider()
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.label_download_queue), title = stringResource(MR.strings.label_download_queue),
subtitle = when (downloadQueueState) { subtitle = when (downloadQueueState) {
DownloadQueueState.Stopped -> null DownloadQueueState.Stopped -> null
is DownloadQueueState.Paused -> { is DownloadQueueState.Paused -> {
val pending = downloadQueueState.pending val pending = downloadQueueState.pending
if (pending == 0) { if (pending == 0) {
stringResource(R.string.paused) stringResource(MR.strings.paused)
} else { } else {
"${stringResource(R.string.paused)}${ "${stringResource(MR.strings.paused)}${
pluralStringResource( pluralStringResource(
id = R.plurals.download_queue_summary, MR.plurals.download_queue_summary,
count = pending, count = pending,
pending, pending,
) )
@ -122,7 +121,7 @@ fun MoreScreen(
} }
is DownloadQueueState.Downloading -> { is DownloadQueueState.Downloading -> {
val pending = downloadQueueState.pending val pending = downloadQueueState.pending
pluralStringResource(id = R.plurals.download_queue_summary, count = pending, pending) pluralStringResource(MR.plurals.download_queue_summary, count = pending, pending)
} }
}, },
icon = Icons.Outlined.GetApp, icon = Icons.Outlined.GetApp,
@ -131,21 +130,21 @@ fun MoreScreen(
} }
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.categories), title = stringResource(MR.strings.categories),
icon = Icons.AutoMirrored.Outlined.Label, icon = Icons.AutoMirrored.Outlined.Label,
onPreferenceClick = onClickCategories, onPreferenceClick = onClickCategories,
) )
} }
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.label_stats), title = stringResource(MR.strings.label_stats),
icon = Icons.Outlined.QueryStats, icon = Icons.Outlined.QueryStats,
onPreferenceClick = onClickStats, onPreferenceClick = onClickStats,
) )
} }
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.label_backup_and_sync), title = stringResource(MR.strings.label_backup_and_sync),
icon = Icons.Outlined.Storage, icon = Icons.Outlined.Storage,
onPreferenceClick = onClickDataAndStorage, onPreferenceClick = onClickDataAndStorage,
) )
@ -155,21 +154,21 @@ fun MoreScreen(
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.label_settings), title = stringResource(MR.strings.label_settings),
icon = Icons.Outlined.Settings, icon = Icons.Outlined.Settings,
onPreferenceClick = onClickSettings, onPreferenceClick = onClickSettings,
) )
} }
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.pref_category_about), title = stringResource(MR.strings.pref_category_about),
icon = Icons.Outlined.Info, icon = Icons.Outlined.Info,
onPreferenceClick = onClickAbout, onPreferenceClick = onClickAbout,
) )
} }
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.label_help), title = stringResource(MR.strings.label_help),
icon = Icons.AutoMirrored.Outlined.HelpOutline, icon = Icons.AutoMirrored.Outlined.HelpOutline,
onPreferenceClick = { uriHandler.openUri(Constants.URL_HELP) }, onPreferenceClick = { uriHandler.openUri(Constants.URL_HELP) },
) )

View File

@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.OpenInNew import androidx.compose.material.icons.automirrored.outlined.OpenInNew
import androidx.compose.material.icons.filled.OpenInNew
import androidx.compose.material.icons.outlined.NewReleases import androidx.compose.material.icons.outlined.NewReleases
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@ -14,7 +13,6 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import com.halilibo.richtext.markdown.Markdown import com.halilibo.richtext.markdown.Markdown
@ -22,8 +20,9 @@ import com.halilibo.richtext.ui.RichTextStyle
import com.halilibo.richtext.ui.material3.Material3RichText import com.halilibo.richtext.ui.material3.Material3RichText
import com.halilibo.richtext.ui.string.RichTextStringStyle import com.halilibo.richtext.ui.string.RichTextStringStyle
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.InfoScreen import tachiyomi.presentation.core.screens.InfoScreen
@Composable @Composable
@ -36,11 +35,11 @@ fun NewUpdateScreen(
) { ) {
InfoScreen( InfoScreen(
icon = Icons.Outlined.NewReleases, icon = Icons.Outlined.NewReleases,
headingText = stringResource(R.string.update_check_notification_update_available), headingText = stringResource(MR.strings.update_check_notification_update_available),
subtitleText = versionName, subtitleText = versionName,
acceptText = stringResource(R.string.update_check_confirm), acceptText = stringResource(MR.strings.update_check_confirm),
onAcceptClick = onAcceptUpdate, onAcceptClick = onAcceptUpdate,
rejectText = stringResource(R.string.action_not_now), rejectText = stringResource(MR.strings.action_not_now),
onRejectClick = onRejectUpdate, onRejectClick = onRejectUpdate,
) { ) {
Material3RichText( Material3RichText(
@ -59,7 +58,7 @@ fun NewUpdateScreen(
onClick = onOpenInBrowser, onClick = onOpenInBrowser,
modifier = Modifier.padding(top = MaterialTheme.padding.small), modifier = Modifier.padding(top = MaterialTheme.padding.small),
) { ) {
Text(text = stringResource(R.string.update_check_open)) Text(text = stringResource(MR.strings.update_check_open))
Spacer(modifier = Modifier.width(MaterialTheme.padding.tiny)) Spacer(modifier = Modifier.width(MaterialTheme.padding.tiny))
Icon(imageVector = Icons.AutoMirrored.Outlined.OpenInNew, contentDescription = null) Icon(imageVector = Icons.AutoMirrored.Outlined.OpenInNew, contentDescription = null)
} }

View File

@ -3,9 +3,9 @@ package eu.kanade.presentation.more.settings
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.Tracker
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.core.preference.Preference as PreferenceData import tachiyomi.core.preference.Preference as PreferenceData
sealed class Preference { sealed class Preference {
@ -109,7 +109,7 @@ sealed class Preference {
v.map { e[it] } v.map { e[it] }
.takeIf { it.isNotEmpty() } .takeIf { it.isNotEmpty() }
?.joinToString() ?.joinToString()
} ?: stringResource(R.string.none) } ?: stringResource(MR.strings.none)
subtitle?.format(combined) subtitle?.format(combined)
}, },
override val icon: ImageVector? = null, override val icon: ImageVector? = null,

View File

@ -1,15 +1,15 @@
package eu.kanade.presentation.more.settings package eu.kanade.presentation.more.settings
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun PreferenceScaffold( fun PreferenceScaffold(
@StringRes titleRes: Int, titleRes: StringResource,
actions: @Composable RowScope.() -> Unit = {}, actions: @Composable RowScope.() -> Unit = {},
onBackPressed: (() -> Unit)? = null, onBackPressed: (() -> Unit)? = null,
itemsProvider: @Composable () -> List<Preference>, itemsProvider: @Composable () -> List<Preference>,

View File

@ -3,10 +3,10 @@ package eu.kanade.presentation.more.settings.screen
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.category.visualName import eu.kanade.presentation.category.visualName
import eu.kanade.tachiyomi.R
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
/** /**
* Returns a string of categories name for settings subtitle * Returns a string of categories name for settings subtitle
@ -34,15 +34,15 @@ fun getCategoriesLabel(
includedCategories.isNotEmpty() && includedCategories.size != allCategories.size -> includedCategories.isNotEmpty() && includedCategories.size != allCategories.size ->
includedCategories.joinToString { it.visualName(context) } includedCategories.joinToString { it.visualName(context) }
// All explicitly selected // All explicitly selected
includedCategories.size == allCategories.size -> stringResource(R.string.all) includedCategories.size == allCategories.size -> stringResource(MR.strings.all)
allExcluded -> stringResource(R.string.none) allExcluded -> stringResource(MR.strings.none)
else -> stringResource(R.string.all) else -> stringResource(MR.strings.all)
} }
val excludedItemsText = when { val excludedItemsText = when {
excludedCategories.isEmpty() -> stringResource(R.string.none) excludedCategories.isEmpty() -> stringResource(MR.strings.none)
allExcluded -> stringResource(R.string.all) allExcluded -> stringResource(MR.strings.all)
else -> excludedCategories.joinToString { it.visualName(context) } else -> excludedCategories.joinToString { it.visualName(context) }
} }
return stringResource(R.string.include, includedItemsText) + "\n" + return stringResource(MR.strings.include, includedItemsText) + "\n" +
stringResource(R.string.exclude, excludedItemsText) stringResource(MR.strings.exclude, excludedItemsText)
} }

View File

@ -1,10 +1,10 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.PreferenceScaffold import eu.kanade.presentation.more.settings.PreferenceScaffold
import eu.kanade.presentation.util.LocalBackPress import eu.kanade.presentation.util.LocalBackPress
@ -13,8 +13,7 @@ interface SearchableSettings : Screen {
@Composable @Composable
@ReadOnlyComposable @ReadOnlyComposable
@StringRes fun getTitleRes(): StringResource
fun getTitleRes(): Int
@Composable @Composable
fun getPreferences(): List<Preference> fun getPreferences(): List<Preference>

View File

@ -7,7 +7,6 @@ import android.os.Build
import android.provider.Settings import android.provider.Settings
import android.webkit.WebStorage import android.webkit.WebStorage
import android.webkit.WebView import android.webkit.WebView
import androidx.annotation.StringRes
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
@ -21,7 +20,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.core.net.toUri import androidx.core.net.toUri
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
@ -29,9 +27,8 @@ import eu.kanade.domain.base.BasePreferences
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.screen.advanced.ClearDatabaseScreen import eu.kanade.presentation.more.settings.screen.advanced.ClearDatabaseScreen
import eu.kanade.presentation.more.settings.screen.debug.DebugInfoScreen import eu.kanade.presentation.more.settings.screen.debug.DebugInfoScreen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.DownloadCache import eu.kanade.tachiyomi.data.download.DownloadCache
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob import eu.kanade.tachiyomi.data.library.MetadataUpdateJob
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.NetworkPreferences import eu.kanade.tachiyomi.network.NetworkPreferences
import eu.kanade.tachiyomi.network.PREF_DOH_360 import eu.kanade.tachiyomi.network.PREF_DOH_360
@ -60,6 +57,8 @@ import tachiyomi.core.util.lang.launchNonCancellable
import tachiyomi.core.util.lang.withUIContext import tachiyomi.core.util.lang.withUIContext
import tachiyomi.core.util.system.logcat import tachiyomi.core.util.system.logcat
import tachiyomi.domain.manga.interactor.ResetViewerFlags import tachiyomi.domain.manga.interactor.ResetViewerFlags
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -69,8 +68,7 @@ object SettingsAdvancedScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
@StringRes override fun getTitleRes() = MR.strings.pref_category_advanced
override fun getTitleRes() = R.string.pref_category_advanced
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -86,13 +84,13 @@ object SettingsAdvancedScreen : SearchableSettings {
listOf( listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = basePreferences.acraEnabled(), pref = basePreferences.acraEnabled(),
title = stringResource(R.string.pref_enable_acra), title = stringResource(MR.strings.pref_enable_acra),
subtitle = stringResource(R.string.pref_acra_summary), subtitle = stringResource(MR.strings.pref_acra_summary),
enabled = isPreviewBuildType || isReleaseBuildType, enabled = isPreviewBuildType || isReleaseBuildType,
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_dump_crash_logs), title = stringResource(MR.strings.pref_dump_crash_logs),
subtitle = stringResource(R.string.pref_dump_crash_logs_summary), subtitle = stringResource(MR.strings.pref_dump_crash_logs_summary),
onClick = { onClick = {
scope.launch { scope.launch {
CrashLogUtil(context).dumpLogs() CrashLogUtil(context).dumpLogs()
@ -101,15 +99,15 @@ object SettingsAdvancedScreen : SearchableSettings {
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = networkPreferences.verboseLogging(), pref = networkPreferences.verboseLogging(),
title = stringResource(R.string.pref_verbose_logging), title = stringResource(MR.strings.pref_verbose_logging),
subtitle = stringResource(R.string.pref_verbose_logging_summary), subtitle = stringResource(MR.strings.pref_verbose_logging_summary),
onValueChanged = { onValueChanged = {
context.toast(R.string.requires_app_restart) context.toast(MR.strings.requires_app_restart)
true true
}, },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_debug_info), title = stringResource(MR.strings.pref_debug_info),
onClick = { navigator.push(DebugInfoScreen()) }, onClick = { navigator.push(DebugInfoScreen()) },
), ),
), ),
@ -117,7 +115,7 @@ object SettingsAdvancedScreen : SearchableSettings {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
add( add(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_manage_notifications), title = stringResource(MR.strings.pref_manage_notifications),
onClick = { onClick = {
val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply { val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName) putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
@ -145,11 +143,11 @@ object SettingsAdvancedScreen : SearchableSettings {
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.label_background_activity), title = stringResource(MR.strings.label_background_activity),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_disable_battery_optimization), title = stringResource(MR.strings.pref_disable_battery_optimization),
subtitle = stringResource(R.string.pref_disable_battery_optimization_summary), subtitle = stringResource(MR.strings.pref_disable_battery_optimization_summary),
onClick = { onClick = {
val packageName: String = context.packageName val packageName: String = context.packageName
if (!context.powerManager.isIgnoringBatteryOptimizations(packageName)) { if (!context.powerManager.isIgnoringBatteryOptimizations(packageName)) {
@ -162,16 +160,16 @@ object SettingsAdvancedScreen : SearchableSettings {
} }
context.startActivity(intent) context.startActivity(intent)
} catch (e: ActivityNotFoundException) { } catch (e: ActivityNotFoundException) {
context.toast(R.string.battery_optimization_setting_activity_not_found) context.toast(MR.strings.battery_optimization_setting_activity_not_found)
} }
} else { } else {
context.toast(R.string.battery_optimization_disabled) context.toast(MR.strings.battery_optimization_disabled)
} }
}, },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = "Don't kill my app!", title = "Don't kill my app!",
subtitle = stringResource(R.string.about_dont_kill_my_app), subtitle = stringResource(MR.strings.about_dont_kill_my_app),
onClick = { uriHandler.openUri("https://dontkillmyapp.com/") }, onClick = { uriHandler.openUri("https://dontkillmyapp.com/") },
), ),
), ),
@ -184,19 +182,19 @@ object SettingsAdvancedScreen : SearchableSettings {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.label_data), title = stringResource(MR.strings.label_data),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_invalidate_download_cache), title = stringResource(MR.strings.pref_invalidate_download_cache),
subtitle = stringResource(R.string.pref_invalidate_download_cache_summary), subtitle = stringResource(MR.strings.pref_invalidate_download_cache_summary),
onClick = { onClick = {
Injekt.get<DownloadCache>().invalidateCache() Injekt.get<DownloadCache>().invalidateCache()
context.toast(R.string.download_cache_invalidated) context.toast(MR.strings.download_cache_invalidated)
}, },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_clear_database), title = stringResource(MR.strings.pref_clear_database),
subtitle = stringResource(R.string.pref_clear_database_summary), subtitle = stringResource(MR.strings.pref_clear_database_summary),
onClick = { navigator.push(ClearDatabaseScreen()) }, onClick = { navigator.push(ClearDatabaseScreen()) },
), ),
), ),
@ -214,17 +212,17 @@ object SettingsAdvancedScreen : SearchableSettings {
val userAgent by userAgentPref.collectAsState() val userAgent by userAgentPref.collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.label_network), title = stringResource(MR.strings.label_network),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_clear_cookies), title = stringResource(MR.strings.pref_clear_cookies),
onClick = { onClick = {
networkHelper.cookieJar.removeAll() networkHelper.cookieJar.removeAll()
context.toast(R.string.cookies_cleared) context.toast(MR.strings.cookies_cleared)
}, },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_clear_webview_data), title = stringResource(MR.strings.pref_clear_webview_data),
onClick = { onClick = {
try { try {
WebView(context).run { WebView(context).run {
@ -236,18 +234,18 @@ object SettingsAdvancedScreen : SearchableSettings {
} }
WebStorage.getInstance().deleteAllData() WebStorage.getInstance().deleteAllData()
context.applicationInfo?.dataDir?.let { File("$it/app_webview/").deleteRecursively() } context.applicationInfo?.dataDir?.let { File("$it/app_webview/").deleteRecursively() }
context.toast(R.string.webview_data_deleted) context.toast(MR.strings.webview_data_deleted)
} catch (e: Throwable) { } catch (e: Throwable) {
logcat(LogPriority.ERROR, e) logcat(LogPriority.ERROR, e)
context.toast(R.string.cache_delete_error) context.toast(MR.strings.cache_delete_error)
} }
}, },
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = networkPreferences.dohProvider(), pref = networkPreferences.dohProvider(),
title = stringResource(R.string.pref_dns_over_https), title = stringResource(MR.strings.pref_dns_over_https),
entries = mapOf( entries = mapOf(
-1 to stringResource(R.string.disabled), -1 to stringResource(MR.strings.disabled),
PREF_DOH_CLOUDFLARE to "Cloudflare", PREF_DOH_CLOUDFLARE to "Cloudflare",
PREF_DOH_GOOGLE to "Google", PREF_DOH_GOOGLE to "Google",
PREF_DOH_ADGUARD to "AdGuard", PREF_DOH_ADGUARD to "AdGuard",
@ -262,30 +260,30 @@ object SettingsAdvancedScreen : SearchableSettings {
PREF_DOH_SHECAN to "Shecan", PREF_DOH_SHECAN to "Shecan",
), ),
onValueChanged = { onValueChanged = {
context.toast(R.string.requires_app_restart) context.toast(MR.strings.requires_app_restart)
true true
}, },
), ),
Preference.PreferenceItem.EditTextPreference( Preference.PreferenceItem.EditTextPreference(
pref = userAgentPref, pref = userAgentPref,
title = stringResource(R.string.pref_user_agent_string), title = stringResource(MR.strings.pref_user_agent_string),
onValueChanged = { onValueChanged = {
try { try {
// OkHttp checks for valid values internally // OkHttp checks for valid values internally
Headers.Builder().add("User-Agent", it) Headers.Builder().add("User-Agent", it)
} catch (_: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
context.toast(R.string.error_user_agent_string_invalid) context.toast(MR.strings.error_user_agent_string_invalid)
return@EditTextPreference false return@EditTextPreference false
} }
true true
}, },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_reset_user_agent_string), title = stringResource(MR.strings.pref_reset_user_agent_string),
enabled = remember(userAgent) { userAgent != userAgentPref.defaultValue() }, enabled = remember(userAgent) { userAgent != userAgentPref.defaultValue() },
onClick = { onClick = {
userAgentPref.delete() userAgentPref.delete()
context.toast(R.string.requires_app_restart) context.toast(MR.strings.requires_app_restart)
}, },
), ),
), ),
@ -298,23 +296,23 @@ object SettingsAdvancedScreen : SearchableSettings {
val context = LocalContext.current val context = LocalContext.current
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.label_library), title = stringResource(MR.strings.label_library),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_refresh_library_covers), title = stringResource(MR.strings.pref_refresh_library_covers),
onClick = { LibraryUpdateJob.startNow(context, target = LibraryUpdateJob.Target.COVERS) }, onClick = { MetadataUpdateJob.startNow(context) },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_reset_viewer_flags), title = stringResource(MR.strings.pref_reset_viewer_flags),
subtitle = stringResource(R.string.pref_reset_viewer_flags_summary), subtitle = stringResource(MR.strings.pref_reset_viewer_flags_summary),
onClick = { onClick = {
scope.launchNonCancellable { scope.launchNonCancellable {
val success = Injekt.get<ResetViewerFlags>().await() val success = Injekt.get<ResetViewerFlags>().await()
withUIContext { withUIContext {
val message = if (success) { val message = if (success) {
R.string.pref_reset_viewer_flags_success MR.strings.pref_reset_viewer_flags_success
} else { } else {
R.string.pref_reset_viewer_flags_error MR.strings.pref_reset_viewer_flags_error
} }
context.toast(message) context.toast(message)
} }
@ -338,11 +336,11 @@ object SettingsAdvancedScreen : SearchableSettings {
val dismiss = { shizukuMissing = false } val dismiss = { shizukuMissing = false }
AlertDialog( AlertDialog(
onDismissRequest = dismiss, onDismissRequest = dismiss,
title = { Text(text = stringResource(R.string.ext_installer_shizuku)) }, title = { Text(text = stringResource(MR.strings.ext_installer_shizuku)) },
text = { Text(text = stringResource(R.string.ext_installer_shizuku_unavailable_dialog)) }, text = { Text(text = stringResource(MR.strings.ext_installer_shizuku_unavailable_dialog)) },
dismissButton = { dismissButton = {
TextButton(onClick = dismiss) { TextButton(onClick = dismiss) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
confirmButton = { confirmButton = {
@ -352,19 +350,19 @@ object SettingsAdvancedScreen : SearchableSettings {
uriHandler.openUri("https://shizuku.rikka.app/download") uriHandler.openUri("https://shizuku.rikka.app/download")
}, },
) { ) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
) )
} }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.label_extensions), title = stringResource(MR.strings.label_extensions),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = extensionInstallerPref, pref = extensionInstallerPref,
title = stringResource(R.string.ext_installer_pref), title = stringResource(MR.strings.ext_installer_pref),
entries = extensionInstallerPref.entries entries = extensionInstallerPref.entries
.associateWith { stringResource(it.titleResId) }, .associateWith { stringResource(it.titleRes) },
onValueChanged = { onValueChanged = {
if (it == BasePreferences.ExtensionInstaller.SHIZUKU && if (it == BasePreferences.ExtensionInstaller.SHIZUKU &&
!context.isShizukuInstalled !context.isShizukuInstalled

View File

@ -3,7 +3,6 @@ package eu.kanade.presentation.more.settings.screen
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@ -13,7 +12,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.os.LocaleListCompat import androidx.core.os.LocaleListCompat
import eu.kanade.domain.ui.UiPreferences import eu.kanade.domain.ui.UiPreferences
@ -29,6 +27,9 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.merge
import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser
import tachiyomi.core.i18n.stringResource
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -38,8 +39,7 @@ object SettingsAppearanceScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
@StringRes override fun getTitleRes() = MR.strings.pref_category_appearance
override fun getTitleRes() = R.string.pref_category_appearance
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -76,26 +76,26 @@ object SettingsAppearanceScreen : SearchableSettings {
} }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_theme), title = stringResource(MR.strings.pref_category_theme),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = themeModePref, pref = themeModePref,
title = stringResource(R.string.pref_theme_mode), title = stringResource(MR.strings.pref_theme_mode),
entries = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { entries = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mapOf( mapOf(
ThemeMode.SYSTEM to stringResource(R.string.theme_system), ThemeMode.SYSTEM to stringResource(MR.strings.theme_system),
ThemeMode.LIGHT to stringResource(R.string.theme_light), ThemeMode.LIGHT to stringResource(MR.strings.theme_light),
ThemeMode.DARK to stringResource(R.string.theme_dark), ThemeMode.DARK to stringResource(MR.strings.theme_dark),
) )
} else { } else {
mapOf( mapOf(
ThemeMode.LIGHT to stringResource(R.string.theme_light), ThemeMode.LIGHT to stringResource(MR.strings.theme_light),
ThemeMode.DARK to stringResource(R.string.theme_dark), ThemeMode.DARK to stringResource(MR.strings.theme_dark),
) )
}, },
), ),
Preference.PreferenceItem.CustomPreference( Preference.PreferenceItem.CustomPreference(
title = stringResource(R.string.pref_app_theme), title = stringResource(MR.strings.pref_app_theme),
) { item -> ) { item ->
val value by appThemePref.collectAsState() val value by appThemePref.collectAsState()
AppThemePreferenceWidget( AppThemePreferenceWidget(
@ -107,7 +107,7 @@ object SettingsAppearanceScreen : SearchableSettings {
}, },
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = amoledPref, pref = amoledPref,
title = stringResource(R.string.pref_dark_theme_pure_black), title = stringResource(MR.strings.pref_dark_theme_pure_black),
enabled = themeMode != ThemeMode.LIGHT, enabled = themeMode != ThemeMode.LIGHT,
), ),
), ),
@ -140,11 +140,11 @@ object SettingsAppearanceScreen : SearchableSettings {
} }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_display), title = stringResource(MR.strings.pref_category_display),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.BasicListPreference( Preference.PreferenceItem.BasicListPreference(
value = currentLanguage, value = currentLanguage,
title = stringResource(R.string.pref_app_language), title = stringResource(MR.strings.pref_app_language),
entries = langs, entries = langs,
onValueChanged = { newValue -> onValueChanged = { newValue ->
currentLanguage = newValue currentLanguage = newValue
@ -153,28 +153,28 @@ object SettingsAppearanceScreen : SearchableSettings {
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = uiPreferences.tabletUiMode(), pref = uiPreferences.tabletUiMode(),
title = stringResource(R.string.pref_tablet_ui_mode), title = stringResource(MR.strings.pref_tablet_ui_mode),
entries = TabletUiMode.entries.associateWith { stringResource(it.titleResId) }, entries = TabletUiMode.entries.associateWith { stringResource(it.titleRes) },
onValueChanged = { onValueChanged = {
context.toast(R.string.requires_app_restart) context.toast(MR.strings.requires_app_restart)
true true
}, },
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = uiPreferences.dateFormat(), pref = uiPreferences.dateFormat(),
title = stringResource(R.string.pref_date_format), title = stringResource(MR.strings.pref_date_format),
entries = DateFormats entries = DateFormats
.associateWith { .associateWith {
val formattedDate = UiPreferences.dateFormat(it).format(now) val formattedDate = UiPreferences.dateFormat(it).format(now)
"${it.ifEmpty { stringResource(R.string.label_default) }} ($formattedDate)" "${it.ifEmpty { stringResource(MR.strings.label_default) }} ($formattedDate)"
}, },
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = uiPreferences.relativeTime(), pref = uiPreferences.relativeTime(),
title = stringResource(R.string.pref_relative_format), title = stringResource(MR.strings.pref_relative_format),
subtitle = stringResource( subtitle = stringResource(
R.string.pref_relative_format_summary, MR.strings.pref_relative_format_summary,
stringResource(R.string.relative_time_today), stringResource(MR.strings.relative_time_today),
formattedNow, formattedNow,
), ),
), ),
@ -201,7 +201,7 @@ object SettingsAppearanceScreen : SearchableSettings {
} }
langs.sortBy { it.second } langs.sortBy { it.second }
langs.add(0, Pair("", context.getString(R.string.label_default))) langs.add(0, Pair("", context.stringResource(MR.strings.label_default)))
return langs.toMap() return langs.toMap()
} }

View File

@ -1,16 +1,16 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.authenticate import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.authenticate
import tachiyomi.core.i18n.stringResource
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -18,8 +18,7 @@ object SettingsBrowseScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
@StringRes override fun getTitleRes() = MR.strings.browse
override fun getTitleRes() = R.string.browse
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -27,28 +26,28 @@ object SettingsBrowseScreen : SearchableSettings {
val sourcePreferences = remember { Injekt.get<SourcePreferences>() } val sourcePreferences = remember { Injekt.get<SourcePreferences>() }
return listOf( return listOf(
Preference.PreferenceGroup( Preference.PreferenceGroup(
title = stringResource(R.string.label_sources), title = stringResource(MR.strings.label_sources),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = sourcePreferences.hideInLibraryItems(), pref = sourcePreferences.hideInLibraryItems(),
title = stringResource(R.string.pref_hide_in_library_items), title = stringResource(MR.strings.pref_hide_in_library_items),
), ),
), ),
), ),
Preference.PreferenceGroup( Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_nsfw_content), title = stringResource(MR.strings.pref_category_nsfw_content),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = sourcePreferences.showNsfwSource(), pref = sourcePreferences.showNsfwSource(),
title = stringResource(R.string.pref_show_nsfw_source), title = stringResource(MR.strings.pref_show_nsfw_source),
subtitle = stringResource(R.string.requires_app_restart), subtitle = stringResource(MR.strings.requires_app_restart),
onValueChanged = { onValueChanged = {
(context as FragmentActivity).authenticate( (context as FragmentActivity).authenticate(
title = context.getString(R.string.pref_category_nsfw_content), title = context.stringResource(MR.strings.pref_category_nsfw_content),
) )
}, },
), ),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.parental_controls_info)), Preference.PreferenceItem.InfoPreference(stringResource(MR.strings.parental_controls_info)),
), ),
), ),
) )

View File

@ -8,7 +8,6 @@ import android.text.format.Formatter
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -27,7 +26,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
@ -36,7 +34,6 @@ import eu.kanade.presentation.more.settings.widget.BasePreferenceWidget
import eu.kanade.presentation.more.settings.widget.PrefsHorizontalPadding import eu.kanade.presentation.more.settings.widget.PrefsHorizontalPadding
import eu.kanade.presentation.permissions.PermissionRequestHelper import eu.kanade.presentation.permissions.PermissionRequestHelper
import eu.kanade.presentation.util.relativeTimeSpanString import eu.kanade.presentation.util.relativeTimeSpanString
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.BackupCreateJob import eu.kanade.tachiyomi.data.backup.BackupCreateJob
import eu.kanade.tachiyomi.data.backup.BackupFileValidator import eu.kanade.tachiyomi.data.backup.BackupFileValidator
import eu.kanade.tachiyomi.data.backup.BackupRestoreJob import eu.kanade.tachiyomi.data.backup.BackupRestoreJob
@ -51,11 +48,14 @@ import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import logcat.LogPriority import logcat.LogPriority
import tachiyomi.core.i18n.stringResource
import tachiyomi.core.util.lang.launchNonCancellable import tachiyomi.core.util.lang.launchNonCancellable
import tachiyomi.core.util.lang.withUIContext import tachiyomi.core.util.lang.withUIContext
import tachiyomi.core.util.system.logcat import tachiyomi.core.util.system.logcat
import tachiyomi.domain.backup.service.BackupPreferences import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.domain.sync.SyncPreferences import tachiyomi.domain.sync.SyncPreferences
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -65,8 +65,7 @@ object SettingsDataScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
@StringRes override fun getTitleRes() = MR.strings.label_backup_and_sync
override fun getTitleRes() = R.string.label_backup_and_sync
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -107,7 +106,7 @@ object SettingsDataScreen : SearchableSettings {
val lastAutoBackup by backupPreferences.lastAutoBackupTimestamp().collectAsState() val lastAutoBackup by backupPreferences.lastAutoBackupTimestamp().collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.label_backup), title = stringResource(MR.strings.label_backup),
preferenceItems = listOf( preferenceItems = listOf(
// Manual actions // Manual actions
getCreateBackupPref(), getCreateBackupPref(),
@ -116,14 +115,14 @@ object SettingsDataScreen : SearchableSettings {
// Automatic backups // Automatic backups
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = backupIntervalPref, pref = backupIntervalPref,
title = stringResource(R.string.pref_backup_interval), title = stringResource(MR.strings.pref_backup_interval),
entries = mapOf( entries = mapOf(
0 to stringResource(R.string.off), 0 to stringResource(MR.strings.off),
6 to stringResource(R.string.update_6hour), 6 to stringResource(MR.strings.update_6hour),
12 to stringResource(R.string.update_12hour), 12 to stringResource(MR.strings.update_12hour),
24 to stringResource(R.string.update_24hour), 24 to stringResource(MR.strings.update_24hour),
48 to stringResource(R.string.update_48hour), 48 to stringResource(MR.strings.update_48hour),
168 to stringResource(R.string.update_weekly), 168 to stringResource(MR.strings.update_weekly),
), ),
onValueChanged = { onValueChanged = {
BackupCreateJob.setupTask(context, it) BackupCreateJob.setupTask(context, it)
@ -133,12 +132,12 @@ object SettingsDataScreen : SearchableSettings {
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = backupPreferences.numberOfBackups(), pref = backupPreferences.numberOfBackups(),
enabled = backupInterval != 0, enabled = backupInterval != 0,
title = stringResource(R.string.pref_backup_slots), title = stringResource(MR.strings.pref_backup_slots),
entries = listOf(2, 3, 4, 5).associateWith { it.toString() }, entries = listOf(2, 3, 4, 5).associateWith { it.toString() },
), ),
Preference.PreferenceItem.InfoPreference( Preference.PreferenceItem.InfoPreference(
stringResource(R.string.backup_info) + "\n\n" + stringResource(MR.strings.backup_info) + "\n\n" +
stringResource(R.string.last_auto_backup_info, relativeTimeSpanString(lastAutoBackup)), stringResource(MR.strings.last_auto_backup_info, relativeTimeSpanString(lastAutoBackup)),
), ),
), ),
) )
@ -148,8 +147,8 @@ object SettingsDataScreen : SearchableSettings {
private fun getCreateBackupPref(): Preference.PreferenceItem.TextPreference { private fun getCreateBackupPref(): Preference.PreferenceItem.TextPreference {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
return Preference.PreferenceItem.TextPreference( return Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_create_backup), title = stringResource(MR.strings.pref_create_backup),
subtitle = stringResource(R.string.pref_create_backup_summ), subtitle = stringResource(MR.strings.pref_create_backup_summ),
onClick = { navigator.push(CreateBackupScreen()) }, onClick = { navigator.push(CreateBackupScreen()) },
) )
} }
@ -164,7 +163,7 @@ object SettingsDataScreen : SearchableSettings {
is InvalidRestore -> { is InvalidRestore -> {
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.invalid_backup_file)) }, title = { Text(text = stringResource(MR.strings.invalid_backup_file)) },
text = { Text(text = listOfNotNull(err.uri, err.message).joinToString("\n\n")) }, text = { Text(text = listOfNotNull(err.uri, err.message).joinToString("\n\n")) },
dismissButton = { dismissButton = {
TextButton( TextButton(
@ -173,12 +172,12 @@ object SettingsDataScreen : SearchableSettings {
onDismissRequest() onDismissRequest()
}, },
) { ) {
Text(text = stringResource(R.string.action_copy_to_clipboard)) Text(text = stringResource(MR.strings.action_copy_to_clipboard))
} }
}, },
confirmButton = { confirmButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
) )
@ -186,15 +185,15 @@ object SettingsDataScreen : SearchableSettings {
is MissingRestoreComponents -> { is MissingRestoreComponents -> {
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.pref_restore_backup)) }, title = { Text(text = stringResource(MR.strings.pref_restore_backup)) },
text = { text = {
Column( Column(
modifier = Modifier.verticalScroll(rememberScrollState()), modifier = Modifier.verticalScroll(rememberScrollState()),
) { ) {
val msg = buildString { val msg = buildString {
append(stringResource(R.string.backup_restore_content_full)) append(stringResource(MR.strings.backup_restore_content_full))
if (err.sources.isNotEmpty()) { if (err.sources.isNotEmpty()) {
append("\n\n").append(stringResource(R.string.backup_restore_missing_sources)) append("\n\n").append(stringResource(MR.strings.backup_restore_missing_sources))
err.sources.joinTo( err.sources.joinTo(
this, this,
separator = "\n- ", separator = "\n- ",
@ -202,7 +201,9 @@ object SettingsDataScreen : SearchableSettings {
) )
} }
if (err.trackers.isNotEmpty()) { if (err.trackers.isNotEmpty()) {
append("\n\n").append(stringResource(R.string.backup_restore_missing_trackers)) append(
"\n\n",
).append(stringResource(MR.strings.backup_restore_missing_trackers))
err.trackers.joinTo( err.trackers.joinTo(
this, this,
separator = "\n- ", separator = "\n- ",
@ -220,7 +221,7 @@ object SettingsDataScreen : SearchableSettings {
onDismissRequest() onDismissRequest()
}, },
) { ) {
Text(text = stringResource(R.string.action_restore)) Text(text = stringResource(MR.strings.action_restore))
} }
}, },
) )
@ -233,12 +234,12 @@ object SettingsDataScreen : SearchableSettings {
object : ActivityResultContracts.GetContent() { object : ActivityResultContracts.GetContent() {
override fun createIntent(context: Context, input: String): Intent { override fun createIntent(context: Context, input: String): Intent {
val intent = super.createIntent(context, input) val intent = super.createIntent(context, input)
return Intent.createChooser(intent, context.getString(R.string.file_select_backup)) return Intent.createChooser(intent, context.stringResource(MR.strings.file_select_backup))
} }
}, },
) { ) {
if (it == null) { if (it == null) {
context.toast(R.string.file_null_uri_error) context.toast(MR.strings.file_null_uri_error)
return@rememberLauncherForActivityResult return@rememberLauncherForActivityResult
} }
@ -258,17 +259,17 @@ object SettingsDataScreen : SearchableSettings {
} }
return Preference.PreferenceItem.TextPreference( return Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_restore_backup), title = stringResource(MR.strings.pref_restore_backup),
subtitle = stringResource(R.string.pref_restore_backup_summ), subtitle = stringResource(MR.strings.pref_restore_backup_summ),
onClick = { onClick = {
if (!BackupRestoreJob.isRunning(context)) { if (!BackupRestoreJob.isRunning(context)) {
if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) { if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) {
context.toast(R.string.restore_miui_warning, Toast.LENGTH_LONG) context.toast(MR.strings.restore_miui_warning, Toast.LENGTH_LONG)
} }
// no need to catch because it's wrapped with a chooser // no need to catch because it's wrapped with a chooser
chooseBackup.launch("*/*") chooseBackup.launch("*/*")
} else { } else {
context.toast(R.string.restore_in_progress) context.toast(MR.strings.restore_in_progress)
} }
}, },
) )
@ -285,31 +286,31 @@ object SettingsDataScreen : SearchableSettings {
val cacheReadableSize = remember(cacheReadableSizeSema) { chapterCache.readableSize } val cacheReadableSize = remember(cacheReadableSizeSema) { chapterCache.readableSize }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.label_data), title = stringResource(MR.strings.label_data),
preferenceItems = listOf( preferenceItems = listOf(
getStorageInfoPref(cacheReadableSize), getStorageInfoPref(cacheReadableSize),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_clear_chapter_cache), title = stringResource(MR.strings.pref_clear_chapter_cache),
subtitle = stringResource(R.string.used_cache, cacheReadableSize), subtitle = stringResource(MR.strings.used_cache, cacheReadableSize),
onClick = { onClick = {
scope.launchNonCancellable { scope.launchNonCancellable {
try { try {
val deletedFiles = chapterCache.clear() val deletedFiles = chapterCache.clear()
withUIContext { withUIContext {
context.toast(context.getString(R.string.cache_deleted, deletedFiles)) context.toast(context.stringResource(MR.strings.cache_deleted, deletedFiles))
cacheReadableSizeSema++ cacheReadableSizeSema++
} }
} catch (e: Throwable) { } catch (e: Throwable) {
logcat(LogPriority.ERROR, e) logcat(LogPriority.ERROR, e)
withUIContext { context.toast(R.string.cache_delete_error) } withUIContext { context.toast(MR.strings.cache_delete_error) }
} }
} }
}, },
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.autoClearChapterCache(), pref = libraryPreferences.autoClearChapterCache(),
title = stringResource(R.string.pref_auto_clear_chapter_cache), title = stringResource(MR.strings.pref_auto_clear_chapter_cache),
), ),
), ),
) )
@ -328,10 +329,10 @@ object SettingsDataScreen : SearchableSettings {
} }
return Preference.PreferenceItem.CustomPreference( return Preference.PreferenceItem.CustomPreference(
title = stringResource(R.string.pref_storage_usage), title = stringResource(MR.strings.pref_storage_usage),
) { ) {
BasePreferenceWidget( BasePreferenceWidget(
title = stringResource(R.string.pref_storage_usage), title = stringResource(MR.strings.pref_storage_usage),
subcomponent = { subcomponent = {
// TODO: downloads, SD cards, bar representation?, i18n // TODO: downloads, SD cards, bar representation?, i18n
Box(modifier = Modifier.padding(horizontal = PrefsHorizontalPadding)) { Box(modifier = Modifier.padding(horizontal = PrefsHorizontalPadding)) {
@ -364,7 +365,7 @@ private fun getGoogleDrivePreferences(): List<Preference> {
val googleDriveSync = Injekt.get<GoogleDriveService>() val googleDriveSync = Injekt.get<GoogleDriveService>()
return listOf( return listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_google_drive_sign_in), title = stringResource(MR.string.pref_google_drive_sign_in),
onClick = { onClick = {
val intent = googleDriveSync.getSignInIntent() val intent = googleDriveSync.getSignInIntent()
context.startActivity(intent) context.startActivity(intent)
@ -389,13 +390,13 @@ private fun getGoogleDrivePurge(): Preference.PreferenceItem.TextPreference {
val result = googleDriveSync.deleteSyncDataFromGoogleDrive() val result = googleDriveSync.deleteSyncDataFromGoogleDrive()
when (result) { when (result) {
GoogleDriveSyncService.DeleteSyncDataStatus.NOT_INITIALIZED -> context.toast( GoogleDriveSyncService.DeleteSyncDataStatus.NOT_INITIALIZED -> context.toast(
R.string.google_drive_not_signed_in, MR.string.google_drive_not_signed_in,
) )
GoogleDriveSyncService.DeleteSyncDataStatus.NO_FILES -> context.toast( GoogleDriveSyncService.DeleteSyncDataStatus.NO_FILES -> context.toast(
R.string.google_drive_sync_data_not_found, MR.string.google_drive_sync_data_not_found,
) )
GoogleDriveSyncService.DeleteSyncDataStatus.SUCCESS -> context.toast( GoogleDriveSyncService.DeleteSyncDataStatus.SUCCESS -> context.toast(
R.string.google_drive_sync_data_purged, MR.string.google_drive_sync_data_purged,
) )
} }
} }
@ -405,7 +406,7 @@ private fun getGoogleDrivePurge(): Preference.PreferenceItem.TextPreference {
} }
return Preference.PreferenceItem.TextPreference( return Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_google_drive_purge_sync_data), title = stringResource(MR.string.pref_google_drive_purge_sync_data),
onClick = { showPurgeDialog.value = true }, onClick = { showPurgeDialog.value = true },
) )
} }
@ -417,11 +418,11 @@ fun PurgeConfirmationDialog(
) { ) {
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.pref_purge_confirmation_title)) }, title = { Text(text = stringResource(MR.string.pref_purge_confirmation_title)) },
text = { Text(text = stringResource(R.string.pref_purge_confirmation_message)) }, text = { Text(text = stringResource(MR.string.pref_purge_confirmation_message)) },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.string.action_cancel))
} }
}, },
confirmButton = { confirmButton = {
@ -437,8 +438,8 @@ private fun getSelfHostPreferences(syncPreferences: SyncPreferences): List<Prefe
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
return listOf( return listOf(
Preference.PreferenceItem.EditTextPreference( Preference.PreferenceItem.EditTextPreference(
title = stringResource(R.string.pref_sync_host), title = stringResource(MR.string.pref_sync_host),
subtitle = stringResource(R.string.pref_sync_host_summ), subtitle = stringResource(MR.string.pref_sync_host_summ),
pref = syncPreferences.syncHost(), pref = syncPreferences.syncHost(),
onValueChanged = { newValue -> onValueChanged = { newValue ->
scope.launch { scope.launch {
@ -451,8 +452,8 @@ private fun getSelfHostPreferences(syncPreferences: SyncPreferences): List<Prefe
}, },
), ),
Preference.PreferenceItem.EditTextPreference( Preference.PreferenceItem.EditTextPreference(
title = stringResource(R.string.pref_sync_api_key), title = stringResource(MR.string.pref_sync_api_key),
subtitle = stringResource(R.string.pref_sync_api_key_summ), subtitle = stringResource(MR.string.pref_sync_api_key_summ),
pref = syncPreferences.syncAPIKey(), pref = syncPreferences.syncAPIKey(),
), ),
) )
@ -471,7 +472,7 @@ private fun getSyncNowPref(): Preference.PreferenceGroup {
if (!SyncDataJob.isAnyJobRunning(context)) { if (!SyncDataJob.isAnyJobRunning(context)) {
SyncDataJob.startNow(context) SyncDataJob.startNow(context)
} else { } else {
context.toast(R.string.sync_in_progress) context.toast(MR.string.sync_in_progress)
} }
} }
}, },
@ -479,11 +480,11 @@ private fun getSyncNowPref(): Preference.PreferenceGroup {
) )
} }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_sync_now_group_title), title = stringResource(MR.string.pref_sync_now_group_title),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_sync_now), title = stringResource(MR.string.pref_sync_now),
subtitle = stringResource(R.string.pref_sync_now_subtitle), subtitle = stringResource(MR.string.pref_sync_now_subtitle),
onClick = { onClick = {
showDialog = true showDialog = true
}, },
@ -499,21 +500,21 @@ private fun getAutomaticSyncGroup(syncPreferences: SyncPreferences): Preference.
val lastSync by syncPreferences.lastSyncTimestamp().collectAsState() val lastSync by syncPreferences.lastSyncTimestamp().collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_sync_service_category), title = stringResource(MR.string.pref_sync_service_category),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = syncIntervalPref, pref = syncIntervalPref,
title = stringResource(R.string.pref_sync_interval), title = stringResource(MR.string.pref_sync_interval),
entries = mapOf( entries = mapOf(
0 to stringResource(R.string.off), 0 to stringResource(MR.string.off),
30 to stringResource(R.string.update_30min), 30 to stringResource(MR.string.update_30min),
60 to stringResource(R.string.update_1hour), 60 to stringResource(MR.string.update_1hour),
180 to stringResource(R.string.update_3hour), 180 to stringResource(MR.string.update_3hour),
360 to stringResource(R.string.update_6hour), 360 to stringResource(MR.string.update_6hour),
720 to stringResource(R.string.update_12hour), 720 to stringResource(MR.string.update_12hour),
1440 to stringResource(R.string.update_24hour), 1440 to stringResource(MR.string.update_24hour),
2880 to stringResource(R.string.update_48hour), 2880 to stringResource(MR.string.update_48hour),
10080 to stringResource(R.string.update_weekly), 10080 to stringResource(MR.string.update_weekly),
), ),
onValueChanged = { onValueChanged = {
SyncDataJob.setupTask(context, it) SyncDataJob.setupTask(context, it)
@ -521,7 +522,7 @@ private fun getAutomaticSyncGroup(syncPreferences: SyncPreferences): Preference.
}, },
), ),
Preference.PreferenceItem.InfoPreference( Preference.PreferenceItem.InfoPreference(
stringResource(R.string.last_synchronization, relativeTimeSpanString(lastSync)), stringResource(MR.string.last_synchronization, relativeTimeSpanString(lastSync)),
), ),
), ),
) )
@ -534,11 +535,11 @@ fun SyncConfirmationDialog(
) { ) {
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.pref_sync_confirmation_title)) }, title = { Text(text = stringResource(MR.string.pref_sync_confirmation_title)) },
text = { Text(text = stringResource(R.string.pref_sync_confirmation_message)) }, text = { Text(text = stringResource(MR.string.pref_sync_confirmation_message)) },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.string.action_cancel))
} }
}, },
confirmButton = { confirmButton = {

View File

@ -4,7 +4,6 @@ import android.content.Intent
import android.os.Environment import android.os.Environment
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
@ -14,19 +13,19 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.util.fastMap import androidx.compose.ui.util.fastMap
import androidx.core.net.toUri import androidx.core.net.toUri
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import eu.kanade.presentation.category.visualName import eu.kanade.presentation.category.visualName
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.widget.TriStateListDialog import eu.kanade.presentation.more.settings.widget.TriStateListDialog
import eu.kanade.tachiyomi.R
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import tachiyomi.domain.category.interactor.GetCategories import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.domain.download.service.DownloadPreferences import tachiyomi.domain.download.service.DownloadPreferences
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -36,8 +35,7 @@ object SettingsDownloadScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
@StringRes override fun getTitleRes() = MR.strings.pref_category_downloads
override fun getTitleRes() = R.string.pref_category_downloads
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -49,16 +47,16 @@ object SettingsDownloadScreen : SearchableSettings {
getDownloadLocationPreference(downloadPreferences = downloadPreferences), getDownloadLocationPreference(downloadPreferences = downloadPreferences),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.downloadOnlyOverWifi(), pref = downloadPreferences.downloadOnlyOverWifi(),
title = stringResource(R.string.connected_to_wifi), title = stringResource(MR.strings.connected_to_wifi),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.saveChaptersAsCBZ(), pref = downloadPreferences.saveChaptersAsCBZ(),
title = stringResource(R.string.save_chapter_as_cbz), title = stringResource(MR.strings.save_chapter_as_cbz),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.splitTallImages(), pref = downloadPreferences.splitTallImages(),
title = stringResource(R.string.split_tall_images), title = stringResource(MR.strings.split_tall_images),
subtitle = stringResource(R.string.split_tall_images_summary), subtitle = stringResource(MR.strings.split_tall_images_summary),
), ),
getDeleteChaptersGroup( getDeleteChaptersGroup(
downloadPreferences = downloadPreferences, downloadPreferences = downloadPreferences,
@ -99,15 +97,15 @@ object SettingsDownloadScreen : SearchableSettings {
return Preference.PreferenceItem.ListPreference( return Preference.PreferenceItem.ListPreference(
pref = currentDirPref, pref = currentDirPref,
title = stringResource(R.string.pref_download_directory), title = stringResource(MR.strings.pref_download_directory),
subtitleProvider = { value, _ -> subtitleProvider = { value, _ ->
remember(value) { remember(value) {
UniFile.fromUri(context, value.toUri())?.filePath UniFile.fromUri(context, value.toUri())?.filePath
} ?: stringResource(R.string.invalid_location, value) } ?: stringResource(MR.strings.invalid_location, value)
}, },
entries = mapOf( entries = mapOf(
defaultDirPair, defaultDirPair,
customDirEntryKey to stringResource(R.string.custom_dir), customDirEntryKey to stringResource(MR.strings.custom_dir),
), ),
onValueChanged = { onValueChanged = {
val default = it == defaultDirPair.first val default = it == defaultDirPair.first
@ -121,7 +119,7 @@ object SettingsDownloadScreen : SearchableSettings {
@Composable @Composable
private fun rememberDefaultDownloadDir(): Pair<String, String> { private fun rememberDefaultDownloadDir(): Pair<String, String> {
val appName = stringResource(R.string.app_name) val appName = stringResource(MR.strings.app_name)
return remember { return remember {
val file = UniFile.fromFile( val file = UniFile.fromFile(
File( File(
@ -139,27 +137,27 @@ object SettingsDownloadScreen : SearchableSettings {
categories: List<Category>, categories: List<Category>,
): Preference.PreferenceGroup { ): Preference.PreferenceGroup {
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_delete_chapters), title = stringResource(MR.strings.pref_category_delete_chapters),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.removeAfterMarkedAsRead(), pref = downloadPreferences.removeAfterMarkedAsRead(),
title = stringResource(R.string.pref_remove_after_marked_as_read), title = stringResource(MR.strings.pref_remove_after_marked_as_read),
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = downloadPreferences.removeAfterReadSlots(), pref = downloadPreferences.removeAfterReadSlots(),
title = stringResource(R.string.pref_remove_after_read), title = stringResource(MR.strings.pref_remove_after_read),
entries = mapOf( entries = mapOf(
-1 to stringResource(R.string.disabled), -1 to stringResource(MR.strings.disabled),
0 to stringResource(R.string.last_read_chapter), 0 to stringResource(MR.strings.last_read_chapter),
1 to stringResource(R.string.second_to_last), 1 to stringResource(MR.strings.second_to_last),
2 to stringResource(R.string.third_to_last), 2 to stringResource(MR.strings.third_to_last),
3 to stringResource(R.string.fourth_to_last), 3 to stringResource(MR.strings.fourth_to_last),
4 to stringResource(R.string.fifth_to_last), 4 to stringResource(MR.strings.fifth_to_last),
), ),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadPreferences.removeBookmarkedChapters(), pref = downloadPreferences.removeBookmarkedChapters(),
title = stringResource(R.string.pref_remove_bookmarked_chapters), title = stringResource(MR.strings.pref_remove_bookmarked_chapters),
), ),
getExcludedCategoriesPreference( getExcludedCategoriesPreference(
downloadPreferences = downloadPreferences, downloadPreferences = downloadPreferences,
@ -176,7 +174,7 @@ object SettingsDownloadScreen : SearchableSettings {
): Preference.PreferenceItem.MultiSelectListPreference { ): Preference.PreferenceItem.MultiSelectListPreference {
return Preference.PreferenceItem.MultiSelectListPreference( return Preference.PreferenceItem.MultiSelectListPreference(
pref = downloadPreferences.removeExcludeCategories(), pref = downloadPreferences.removeExcludeCategories(),
title = stringResource(R.string.pref_remove_exclude_categories), title = stringResource(MR.strings.pref_remove_exclude_categories),
entries = categories().associate { it.id.toString() to it.visualName }, entries = categories().associate { it.id.toString() to it.visualName },
) )
} }
@ -197,8 +195,8 @@ object SettingsDownloadScreen : SearchableSettings {
var showDialog by rememberSaveable { mutableStateOf(false) } var showDialog by rememberSaveable { mutableStateOf(false) }
if (showDialog) { if (showDialog) {
TriStateListDialog( TriStateListDialog(
title = stringResource(R.string.categories), title = stringResource(MR.strings.categories),
message = stringResource(R.string.pref_download_new_categories_details), message = stringResource(MR.strings.pref_download_new_categories_details),
items = allCategories, items = allCategories,
initialChecked = included.mapNotNull { id -> allCategories.find { it.id.toString() == id } }, initialChecked = included.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
initialInversed = excluded.mapNotNull { id -> allCategories.find { it.id.toString() == id } }, initialInversed = excluded.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
@ -213,14 +211,14 @@ object SettingsDownloadScreen : SearchableSettings {
} }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_auto_download), title = stringResource(MR.strings.pref_category_auto_download),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = downloadNewChaptersPref, pref = downloadNewChaptersPref,
title = stringResource(R.string.pref_download_new), title = stringResource(MR.strings.pref_download_new),
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.categories), title = stringResource(MR.strings.categories),
subtitle = getCategoriesLabel( subtitle = getCategoriesLabel(
allCategories = allCategories, allCategories = allCategories,
included = included, included = included,
@ -238,20 +236,20 @@ object SettingsDownloadScreen : SearchableSettings {
downloadPreferences: DownloadPreferences, downloadPreferences: DownloadPreferences,
): Preference.PreferenceGroup { ): Preference.PreferenceGroup {
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.download_ahead), title = stringResource(MR.strings.download_ahead),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = downloadPreferences.autoDownloadWhileReading(), pref = downloadPreferences.autoDownloadWhileReading(),
title = stringResource(R.string.auto_download_while_reading), title = stringResource(MR.strings.auto_download_while_reading),
entries = listOf(0, 2, 3, 5, 10).associateWith { entries = listOf(0, 2, 3, 5, 10).associateWith {
if (it == 0) { if (it == 0) {
stringResource(R.string.disabled) stringResource(MR.strings.disabled)
} else { } else {
pluralStringResource(id = R.plurals.next_unread_chapters, count = it, it) pluralStringResource(MR.plurals.next_unread_chapters, count = it, it)
} }
}, },
), ),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.download_ahead_info)), Preference.PreferenceItem.InfoPreference(stringResource(MR.strings.download_ahead_info)),
), ),
) )
} }

View File

@ -1,6 +1,5 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
@ -11,8 +10,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.util.fastMap import androidx.compose.ui.util.fastMap
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
@ -21,7 +18,6 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.category.visualName import eu.kanade.presentation.category.visualName
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.widget.TriStateListDialog import eu.kanade.presentation.more.settings.widget.TriStateListDialog
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.ui.category.CategoryScreen import eu.kanade.tachiyomi.ui.category.CategoryScreen
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -37,6 +33,9 @@ import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_HAS_U
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_COMPLETED import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_COMPLETED
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_READ import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_READ
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_OUTSIDE_RELEASE_PERIOD import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_OUTSIDE_RELEASE_PERIOD
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -45,8 +44,7 @@ object SettingsLibraryScreen : SearchableSettings {
@Composable @Composable
@ReadOnlyComposable @ReadOnlyComposable
@StringRes override fun getTitleRes() = MR.strings.pref_category_library
override fun getTitleRes() = R.string.pref_category_library
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -77,16 +75,16 @@ object SettingsLibraryScreen : SearchableSettings {
// For default category // For default category
val ids = listOf(libraryPreferences.defaultCategory().defaultValue()) + val ids = listOf(libraryPreferences.defaultCategory().defaultValue()) +
allCategories.fastMap { it.id.toInt() } allCategories.fastMap { it.id.toInt() }
val labels = listOf(stringResource(R.string.default_category_summary)) + val labels = listOf(stringResource(MR.strings.default_category_summary)) +
allCategories.fastMap { it.visualName(context) } allCategories.fastMap { it.visualName(context) }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.categories), title = stringResource(MR.strings.categories),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.action_edit_categories), title = stringResource(MR.strings.action_edit_categories),
subtitle = pluralStringResource( subtitle = pluralStringResource(
id = R.plurals.num_categories, MR.plurals.num_categories,
count = userCategoriesCount, count = userCategoriesCount,
userCategoriesCount, userCategoriesCount,
), ),
@ -94,13 +92,13 @@ object SettingsLibraryScreen : SearchableSettings {
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = libraryPreferences.defaultCategory(), pref = libraryPreferences.defaultCategory(),
title = stringResource(R.string.default_category), title = stringResource(MR.strings.default_category),
subtitle = selectedCategory?.visualName ?: stringResource(R.string.default_category_summary), subtitle = selectedCategory?.visualName ?: stringResource(MR.strings.default_category_summary),
entries = ids.zip(labels).toMap(), entries = ids.zip(labels).toMap(),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.categorizedDisplaySettings(), pref = libraryPreferences.categorizedDisplaySettings(),
title = stringResource(R.string.categorized_display_settings), title = stringResource(MR.strings.categorized_display_settings),
onValueChanged = { onValueChanged = {
if (!it) { if (!it) {
scope.launch { scope.launch {
@ -132,8 +130,8 @@ object SettingsLibraryScreen : SearchableSettings {
var showCategoriesDialog by rememberSaveable { mutableStateOf(false) } var showCategoriesDialog by rememberSaveable { mutableStateOf(false) }
if (showCategoriesDialog) { if (showCategoriesDialog) {
TriStateListDialog( TriStateListDialog(
title = stringResource(R.string.categories), title = stringResource(MR.strings.categories),
message = stringResource(R.string.pref_library_update_categories_details), message = stringResource(MR.strings.pref_library_update_categories_details),
items = allCategories, items = allCategories,
initialChecked = included.mapNotNull { id -> allCategories.find { it.id.toString() == id } }, initialChecked = included.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
initialInversed = excluded.mapNotNull { id -> allCategories.find { it.id.toString() == id } }, initialInversed = excluded.mapNotNull { id -> allCategories.find { it.id.toString() == id } },
@ -148,18 +146,18 @@ object SettingsLibraryScreen : SearchableSettings {
} }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_library_update), title = stringResource(MR.strings.pref_category_library_update),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = autoUpdateIntervalPref, pref = autoUpdateIntervalPref,
title = stringResource(R.string.pref_library_update_interval), title = stringResource(MR.strings.pref_library_update_interval),
entries = mapOf( entries = mapOf(
0 to stringResource(R.string.update_never), 0 to stringResource(MR.strings.update_never),
12 to stringResource(R.string.update_12hour), 12 to stringResource(MR.strings.update_12hour),
24 to stringResource(R.string.update_24hour), 24 to stringResource(MR.strings.update_24hour),
48 to stringResource(R.string.update_48hour), 48 to stringResource(MR.strings.update_48hour),
72 to stringResource(R.string.update_72hour), 72 to stringResource(MR.strings.update_72hour),
168 to stringResource(R.string.update_weekly), 168 to stringResource(MR.strings.update_weekly),
), ),
onValueChanged = { onValueChanged = {
LibraryUpdateJob.setupTask(context, it) LibraryUpdateJob.setupTask(context, it)
@ -169,12 +167,12 @@ object SettingsLibraryScreen : SearchableSettings {
Preference.PreferenceItem.MultiSelectListPreference( Preference.PreferenceItem.MultiSelectListPreference(
pref = libraryPreferences.autoUpdateDeviceRestrictions(), pref = libraryPreferences.autoUpdateDeviceRestrictions(),
enabled = autoUpdateInterval > 0, enabled = autoUpdateInterval > 0,
title = stringResource(R.string.pref_library_update_restriction), title = stringResource(MR.strings.pref_library_update_restriction),
subtitle = stringResource(R.string.restrictions), subtitle = stringResource(MR.strings.restrictions),
entries = mapOf( entries = mapOf(
DEVICE_ONLY_ON_WIFI to stringResource(R.string.connected_to_wifi), DEVICE_ONLY_ON_WIFI to stringResource(MR.strings.connected_to_wifi),
DEVICE_NETWORK_NOT_METERED to stringResource(R.string.network_not_metered), DEVICE_NETWORK_NOT_METERED to stringResource(MR.strings.network_not_metered),
DEVICE_CHARGING to stringResource(R.string.charging), DEVICE_CHARGING to stringResource(MR.strings.charging),
), ),
onValueChanged = { onValueChanged = {
// Post to event looper to allow the preference to be updated. // Post to event looper to allow the preference to be updated.
@ -183,7 +181,7 @@ object SettingsLibraryScreen : SearchableSettings {
}, },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.categories), title = stringResource(MR.strings.categories),
subtitle = getCategoriesLabel( subtitle = getCategoriesLabel(
allCategories = allCategories, allCategories = allCategories,
included = included, included = included,
@ -193,22 +191,22 @@ object SettingsLibraryScreen : SearchableSettings {
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.autoUpdateMetadata(), pref = libraryPreferences.autoUpdateMetadata(),
title = stringResource(R.string.pref_library_update_refresh_metadata), title = stringResource(MR.strings.pref_library_update_refresh_metadata),
subtitle = stringResource(R.string.pref_library_update_refresh_metadata_summary), subtitle = stringResource(MR.strings.pref_library_update_refresh_metadata_summary),
), ),
Preference.PreferenceItem.MultiSelectListPreference( Preference.PreferenceItem.MultiSelectListPreference(
pref = libraryPreferences.autoUpdateMangaRestrictions(), pref = libraryPreferences.autoUpdateMangaRestrictions(),
title = stringResource(R.string.pref_library_update_manga_restriction), title = stringResource(MR.strings.pref_library_update_manga_restriction),
entries = mapOf( entries = mapOf(
MANGA_HAS_UNREAD to stringResource(R.string.pref_update_only_completely_read), MANGA_HAS_UNREAD to stringResource(MR.strings.pref_update_only_completely_read),
MANGA_NON_READ to stringResource(R.string.pref_update_only_started), MANGA_NON_READ to stringResource(MR.strings.pref_update_only_started),
MANGA_NON_COMPLETED to stringResource(R.string.pref_update_only_non_completed), MANGA_NON_COMPLETED to stringResource(MR.strings.pref_update_only_non_completed),
MANGA_OUTSIDE_RELEASE_PERIOD to stringResource(R.string.pref_update_only_in_release_period), MANGA_OUTSIDE_RELEASE_PERIOD to stringResource(MR.strings.pref_update_only_in_release_period),
), ),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.newShowUpdatesCount(), pref = libraryPreferences.newShowUpdatesCount(),
title = stringResource(R.string.pref_library_update_show_tab_badge), title = stringResource(MR.strings.pref_library_update_show_tab_badge),
), ),
), ),
) )
@ -219,34 +217,34 @@ object SettingsLibraryScreen : SearchableSettings {
libraryPreferences: LibraryPreferences, libraryPreferences: LibraryPreferences,
): Preference.PreferenceGroup { ): Preference.PreferenceGroup {
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_chapter_swipe), title = stringResource(MR.strings.pref_chapter_swipe),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = libraryPreferences.swipeToStartAction(), pref = libraryPreferences.swipeToStartAction(),
title = stringResource(R.string.pref_chapter_swipe_start), title = stringResource(MR.strings.pref_chapter_swipe_start),
entries = mapOf( entries = mapOf(
LibraryPreferences.ChapterSwipeAction.Disabled to LibraryPreferences.ChapterSwipeAction.Disabled to
stringResource(R.string.disabled), stringResource(MR.strings.disabled),
LibraryPreferences.ChapterSwipeAction.ToggleBookmark to LibraryPreferences.ChapterSwipeAction.ToggleBookmark to
stringResource(R.string.action_bookmark), stringResource(MR.strings.action_bookmark),
LibraryPreferences.ChapterSwipeAction.ToggleRead to LibraryPreferences.ChapterSwipeAction.ToggleRead to
stringResource(R.string.action_mark_as_read), stringResource(MR.strings.action_mark_as_read),
LibraryPreferences.ChapterSwipeAction.Download to LibraryPreferences.ChapterSwipeAction.Download to
stringResource(R.string.action_download), stringResource(MR.strings.action_download),
), ),
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = libraryPreferences.swipeToEndAction(), pref = libraryPreferences.swipeToEndAction(),
title = stringResource(R.string.pref_chapter_swipe_end), title = stringResource(MR.strings.pref_chapter_swipe_end),
entries = mapOf( entries = mapOf(
LibraryPreferences.ChapterSwipeAction.Disabled to LibraryPreferences.ChapterSwipeAction.Disabled to
stringResource(R.string.disabled), stringResource(MR.strings.disabled),
LibraryPreferences.ChapterSwipeAction.ToggleBookmark to LibraryPreferences.ChapterSwipeAction.ToggleBookmark to
stringResource(R.string.action_bookmark), stringResource(MR.strings.action_bookmark),
LibraryPreferences.ChapterSwipeAction.ToggleRead to LibraryPreferences.ChapterSwipeAction.ToggleRead to
stringResource(R.string.action_mark_as_read), stringResource(MR.strings.action_mark_as_read),
LibraryPreferences.ChapterSwipeAction.Download to LibraryPreferences.ChapterSwipeAction.Download to
stringResource(R.string.action_download), stringResource(MR.strings.action_download),
), ),
), ),
), ),

View File

@ -1,6 +1,5 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -10,7 +9,6 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ChromeReaderMode import androidx.compose.material.icons.automirrored.outlined.ChromeReaderMode
import androidx.compose.material.icons.outlined.ChromeReaderMode
import androidx.compose.material.icons.outlined.Code import androidx.compose.material.icons.outlined.Code
import androidx.compose.material.icons.outlined.CollectionsBookmark import androidx.compose.material.icons.outlined.CollectionsBookmark
import androidx.compose.material.icons.outlined.Explore import androidx.compose.material.icons.outlined.Explore
@ -34,21 +32,22 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.Navigator import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.more.settings.screen.about.AboutScreen import eu.kanade.presentation.more.settings.screen.about.AboutScreen
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.presentation.util.LocalBackPress import eu.kanade.presentation.util.LocalBackPress
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import cafe.adriel.voyager.core.screen.Screen as VoyagerScreen import cafe.adriel.voyager.core.screen.Screen as VoyagerScreen
object SettingsMainScreen : Screen() { object SettingsMainScreen : Screen() {
@ -85,13 +84,13 @@ object SettingsMainScreen : Screen() {
topBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(topBarState), topBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(topBarState),
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
AppBar( AppBar(
title = stringResource(R.string.label_settings), title = stringResource(MR.strings.label_settings),
navigateUp = backPress::invoke, navigateUp = backPress::invoke,
actions = { actions = {
AppBarActions( AppBarActions(
persistentListOf( persistentListOf(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_search), title = stringResource(MR.strings.action_search),
icon = Icons.Outlined.Search, icon = Icons.Outlined.Search,
onClick = { navigator.navigate(SettingsSearchScreen(), twoPane) }, onClick = { navigator.navigate(SettingsSearchScreen(), twoPane) },
), ),
@ -165,73 +164,72 @@ object SettingsMainScreen : Screen() {
} }
private data class Item( private data class Item(
@StringRes val titleRes: Int, val titleRes: StringResource,
@StringRes val subtitleRes: Int, val subtitleRes: StringResource? = null,
val formatSubtitle: @Composable () -> String = { stringResource(subtitleRes) }, val formatSubtitle: @Composable () -> String? = { subtitleRes?.let { stringResource(it) } },
val icon: ImageVector, val icon: ImageVector,
val screen: VoyagerScreen, val screen: VoyagerScreen,
) )
private val items = listOf( private val items = listOf(
Item( Item(
titleRes = R.string.pref_category_appearance, titleRes = MR.strings.pref_category_appearance,
subtitleRes = R.string.pref_appearance_summary, subtitleRes = MR.strings.pref_appearance_summary,
icon = Icons.Outlined.Palette, icon = Icons.Outlined.Palette,
screen = SettingsAppearanceScreen, screen = SettingsAppearanceScreen,
), ),
Item( Item(
titleRes = R.string.pref_category_library, titleRes = MR.strings.pref_category_library,
subtitleRes = R.string.pref_library_summary, subtitleRes = MR.strings.pref_library_summary,
icon = Icons.Outlined.CollectionsBookmark, icon = Icons.Outlined.CollectionsBookmark,
screen = SettingsLibraryScreen, screen = SettingsLibraryScreen,
), ),
Item( Item(
titleRes = R.string.pref_category_reader, titleRes = MR.strings.pref_category_reader,
subtitleRes = R.string.pref_reader_summary, subtitleRes = MR.strings.pref_reader_summary,
icon = Icons.AutoMirrored.Outlined.ChromeReaderMode, icon = Icons.AutoMirrored.Outlined.ChromeReaderMode,
screen = SettingsReaderScreen, screen = SettingsReaderScreen,
), ),
Item( Item(
titleRes = R.string.pref_category_downloads, titleRes = MR.strings.pref_category_downloads,
subtitleRes = R.string.pref_downloads_summary, subtitleRes = MR.strings.pref_downloads_summary,
icon = Icons.Outlined.GetApp, icon = Icons.Outlined.GetApp,
screen = SettingsDownloadScreen, screen = SettingsDownloadScreen,
), ),
Item( Item(
titleRes = R.string.pref_category_tracking, titleRes = MR.strings.pref_category_tracking,
subtitleRes = R.string.pref_tracking_summary, subtitleRes = MR.strings.pref_tracking_summary,
icon = Icons.Outlined.Sync, icon = Icons.Outlined.Sync,
screen = SettingsTrackingScreen, screen = SettingsTrackingScreen,
), ),
Item( Item(
titleRes = R.string.browse, titleRes = MR.strings.browse,
subtitleRes = R.string.pref_browse_summary, subtitleRes = MR.strings.pref_browse_summary,
icon = Icons.Outlined.Explore, icon = Icons.Outlined.Explore,
screen = SettingsBrowseScreen, screen = SettingsBrowseScreen,
), ),
Item( Item(
titleRes = R.string.label_backup_and_sync, titleRes = MR.strings.label_backup_and_sync,
subtitleRes = R.string.pref_backup_summary, subtitleRes = MR.strings.pref_backup_summary,
icon = Icons.Outlined.Storage, icon = Icons.Outlined.Storage,
screen = SettingsDataScreen, screen = SettingsDataScreen,
), ),
Item( Item(
titleRes = R.string.pref_category_security, titleRes = MR.strings.pref_category_security,
subtitleRes = R.string.pref_security_summary, subtitleRes = MR.strings.pref_security_summary,
icon = Icons.Outlined.Security, icon = Icons.Outlined.Security,
screen = SettingsSecurityScreen, screen = SettingsSecurityScreen,
), ),
Item( Item(
titleRes = R.string.pref_category_advanced, titleRes = MR.strings.pref_category_advanced,
subtitleRes = R.string.pref_advanced_summary, subtitleRes = MR.strings.pref_advanced_summary,
icon = Icons.Outlined.Code, icon = Icons.Outlined.Code,
screen = SettingsAdvancedScreen, screen = SettingsAdvancedScreen,
), ),
Item( Item(
titleRes = R.string.pref_category_about, titleRes = MR.strings.pref_category_about,
subtitleRes = 0,
formatSubtitle = { formatSubtitle = {
"${stringResource(R.string.app_name)} ${AboutScreen.getVersionName(withBuildDate = false)}" "${stringResource(MR.strings.app_name)} ${AboutScreen.getVersionName(withBuildDate = false)}"
}, },
icon = Icons.Outlined.Info, icon = Icons.Outlined.Info,
screen = AboutScreen, screen = AboutScreen,

View File

@ -1,18 +1,17 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import android.os.Build import android.os.Build
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -22,8 +21,7 @@ object SettingsReaderScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
@StringRes override fun getTitleRes() = MR.strings.pref_category_reader
override fun getTitleRes() = R.string.pref_category_reader
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -31,43 +29,43 @@ object SettingsReaderScreen : SearchableSettings {
return listOf( return listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPref.defaultReadingMode(), pref = readerPref.defaultReadingMode(),
title = stringResource(R.string.pref_viewer_type), title = stringResource(MR.strings.pref_viewer_type),
entries = ReadingMode.entries.drop(1) entries = ReadingMode.entries.drop(1)
.associate { it.flagValue to stringResource(it.stringRes) }, .associate { it.flagValue to stringResource(it.stringRes) },
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPref.doubleTapAnimSpeed(), pref = readerPref.doubleTapAnimSpeed(),
title = stringResource(R.string.pref_double_tap_anim_speed), title = stringResource(MR.strings.pref_double_tap_anim_speed),
entries = mapOf( entries = mapOf(
1 to stringResource(R.string.double_tap_anim_speed_0), 1 to stringResource(MR.strings.double_tap_anim_speed_0),
500 to stringResource(R.string.double_tap_anim_speed_normal), 500 to stringResource(MR.strings.double_tap_anim_speed_normal),
250 to stringResource(R.string.double_tap_anim_speed_fast), 250 to stringResource(MR.strings.double_tap_anim_speed_fast),
), ),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPref.showReadingMode(), pref = readerPref.showReadingMode(),
title = stringResource(R.string.pref_show_reading_mode), title = stringResource(MR.strings.pref_show_reading_mode),
subtitle = stringResource(R.string.pref_show_reading_mode_summary), subtitle = stringResource(MR.strings.pref_show_reading_mode_summary),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPref.showNavigationOverlayOnStart(), pref = readerPref.showNavigationOverlayOnStart(),
title = stringResource(R.string.pref_show_navigation_mode), title = stringResource(MR.strings.pref_show_navigation_mode),
subtitle = stringResource(R.string.pref_show_navigation_mode_summary), subtitle = stringResource(MR.strings.pref_show_navigation_mode_summary),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPref.trueColor(), pref = readerPref.trueColor(),
title = stringResource(R.string.pref_true_color), title = stringResource(MR.strings.pref_true_color),
subtitle = stringResource(R.string.pref_true_color_summary), subtitle = stringResource(MR.strings.pref_true_color_summary),
enabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O, enabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O,
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPref.pageTransitions(), pref = readerPref.pageTransitions(),
title = stringResource(R.string.pref_page_transitions), title = stringResource(MR.strings.pref_page_transitions),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPref.flashOnPageChange(), pref = readerPref.flashOnPageChange(),
title = stringResource(R.string.pref_flash_page), title = stringResource(MR.strings.pref_flash_page),
subtitle = stringResource(R.string.pref_flash_page_summ), subtitle = stringResource(MR.strings.pref_flash_page_summ),
), ),
getDisplayGroup(readerPreferences = readerPref), getDisplayGroup(readerPreferences = readerPref),
getReadingGroup(readerPreferences = readerPref), getReadingGroup(readerPreferences = readerPref),
@ -83,42 +81,42 @@ object SettingsReaderScreen : SearchableSettings {
val fullscreenPref = readerPreferences.fullscreen() val fullscreenPref = readerPreferences.fullscreen()
val fullscreen by fullscreenPref.collectAsState() val fullscreen by fullscreenPref.collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_display), title = stringResource(MR.strings.pref_category_display),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.defaultOrientationType(), pref = readerPreferences.defaultOrientationType(),
title = stringResource(R.string.pref_rotation_type), title = stringResource(MR.strings.pref_rotation_type),
entries = ReaderOrientation.entries.drop(1) entries = ReaderOrientation.entries.drop(1)
.associate { it.flagValue to stringResource(it.stringRes) }, .associate { it.flagValue to stringResource(it.stringRes) },
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.readerTheme(), pref = readerPreferences.readerTheme(),
title = stringResource(R.string.pref_reader_theme), title = stringResource(MR.strings.pref_reader_theme),
entries = mapOf( entries = mapOf(
1 to stringResource(R.string.black_background), 1 to stringResource(MR.strings.black_background),
2 to stringResource(R.string.gray_background), 2 to stringResource(MR.strings.gray_background),
0 to stringResource(R.string.white_background), 0 to stringResource(MR.strings.white_background),
3 to stringResource(R.string.automatic_background), 3 to stringResource(MR.strings.automatic_background),
), ),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = fullscreenPref, pref = fullscreenPref,
title = stringResource(R.string.pref_fullscreen), title = stringResource(MR.strings.pref_fullscreen),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.cutoutShort(), pref = readerPreferences.cutoutShort(),
title = stringResource(R.string.pref_cutout_short), title = stringResource(MR.strings.pref_cutout_short),
enabled = fullscreen && enabled = fullscreen &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P &&
LocalView.current.rootWindowInsets?.displayCutout != null, // has cutout LocalView.current.rootWindowInsets?.displayCutout != null, // has cutout
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.keepScreenOn(), pref = readerPreferences.keepScreenOn(),
title = stringResource(R.string.pref_keep_screen_on), title = stringResource(MR.strings.pref_keep_screen_on),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.showPageNumber(), pref = readerPreferences.showPageNumber(),
title = stringResource(R.string.pref_show_page_number), title = stringResource(MR.strings.pref_show_page_number),
), ),
), ),
) )
@ -127,23 +125,23 @@ object SettingsReaderScreen : SearchableSettings {
@Composable @Composable
private fun getReadingGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup { private fun getReadingGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup {
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_reading), title = stringResource(MR.strings.pref_category_reading),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.skipRead(), pref = readerPreferences.skipRead(),
title = stringResource(R.string.pref_skip_read_chapters), title = stringResource(MR.strings.pref_skip_read_chapters),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.skipFiltered(), pref = readerPreferences.skipFiltered(),
title = stringResource(R.string.pref_skip_filtered_chapters), title = stringResource(MR.strings.pref_skip_filtered_chapters),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.skipDupe(), pref = readerPreferences.skipDupe(),
title = stringResource(R.string.pref_skip_dupe_chapters), title = stringResource(MR.strings.pref_skip_dupe_chapters),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.alwaysShowChapterTransition(), pref = readerPreferences.alwaysShowChapterTransition(),
title = stringResource(R.string.pref_always_show_chapter_transition), title = stringResource(MR.strings.pref_always_show_chapter_transition),
), ),
), ),
) )
@ -162,57 +160,57 @@ object SettingsReaderScreen : SearchableSettings {
val rotateToFit by rotateToFitPref.collectAsState() val rotateToFit by rotateToFitPref.collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pager_viewer), title = stringResource(MR.strings.pager_viewer),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = navModePref, pref = navModePref,
title = stringResource(R.string.pref_viewer_nav), title = stringResource(MR.strings.pref_viewer_nav),
entries = ReaderPreferences.TapZones entries = ReaderPreferences.TapZones
.mapIndexed { index, it -> index to stringResource(it) } .mapIndexed { index, it -> index to stringResource(it) }
.toMap(), .toMap(),
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.pagerNavInverted(), pref = readerPreferences.pagerNavInverted(),
title = stringResource(R.string.pref_read_with_tapping_inverted), title = stringResource(MR.strings.pref_read_with_tapping_inverted),
entries = listOf( entries = listOf(
ReaderPreferences.TappingInvertMode.NONE, ReaderPreferences.TappingInvertMode.NONE,
ReaderPreferences.TappingInvertMode.HORIZONTAL, ReaderPreferences.TappingInvertMode.HORIZONTAL,
ReaderPreferences.TappingInvertMode.VERTICAL, ReaderPreferences.TappingInvertMode.VERTICAL,
ReaderPreferences.TappingInvertMode.BOTH, ReaderPreferences.TappingInvertMode.BOTH,
).associateWith { stringResource(it.titleResId) }, ).associateWith { stringResource(it.titleRes) },
enabled = navMode != 5, enabled = navMode != 5,
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = imageScaleTypePref, pref = imageScaleTypePref,
title = stringResource(R.string.pref_image_scale_type), title = stringResource(MR.strings.pref_image_scale_type),
entries = ReaderPreferences.ImageScaleType entries = ReaderPreferences.ImageScaleType
.mapIndexed { index, it -> index + 1 to stringResource(it) } .mapIndexed { index, it -> index + 1 to stringResource(it) }
.toMap(), .toMap(),
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.zoomStart(), pref = readerPreferences.zoomStart(),
title = stringResource(R.string.pref_zoom_start), title = stringResource(MR.strings.pref_zoom_start),
entries = ReaderPreferences.ZoomStart entries = ReaderPreferences.ZoomStart
.mapIndexed { index, it -> index + 1 to stringResource(it) } .mapIndexed { index, it -> index + 1 to stringResource(it) }
.toMap(), .toMap(),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.cropBorders(), pref = readerPreferences.cropBorders(),
title = stringResource(R.string.pref_crop_borders), title = stringResource(MR.strings.pref_crop_borders),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.landscapeZoom(), pref = readerPreferences.landscapeZoom(),
title = stringResource(R.string.pref_landscape_zoom), title = stringResource(MR.strings.pref_landscape_zoom),
enabled = imageScaleType == 1, enabled = imageScaleType == 1,
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.navigateToPan(), pref = readerPreferences.navigateToPan(),
title = stringResource(R.string.pref_navigate_pan), title = stringResource(MR.strings.pref_navigate_pan),
enabled = navMode != 5, enabled = navMode != 5,
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = dualPageSplitPref, pref = dualPageSplitPref,
title = stringResource(R.string.pref_dual_page_split), title = stringResource(MR.strings.pref_dual_page_split),
onValueChanged = { onValueChanged = {
rotateToFitPref.set(false) rotateToFitPref.set(false)
true true
@ -220,13 +218,13 @@ object SettingsReaderScreen : SearchableSettings {
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.dualPageInvertPaged(), pref = readerPreferences.dualPageInvertPaged(),
title = stringResource(R.string.pref_dual_page_invert), title = stringResource(MR.strings.pref_dual_page_invert),
subtitle = stringResource(R.string.pref_dual_page_invert_summary), subtitle = stringResource(MR.strings.pref_dual_page_invert_summary),
enabled = dualPageSplit, enabled = dualPageSplit,
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = rotateToFitPref, pref = rotateToFitPref,
title = stringResource(R.string.pref_page_rotate), title = stringResource(MR.strings.pref_page_rotate),
onValueChanged = { onValueChanged = {
dualPageSplitPref.set(false) dualPageSplitPref.set(false)
true true
@ -234,7 +232,7 @@ object SettingsReaderScreen : SearchableSettings {
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.dualPageRotateToFitInvert(), pref = readerPreferences.dualPageRotateToFitInvert(),
title = stringResource(R.string.pref_page_rotate_invert), title = stringResource(MR.strings.pref_page_rotate_invert),
enabled = rotateToFit, enabled = rotateToFit,
), ),
), ),
@ -254,29 +252,29 @@ object SettingsReaderScreen : SearchableSettings {
val webtoonSidePadding by webtoonSidePaddingPref.collectAsState() val webtoonSidePadding by webtoonSidePaddingPref.collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.webtoon_viewer), title = stringResource(MR.strings.webtoon_viewer),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = navModePref, pref = navModePref,
title = stringResource(R.string.pref_viewer_nav), title = stringResource(MR.strings.pref_viewer_nav),
entries = ReaderPreferences.TapZones entries = ReaderPreferences.TapZones
.mapIndexed { index, it -> index to stringResource(it) } .mapIndexed { index, it -> index to stringResource(it) }
.toMap(), .toMap(),
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.webtoonNavInverted(), pref = readerPreferences.webtoonNavInverted(),
title = stringResource(R.string.pref_read_with_tapping_inverted), title = stringResource(MR.strings.pref_read_with_tapping_inverted),
entries = listOf( entries = listOf(
ReaderPreferences.TappingInvertMode.NONE, ReaderPreferences.TappingInvertMode.NONE,
ReaderPreferences.TappingInvertMode.HORIZONTAL, ReaderPreferences.TappingInvertMode.HORIZONTAL,
ReaderPreferences.TappingInvertMode.VERTICAL, ReaderPreferences.TappingInvertMode.VERTICAL,
ReaderPreferences.TappingInvertMode.BOTH, ReaderPreferences.TappingInvertMode.BOTH,
).associateWith { stringResource(it.titleResId) }, ).associateWith { stringResource(it.titleRes) },
enabled = navMode != 5, enabled = navMode != 5,
), ),
Preference.PreferenceItem.SliderPreference( Preference.PreferenceItem.SliderPreference(
value = webtoonSidePadding, value = webtoonSidePadding,
title = stringResource(R.string.pref_webtoon_side_padding), title = stringResource(MR.strings.pref_webtoon_side_padding),
subtitle = numberFormat.format(webtoonSidePadding / 100f), subtitle = numberFormat.format(webtoonSidePadding / 100f),
min = ReaderPreferences.WEBTOON_PADDING_MIN, min = ReaderPreferences.WEBTOON_PADDING_MIN,
max = ReaderPreferences.WEBTOON_PADDING_MAX, max = ReaderPreferences.WEBTOON_PADDING_MAX,
@ -287,31 +285,31 @@ object SettingsReaderScreen : SearchableSettings {
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = readerPreferences.readerHideThreshold(), pref = readerPreferences.readerHideThreshold(),
title = stringResource(R.string.pref_hide_threshold), title = stringResource(MR.strings.pref_hide_threshold),
entries = mapOf( entries = mapOf(
ReaderPreferences.ReaderHideThreshold.HIGHEST to stringResource(R.string.pref_highest), ReaderPreferences.ReaderHideThreshold.HIGHEST to stringResource(MR.strings.pref_highest),
ReaderPreferences.ReaderHideThreshold.HIGH to stringResource(R.string.pref_high), ReaderPreferences.ReaderHideThreshold.HIGH to stringResource(MR.strings.pref_high),
ReaderPreferences.ReaderHideThreshold.LOW to stringResource(R.string.pref_low), ReaderPreferences.ReaderHideThreshold.LOW to stringResource(MR.strings.pref_low),
ReaderPreferences.ReaderHideThreshold.LOWEST to stringResource(R.string.pref_lowest), ReaderPreferences.ReaderHideThreshold.LOWEST to stringResource(MR.strings.pref_lowest),
), ),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.cropBordersWebtoon(), pref = readerPreferences.cropBordersWebtoon(),
title = stringResource(R.string.pref_crop_borders), title = stringResource(MR.strings.pref_crop_borders),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = dualPageSplitPref, pref = dualPageSplitPref,
title = stringResource(R.string.pref_dual_page_split), title = stringResource(MR.strings.pref_dual_page_split),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.dualPageInvertWebtoon(), pref = readerPreferences.dualPageInvertWebtoon(),
title = stringResource(R.string.pref_dual_page_invert), title = stringResource(MR.strings.pref_dual_page_invert),
subtitle = stringResource(R.string.pref_dual_page_invert_summary), subtitle = stringResource(MR.strings.pref_dual_page_invert_summary),
enabled = dualPageSplit, enabled = dualPageSplit,
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.webtoonDoubleTapZoomEnabled(), pref = readerPreferences.webtoonDoubleTapZoomEnabled(),
title = stringResource(R.string.pref_double_tap_zoom), title = stringResource(MR.strings.pref_double_tap_zoom),
enabled = true, enabled = true,
), ),
), ),
@ -323,15 +321,15 @@ object SettingsReaderScreen : SearchableSettings {
val readWithVolumeKeysPref = readerPreferences.readWithVolumeKeys() val readWithVolumeKeysPref = readerPreferences.readWithVolumeKeys()
val readWithVolumeKeys by readWithVolumeKeysPref.collectAsState() val readWithVolumeKeys by readWithVolumeKeysPref.collectAsState()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_reader_navigation), title = stringResource(MR.strings.pref_reader_navigation),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readWithVolumeKeysPref, pref = readWithVolumeKeysPref,
title = stringResource(R.string.pref_read_with_volume_keys), title = stringResource(MR.strings.pref_read_with_volume_keys),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.readWithVolumeKeysInverted(), pref = readerPreferences.readWithVolumeKeysInverted(),
title = stringResource(R.string.pref_read_with_volume_keys_inverted), title = stringResource(MR.strings.pref_read_with_volume_keys_inverted),
enabled = readWithVolumeKeys, enabled = readWithVolumeKeys,
), ),
), ),
@ -341,16 +339,16 @@ object SettingsReaderScreen : SearchableSettings {
@Composable @Composable
private fun getActionsGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup { private fun getActionsGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup {
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(R.string.pref_reader_actions), title = stringResource(MR.strings.pref_reader_actions),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.readWithLongTap(), pref = readerPreferences.readWithLongTap(),
title = stringResource(R.string.pref_read_with_long_tap), title = stringResource(MR.strings.pref_read_with_long_tap),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.folderPerManga(), pref = readerPreferences.folderPerManga(),
title = stringResource(R.string.pref_create_folder_per_manga), title = stringResource(MR.strings.pref_create_folder_per_manga),
subtitle = stringResource(R.string.pref_create_folder_per_manga_summary), subtitle = stringResource(MR.strings.pref_create_folder_per_manga_summary),
), ),
), ),
) )

View File

@ -41,7 +41,6 @@ import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
@ -53,8 +52,9 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.components.UpIcon import eu.kanade.presentation.components.UpIcon
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.util.runOnEnterKeyPressed import tachiyomi.presentation.core.util.runOnEnterKeyPressed
import cafe.adriel.voyager.core.screen.Screen as VoyagerScreen import cafe.adriel.voyager.core.screen.Screen as VoyagerScreen
@ -118,7 +118,7 @@ class SettingsSearchScreen : Screen() {
decorationBox = { decorationBox = {
if (textFieldValue.text.isEmpty()) { if (textFieldValue.text.isEmpty()) {
Text( Text(
text = stringResource(R.string.action_search_settings), text = stringResource(MR.strings.action_search_settings),
color = MaterialTheme.colorScheme.onSurfaceVariant, color = MaterialTheme.colorScheme.onSurfaceVariant,
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
) )
@ -222,7 +222,7 @@ private fun SearchResult(
when { when {
it == null -> {} it == null -> {}
it.isEmpty() -> { it.isEmpty() -> {
EmptyScreen(stringResource(R.string.no_results_found)) EmptyScreen(stringResource(MR.strings.no_results_found))
} }
else -> { else -> {
LazyColumn( LazyColumn(

View File

@ -1,19 +1,19 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.authenticate import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.authenticate
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.isAuthenticationSupported import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.isAuthenticationSupported
import tachiyomi.core.i18n.stringResource
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -22,8 +22,7 @@ object SettingsSecurityScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
@StringRes override fun getTitleRes() = MR.strings.pref_category_security
override fun getTitleRes() = R.string.pref_category_security
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
@ -37,43 +36,43 @@ object SettingsSecurityScreen : SearchableSettings {
return listOf( return listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = useAuthPref, pref = useAuthPref,
title = stringResource(R.string.lock_with_biometrics), title = stringResource(MR.strings.lock_with_biometrics),
enabled = authSupported, enabled = authSupported,
onValueChanged = { onValueChanged = {
(context as FragmentActivity).authenticate( (context as FragmentActivity).authenticate(
title = context.getString(R.string.lock_with_biometrics), title = context.stringResource(MR.strings.lock_with_biometrics),
) )
}, },
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = securityPreferences.lockAppAfter(), pref = securityPreferences.lockAppAfter(),
title = stringResource(R.string.lock_when_idle), title = stringResource(MR.strings.lock_when_idle),
enabled = authSupported && useAuth, enabled = authSupported && useAuth,
entries = LockAfterValues entries = LockAfterValues
.associateWith { .associateWith {
when (it) { when (it) {
-1 -> stringResource(R.string.lock_never) -1 -> stringResource(MR.strings.lock_never)
0 -> stringResource(R.string.lock_always) 0 -> stringResource(MR.strings.lock_always)
else -> pluralStringResource(id = R.plurals.lock_after_mins, count = it, it) else -> pluralStringResource(MR.plurals.lock_after_mins, count = it, it)
} }
}, },
onValueChanged = { onValueChanged = {
(context as FragmentActivity).authenticate( (context as FragmentActivity).authenticate(
title = context.getString(R.string.lock_when_idle), title = context.stringResource(MR.strings.lock_when_idle),
) )
}, },
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = securityPreferences.hideNotificationContent(), pref = securityPreferences.hideNotificationContent(),
title = stringResource(R.string.hide_notification_content), title = stringResource(MR.strings.hide_notification_content),
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
pref = securityPreferences.secureScreen(), pref = securityPreferences.secureScreen(),
title = stringResource(R.string.secure_screen), title = stringResource(MR.strings.secure_screen),
entries = SecurityPreferences.SecureScreenMode.entries entries = SecurityPreferences.SecureScreenMode.entries
.associateWith { stringResource(it.titleResId) }, .associateWith { stringResource(it.titleRes) },
), ),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.secure_screen_summary)), Preference.PreferenceItem.InfoPreference(stringResource(MR.strings.secure_screen_summary)),
) )
} }
} }

View File

@ -1,7 +1,6 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import android.content.Context import android.content.Context
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@ -13,7 +12,6 @@ import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.filled.Visibility import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material.icons.outlined.Close import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
@ -34,7 +32,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.PasswordVisualTransformation
@ -42,9 +39,9 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import dev.icerock.moko.resources.StringResource
import eu.kanade.domain.track.service.TrackPreferences import eu.kanade.domain.track.service.TrackPreferences
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.EnhancedTracker import eu.kanade.tachiyomi.data.track.EnhancedTracker
import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.Tracker
import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.data.track.TrackerManager
@ -57,7 +54,9 @@ import eu.kanade.tachiyomi.util.system.toast
import tachiyomi.core.util.lang.launchIO import tachiyomi.core.util.lang.launchIO
import tachiyomi.core.util.lang.withUIContext import tachiyomi.core.util.lang.withUIContext
import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.source.service.SourceManager
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -65,8 +64,7 @@ object SettingsTrackingScreen : SearchableSettings {
@ReadOnlyComposable @ReadOnlyComposable
@Composable @Composable
@StringRes override fun getTitleRes() = MR.strings.pref_category_tracking
override fun getTitleRes() = R.string.pref_category_tracking
@Composable @Composable
override fun RowScope.AppBarAction() { override fun RowScope.AppBarAction() {
@ -74,7 +72,7 @@ object SettingsTrackingScreen : SearchableSettings {
IconButton(onClick = { uriHandler.openUri("https://tachiyomi.org/docs/guides/tracking") }) { IconButton(onClick = { uriHandler.openUri("https://tachiyomi.org/docs/guides/tracking") }) {
Icon( Icon(
imageVector = Icons.AutoMirrored.Outlined.HelpOutline, imageVector = Icons.AutoMirrored.Outlined.HelpOutline,
contentDescription = stringResource(R.string.tracking_guide), contentDescription = stringResource(MR.strings.tracking_guide),
) )
} }
} }
@ -111,10 +109,10 @@ object SettingsTrackingScreen : SearchableSettings {
val acceptedSources = (service as EnhancedTracker).getAcceptedSources() val acceptedSources = (service as EnhancedTracker).getAcceptedSources()
sourceManager.getCatalogueSources().any { it::class.qualifiedName in acceptedSources } sourceManager.getCatalogueSources().any { it::class.qualifiedName in acceptedSources }
} }
var enhancedTrackerInfo = stringResource(R.string.enhanced_tracking_info) var enhancedTrackerInfo = stringResource(MR.strings.enhanced_tracking_info)
if (enhancedTrackers.second.isNotEmpty()) { if (enhancedTrackers.second.isNotEmpty()) {
val missingSourcesInfo = stringResource( val missingSourcesInfo = stringResource(
R.string.enhanced_services_not_installed, MR.strings.enhanced_services_not_installed,
enhancedTrackers.second.joinToString { it.name }, enhancedTrackers.second.joinToString { it.name },
) )
enhancedTrackerInfo += "\n\n$missingSourcesInfo" enhancedTrackerInfo += "\n\n$missingSourcesInfo"
@ -123,10 +121,10 @@ object SettingsTrackingScreen : SearchableSettings {
return listOf( return listOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = trackPreferences.autoUpdateTrack(), pref = trackPreferences.autoUpdateTrack(),
title = stringResource(R.string.pref_auto_update_manga_sync), title = stringResource(MR.strings.pref_auto_update_manga_sync),
), ),
Preference.PreferenceGroup( Preference.PreferenceGroup(
title = stringResource(R.string.services), title = stringResource(MR.strings.services),
preferenceItems = listOf( preferenceItems = listOf(
Preference.PreferenceItem.TrackerPreference( Preference.PreferenceItem.TrackerPreference(
title = trackerManager.myAnimeList.name, title = trackerManager.myAnimeList.name,
@ -143,13 +141,13 @@ object SettingsTrackingScreen : SearchableSettings {
Preference.PreferenceItem.TrackerPreference( Preference.PreferenceItem.TrackerPreference(
title = trackerManager.kitsu.name, title = trackerManager.kitsu.name,
tracker = trackerManager.kitsu, tracker = trackerManager.kitsu,
login = { dialog = LoginDialog(trackerManager.kitsu, R.string.email) }, login = { dialog = LoginDialog(trackerManager.kitsu, MR.strings.email) },
logout = { dialog = LogoutDialog(trackerManager.kitsu) }, logout = { dialog = LogoutDialog(trackerManager.kitsu) },
), ),
Preference.PreferenceItem.TrackerPreference( Preference.PreferenceItem.TrackerPreference(
title = trackerManager.mangaUpdates.name, title = trackerManager.mangaUpdates.name,
tracker = trackerManager.mangaUpdates, tracker = trackerManager.mangaUpdates,
login = { dialog = LoginDialog(trackerManager.mangaUpdates, R.string.username) }, login = { dialog = LoginDialog(trackerManager.mangaUpdates, MR.strings.username) },
logout = { dialog = LogoutDialog(trackerManager.mangaUpdates) }, logout = { dialog = LogoutDialog(trackerManager.mangaUpdates) },
), ),
Preference.PreferenceItem.TrackerPreference( Preference.PreferenceItem.TrackerPreference(
@ -164,11 +162,11 @@ object SettingsTrackingScreen : SearchableSettings {
login = { context.openInBrowser(BangumiApi.authUrl(), forceDefaultBrowser = true) }, login = { context.openInBrowser(BangumiApi.authUrl(), forceDefaultBrowser = true) },
logout = { dialog = LogoutDialog(trackerManager.bangumi) }, logout = { dialog = LogoutDialog(trackerManager.bangumi) },
), ),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.tracking_info)), Preference.PreferenceItem.InfoPreference(stringResource(MR.strings.tracking_info)),
), ),
), ),
Preference.PreferenceGroup( Preference.PreferenceGroup(
title = stringResource(R.string.enhanced_services), title = stringResource(MR.strings.enhanced_services),
preferenceItems = enhancedTrackers.first preferenceItems = enhancedTrackers.first
.map { service -> .map { service ->
Preference.PreferenceItem.TrackerPreference( Preference.PreferenceItem.TrackerPreference(
@ -185,7 +183,7 @@ object SettingsTrackingScreen : SearchableSettings {
@Composable @Composable
private fun TrackingLoginDialog( private fun TrackingLoginDialog(
tracker: Tracker, tracker: Tracker,
@StringRes uNameStringRes: Int, uNameStringRes: StringResource,
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
) { ) {
val context = LocalContext.current val context = LocalContext.current
@ -201,13 +199,13 @@ object SettingsTrackingScreen : SearchableSettings {
title = { title = {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
Text( Text(
text = stringResource(R.string.login_title, tracker.name), text = stringResource(MR.strings.login_title, tracker.name),
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
) )
IconButton(onClick = onDismissRequest) { IconButton(onClick = onDismissRequest) {
Icon( Icon(
imageVector = Icons.Outlined.Close, imageVector = Icons.Outlined.Close,
contentDescription = stringResource(R.string.action_close), contentDescription = stringResource(MR.strings.action_close),
) )
} }
} }
@ -229,7 +227,7 @@ object SettingsTrackingScreen : SearchableSettings {
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
value = password, value = password,
onValueChange = { password = it }, onValueChange = { password = it },
label = { Text(text = stringResource(R.string.password)) }, label = { Text(text = stringResource(MR.strings.password)) },
trailingIcon = { trailingIcon = {
IconButton(onClick = { hidePassword = !hidePassword }) { IconButton(onClick = { hidePassword = !hidePassword }) {
Icon( Icon(
@ -275,7 +273,7 @@ object SettingsTrackingScreen : SearchableSettings {
} }
}, },
) { ) {
val id = if (processing) R.string.loading else R.string.login val id = if (processing) MR.strings.loading else MR.strings.login
Text(text = stringResource(id)) Text(text = stringResource(id))
} }
}, },
@ -290,7 +288,7 @@ object SettingsTrackingScreen : SearchableSettings {
): Boolean { ): Boolean {
return try { return try {
tracker.login(username, password) tracker.login(username, password)
withUIContext { context.toast(R.string.login_success) } withUIContext { context.toast(MR.strings.login_success) }
true true
} catch (e: Throwable) { } catch (e: Throwable) {
tracker.logout() tracker.logout()
@ -309,7 +307,7 @@ object SettingsTrackingScreen : SearchableSettings {
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { title = {
Text( Text(
text = stringResource(R.string.logout_title, tracker.name), text = stringResource(MR.strings.logout_title, tracker.name),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
) )
@ -320,21 +318,21 @@ object SettingsTrackingScreen : SearchableSettings {
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
onClick = onDismissRequest, onClick = onDismissRequest,
) { ) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
Button( Button(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
onClick = { onClick = {
tracker.logout() tracker.logout()
onDismissRequest() onDismissRequest()
context.toast(R.string.logout_success) context.toast(MR.strings.logout_success)
}, },
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.error, containerColor = MaterialTheme.colorScheme.error,
contentColor = MaterialTheme.colorScheme.onError, contentColor = MaterialTheme.colorScheme.onError,
), ),
) { ) {
Text(text = stringResource(R.string.logout)) Text(text = stringResource(MR.strings.logout))
} }
} }
}, },
@ -344,7 +342,7 @@ object SettingsTrackingScreen : SearchableSettings {
private data class LoginDialog( private data class LoginDialog(
val tracker: Tracker, val tracker: Tracker,
@StringRes val uNameStringRes: Int, val uNameStringRes: StringResource,
) )
private data class LogoutDialog( private data class LogoutDialog(

View File

@ -19,7 +19,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
@ -30,7 +29,6 @@ import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.presentation.util.LocalBackPress import eu.kanade.presentation.util.LocalBackPress
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.updater.AppUpdateChecker import eu.kanade.tachiyomi.data.updater.AppUpdateChecker
import eu.kanade.tachiyomi.data.updater.RELEASE_URL import eu.kanade.tachiyomi.data.updater.RELEASE_URL
import eu.kanade.tachiyomi.ui.more.NewUpdateScreen import eu.kanade.tachiyomi.ui.more.NewUpdateScreen
@ -44,9 +42,11 @@ import tachiyomi.core.util.lang.withIOContext
import tachiyomi.core.util.lang.withUIContext import tachiyomi.core.util.lang.withUIContext
import tachiyomi.core.util.system.logcat import tachiyomi.core.util.system.logcat
import tachiyomi.domain.release.interactor.GetApplicationRelease import tachiyomi.domain.release.interactor.GetApplicationRelease
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LinkIcon import tachiyomi.presentation.core.components.LinkIcon
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.icons.CustomIcons import tachiyomi.presentation.core.icons.CustomIcons
import tachiyomi.presentation.core.icons.Discord import tachiyomi.presentation.core.icons.Discord
import tachiyomi.presentation.core.icons.Facebook import tachiyomi.presentation.core.icons.Facebook
@ -74,7 +74,7 @@ object AboutScreen : Screen() {
Scaffold( Scaffold(
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
AppBar( AppBar(
title = stringResource(R.string.pref_category_about), title = stringResource(MR.strings.pref_category_about),
navigateUp = if (handleBack != null) handleBack::invoke else null, navigateUp = if (handleBack != null) handleBack::invoke else null,
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
) )
@ -89,7 +89,7 @@ object AboutScreen : Screen() {
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.version), title = stringResource(MR.strings.version),
subtitle = getVersionName(withBuildDate = true), subtitle = getVersionName(withBuildDate = true),
onPreferenceClick = { onPreferenceClick = {
val deviceInfo = CrashLogUtil(context).getDebugInfo() val deviceInfo = CrashLogUtil(context).getDebugInfo()
@ -101,7 +101,7 @@ object AboutScreen : Screen() {
if (BuildConfig.INCLUDE_UPDATER) { if (BuildConfig.INCLUDE_UPDATER) {
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.check_for_updates), title = stringResource(MR.strings.check_for_updates),
widget = { widget = {
AnimatedVisibility(visible = isCheckingUpdates) { AnimatedVisibility(visible = isCheckingUpdates) {
CircularProgressIndicator( CircularProgressIndicator(
@ -140,7 +140,7 @@ object AboutScreen : Screen() {
if (!BuildConfig.DEBUG) { if (!BuildConfig.DEBUG) {
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.whats_new), title = stringResource(MR.strings.whats_new),
onPreferenceClick = { uriHandler.openUri(RELEASE_URL) }, onPreferenceClick = { uriHandler.openUri(RELEASE_URL) },
) )
} }
@ -148,21 +148,21 @@ object AboutScreen : Screen() {
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.help_translate), title = stringResource(MR.strings.help_translate),
onPreferenceClick = { uriHandler.openUri("https://tachiyomi.org/docs/contribute#translation") }, onPreferenceClick = { uriHandler.openUri("https://tachiyomi.org/docs/contribute#translation") },
) )
} }
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.licenses), title = stringResource(MR.strings.licenses),
onPreferenceClick = { navigator.push(OpenSourceLicensesScreen()) }, onPreferenceClick = { navigator.push(OpenSourceLicensesScreen()) },
) )
} }
item { item {
TextPreferenceWidget( TextPreferenceWidget(
title = stringResource(R.string.privacy_policy), title = stringResource(MR.strings.privacy_policy),
onPreferenceClick = { uriHandler.openUri("https://tachiyomi.org/privacy/") }, onPreferenceClick = { uriHandler.openUri("https://tachiyomi.org/privacy/") },
) )
} }
@ -175,7 +175,7 @@ object AboutScreen : Screen() {
horizontalArrangement = Arrangement.Center, horizontalArrangement = Arrangement.Center,
) { ) {
LinkIcon( LinkIcon(
label = stringResource(R.string.website), label = stringResource(MR.strings.website),
icon = Icons.Outlined.Public, icon = Icons.Outlined.Public,
url = "https://tachiyomi.org", url = "https://tachiyomi.org",
) )
@ -226,10 +226,10 @@ object AboutScreen : Screen() {
onAvailableUpdate(result) onAvailableUpdate(result)
} }
is GetApplicationRelease.Result.NoNewUpdate -> { is GetApplicationRelease.Result.NoNewUpdate -> {
context.toast(R.string.update_check_no_new_updates) context.toast(MR.strings.update_check_no_new_updates)
} }
is GetApplicationRelease.Result.OsTooOld -> { is GetApplicationRelease.Result.OsTooOld -> {
context.toast(R.string.update_check_eol) context.toast(MR.strings.update_check_eol)
} }
else -> {} else -> {}
} }

View File

@ -9,7 +9,6 @@ import androidx.compose.material.icons.filled.Public
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
@ -19,9 +18,10 @@ import com.google.android.material.textview.MaterialTextView
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
class OpenSourceLibraryLicenseScreen( class OpenSourceLibraryLicenseScreen(
private val name: String, private val name: String,
@ -44,7 +44,7 @@ class OpenSourceLibraryLicenseScreen(
AppBarActions( AppBarActions(
persistentListOf( persistentListOf(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.website), title = stringResource(MR.strings.website),
icon = Icons.Default.Public, icon = Icons.Default.Public,
onClick = { uriHandler.openUri(website) }, onClick = { uriHandler.openUri(website) },
), ),

View File

@ -4,7 +4,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import com.mikepenz.aboutlibraries.ui.compose.LibrariesContainer import com.mikepenz.aboutlibraries.ui.compose.LibrariesContainer
@ -12,8 +11,9 @@ import com.mikepenz.aboutlibraries.ui.compose.LibraryDefaults
import com.mikepenz.aboutlibraries.ui.compose.util.htmlReadyLicenseContent import com.mikepenz.aboutlibraries.ui.compose.util.htmlReadyLicenseContent
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
class OpenSourceLicensesScreen : Screen() { class OpenSourceLicensesScreen : Screen() {
@ -23,7 +23,7 @@ class OpenSourceLicensesScreen : Screen() {
Scaffold( Scaffold(
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
AppBar( AppBar(
title = stringResource(R.string.licenses), title = stringResource(MR.strings.licenses),
navigateUp = navigator::pop, navigateUp = navigator::pop,
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
) )

View File

@ -27,7 +27,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastMap import androidx.compose.ui.util.fastMap
import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.StateScreenModel
@ -39,7 +38,6 @@ import eu.kanade.presentation.browse.components.SourceIcon
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
@ -51,7 +49,9 @@ import tachiyomi.data.Database
import tachiyomi.domain.source.interactor.GetSourcesWithNonLibraryManga import tachiyomi.domain.source.interactor.GetSourcesWithNonLibraryManga
import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.Source
import tachiyomi.domain.source.model.SourceWithCount import tachiyomi.domain.source.model.SourceWithCount
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
import tachiyomi.presentation.core.util.selectedBackground import tachiyomi.presentation.core.util.selectedBackground
@ -81,20 +81,20 @@ class ClearDatabaseScreen : Screen() {
model.removeMangaBySourceId() model.removeMangaBySourceId()
model.clearSelection() model.clearSelection()
model.hideConfirmation() model.hideConfirmation()
context.toast(R.string.clear_database_completed) context.toast(MR.strings.clear_database_completed)
} }
}, },
) { ) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = model::hideConfirmation) { TextButton(onClick = model::hideConfirmation) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
text = { text = {
Text(text = stringResource(R.string.clear_database_confirmation)) Text(text = stringResource(MR.strings.clear_database_confirmation))
}, },
) )
} }
@ -102,19 +102,19 @@ class ClearDatabaseScreen : Screen() {
Scaffold( Scaffold(
topBar = { scrollBehavior -> topBar = { scrollBehavior ->
AppBar( AppBar(
title = stringResource(R.string.pref_clear_database), title = stringResource(MR.strings.pref_clear_database),
navigateUp = navigator::pop, navigateUp = navigator::pop,
actions = { actions = {
if (s.items.isNotEmpty()) { if (s.items.isNotEmpty()) {
AppBarActions( AppBarActions(
actions = persistentListOf( actions = persistentListOf(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_select_all), title = stringResource(MR.strings.action_select_all),
icon = Icons.Outlined.SelectAll, icon = Icons.Outlined.SelectAll,
onClick = model::selectAll, onClick = model::selectAll,
), ),
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_select_all), title = stringResource(MR.strings.action_select_all),
icon = Icons.Outlined.FlipToBack, icon = Icons.Outlined.FlipToBack,
onClick = model::invertSelection, onClick = model::invertSelection,
), ),
@ -128,7 +128,7 @@ class ClearDatabaseScreen : Screen() {
) { contentPadding -> ) { contentPadding ->
if (s.items.isEmpty()) { if (s.items.isEmpty()) {
EmptyScreen( EmptyScreen(
message = stringResource(R.string.database_clean), message = stringResource(MR.strings.database_clean),
modifier = Modifier.padding(contentPadding), modifier = Modifier.padding(contentPadding),
) )
} else { } else {
@ -160,7 +160,7 @@ class ClearDatabaseScreen : Screen() {
enabled = s.selection.isNotEmpty(), enabled = s.selection.isNotEmpty(),
) { ) {
Text( Text(
text = stringResource(R.string.action_delete), text = stringResource(MR.strings.action_delete),
color = MaterialTheme.colorScheme.onPrimary, color = MaterialTheme.colorScheme.onPrimary,
) )
} }
@ -196,7 +196,7 @@ class ClearDatabaseScreen : Screen() {
text = source.visualName, text = source.visualName,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
) )
Text(text = stringResource(R.string.clear_database_source_item_count, count)) Text(text = stringResource(MR.strings.clear_database_source_item_count, count))
} }
Checkbox( Checkbox(
checked = isSelected, checked = isSelected,

View File

@ -22,7 +22,6 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.rememberScreenModel import cafe.adriel.voyager.core.model.rememberScreenModel
@ -30,7 +29,6 @@ import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.BackupCreateFlags import eu.kanade.tachiyomi.data.backup.BackupCreateFlags
import eu.kanade.tachiyomi.data.backup.BackupCreateJob import eu.kanade.tachiyomi.data.backup.BackupCreateJob
import eu.kanade.tachiyomi.data.backup.models.Backup import eu.kanade.tachiyomi.data.backup.models.Backup
@ -41,9 +39,11 @@ import kotlinx.collections.immutable.minus
import kotlinx.collections.immutable.plus import kotlinx.collections.immutable.plus
import kotlinx.collections.immutable.toPersistentSet import kotlinx.collections.immutable.toPersistentSet
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LabeledCheckbox import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
class CreateBackupScreen : Screen() { class CreateBackupScreen : Screen() {
@ -71,7 +71,7 @@ class CreateBackupScreen : Screen() {
Scaffold( Scaffold(
topBar = { topBar = {
AppBar( AppBar(
title = stringResource(R.string.pref_create_backup), title = stringResource(MR.strings.pref_create_backup),
navigateUp = navigator::pop, navigateUp = navigator::pop,
scrollBehavior = it, scrollBehavior = it,
) )
@ -89,7 +89,7 @@ class CreateBackupScreen : Screen() {
) { ) {
item { item {
LabeledCheckbox( LabeledCheckbox(
label = stringResource(R.string.manga), label = stringResource(MR.strings.manga),
checked = true, checked = true,
onCheckedChange = {}, onCheckedChange = {},
enabled = false, enabled = false,
@ -117,20 +117,20 @@ class CreateBackupScreen : Screen() {
onClick = { onClick = {
if (!BackupCreateJob.isManualJobRunning(context)) { if (!BackupCreateJob.isManualJobRunning(context)) {
if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) { if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) {
context.toast(R.string.restore_miui_warning, Toast.LENGTH_LONG) context.toast(MR.strings.restore_miui_warning, Toast.LENGTH_LONG)
} }
try { try {
chooseBackupDir.launch(Backup.getFilename()) chooseBackupDir.launch(Backup.getFilename())
} catch (e: ActivityNotFoundException) { } catch (e: ActivityNotFoundException) {
context.toast(R.string.file_picker_error) context.toast(MR.strings.file_picker_error)
} }
} else { } else {
context.toast(R.string.backup_in_progress) context.toast(MR.strings.backup_in_progress)
} }
}, },
) { ) {
Text( Text(
text = stringResource(R.string.action_create), text = stringResource(MR.strings.action_create),
color = MaterialTheme.colorScheme.onPrimary, color = MaterialTheme.colorScheme.onPrimary,
) )
} }
@ -163,10 +163,10 @@ private class CreateBackupScreenModel : StateScreenModel<CreateBackupScreenModel
} }
private val BackupChoices = mapOf( private val BackupChoices = mapOf(
BackupCreateFlags.BACKUP_CATEGORY to R.string.categories, BackupCreateFlags.BACKUP_CATEGORY to MR.strings.categories,
BackupCreateFlags.BACKUP_CHAPTER to R.string.chapters, BackupCreateFlags.BACKUP_CHAPTER to MR.strings.chapters,
BackupCreateFlags.BACKUP_TRACK to R.string.track, BackupCreateFlags.BACKUP_TRACK to MR.strings.track,
BackupCreateFlags.BACKUP_HISTORY to R.string.history, BackupCreateFlags.BACKUP_HISTORY to MR.strings.history,
BackupCreateFlags.BACKUP_APP_PREFS to R.string.app_settings, BackupCreateFlags.BACKUP_APP_PREFS to MR.strings.app_settings,
BackupCreateFlags.BACKUP_SOURCE_PREFS to R.string.source_settings, BackupCreateFlags.BACKUP_SOURCE_PREFS to MR.strings.source_settings,
) )

View File

@ -10,7 +10,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
@ -18,12 +17,13 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.models.Backup import eu.kanade.tachiyomi.data.backup.models.Backup
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.serialization.protobuf.schema.ProtoBufSchemaGenerator import kotlinx.serialization.protobuf.schema.ProtoBufSchemaGenerator
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
class BackupSchemaScreen : Screen() { class BackupSchemaScreen : Screen() {
@ -47,7 +47,7 @@ class BackupSchemaScreen : Screen() {
AppBarActions( AppBarActions(
persistentListOf( persistentListOf(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_copy_to_clipboard), title = stringResource(MR.strings.action_copy_to_clipboard),
icon = Icons.Default.ContentCopy, icon = Icons.Default.ContentCopy,
onClick = { onClick = {
context.copyToClipboard(title, schema) context.copyToClipboard(title, schema)

View File

@ -17,6 +17,7 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.DeviceUtil import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.WebViewUtil import eu.kanade.tachiyomi.util.system.WebViewUtil
import kotlinx.coroutines.guava.await import kotlinx.coroutines.guava.await
import tachiyomi.i18n.MR
class DebugInfoScreen : Screen() { class DebugInfoScreen : Screen() {
@ -24,7 +25,7 @@ class DebugInfoScreen : Screen() {
override fun Content() { override fun Content() {
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
PreferenceScaffold( PreferenceScaffold(
titleRes = R.string.pref_debug_info, titleRes = MR.strings.pref_debug_info,
onBackPressed = navigator::pop, onBackPressed = navigator::pop,
itemsProvider = { itemsProvider = {
listOf( listOf(

View File

@ -15,7 +15,6 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEach import androidx.compose.ui.util.fastForEach
@ -30,14 +29,15 @@ import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.presentation.util.ioCoroutineScope import eu.kanade.presentation.util.ioCoroutineScope
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.system.workManager import eu.kanade.tachiyomi.util.system.workManager
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.plus import tachiyomi.presentation.core.util.plus
class WorkerInfoScreen : Screen() { class WorkerInfoScreen : Screen() {
@ -65,7 +65,7 @@ class WorkerInfoScreen : Screen() {
AppBarActions( AppBarActions(
persistentListOf( persistentListOf(
AppBar.Action( AppBar.Action(
title = stringResource(R.string.action_copy_to_clipboard), title = stringResource(MR.strings.action_copy_to_clipboard),
icon = Icons.Default.ContentCopy, icon = Icons.Default.ContentCopy,
onClick = { onClick = {
context.copyToClipboard(title, enqueued + finished + running) context.copyToClipboard(title, enqueued + finished + running)

View File

@ -36,17 +36,17 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.domain.ui.model.AppTheme import eu.kanade.domain.ui.model.AppTheme
import eu.kanade.presentation.manga.components.MangaCover import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.DeviceUtil import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.secondaryItemAlpha import tachiyomi.presentation.core.util.secondaryItemAlpha
@Composable @Composable
@ -76,7 +76,7 @@ private fun AppThemesList(
) { ) {
val appThemes = remember { val appThemes = remember {
AppTheme.entries AppTheme.entries
.filterNot { it.titleResId == null || (it == AppTheme.MONET && !DeviceUtil.isDynamicColorAvailable) } .filterNot { it.titleRes == null || (it == AppTheme.MONET && !DeviceUtil.isDynamicColorAvailable) }
} }
LazyRow( LazyRow(
contentPadding = PaddingValues(horizontal = PrefsHorizontalPadding), contentPadding = PaddingValues(horizontal = PrefsHorizontalPadding),
@ -104,7 +104,7 @@ private fun AppThemesList(
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
text = stringResource(appTheme.titleResId!!), text = stringResource(appTheme.titleRes!!),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.secondaryItemAlpha(), .secondaryItemAlpha(),
@ -167,7 +167,7 @@ fun AppThemePreviewItem(
if (selected) { if (selected) {
Icon( Icon(
imageVector = Icons.Filled.CheckCircle, imageVector = Icons.Filled.CheckCircle,
contentDescription = stringResource(R.string.selected), contentDescription = stringResource(MR.strings.selected),
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
) )
} }

View File

@ -19,11 +19,11 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import eu.kanade.tachiyomi.R
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun EditTextPreferenceWidget( fun EditTextPreferenceWidget(
@ -83,12 +83,12 @@ fun EditTextPreferenceWidget(
} }
}, },
) { ) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
) )

View File

@ -11,11 +11,11 @@ import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.secondaryItemAlpha import tachiyomi.presentation.core.util.secondaryItemAlpha
@Composable @Composable
@ -45,7 +45,7 @@ internal fun InfoWidget(text: String) {
private fun InfoWidgetPreview() { private fun InfoWidgetPreview() {
TachiyomiTheme { TachiyomiTheme {
Surface { Surface {
InfoWidget(text = stringResource(R.string.download_ahead_info)) InfoWidget(text = stringResource(MR.strings.download_ahead_info))
} }
} }
} }

View File

@ -22,10 +22,10 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart import tachiyomi.presentation.core.util.isScrolledToStart
@ -75,7 +75,7 @@ fun <T> ListPreferenceWidget(
}, },
confirmButton = { confirmButton = {
TextButton(onClick = { isDialogShown = false }) { TextButton(onClick = { isDialogShown = false }) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
) )

View File

@ -10,11 +10,11 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.runtime.toMutableStateList import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LabeledCheckbox import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun MultiSelectListPreferenceWidget( fun MultiSelectListPreferenceWidget(
@ -70,12 +70,12 @@ fun MultiSelectListPreferenceWidget(
isDialogShown = false isDialogShown = false
}, },
) { ) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = { isDialogShown = false }) { TextButton(onClick = { isDialogShown = false }) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
) )

View File

@ -15,12 +15,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.more.settings.LocalPreferenceHighlighted import eu.kanade.presentation.more.settings.LocalPreferenceHighlighted
import eu.kanade.presentation.track.components.TrackLogoIcon import eu.kanade.presentation.track.components.TrackLogoIcon
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.Tracker
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun TrackingPreferenceWidget( fun TrackingPreferenceWidget(
@ -55,7 +55,7 @@ fun TrackingPreferenceWidget(
.padding(4.dp) .padding(4.dp)
.size(32.dp), .size(32.dp),
tint = Color(0xFF4CAF50), tint = Color(0xFF4CAF50),
contentDescription = stringResource(R.string.login_success), contentDescription = stringResource(MR.strings.login_success),
) )
} }
} }

View File

@ -27,9 +27,9 @@ import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart import tachiyomi.presentation.core.util.isScrolledToStart
@ -104,9 +104,9 @@ fun <T> TriStateListDialog(
}, },
contentDescription = stringResource( contentDescription = stringResource(
when (state) { when (state) {
State.UNCHECKED -> R.string.not_selected State.UNCHECKED -> MR.strings.not_selected
State.CHECKED -> R.string.selected State.CHECKED -> MR.strings.selected
State.INVERSED -> R.string.disabled State.INVERSED -> MR.strings.disabled
}, },
), ),
) )
@ -130,7 +130,7 @@ fun <T> TriStateListDialog(
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
}, },
confirmButton = { confirmButton = {
@ -145,7 +145,7 @@ fun <T> TriStateListDialog(
onValueChanged(included, excluded) onValueChanged(included, excluded)
}, },
) { ) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
}, },
) )

View File

@ -13,14 +13,14 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.more.stats.components.StatsItem import eu.kanade.presentation.more.stats.components.StatsItem
import eu.kanade.presentation.more.stats.components.StatsOverviewItem import eu.kanade.presentation.more.stats.components.StatsOverviewItem
import eu.kanade.presentation.more.stats.components.StatsSection import eu.kanade.presentation.more.stats.components.StatsSection
import eu.kanade.presentation.more.stats.data.StatsData import eu.kanade.presentation.more.stats.data.StatsData
import eu.kanade.presentation.util.toDurationString import eu.kanade.presentation.util.toDurationString
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import java.util.Locale import java.util.Locale
import kotlin.time.DurationUnit import kotlin.time.DurationUnit
import kotlin.time.toDuration import kotlin.time.toDuration
@ -55,28 +55,28 @@ fun StatsScreenContent(
private fun OverviewSection( private fun OverviewSection(
data: StatsData.Overview, data: StatsData.Overview,
) { ) {
val none = stringResource(R.string.none) val none = stringResource(MR.strings.none)
val context = LocalContext.current val context = LocalContext.current
val readDurationString = remember(data.totalReadDuration) { val readDurationString = remember(data.totalReadDuration) {
data.totalReadDuration data.totalReadDuration
.toDuration(DurationUnit.MILLISECONDS) .toDuration(DurationUnit.MILLISECONDS)
.toDurationString(context, fallback = none) .toDurationString(context, fallback = none)
} }
StatsSection(R.string.label_overview_section) { StatsSection(MR.strings.label_overview_section) {
Row { Row {
StatsOverviewItem( StatsOverviewItem(
title = data.libraryMangaCount.toString(), title = data.libraryMangaCount.toString(),
subtitle = stringResource(R.string.in_library), subtitle = stringResource(MR.strings.in_library),
icon = Icons.Outlined.CollectionsBookmark, icon = Icons.Outlined.CollectionsBookmark,
) )
StatsOverviewItem( StatsOverviewItem(
title = data.completedMangaCount.toString(), title = data.completedMangaCount.toString(),
subtitle = stringResource(R.string.label_completed_titles), subtitle = stringResource(MR.strings.label_completed_titles),
icon = Icons.Outlined.LocalLibrary, icon = Icons.Outlined.LocalLibrary,
) )
StatsOverviewItem( StatsOverviewItem(
title = readDurationString, title = readDurationString,
subtitle = stringResource(R.string.label_read_duration), subtitle = stringResource(MR.strings.label_read_duration),
icon = Icons.Outlined.Schedule, icon = Icons.Outlined.Schedule,
) )
} }
@ -87,19 +87,19 @@ private fun OverviewSection(
private fun TitlesStats( private fun TitlesStats(
data: StatsData.Titles, data: StatsData.Titles,
) { ) {
StatsSection(R.string.label_titles_section) { StatsSection(MR.strings.label_titles_section) {
Row { Row {
StatsItem( StatsItem(
data.globalUpdateItemCount.toString(), data.globalUpdateItemCount.toString(),
stringResource(R.string.label_titles_in_global_update), stringResource(MR.strings.label_titles_in_global_update),
) )
StatsItem( StatsItem(
data.startedMangaCount.toString(), data.startedMangaCount.toString(),
stringResource(R.string.label_started), stringResource(MR.strings.label_started),
) )
StatsItem( StatsItem(
data.localMangaCount.toString(), data.localMangaCount.toString(),
stringResource(R.string.label_local), stringResource(MR.strings.label_local),
) )
} }
} }
@ -109,19 +109,19 @@ private fun TitlesStats(
private fun ChapterStats( private fun ChapterStats(
data: StatsData.Chapters, data: StatsData.Chapters,
) { ) {
StatsSection(R.string.chapters) { StatsSection(MR.strings.chapters) {
Row { Row {
StatsItem( StatsItem(
data.totalChapterCount.toString(), data.totalChapterCount.toString(),
stringResource(R.string.label_total_chapters), stringResource(MR.strings.label_total_chapters),
) )
StatsItem( StatsItem(
data.readChapterCount.toString(), data.readChapterCount.toString(),
stringResource(R.string.label_read_chapters), stringResource(MR.strings.label_read_chapters),
) )
StatsItem( StatsItem(
data.downloadCount.toString(), data.downloadCount.toString(),
stringResource(R.string.label_downloaded), stringResource(MR.strings.label_downloaded),
) )
} }
} }
@ -131,7 +131,7 @@ private fun ChapterStats(
private fun TrackerStats( private fun TrackerStats(
data: StatsData.Trackers, data: StatsData.Trackers,
) { ) {
val notApplicable = stringResource(R.string.not_applicable) val notApplicable = stringResource(MR.strings.not_applicable)
val meanScoreStr = remember(data.trackedTitleCount, data.meanScore) { val meanScoreStr = remember(data.trackedTitleCount, data.meanScore) {
if (data.trackedTitleCount > 0 && !data.meanScore.isNaN()) { if (data.trackedTitleCount > 0 && !data.meanScore.isNaN()) {
// All other numbers are localized in English // All other numbers are localized in English
@ -140,19 +140,19 @@ private fun TrackerStats(
notApplicable notApplicable
} }
} }
StatsSection(R.string.label_tracker_section) { StatsSection(MR.strings.label_tracker_section) {
Row { Row {
StatsItem( StatsItem(
data.trackedTitleCount.toString(), data.trackedTitleCount.toString(),
stringResource(R.string.label_tracked_titles), stringResource(MR.strings.label_tracked_titles),
) )
StatsItem( StatsItem(
meanScoreStr, meanScoreStr,
stringResource(R.string.label_mean_score), stringResource(MR.strings.label_mean_score),
) )
StatsItem( StatsItem(
data.trackerCount.toString(), data.trackerCount.toString(),
stringResource(R.string.label_used), stringResource(MR.strings.label_used),
) )
} }
} }

View File

@ -1,6 +1,5 @@
package eu.kanade.presentation.more.stats.components package eu.kanade.presentation.more.stats.components
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -9,12 +8,13 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import dev.icerock.moko.resources.StringResource
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun StatsSection( fun StatsSection(
@StringRes titleRes: Int, titleRes: StringResource,
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
Text( Text(

View File

@ -26,8 +26,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.Placeholder import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign import androidx.compose.ui.text.PlaceholderVerticalAlign
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
@ -36,13 +34,15 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.ChapterImpl import eu.kanade.tachiyomi.data.database.models.ChapterImpl
import eu.kanade.tachiyomi.data.database.models.toDomainChapter import eu.kanade.tachiyomi.data.database.models.toDomainChapter
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import tachiyomi.domain.chapter.service.calculateChapterGap import tachiyomi.domain.chapter.service.calculateChapterGap
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.secondaryItemAlpha import tachiyomi.presentation.core.util.secondaryItemAlpha
@Composable @Composable
@ -58,25 +58,25 @@ fun ChapterTransition(
when (transition) { when (transition) {
is ChapterTransition.Prev -> { is ChapterTransition.Prev -> {
TransitionText( TransitionText(
topLabel = stringResource(R.string.transition_previous), topLabel = stringResource(MR.strings.transition_previous),
topChapter = goingToChapter, topChapter = goingToChapter,
topChapterDownloaded = goingToChapterDownloaded, topChapterDownloaded = goingToChapterDownloaded,
bottomLabel = stringResource(R.string.transition_current), bottomLabel = stringResource(MR.strings.transition_current),
bottomChapter = currChapter, bottomChapter = currChapter,
bottomChapterDownloaded = currChapterDownloaded, bottomChapterDownloaded = currChapterDownloaded,
fallbackLabel = stringResource(R.string.transition_no_previous), fallbackLabel = stringResource(MR.strings.transition_no_previous),
chapterGap = calculateChapterGap(currChapter.toDomainChapter(), goingToChapter?.toDomainChapter()), chapterGap = calculateChapterGap(currChapter.toDomainChapter(), goingToChapter?.toDomainChapter()),
) )
} }
is ChapterTransition.Next -> { is ChapterTransition.Next -> {
TransitionText( TransitionText(
topLabel = stringResource(R.string.transition_finished), topLabel = stringResource(MR.strings.transition_finished),
topChapter = currChapter, topChapter = currChapter,
topChapterDownloaded = currChapterDownloaded, topChapterDownloaded = currChapterDownloaded,
bottomLabel = stringResource(R.string.transition_next), bottomLabel = stringResource(MR.strings.transition_next),
bottomChapter = goingToChapter, bottomChapter = goingToChapter,
bottomChapterDownloaded = goingToChapterDownloaded, bottomChapterDownloaded = goingToChapterDownloaded,
fallbackLabel = stringResource(R.string.transition_no_next), fallbackLabel = stringResource(MR.strings.transition_no_next),
chapterGap = calculateChapterGap(goingToChapter?.toDomainChapter(), currChapter.toDomainChapter()), chapterGap = calculateChapterGap(goingToChapter?.toDomainChapter(), currChapter.toDomainChapter()),
) )
} }
@ -191,7 +191,7 @@ private fun ChapterGapWarning(
) )
Text( Text(
text = pluralStringResource(R.plurals.missing_chapters_warning, count = gapCount, gapCount), text = pluralStringResource(MR.plurals.missing_chapters_warning, count = gapCount, gapCount),
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
) )
} }
@ -245,7 +245,7 @@ private fun ChapterText(
) { ) {
Icon( Icon(
imageVector = Icons.Filled.CheckCircle, imageVector = Icons.Filled.CheckCircle,
contentDescription = stringResource(R.string.label_downloaded), contentDescription = stringResource(MR.strings.label_downloaded),
) )
}, },
), ),

View File

@ -12,18 +12,19 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import dev.icerock.moko.resources.StringResource
import eu.kanade.domain.manga.model.readerOrientation import eu.kanade.domain.manga.model.readerOrientation
import eu.kanade.presentation.components.AdaptiveSheet import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.presentation.reader.components.ModeSelectionDialog import eu.kanade.presentation.reader.components.ModeSelectionDialog
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.SettingsIconGrid import tachiyomi.presentation.core.components.SettingsIconGrid
import tachiyomi.presentation.core.components.material.IconToggleButton import tachiyomi.presentation.core.components.material.IconToggleButton
import tachiyomi.presentation.core.i18n.stringResource
private val ReaderOrientationsWithoutDefault = ReaderOrientation.entries - ReaderOrientation.DEFAULT private val ReaderOrientationsWithoutDefault = ReaderOrientation.entries - ReaderOrientation.DEFAULT
@ -31,7 +32,7 @@ private val ReaderOrientationsWithoutDefault = ReaderOrientation.entries - Reade
fun OrientationSelectDialog( fun OrientationSelectDialog(
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
screenModel: ReaderSettingsScreenModel, screenModel: ReaderSettingsScreenModel,
onChange: (Int) -> Unit, onChange: (StringResource) -> Unit,
) { ) {
val manga by screenModel.mangaFlow.collectAsState() val manga by screenModel.mangaFlow.collectAsState()
val orientation = remember(manga) { ReaderOrientation.fromPreference(manga?.readerOrientation?.toInt()) } val orientation = remember(manga) { ReaderOrientation.fromPreference(manga?.readerOrientation?.toInt()) }
@ -63,7 +64,7 @@ private fun DialogContent(
}.takeIf { orientation != ReaderOrientation.DEFAULT }, }.takeIf { orientation != ReaderOrientation.DEFAULT },
onApply = { onChangeOrientation(selected) }, onApply = { onChangeOrientation(selected) },
) { ) {
SettingsIconGrid(R.string.rotation_type) { SettingsIconGrid(MR.strings.rotation_type) {
items(ReaderOrientationsWithoutDefault) { mode -> items(ReaderOrientationsWithoutDefault) { mode ->
IconToggleButton( IconToggleButton(
checked = mode == selected, checked = mode == selected,

View File

@ -17,12 +17,12 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.AdaptiveSheet import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ActionButton import tachiyomi.presentation.core.components.ActionButton
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun ReaderPageActionsDialog( fun ReaderPageActionsDialog(
@ -42,13 +42,13 @@ fun ReaderPageActionsDialog(
) { ) {
ActionButton( ActionButton(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
title = stringResource(R.string.set_as_cover), title = stringResource(MR.strings.set_as_cover),
icon = Icons.Outlined.Photo, icon = Icons.Outlined.Photo,
onClick = { showSetCoverDialog = true }, onClick = { showSetCoverDialog = true },
) )
ActionButton( ActionButton(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
title = stringResource(R.string.action_share), title = stringResource(MR.strings.action_share),
icon = Icons.Outlined.Share, icon = Icons.Outlined.Share,
onClick = { onClick = {
onShare() onShare()
@ -57,7 +57,7 @@ fun ReaderPageActionsDialog(
) )
ActionButton( ActionButton(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
title = stringResource(R.string.action_save), title = stringResource(MR.strings.action_save),
icon = Icons.Outlined.Save, icon = Icons.Outlined.Save,
onClick = { onClick = {
onSave() onSave()
@ -85,16 +85,16 @@ private fun SetCoverDialog(
) { ) {
AlertDialog( AlertDialog(
text = { text = {
Text(stringResource(R.string.confirm_set_image_as_cover)) Text(stringResource(MR.strings.confirm_set_image_as_cover))
}, },
confirmButton = { confirmButton = {
TextButton(onClick = onConfirm) { TextButton(onClick = onConfirm) {
Text(stringResource(R.string.action_ok)) Text(stringResource(MR.strings.action_ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismiss) { TextButton(onClick = onDismiss) {
Text(stringResource(R.string.action_cancel)) Text(stringResource(MR.strings.action_cancel))
} }
}, },
onDismissRequest = onDismiss, onDismissRequest = onDismiss,

View File

@ -12,18 +12,19 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import dev.icerock.moko.resources.StringResource
import eu.kanade.domain.manga.model.readingMode import eu.kanade.domain.manga.model.readingMode
import eu.kanade.presentation.components.AdaptiveSheet import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.presentation.reader.components.ModeSelectionDialog import eu.kanade.presentation.reader.components.ModeSelectionDialog
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.SettingsIconGrid import tachiyomi.presentation.core.components.SettingsIconGrid
import tachiyomi.presentation.core.components.material.IconToggleButton import tachiyomi.presentation.core.components.material.IconToggleButton
import tachiyomi.presentation.core.i18n.stringResource
private val ReadingModesWithoutDefault = ReadingMode.entries - ReadingMode.DEFAULT private val ReadingModesWithoutDefault = ReadingMode.entries - ReadingMode.DEFAULT
@ -31,7 +32,7 @@ private val ReadingModesWithoutDefault = ReadingMode.entries - ReadingMode.DEFAU
fun ReadingModeSelectDialog( fun ReadingModeSelectDialog(
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
screenModel: ReaderSettingsScreenModel, screenModel: ReaderSettingsScreenModel,
onChange: (Int) -> Unit, onChange: (StringResource) -> Unit,
) { ) {
val manga by screenModel.mangaFlow.collectAsState() val manga by screenModel.mangaFlow.collectAsState()
val readingMode = remember(manga) { ReadingMode.fromPreference(manga?.readingMode?.toInt()) } val readingMode = remember(manga) { ReadingMode.fromPreference(manga?.readingMode?.toInt()) }
@ -59,7 +60,7 @@ private fun DialogContent(
onUseDefault = { onChangeReadingMode(ReadingMode.DEFAULT) }.takeIf { readingMode != ReadingMode.DEFAULT }, onUseDefault = { onChangeReadingMode(ReadingMode.DEFAULT) }.takeIf { readingMode != ReadingMode.DEFAULT },
onApply = { onChangeReadingMode(selected) }, onApply = { onChangeReadingMode(selected) },
) { ) {
SettingsIconGrid(R.string.pref_category_reading_mode) { SettingsIconGrid(MR.strings.pref_category_reading_mode) {
items(ReadingModesWithoutDefault) { mode -> items(ReadingModesWithoutDefault) { mode ->
IconToggleButton( IconToggleButton(
checked = mode == selected, checked = mode == selected,

View File

@ -14,11 +14,12 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun BottomReaderBar( fun BottomReaderBar(
@ -42,28 +43,28 @@ fun BottomReaderBar(
IconButton(onClick = onClickReadingMode) { IconButton(onClick = onClickReadingMode) {
Icon( Icon(
painter = painterResource(readingMode.iconRes), painter = painterResource(readingMode.iconRes),
contentDescription = stringResource(R.string.viewer), contentDescription = stringResource(MR.strings.viewer),
) )
} }
IconButton(onClick = onClickOrientation) { IconButton(onClick = onClickOrientation) {
Icon( Icon(
painter = painterResource(orientation.iconRes), painter = painterResource(orientation.iconRes),
contentDescription = stringResource(R.string.rotation_type), contentDescription = stringResource(MR.strings.rotation_type),
) )
} }
IconButton(onClick = onClickCropBorder) { IconButton(onClick = onClickCropBorder) {
Icon( Icon(
painter = painterResource(if (cropEnabled) R.drawable.ic_crop_24dp else R.drawable.ic_crop_off_24dp), painter = painterResource(if (cropEnabled) R.drawable.ic_crop_24dp else R.drawable.ic_crop_off_24dp),
contentDescription = stringResource(R.string.pref_crop_borders), contentDescription = stringResource(MR.strings.pref_crop_borders),
) )
} }
IconButton(onClick = onClickSettings) { IconButton(onClick = onClickSettings) {
Icon( Icon(
imageVector = Icons.Outlined.Settings, imageVector = Icons.Outlined.Settings,
contentDescription = stringResource(R.string.action_settings), contentDescription = stringResource(MR.strings.action_settings),
) )
} }
} }

View File

@ -18,18 +18,18 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.reader.components.ChapterNavigator import eu.kanade.presentation.reader.components.ChapterNavigator
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import eu.kanade.tachiyomi.ui.reader.viewer.Viewer import eu.kanade.tachiyomi.ui.reader.viewer.Viewer
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
private val animationSpec = tween<IntOffset>(200) private val animationSpec = tween<IntOffset>(200)
@ -105,9 +105,9 @@ fun ReaderAppBars(
AppBar.Action( AppBar.Action(
title = stringResource( title = stringResource(
if (bookmarked) { if (bookmarked) {
R.string.action_remove_bookmark MR.strings.action_remove_bookmark
} else { } else {
R.string.action_bookmark MR.strings.action_bookmark
}, },
), ),
icon = if (bookmarked) { icon = if (bookmarked) {
@ -121,7 +121,7 @@ fun ReaderAppBars(
onOpenInWebView?.let { onOpenInWebView?.let {
add( add(
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_open_in_web_view), title = stringResource(MR.strings.action_open_in_web_view),
onClick = it, onClick = it,
), ),
) )
@ -129,7 +129,7 @@ fun ReaderAppBars(
onShare?.let { onShare?.let {
add( add(
AppBar.OverflowAction( AppBar.OverflowAction(
title = stringResource(R.string.action_share), title = stringResource(MR.strings.action_share),
onClick = it, onClick = it,
), ),
) )

View File

@ -30,11 +30,11 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.util.isTabletUi import eu.kanade.presentation.util.isTabletUi
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import kotlin.math.roundToInt import kotlin.math.roundToInt
@Composable @Composable
@ -78,7 +78,7 @@ fun ChapterNavigator(
Icon( Icon(
imageVector = Icons.Outlined.SkipPrevious, imageVector = Icons.Outlined.SkipPrevious,
contentDescription = stringResource( contentDescription = stringResource(
if (isRtl) R.string.action_next_chapter else R.string.action_previous_chapter, if (isRtl) MR.strings.action_next_chapter else MR.strings.action_previous_chapter,
), ),
) )
} }
@ -130,7 +130,7 @@ fun ChapterNavigator(
Icon( Icon(
imageVector = Icons.Outlined.SkipNext, imageVector = Icons.Outlined.SkipNext,
contentDescription = stringResource( contentDescription = stringResource(
if (isRtl) R.string.action_previous_chapter else R.string.action_next_chapter, if (isRtl) MR.strings.action_previous_chapter else MR.strings.action_next_chapter,
), ),
) )
} }

View File

@ -16,12 +16,12 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.SettingsItemsPaddings import tachiyomi.presentation.core.components.SettingsItemsPaddings
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun ModeSelectionDialog( fun ModeSelectionDialog(
@ -40,7 +40,7 @@ fun ModeSelectionDialog(
) { ) {
onUseDefault?.let { onUseDefault?.let {
OutlinedButton(onClick = it) { OutlinedButton(onClick = it) {
Text(text = stringResource(R.string.action_revert_to_default)) Text(text = stringResource(MR.strings.action_revert_to_default))
} }
} }
@ -57,7 +57,7 @@ fun ModeSelectionDialog(
imageVector = Icons.Outlined.Check, imageVector = Icons.Outlined.Check,
contentDescription = null, contentDescription = null,
) )
Text(text = stringResource(R.string.action_apply)) Text(text = stringResource(MR.strings.action_apply))
} }
} }
} }

View File

@ -6,17 +6,17 @@ import androidx.compose.material3.FilterChip
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.res.stringResource
import androidx.core.graphics.alpha import androidx.core.graphics.alpha
import androidx.core.graphics.blue import androidx.core.graphics.blue
import androidx.core.graphics.green import androidx.core.graphics.green
import androidx.core.graphics.red import androidx.core.graphics.red
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
import tachiyomi.core.preference.getAndSet import tachiyomi.core.preference.getAndSet
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.CheckboxItem import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.SettingsChipRow import tachiyomi.presentation.core.components.SettingsChipRow
import tachiyomi.presentation.core.components.SliderItem import tachiyomi.presentation.core.components.SliderItem
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
@Composable @Composable
@ -24,17 +24,17 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
val colorFilterModes = buildList { val colorFilterModes = buildList {
addAll( addAll(
listOf( listOf(
R.string.label_default, MR.strings.label_default,
R.string.filter_mode_multiply, MR.strings.filter_mode_multiply,
R.string.filter_mode_screen, MR.strings.filter_mode_screen,
), ),
) )
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
addAll( addAll(
listOf( listOf(
R.string.filter_mode_overlay, MR.strings.filter_mode_overlay,
R.string.filter_mode_lighten, MR.strings.filter_mode_lighten,
R.string.filter_mode_darken, MR.strings.filter_mode_darken,
), ),
) )
} }
@ -42,7 +42,7 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
val customBrightness by screenModel.preferences.customBrightness().collectAsState() val customBrightness by screenModel.preferences.customBrightness().collectAsState()
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_custom_brightness), label = stringResource(MR.strings.pref_custom_brightness),
pref = screenModel.preferences.customBrightness(), pref = screenModel.preferences.customBrightness(),
) )
@ -55,7 +55,7 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
if (customBrightness) { if (customBrightness) {
val customBrightnessValue by screenModel.preferences.customBrightnessValue().collectAsState() val customBrightnessValue by screenModel.preferences.customBrightnessValue().collectAsState()
SliderItem( SliderItem(
label = stringResource(R.string.pref_custom_brightness), label = stringResource(MR.strings.pref_custom_brightness),
min = -75, min = -75,
max = 100, max = 100,
value = customBrightnessValue, value = customBrightnessValue,
@ -66,13 +66,13 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
val colorFilter by screenModel.preferences.colorFilter().collectAsState() val colorFilter by screenModel.preferences.colorFilter().collectAsState()
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_custom_color_filter), label = stringResource(MR.strings.pref_custom_color_filter),
pref = screenModel.preferences.colorFilter(), pref = screenModel.preferences.colorFilter(),
) )
if (colorFilter) { if (colorFilter) {
val colorFilterValue by screenModel.preferences.colorFilterValue().collectAsState() val colorFilterValue by screenModel.preferences.colorFilterValue().collectAsState()
SliderItem( SliderItem(
label = stringResource(R.string.color_filter_r_value), label = stringResource(MR.strings.color_filter_r_value),
max = 255, max = 255,
value = colorFilterValue.red, value = colorFilterValue.red,
valueText = colorFilterValue.red.toString(), valueText = colorFilterValue.red.toString(),
@ -83,7 +83,7 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
}, },
) )
SliderItem( SliderItem(
label = stringResource(R.string.color_filter_g_value), label = stringResource(MR.strings.color_filter_g_value),
max = 255, max = 255,
value = colorFilterValue.green, value = colorFilterValue.green,
valueText = colorFilterValue.green.toString(), valueText = colorFilterValue.green.toString(),
@ -94,7 +94,7 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
}, },
) )
SliderItem( SliderItem(
label = stringResource(R.string.color_filter_b_value), label = stringResource(MR.strings.color_filter_b_value),
max = 255, max = 255,
value = colorFilterValue.blue, value = colorFilterValue.blue,
valueText = colorFilterValue.blue.toString(), valueText = colorFilterValue.blue.toString(),
@ -105,7 +105,7 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
}, },
) )
SliderItem( SliderItem(
label = stringResource(R.string.color_filter_a_value), label = stringResource(MR.strings.color_filter_a_value),
max = 255, max = 255,
value = colorFilterValue.alpha, value = colorFilterValue.alpha,
valueText = colorFilterValue.alpha.toString(), valueText = colorFilterValue.alpha.toString(),
@ -117,7 +117,7 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
) )
val colorFilterMode by screenModel.preferences.colorFilterMode().collectAsState() val colorFilterMode by screenModel.preferences.colorFilterMode().collectAsState()
SettingsChipRow(R.string.pref_color_filter_mode) { SettingsChipRow(MR.strings.pref_color_filter_mode) {
colorFilterModes.mapIndexed { index, it -> colorFilterModes.mapIndexed { index, it ->
FilterChip( FilterChip(
selected = colorFilterMode == index, selected = colorFilterMode == index,
@ -129,11 +129,11 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
} }
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_grayscale), label = stringResource(MR.strings.pref_grayscale),
pref = screenModel.preferences.grayscale(), pref = screenModel.preferences.grayscale(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_inverted_colors), label = stringResource(MR.strings.pref_inverted_colors),
pref = screenModel.preferences.invertedColors(), pref = screenModel.preferences.invertedColors(),
) )
} }

View File

@ -5,24 +5,24 @@ import androidx.compose.material3.FilterChip
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.res.stringResource
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.CheckboxItem import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.SettingsChipRow import tachiyomi.presentation.core.components.SettingsChipRow
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
private val themes = listOf( private val themes = listOf(
R.string.black_background to 1, MR.strings.black_background to 1,
R.string.gray_background to 2, MR.strings.gray_background to 2,
R.string.white_background to 0, MR.strings.white_background to 0,
R.string.automatic_background to 3, MR.strings.automatic_background to 3,
) )
@Composable @Composable
internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) { internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
val readerTheme by screenModel.preferences.readerTheme().collectAsState() val readerTheme by screenModel.preferences.readerTheme().collectAsState()
SettingsChipRow(R.string.pref_reader_theme) { SettingsChipRow(MR.strings.pref_reader_theme) {
themes.map { (labelRes, value) -> themes.map { (labelRes, value) ->
FilterChip( FilterChip(
selected = readerTheme == value, selected = readerTheme == value,
@ -33,44 +33,44 @@ internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
} }
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_show_page_number), label = stringResource(MR.strings.pref_show_page_number),
pref = screenModel.preferences.showPageNumber(), pref = screenModel.preferences.showPageNumber(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_fullscreen), label = stringResource(MR.strings.pref_fullscreen),
pref = screenModel.preferences.fullscreen(), pref = screenModel.preferences.fullscreen(),
) )
if (screenModel.hasDisplayCutout) { if (screenModel.hasDisplayCutout) {
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_cutout_short), label = stringResource(MR.strings.pref_cutout_short),
pref = screenModel.preferences.cutoutShort(), pref = screenModel.preferences.cutoutShort(),
) )
} }
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_keep_screen_on), label = stringResource(MR.strings.pref_keep_screen_on),
pref = screenModel.preferences.keepScreenOn(), pref = screenModel.preferences.keepScreenOn(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_read_with_long_tap), label = stringResource(MR.strings.pref_read_with_long_tap),
pref = screenModel.preferences.readWithLongTap(), pref = screenModel.preferences.readWithLongTap(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_always_show_chapter_transition), label = stringResource(MR.strings.pref_always_show_chapter_transition),
pref = screenModel.preferences.alwaysShowChapterTransition(), pref = screenModel.preferences.alwaysShowChapterTransition(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_page_transitions), label = stringResource(MR.strings.pref_page_transitions),
pref = screenModel.preferences.pageTransitions(), pref = screenModel.preferences.pageTransitions(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_flash_page), label = stringResource(MR.strings.pref_flash_page),
pref = screenModel.preferences.flashOnPageChange(), pref = screenModel.preferences.flashOnPageChange(),
) )
} }

View File

@ -11,13 +11,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.window.DialogWindowProvider import androidx.compose.ui.window.DialogWindowProvider
import eu.kanade.presentation.components.TabbedDialog import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun ReaderSettingsDialog( fun ReaderSettingsDialog(
@ -27,9 +27,9 @@ fun ReaderSettingsDialog(
screenModel: ReaderSettingsScreenModel, screenModel: ReaderSettingsScreenModel,
) { ) {
val tabTitles = persistentListOf( val tabTitles = persistentListOf(
stringResource(R.string.pref_category_reading_mode), stringResource(MR.strings.pref_category_reading_mode),
stringResource(R.string.pref_category_general), stringResource(MR.strings.pref_category_general),
stringResource(R.string.custom_filter), stringResource(MR.strings.custom_filter),
) )
val pagerState = rememberPagerState { tabTitles.size } val pagerState = rememberPagerState { tabTitles.size }

View File

@ -7,29 +7,29 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.res.stringResource
import eu.kanade.domain.manga.model.readerOrientation import eu.kanade.domain.manga.model.readerOrientation
import eu.kanade.domain.manga.model.readingMode import eu.kanade.domain.manga.model.readingMode
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.CheckboxItem import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.HeadingItem import tachiyomi.presentation.core.components.HeadingItem
import tachiyomi.presentation.core.components.SettingsChipRow import tachiyomi.presentation.core.components.SettingsChipRow
import tachiyomi.presentation.core.components.SliderItem import tachiyomi.presentation.core.components.SliderItem
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
import java.text.NumberFormat import java.text.NumberFormat
@Composable @Composable
internal fun ColumnScope.ReadingModePage(screenModel: ReaderSettingsScreenModel) { internal fun ColumnScope.ReadingModePage(screenModel: ReaderSettingsScreenModel) {
HeadingItem(R.string.pref_category_for_this_series) HeadingItem(MR.strings.pref_category_for_this_series)
val manga by screenModel.mangaFlow.collectAsState() val manga by screenModel.mangaFlow.collectAsState()
val readingMode = remember(manga) { ReadingMode.fromPreference(manga?.readingMode?.toInt()) } val readingMode = remember(manga) { ReadingMode.fromPreference(manga?.readingMode?.toInt()) }
SettingsChipRow(R.string.pref_category_reading_mode) { SettingsChipRow(MR.strings.pref_category_reading_mode) {
ReadingMode.entries.map { ReadingMode.entries.map {
FilterChip( FilterChip(
selected = it == readingMode, selected = it == readingMode,
@ -40,7 +40,7 @@ internal fun ColumnScope.ReadingModePage(screenModel: ReaderSettingsScreenModel)
} }
val orientation = remember(manga) { ReaderOrientation.fromPreference(manga?.readerOrientation?.toInt()) } val orientation = remember(manga) { ReaderOrientation.fromPreference(manga?.readerOrientation?.toInt()) }
SettingsChipRow(R.string.rotation_type) { SettingsChipRow(MR.strings.rotation_type) {
ReaderOrientation.entries.map { ReaderOrientation.entries.map {
FilterChip( FilterChip(
selected = it == orientation, selected = it == orientation,
@ -60,7 +60,7 @@ internal fun ColumnScope.ReadingModePage(screenModel: ReaderSettingsScreenModel)
@Composable @Composable
private fun ColumnScope.PagerViewerSettings(screenModel: ReaderSettingsScreenModel) { private fun ColumnScope.PagerViewerSettings(screenModel: ReaderSettingsScreenModel) {
HeadingItem(R.string.pager_viewer) HeadingItem(MR.strings.pager_viewer)
val navigationModePager by screenModel.preferences.navigationModePager().collectAsState() val navigationModePager by screenModel.preferences.navigationModePager().collectAsState()
val pagerNavInverted by screenModel.preferences.pagerNavInverted().collectAsState() val pagerNavInverted by screenModel.preferences.pagerNavInverted().collectAsState()
@ -72,7 +72,7 @@ private fun ColumnScope.PagerViewerSettings(screenModel: ReaderSettingsScreenMod
) )
val imageScaleType by screenModel.preferences.imageScaleType().collectAsState() val imageScaleType by screenModel.preferences.imageScaleType().collectAsState()
SettingsChipRow(R.string.pref_image_scale_type) { SettingsChipRow(MR.strings.pref_image_scale_type) {
ReaderPreferences.ImageScaleType.mapIndexed { index, it -> ReaderPreferences.ImageScaleType.mapIndexed { index, it ->
FilterChip( FilterChip(
selected = imageScaleType == index + 1, selected = imageScaleType == index + 1,
@ -83,7 +83,7 @@ private fun ColumnScope.PagerViewerSettings(screenModel: ReaderSettingsScreenMod
} }
val zoomStart by screenModel.preferences.zoomStart().collectAsState() val zoomStart by screenModel.preferences.zoomStart().collectAsState()
SettingsChipRow(R.string.pref_zoom_start) { SettingsChipRow(MR.strings.pref_zoom_start) {
ReaderPreferences.ZoomStart.mapIndexed { index, it -> ReaderPreferences.ZoomStart.mapIndexed { index, it ->
FilterChip( FilterChip(
selected = zoomStart == index + 1, selected = zoomStart == index + 1,
@ -94,42 +94,42 @@ private fun ColumnScope.PagerViewerSettings(screenModel: ReaderSettingsScreenMod
} }
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_crop_borders), label = stringResource(MR.strings.pref_crop_borders),
pref = screenModel.preferences.cropBorders(), pref = screenModel.preferences.cropBorders(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_landscape_zoom), label = stringResource(MR.strings.pref_landscape_zoom),
pref = screenModel.preferences.landscapeZoom(), pref = screenModel.preferences.landscapeZoom(),
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_navigate_pan), label = stringResource(MR.strings.pref_navigate_pan),
pref = screenModel.preferences.navigateToPan(), pref = screenModel.preferences.navigateToPan(),
) )
val dualPageSplitPaged by screenModel.preferences.dualPageSplitPaged().collectAsState() val dualPageSplitPaged by screenModel.preferences.dualPageSplitPaged().collectAsState()
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_dual_page_split), label = stringResource(MR.strings.pref_dual_page_split),
pref = screenModel.preferences.dualPageSplitPaged(), pref = screenModel.preferences.dualPageSplitPaged(),
) )
if (dualPageSplitPaged) { if (dualPageSplitPaged) {
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_dual_page_invert), label = stringResource(MR.strings.pref_dual_page_invert),
pref = screenModel.preferences.dualPageInvertPaged(), pref = screenModel.preferences.dualPageInvertPaged(),
) )
} }
val dualPageRotateToFit by screenModel.preferences.dualPageRotateToFit().collectAsState() val dualPageRotateToFit by screenModel.preferences.dualPageRotateToFit().collectAsState()
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_page_rotate), label = stringResource(MR.strings.pref_page_rotate),
pref = screenModel.preferences.dualPageRotateToFit(), pref = screenModel.preferences.dualPageRotateToFit(),
) )
if (dualPageRotateToFit) { if (dualPageRotateToFit) {
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_page_rotate_invert), label = stringResource(MR.strings.pref_page_rotate_invert),
pref = screenModel.preferences.dualPageRotateToFitInvert(), pref = screenModel.preferences.dualPageRotateToFitInvert(),
) )
} }
@ -139,7 +139,7 @@ private fun ColumnScope.PagerViewerSettings(screenModel: ReaderSettingsScreenMod
private fun ColumnScope.WebtoonViewerSettings(screenModel: ReaderSettingsScreenModel) { private fun ColumnScope.WebtoonViewerSettings(screenModel: ReaderSettingsScreenModel) {
val numberFormat = remember { NumberFormat.getPercentInstance() } val numberFormat = remember { NumberFormat.getPercentInstance() }
HeadingItem(R.string.webtoon_viewer) HeadingItem(MR.strings.webtoon_viewer)
val navigationModeWebtoon by screenModel.preferences.navigationModeWebtoon().collectAsState() val navigationModeWebtoon by screenModel.preferences.navigationModeWebtoon().collectAsState()
val webtoonNavInverted by screenModel.preferences.webtoonNavInverted().collectAsState() val webtoonNavInverted by screenModel.preferences.webtoonNavInverted().collectAsState()
@ -152,7 +152,7 @@ private fun ColumnScope.WebtoonViewerSettings(screenModel: ReaderSettingsScreenM
val webtoonSidePadding by screenModel.preferences.webtoonSidePadding().collectAsState() val webtoonSidePadding by screenModel.preferences.webtoonSidePadding().collectAsState()
SliderItem( SliderItem(
label = stringResource(R.string.pref_webtoon_side_padding), label = stringResource(MR.strings.pref_webtoon_side_padding),
min = ReaderPreferences.WEBTOON_PADDING_MIN, min = ReaderPreferences.WEBTOON_PADDING_MIN,
max = ReaderPreferences.WEBTOON_PADDING_MAX, max = ReaderPreferences.WEBTOON_PADDING_MAX,
value = webtoonSidePadding, value = webtoonSidePadding,
@ -163,25 +163,25 @@ private fun ColumnScope.WebtoonViewerSettings(screenModel: ReaderSettingsScreenM
) )
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_crop_borders), label = stringResource(MR.strings.pref_crop_borders),
pref = screenModel.preferences.cropBordersWebtoon(), pref = screenModel.preferences.cropBordersWebtoon(),
) )
val dualPageSplitWebtoon by screenModel.preferences.dualPageSplitWebtoon().collectAsState() val dualPageSplitWebtoon by screenModel.preferences.dualPageSplitWebtoon().collectAsState()
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_dual_page_split), label = stringResource(MR.strings.pref_dual_page_split),
pref = screenModel.preferences.dualPageSplitWebtoon(), pref = screenModel.preferences.dualPageSplitWebtoon(),
) )
if (dualPageSplitWebtoon) { if (dualPageSplitWebtoon) {
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_dual_page_invert), label = stringResource(MR.strings.pref_dual_page_invert),
pref = screenModel.preferences.dualPageInvertWebtoon(), pref = screenModel.preferences.dualPageInvertWebtoon(),
) )
} }
CheckboxItem( CheckboxItem(
label = stringResource(R.string.pref_double_tap_zoom), label = stringResource(MR.strings.pref_double_tap_zoom),
pref = screenModel.preferences.webtoonDoubleTapZoomEnabled(), pref = screenModel.preferences.webtoonDoubleTapZoomEnabled(),
) )
} }
@ -193,7 +193,7 @@ private fun ColumnScope.TapZonesItems(
invertMode: ReaderPreferences.TappingInvertMode, invertMode: ReaderPreferences.TappingInvertMode,
onSelectInvertMode: (ReaderPreferences.TappingInvertMode) -> Unit, onSelectInvertMode: (ReaderPreferences.TappingInvertMode) -> Unit,
) { ) {
SettingsChipRow(R.string.pref_viewer_nav) { SettingsChipRow(MR.strings.pref_viewer_nav) {
ReaderPreferences.TapZones.mapIndexed { index, it -> ReaderPreferences.TapZones.mapIndexed { index, it ->
FilterChip( FilterChip(
selected = selected == index, selected = selected == index,
@ -204,12 +204,12 @@ private fun ColumnScope.TapZonesItems(
} }
if (selected != 5) { if (selected != 5) {
SettingsChipRow(R.string.pref_read_with_tapping_inverted) { SettingsChipRow(MR.strings.pref_read_with_tapping_inverted) {
ReaderPreferences.TappingInvertMode.entries.map { ReaderPreferences.TappingInvertMode.entries.map {
FilterChip( FilterChip(
selected = it == invertMode, selected = it == invertMode,
onClick = { onSelectInvertMode(it) }, onClick = { onSelectInvertMode(it) },
label = { Text(stringResource(it.titleResId)) }, label = { Text(stringResource(it.titleRes)) },
) )
} }
} }

View File

@ -1,6 +1,5 @@
package eu.kanade.presentation.track package eu.kanade.presentation.track
import androidx.annotation.StringRes
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -42,20 +41,21 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import dev.icerock.moko.resources.StringResource
import eu.kanade.domain.track.model.toDbTrack import eu.kanade.domain.track.model.toDbTrack
import eu.kanade.presentation.components.DropdownMenu import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.presentation.track.components.TrackLogoIcon import eu.kanade.presentation.track.components.TrackLogoIcon
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.Tracker
import eu.kanade.tachiyomi.ui.manga.track.TrackItem import eu.kanade.tachiyomi.ui.manga.track.TrackItem
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import java.text.DateFormat import java.text.DateFormat
private const val UnsetStatusTextAlpha = 0.5F private const val UnsetStatusTextAlpha = 0.5F
@ -131,7 +131,7 @@ fun TrackInfoDialogHome(
private fun TrackInfoItem( private fun TrackInfoItem(
title: String, title: String,
tracker: Tracker, tracker: Tracker,
@StringRes status: Int?, status: StringResource?,
onStatusClick: () -> Unit, onStatusClick: () -> Unit,
chapters: String, chapters: String,
onChaptersClick: () -> Unit, onChaptersClick: () -> Unit,
@ -209,7 +209,7 @@ private fun TrackInfoItem(
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.alpha(if (score == null) UnsetStatusTextAlpha else 1f), .alpha(if (score == null) UnsetStatusTextAlpha else 1f),
text = score ?: stringResource(R.string.score), text = score ?: stringResource(MR.strings.score),
onClick = onScoreClick, onClick = onScoreClick,
) )
} }
@ -221,14 +221,14 @@ private fun TrackInfoItem(
TrackDetailsItem( TrackDetailsItem(
modifier = Modifier.weight(1F), modifier = Modifier.weight(1F),
text = startDate, text = startDate,
placeholder = stringResource(R.string.track_started_reading_date), placeholder = stringResource(MR.strings.track_started_reading_date),
onClick = onStartDateClick, onClick = onStartDateClick,
) )
VerticalDivider() VerticalDivider()
TrackDetailsItem( TrackDetailsItem(
modifier = Modifier.weight(1F), modifier = Modifier.weight(1F),
text = endDate, text = endDate,
placeholder = stringResource(R.string.track_finished_reading_date), placeholder = stringResource(MR.strings.track_finished_reading_date),
onClick = onEndDateClick, onClick = onEndDateClick,
) )
} }
@ -279,7 +279,7 @@ private fun TrackInfoItemEmpty(
.padding(start = 16.dp) .padding(start = 16.dp)
.weight(1f), .weight(1f),
) { ) {
Text(text = stringResource(R.string.add_tracking)) Text(text = stringResource(MR.strings.add_tracking))
} }
} }
} }
@ -294,7 +294,7 @@ private fun TrackInfoItemMenu(
IconButton(onClick = { expanded = true }) { IconButton(onClick = { expanded = true }) {
Icon( Icon(
imageVector = Icons.Default.MoreVert, imageVector = Icons.Default.MoreVert,
contentDescription = stringResource(R.string.label_more), contentDescription = stringResource(MR.strings.label_more),
) )
} }
DropdownMenu( DropdownMenu(
@ -302,14 +302,14 @@ private fun TrackInfoItemMenu(
onDismissRequest = { expanded = false }, onDismissRequest = { expanded = false },
) { ) {
DropdownMenuItem( DropdownMenuItem(
text = { Text(stringResource(R.string.action_open_in_browser)) }, text = { Text(stringResource(MR.strings.action_open_in_browser)) },
onClick = { onClick = {
onOpenInBrowser() onOpenInBrowser()
expanded = false expanded = false
}, },
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text(stringResource(R.string.action_remove)) }, text = { Text(stringResource(MR.strings.action_remove)) },
onClick = { onClick = {
onRemoved() onRemoved()
expanded = false expanded = false

View File

@ -29,18 +29,19 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.WheelNumberPicker import tachiyomi.presentation.core.components.WheelNumberPicker
import tachiyomi.presentation.core.components.WheelTextPicker import tachiyomi.presentation.core.components.WheelTextPicker
import tachiyomi.presentation.core.components.material.AlertDialogContent import tachiyomi.presentation.core.components.material.AlertDialogContent
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart import tachiyomi.presentation.core.util.isScrolledToStart
@ -48,12 +49,12 @@ import tachiyomi.presentation.core.util.isScrolledToStart
fun TrackStatusSelector( fun TrackStatusSelector(
selection: Int, selection: Int,
onSelectionChange: (Int) -> Unit, onSelectionChange: (Int) -> Unit,
selections: Map<Int, Int?>, selections: Map<Int, StringResource?>,
onConfirm: () -> Unit, onConfirm: () -> Unit,
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
) { ) {
BaseSelector( BaseSelector(
title = stringResource(R.string.status), title = stringResource(MR.strings.status),
content = { content = {
val state = rememberLazyListState() val state = rememberLazyListState()
ScrollbarLazyColumn(state = state) { ScrollbarLazyColumn(state = state) {
@ -101,7 +102,7 @@ fun TrackChapterSelector(
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
) { ) {
BaseSelector( BaseSelector(
title = stringResource(R.string.chapters), title = stringResource(MR.strings.chapters),
content = { content = {
WheelNumberPicker( WheelNumberPicker(
items = range.toImmutableList(), items = range.toImmutableList(),
@ -124,7 +125,7 @@ fun TrackScoreSelector(
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
) { ) {
BaseSelector( BaseSelector(
title = stringResource(R.string.score), title = stringResource(MR.strings.score),
content = { content = {
WheelTextPicker( WheelTextPicker(
items = selections, items = selections,
@ -171,15 +172,15 @@ fun TrackDateSelector(
) { ) {
if (onRemove != null) { if (onRemove != null) {
TextButton(onClick = onRemove) { TextButton(onClick = onRemove) {
Text(text = stringResource(R.string.action_remove)) Text(text = stringResource(MR.strings.action_remove))
} }
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
} }
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
TextButton(onClick = { onConfirm(pickerState.selectedDateMillis!!) }) { TextButton(onClick = { onConfirm(pickerState.selectedDateMillis!!) }) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
} }
} }
@ -214,10 +215,10 @@ private fun BaseSelector(
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
} }
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel)) Text(text = stringResource(MR.strings.action_cancel))
} }
TextButton(onClick = onConfirm) { TextButton(onClick = onConfirm) {
Text(text = stringResource(R.string.action_ok)) Text(text = stringResource(MR.strings.action_ok))
} }
} }
}, },
@ -234,12 +235,12 @@ private fun TrackStatusSelectorPreviews() {
onSelectionChange = {}, onSelectionChange = {},
selections = mapOf( selections = mapOf(
// Anilist values // Anilist values
1 to R.string.reading, 1 to MR.strings.reading,
2 to R.string.plan_to_read, 2 to MR.strings.plan_to_read,
3 to R.string.completed, 3 to MR.strings.completed,
4 to R.string.on_hold, 4 to MR.strings.on_hold,
5 to R.string.dropped, 5 to MR.strings.dropped,
6 to R.string.repeating, 6 to MR.strings.repeating,
), ),
onConfirm = {}, onConfirm = {},
onDismissRequest = {}, onDismissRequest = {},

View File

@ -29,7 +29,6 @@ import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.CheckCircle import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Button import androidx.compose.material3.Button
@ -50,7 +49,6 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.capitalize import androidx.compose.ui.text.capitalize
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
@ -62,11 +60,12 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.manga.components.MangaCover import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
import tachiyomi.presentation.core.util.plus import tachiyomi.presentation.core.util.plus
@ -121,7 +120,7 @@ fun TrackerSearch(
decorationBox = { decorationBox = {
if (query.text.isEmpty()) { if (query.text.isEmpty()) {
Text( Text(
text = stringResource(R.string.action_search_hint), text = stringResource(MR.strings.action_search_hint),
color = MaterialTheme.colorScheme.onSurfaceVariant, color = MaterialTheme.colorScheme.onSurfaceVariant,
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
) )
@ -164,7 +163,7 @@ fun TrackerSearch(
.fillMaxWidth(), .fillMaxWidth(),
elevation = ButtonDefaults.elevatedButtonElevation(), elevation = ButtonDefaults.elevatedButtonElevation(),
) { ) {
Text(text = stringResource(R.string.action_track)) Text(text = stringResource(MR.strings.action_track))
} }
} }
}, },
@ -177,7 +176,7 @@ fun TrackerSearch(
if (availableTracks.isEmpty()) { if (availableTracks.isEmpty()) {
EmptyScreen( EmptyScreen(
modifier = Modifier.padding(innerPadding), modifier = Modifier.padding(innerPadding),
textResource = R.string.no_results_found, stringRes = MR.strings.no_results_found,
) )
} else { } else {
ScrollbarLazyColumn( ScrollbarLazyColumn(
@ -205,7 +204,7 @@ fun TrackerSearch(
EmptyScreen( EmptyScreen(
modifier = Modifier.padding(innerPadding), modifier = Modifier.padding(innerPadding),
message = queryResult.exceptionOrNull()?.message message = queryResult.exceptionOrNull()?.message
?: stringResource(R.string.unknown_error), ?: stringResource(MR.strings.unknown_error),
) )
} }
} }
@ -264,19 +263,19 @@ private fun SearchResultItem(
) )
if (type.isNotBlank()) { if (type.isNotBlank()) {
SearchResultItemDetails( SearchResultItemDetails(
title = stringResource(R.string.track_type), title = stringResource(MR.strings.track_type),
text = type, text = type,
) )
} }
if (startDate.isNotBlank()) { if (startDate.isNotBlank()) {
SearchResultItemDetails( SearchResultItemDetails(
title = stringResource(R.string.label_started), title = stringResource(MR.strings.label_started),
text = startDate, text = startDate,
) )
} }
if (status.isNotBlank()) { if (status.isNotBlank()) {
SearchResultItemDetails( SearchResultItemDetails(
title = stringResource(R.string.track_status), title = stringResource(MR.strings.track_status),
text = status, text = status,
) )
} }

Some files were not shown because too many files have changed in this diff Show More