diff --git a/app/src/main/java/eu/kanade/presentation/components/DownloadDropdownMenu.kt b/app/src/main/java/eu/kanade/presentation/components/DownloadDropdownMenu.kt index 6ac95a130..2ee7e95cb 100644 --- a/app/src/main/java/eu/kanade/presentation/components/DownloadDropdownMenu.kt +++ b/app/src/main/java/eu/kanade/presentation/components/DownloadDropdownMenu.kt @@ -3,6 +3,7 @@ package eu.kanade.presentation.components import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.Text 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.tachiyomi.R @@ -18,46 +19,18 @@ fun DownloadDropdownMenu( expanded = expanded, onDismissRequest = onDismissRequest, ) { - DropdownMenuItem( - text = { Text(text = stringResource(R.string.download_1)) }, - onClick = { - onDownloadClicked(DownloadAction.NEXT_1_CHAPTER) - onDismissRequest() - }, - ) - DropdownMenuItem( - text = { Text(text = stringResource(R.string.download_5)) }, - onClick = { - onDownloadClicked(DownloadAction.NEXT_5_CHAPTERS) - onDismissRequest() - }, - ) - DropdownMenuItem( - text = { Text(text = stringResource(R.string.download_10)) }, - onClick = { - onDownloadClicked(DownloadAction.NEXT_10_CHAPTERS) - onDismissRequest() - }, - ) - DropdownMenuItem( - text = { Text(text = stringResource(R.string.download_custom)) }, - onClick = { - onDownloadClicked(DownloadAction.CUSTOM) - onDismissRequest() - }, - ) - DropdownMenuItem( - text = { Text(text = stringResource(R.string.download_unread)) }, - onClick = { - onDownloadClicked(DownloadAction.UNREAD_CHAPTERS) - onDismissRequest() - }, - ) - if (includeDownloadAllOption) { + listOfNotNull( + DownloadAction.NEXT_1_CHAPTER to pluralStringResource(R.plurals.download_amount, 1, 1), + DownloadAction.NEXT_5_CHAPTERS to pluralStringResource(R.plurals.download_amount, 5, 5), + DownloadAction.NEXT_10_CHAPTERS to pluralStringResource(R.plurals.download_amount, 10, 10), + DownloadAction.NEXT_25_CHAPTERS to pluralStringResource(R.plurals.download_amount, 25, 25), + DownloadAction.UNREAD_CHAPTERS to stringResource(R.string.download_unread), + (DownloadAction.ALL_CHAPTERS to stringResource(R.string.download_all)).takeIf { includeDownloadAllOption }, + ).map { (downloadAction, string) -> DropdownMenuItem( - text = { Text(text = stringResource(R.string.download_all)) }, + text = { Text(text = string) }, onClick = { - onDownloadClicked(DownloadAction.ALL_CHAPTERS) + onDownloadClicked(downloadAction) onDismissRequest() }, ) diff --git a/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt b/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt index e98e85c54..55eece48c 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt @@ -4,7 +4,7 @@ enum class DownloadAction { NEXT_1_CHAPTER, NEXT_5_CHAPTERS, NEXT_10_CHAPTERS, - CUSTOM, + NEXT_25_CHAPTERS, UNREAD_CHAPTERS, ALL_CHAPTERS, } diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/DownloadCustomChaptersDialog.kt b/app/src/main/java/eu/kanade/presentation/manga/components/DownloadCustomChaptersDialog.kt deleted file mode 100644 index 53d594434..000000000 --- a/app/src/main/java/eu/kanade/presentation/manga/components/DownloadCustomChaptersDialog.kt +++ /dev/null @@ -1,96 +0,0 @@ -package eu.kanade.presentation.manga.components - -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.ChevronLeft -import androidx.compose.material.icons.outlined.ChevronRight -import androidx.compose.material.icons.outlined.KeyboardDoubleArrowLeft -import androidx.compose.material.icons.outlined.KeyboardDoubleArrowRight -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.LocalTextStyle -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.style.TextAlign -import eu.kanade.tachiyomi.R - -@Composable -fun DownloadCustomAmountDialog( - maxAmount: Int, - onDismissRequest: () -> Unit, - onConfirm: (Int) -> Unit, -) { - var amount by remember { mutableStateOf(0) } - AlertDialog( - onDismissRequest = onDismissRequest, - dismissButton = { - TextButton(onClick = onDismissRequest) { - Text(text = stringResource(R.string.action_cancel)) - } - }, - confirmButton = { - TextButton( - enabled = amount != 0, - onClick = { - onDismissRequest() - onConfirm(amount.coerceIn(0, maxAmount)) - }, - ) { - Text(text = stringResource(R.string.action_download)) - } - }, - title = { - Text(text = stringResource(R.string.custom_download)) - }, - text = { - val setAmount: (Int) -> Unit = { amount = it.coerceIn(0, maxAmount) } - Row( - verticalAlignment = Alignment.CenterVertically, - ) { - IconButton( - onClick = { setAmount(amount - 10) }, - enabled = amount > 0, - ) { - Icon(imageVector = Icons.Outlined.KeyboardDoubleArrowLeft, contentDescription = "-10") - } - IconButton( - onClick = { setAmount(amount - 1) }, - enabled = amount > 0, - ) { - Icon(imageVector = Icons.Outlined.ChevronLeft, contentDescription = "-1") - } - OutlinedTextField( - modifier = Modifier.weight(1f), - value = amount.toString(), - onValueChange = { setAmount(it.toIntOrNull() ?: 0) }, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), - textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center), - ) - IconButton( - onClick = { setAmount(amount + 1) }, - enabled = amount < maxAmount, - ) { - Icon(imageVector = Icons.Outlined.ChevronRight, contentDescription = "+1") - } - IconButton( - onClick = { setAmount(amount + 10) }, - enabled = amount < maxAmount, - ) { - Icon(imageVector = Icons.Outlined.KeyboardDoubleArrowRight, contentDescription = "+10") - } - } - }, - ) -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt index 8e004d81c..c984edb04 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt @@ -456,18 +456,8 @@ class LibraryScreenModel( DownloadAction.NEXT_1_CHAPTER -> downloadUnreadChapters(mangas, 1) DownloadAction.NEXT_5_CHAPTERS -> downloadUnreadChapters(mangas, 5) DownloadAction.NEXT_10_CHAPTERS -> downloadUnreadChapters(mangas, 10) + DownloadAction.NEXT_25_CHAPTERS -> downloadUnreadChapters(mangas, 25) DownloadAction.UNREAD_CHAPTERS -> downloadUnreadChapters(mangas, null) - DownloadAction.CUSTOM -> { - mutableState.update { state -> - state.copy( - dialog = Dialog.DownloadCustomAmount( - mangas, - selection.maxOf { it.unreadCount }.toInt(), - ), - ) - } - return - } else -> {} } clearSelection() @@ -479,7 +469,7 @@ class LibraryScreenModel( * @param mangas the list of manga. * @param amount the amount to queue or null to queue all */ - fun downloadUnreadChapters(mangas: List, amount: Int?) { + private fun downloadUnreadChapters(mangas: List, amount: Int?) { coroutineScope.launchNonCancellable { mangas.forEach { manga -> val chapters = getNextChapters.await(manga.id) @@ -701,7 +691,6 @@ class LibraryScreenModel( sealed class Dialog { data class ChangeCategory(val manga: List, val initialSelection: List>) : Dialog() data class DeleteManga(val manga: List) : Dialog() - data class DownloadCustomAmount(val manga: List, val max: Int) : Dialog() } @Immutable diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryTab.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryTab.kt index ca44167b7..f2a12caba 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryTab.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryTab.kt @@ -38,7 +38,6 @@ import eu.kanade.presentation.components.LoadingScreen import eu.kanade.presentation.components.Scaffold import eu.kanade.presentation.library.components.LibraryContent import eu.kanade.presentation.library.components.LibraryToolbar -import eu.kanade.presentation.manga.components.DownloadCustomAmountDialog import eu.kanade.presentation.util.Tab import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.library.LibraryUpdateJob @@ -226,16 +225,6 @@ object LibraryTab : Tab { }, ) } - is LibraryScreenModel.Dialog.DownloadCustomAmount -> { - DownloadCustomAmountDialog( - maxAmount = dialog.max, - onDismissRequest = onDismissRequest, - onConfirm = { amount -> - screenModel.downloadUnreadChapters(dialog.manga, amount) - screenModel.clearSelection() - }, - ) - } null -> {} } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt index 570f8b90d..2ae74a509 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt @@ -32,7 +32,6 @@ import eu.kanade.presentation.manga.ChapterSettingsDialog import eu.kanade.presentation.manga.EditCoverAction import eu.kanade.presentation.manga.MangaScreen import eu.kanade.presentation.manga.components.DeleteChaptersDialog -import eu.kanade.presentation.manga.components.DownloadCustomAmountDialog import eu.kanade.presentation.manga.components.MangaCoverDialog import eu.kanade.presentation.util.AssistContentScreen import eu.kanade.presentation.util.isTabletUi @@ -156,18 +155,6 @@ class MangaScreen( }, ) } - is MangaInfoScreenModel.Dialog.DownloadCustomAmount -> { - DownloadCustomAmountDialog( - maxAmount = dialog.max, - onDismissRequest = onDismissRequest, - onConfirm = { amount -> - val chaptersToDownload = screenModel.getUnreadChaptersSorted().take(amount) - if (chaptersToDownload.isNotEmpty()) { - screenModel.startDownload(chapters = chaptersToDownload, startNow = false) - } - }, - ) - } is MangaInfoScreenModel.Dialog.DuplicateManga -> DuplicateMangaDialog( onDismissRequest = onDismissRequest, onConfirm = { screenModel.toggleFavorite(onRemoved = {}, checkDuplicate = false) }, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt index c8541988d..3bb4a2906 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt @@ -83,8 +83,8 @@ class MangaInfoScreenModel( private val isFromSource: Boolean, private val downloadPreferences: DownloadPreferences = Injekt.get(), private val libraryPreferences: LibraryPreferences = Injekt.get(), - private val readerPreferences: ReaderPreferences = Injekt.get(), - private val uiPreferences: UiPreferences = Injekt.get(), + readerPreferences: ReaderPreferences = Injekt.get(), + uiPreferences: UiPreferences = Injekt.get(), private val trackManager: TrackManager = Injekt.get(), private val downloadManager: DownloadManager = Injekt.get(), private val downloadCache: DownloadCache = Injekt.get(), @@ -123,8 +123,8 @@ class MangaInfoScreenModel( get() = successState?.processedChapters val relativeTime by uiPreferences.relativeTime().asState(coroutineScope) - val skipFiltered by readerPreferences.skipFiltered().asState(coroutineScope) val dateFormat by mutableStateOf(UiPreferences.dateFormat(uiPreferences.dateFormat().get())) + private val skipFiltered by readerPreferences.skipFiltered().asState(coroutineScope) private val selectedPositions: Array = arrayOf(-1, -1) // first and last selected index in list private val selectedChapterIds: HashSet = HashSet() @@ -354,7 +354,7 @@ class MangaInfoScreenModel( /** * Returns true if the manga has any downloads. */ - fun hasDownloads(): Boolean { + private fun hasDownloads(): Boolean { val manga = successState?.manga ?: return false return downloadManager.getDownloadCount(manga) > 0 } @@ -527,7 +527,7 @@ class MangaInfoScreenModel( /** * Returns the list of filtered or all chapter items if [skipFiltered] is false. */ - fun getChapterItems(): List { + private fun getChapterItems(): List { return if (skipFiltered) filteredChapters.orEmpty().toList() else allChapters.orEmpty() } @@ -539,19 +539,19 @@ class MangaInfoScreenModel( return successState.chapters.getNextUnread(successState.manga) } - fun getUnreadChapters(): List { + private fun getUnreadChapters(): List { return getChapterItems() .filter { (chapter, dlStatus) -> !chapter.read && dlStatus == Download.State.NOT_DOWNLOADED } .map { it.chapter } } - fun getUnreadChaptersSorted(): List { + private fun getUnreadChaptersSorted(): List { val manga = successState?.manga ?: return emptyList() val chaptersSorted = getUnreadChapters().sortedWith(getChapterSort(manga)) return if (manga.sortDescending()) chaptersSorted.reversed() else chaptersSorted } - fun startDownload( + private fun startDownload( chapters: List, startNow: Boolean, ) { @@ -611,19 +611,16 @@ class MangaInfoScreenModel( DownloadAction.NEXT_1_CHAPTER -> getUnreadChaptersSorted().take(1) DownloadAction.NEXT_5_CHAPTERS -> getUnreadChaptersSorted().take(5) DownloadAction.NEXT_10_CHAPTERS -> getUnreadChaptersSorted().take(10) - DownloadAction.CUSTOM -> { - showDownloadCustomDialog() - return - } + DownloadAction.NEXT_25_CHAPTERS -> getUnreadChaptersSorted().take(25) DownloadAction.UNREAD_CHAPTERS -> getUnreadChapters() DownloadAction.ALL_CHAPTERS -> getChapterItems().map { it.chapter } } - if (!chaptersToDownload.isNullOrEmpty()) { + if (chaptersToDownload.isNotEmpty()) { startDownload(chaptersToDownload, false) } } - fun cancelDownload(chapterId: Long) { + private fun cancelDownload(chapterId: Long) { val activeDownload = downloadManager.getQueuedDownloadOrNull(chapterId) ?: return downloadManager.cancelQueuedDownloads(listOf(activeDownload)) updateDownloadState(activeDownload.apply { status = Download.State.NOT_DOWNLOADED }) @@ -913,7 +910,6 @@ class MangaInfoScreenModel( data class ChangeCategory(val manga: Manga, val initialSelection: List>) : Dialog() data class DeleteChapters(val chapters: List) : Dialog() data class DuplicateManga(val manga: Manga, val duplicate: Manga) : Dialog() - data class DownloadCustomAmount(val max: Int) : Dialog() object SettingsSheet : Dialog() object TrackSheet : Dialog() object FullCover : Dialog() @@ -928,16 +924,6 @@ class MangaInfoScreenModel( } } - private fun showDownloadCustomDialog() { - val max = getChapterItems().count() - mutableState.update { state -> - when (state) { - MangaScreenState.Loading -> state - is MangaScreenState.Success -> state.copy(dialog = Dialog.DownloadCustomAmount(max)) - } - } - } - fun showDeleteChapterDialog(chapters: List) { mutableState.update { state -> when (state) { diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index 35531348f..3dfe8599b 100644 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -653,11 +653,10 @@ By chapter number By upload date Download - Download custom amount - Next chapter - Next 5 chapters - Next 10 chapters - Custom + + Next chapter + Next %d chapters + All Unread Custom cover