瀏覽代碼

Replace custom download amount with next 25

Simplifies things and maybe discourages whacky downloading behavior?
Users can still range select in the chapters list to download custom amounts.
arkon 2 年之前
父節點
當前提交
f6e6a7ddf1

+ 11 - 38
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()
                 },
             )

+ 1 - 1
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,
 }

+ 0 - 96
app/src/main/java/eu/kanade/presentation/manga/components/DownloadCustomChaptersDialog.kt

@@ -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")
-                }
-            }
-        },
-    )
-}

+ 2 - 13
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<Manga>, amount: Int?) {
+    private fun downloadUnreadChapters(mangas: List<Manga>, 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<Manga>, val initialSelection: List<CheckboxState<Category>>) : Dialog()
         data class DeleteManga(val manga: List<Manga>) : Dialog()
-        data class DownloadCustomAmount(val manga: List<Manga>, val max: Int) : Dialog()
     }
 
     @Immutable

+ 0 - 11
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 -> {}
         }
 

+ 0 - 13
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) },

+ 11 - 25
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<Int> = arrayOf(-1, -1) // first and last selected index in list
     private val selectedChapterIds: HashSet<Long> = 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<ChapterItem> {
+    private fun getChapterItems(): List<ChapterItem> {
         return if (skipFiltered) filteredChapters.orEmpty().toList() else allChapters.orEmpty()
     }
 
@@ -539,19 +539,19 @@ class MangaInfoScreenModel(
         return successState.chapters.getNextUnread(successState.manga)
     }
 
-    fun getUnreadChapters(): List<Chapter> {
+    private fun getUnreadChapters(): List<Chapter> {
         return getChapterItems()
             .filter { (chapter, dlStatus) -> !chapter.read && dlStatus == Download.State.NOT_DOWNLOADED }
             .map { it.chapter }
     }
 
-    fun getUnreadChaptersSorted(): List<Chapter> {
+    private fun getUnreadChaptersSorted(): List<Chapter> {
         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<Chapter>,
         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<CheckboxState<Category>>) : Dialog()
         data class DeleteChapters(val chapters: List<Chapter>) : 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<Chapter>) {
         mutableState.update { state ->
             when (state) {

+ 4 - 5
i18n/src/main/res/values/strings.xml

@@ -653,11 +653,10 @@
     <string name="sort_by_number">By chapter number</string>
     <string name="sort_by_upload_date">By upload date</string>
     <string name="manga_download">Download</string>
-    <string name="custom_download">Download custom amount</string>
-    <string name="download_1">Next chapter</string>
-    <string name="download_5">Next 5 chapters</string>
-    <string name="download_10">Next 10 chapters</string>
-    <string name="download_custom">Custom</string>
+    <plurals name="download_amount">
+        <item quantity="one">Next chapter</item>
+        <item quantity="other">Next %d chapters</item>
+    </plurals>
     <string name="download_all">All</string>
     <string name="download_unread">Unread</string>
     <string name="custom_cover">Custom cover</string>