diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 310ac1454..faccc9575 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -75,3 +75,6 @@ # XmlUtil -keep public enum nl.adaptivity.xmlutil.EventType { *; } + +# org.apache.commons:commons-compress +-keep,allowoptimization class org.apache.commons.compress.archivers.zip.** diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt index 0e2f94146..f5ff4e2a1 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt @@ -10,11 +10,14 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.StringRes import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.AlertDialog import androidx.compose.material3.Checkbox import androidx.compose.material3.MaterialTheme @@ -272,18 +275,30 @@ object SettingsBackupScreen : SearchableSettings { onDismissRequest = onDismissRequest, title = { Text(text = stringResource(R.string.pref_restore_backup)) }, text = { - val msg = buildString { - append(stringResource(R.string.backup_restore_content_full)) - if (err.sources.isNotEmpty()) { - append("\n\n").append(stringResource(R.string.backup_restore_missing_sources)) - err.sources.joinTo(this, separator = "\n- ", prefix = "\n- ") - } - if (err.trackers.isNotEmpty()) { - append("\n\n").append(stringResource(R.string.backup_restore_missing_trackers)) - err.trackers.joinTo(this, separator = "\n- ", prefix = "\n- ") + Column( + modifier = Modifier.verticalScroll(rememberScrollState()), + ) { + val msg = buildString { + append(stringResource(R.string.backup_restore_content_full)) + if (err.sources.isNotEmpty()) { + append("\n\n").append(stringResource(R.string.backup_restore_missing_sources)) + err.sources.joinTo( + this, + separator = "\n- ", + prefix = "\n- ", + ) + } + if (err.trackers.isNotEmpty()) { + append("\n\n").append(stringResource(R.string.backup_restore_missing_trackers)) + err.trackers.joinTo( + this, + separator = "\n- ", + prefix = "\n- ", + ) + } } + Text(text = msg) } - Text(text = msg) }, confirmButton = { TextButton( @@ -344,7 +359,7 @@ object SettingsBackupScreen : SearchableSettings { } @Composable - fun getAutomaticBackupGroup( + private fun getAutomaticBackupGroup( backupPreferences: BackupPreferences, ): Preference.PreferenceGroup { val context = LocalContext.current @@ -440,7 +455,7 @@ private data class MissingRestoreComponents( val trackers: List, ) -data class InvalidRestore( +private data class InvalidRestore( val uri: Uri, val message: String, ) diff --git a/app/src/main/java/eu/kanade/presentation/reader/ChapterNavigator.kt b/app/src/main/java/eu/kanade/presentation/reader/ChapterNavigator.kt index a394bd892..fbd1f2fae 100644 --- a/app/src/main/java/eu/kanade/presentation/reader/ChapterNavigator.kt +++ b/app/src/main/java/eu/kanade/presentation/reader/ChapterNavigator.kt @@ -64,20 +64,19 @@ fun ChapterNavigator( val backgroundColor = MaterialTheme.colorScheme .surfaceColorAtElevation(3.dp) .copy(alpha = if (isSystemInDarkTheme()) 0.9f else 0.95f) - - val isLeftEnabled = if (isRtl) enabledNext else enabledPrevious - if (isLeftEnabled) { - FilledIconButton( - onClick = if (isRtl) onNextChapter else onPreviousChapter, - colors = IconButtonDefaults.filledIconButtonColors( - containerColor = backgroundColor, - ), - ) { - Icon( - imageVector = Icons.Outlined.SkipPrevious, - contentDescription = stringResource(if (isRtl) R.string.action_next_chapter else R.string.action_previous_chapter), - ) - } + val buttonColor = IconButtonDefaults.filledIconButtonColors( + containerColor = backgroundColor, + disabledContainerColor = backgroundColor, + ) + FilledIconButton( + enabled = if (isRtl) enabledNext else enabledPrevious, + onClick = if (isRtl) onNextChapter else onPreviousChapter, + colors = buttonColor, + ) { + Icon( + imageVector = Icons.Outlined.SkipPrevious, + contentDescription = stringResource(if (isRtl) R.string.action_next_chapter else R.string.action_previous_chapter), + ) } if (totalPages > 1) { @@ -106,7 +105,7 @@ fun ChapterNavigator( .padding(horizontal = 8.dp), value = currentPage.toFloat(), valueRange = 1f..totalPages.toFloat(), - steps = totalPages, + steps = totalPages - 2, onValueChange = { onSliderValueChange(it.toInt() - 1) }, @@ -120,19 +119,15 @@ fun ChapterNavigator( Spacer(Modifier.weight(1f)) } - val isRightEnabled = if (isRtl) enabledPrevious else enabledNext - if (isRightEnabled) { - FilledIconButton( - onClick = if (isRtl) onPreviousChapter else onNextChapter, - colors = IconButtonDefaults.filledIconButtonColors( - containerColor = backgroundColor, - ), - ) { - Icon( - imageVector = Icons.Outlined.SkipNext, - contentDescription = stringResource(if (isRtl) R.string.action_previous_chapter else R.string.action_next_chapter), - ) - } + FilledIconButton( + enabled = if (isRtl) enabledPrevious else enabledNext, + onClick = if (isRtl) onPreviousChapter else onNextChapter, + colors = buttonColor, + ) { + Icon( + imageVector = Icons.Outlined.SkipNext, + contentDescription = stringResource(if (isRtl) R.string.action_previous_chapter else R.string.action_next_chapter), + ) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/migration/search/AnimeSourceSearchScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/migration/search/AnimeSourceSearchScreen.kt index 3238f4546..3a1dbcb31 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/migration/search/AnimeSourceSearchScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/anime/migration/search/AnimeSourceSearchScreen.kt @@ -26,6 +26,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource import eu.kanade.tachiyomi.core.Constants import eu.kanade.tachiyomi.ui.browse.anime.source.browse.BrowseAnimeSourceScreenModel +import eu.kanade.tachiyomi.ui.browse.anime.source.browse.SourceFilterAnimeDialog import eu.kanade.tachiyomi.ui.entries.anime.AnimeScreen import eu.kanade.tachiyomi.ui.home.HomeScreen import eu.kanade.tachiyomi.ui.webview.WebViewScreen @@ -101,13 +102,23 @@ data class AnimeSourceSearchScreen( ) } + val onDismissRequest = { screenModel.setDialog(null) } when (val dialog = state.dialog) { + is BrowseAnimeSourceScreenModel.Dialog.Filter -> { + SourceFilterAnimeDialog( + onDismissRequest = onDismissRequest, + filters = state.filters, + onReset = screenModel::resetFilters, + onFilter = { screenModel.search(filters = state.filters) }, + onUpdate = screenModel::setFilters, + ) + } is BrowseAnimeSourceScreenModel.Dialog.Migrate -> { MigrateAnimeDialog( oldAnime = oldAnime, newAnime = dialog.newAnime, screenModel = rememberScreenModel { MigrateAnimeDialogScreenModel() }, - onDismissRequest = { screenModel.setDialog(null) }, + onDismissRequest = onDismissRequest, onClickTitle = { navigator.push(AnimeScreen(dialog.newAnime.id)) }, onPopScreen = { scope.launch { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/migration/search/MangaSourceSearchScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/migration/search/MangaSourceSearchScreen.kt index 2896e323a..7254b1da4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/migration/search/MangaSourceSearchScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/manga/migration/search/MangaSourceSearchScreen.kt @@ -26,6 +26,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.core.Constants import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.browse.manga.source.browse.BrowseMangaSourceScreenModel +import eu.kanade.tachiyomi.ui.browse.manga.source.browse.SourceFilterMangaDialog import eu.kanade.tachiyomi.ui.entries.manga.MangaScreen import eu.kanade.tachiyomi.ui.home.HomeScreen import eu.kanade.tachiyomi.ui.webview.WebViewScreen @@ -101,13 +102,23 @@ data class MangaSourceSearchScreen( ) } + val onDismissRequest = { screenModel.setDialog(null) } when (val dialog = state.dialog) { + is BrowseMangaSourceScreenModel.Dialog.Filter -> { + SourceFilterMangaDialog( + onDismissRequest = onDismissRequest, + filters = state.filters, + onReset = screenModel::resetFilters, + onFilter = { screenModel.search(filters = state.filters) }, + onUpdate = screenModel::setFilters, + ) + } is BrowseMangaSourceScreenModel.Dialog.Migrate -> { MigrateMangaDialog( oldManga = oldManga, newManga = dialog.newManga, screenModel = rememberScreenModel { MigrateMangaDialogScreenModel() }, - onDismissRequest = { screenModel.setDialog(null) }, + onDismissRequest = onDismissRequest, onClickTitle = { navigator.push(MangaScreen(dialog.newManga.id)) }, onPopScreen = { scope.launch {