Last Commit Merged: f6e6a7ddf1
This commit is contained in:
LuftVerbot 2023-05-30 14:20:22 +02:00
parent c6daaae9e6
commit 24e9e1846d
26 changed files with 86 additions and 308 deletions

View file

@ -61,9 +61,9 @@ class DelayedAnimeTrackingUpdateJob(context: Context, workerParams: WorkerParame
private const val TAG = "DelayedTrackingUpdate"
fun setupTask(context: Context) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val constraints = Constraints(
requiredNetworkType = NetworkType.CONNECTED,
)
val request = OneTimeWorkRequestBuilder<DelayedAnimeTrackingUpdateJob>()
.setConstraints(constraints)

View file

@ -61,9 +61,9 @@ class DelayedMangaTrackingUpdateJob(context: Context, workerParams: WorkerParame
private const val TAG = "DelayedTrackingUpdate"
fun setupTask(context: Context) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val constraints = Constraints(
requiredNetworkType = NetworkType.CONNECTED,
)
val request = OneTimeWorkRequestBuilder<DelayedMangaTrackingUpdateJob>()
.setConstraints(constraints)

View file

@ -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.entries.DownloadAction
import eu.kanade.tachiyomi.R
@ -19,50 +20,20 @@ fun EntryDownloadDropdownMenu(
expanded = expanded,
onDismissRequest = onDismissRequest,
) {
val download1 = if (isManga) R.string.download_1 else R.string.download_1_episode
DropdownMenuItem(
text = { Text(text = stringResource(download1)) },
onClick = {
onDownloadClicked(DownloadAction.NEXT_1_ITEM)
onDismissRequest()
},
)
val download5 = if (isManga) R.string.download_5 else R.string.download_5_episodes
DropdownMenuItem(
text = { Text(text = stringResource(download5)) },
onClick = {
onDownloadClicked(DownloadAction.NEXT_5_ITEMS)
onDismissRequest()
},
)
val download10 = if (isManga) R.string.download_10 else R.string.download_10_episodes
DropdownMenuItem(
text = { Text(text = stringResource(download10)) },
onClick = {
onDownloadClicked(DownloadAction.NEXT_10_ITEMS)
onDismissRequest()
},
)
DropdownMenuItem(
text = { Text(text = stringResource(R.string.download_custom)) },
onClick = {
onDownloadClicked(DownloadAction.CUSTOM)
onDismissRequest()
},
)
val downloadAmount = if (isManga) R.plurals.download_amount_manga else R.plurals.download_amount_anime
val downloadUnviewed = if (isManga) R.string.download_unread else R.string.download_unseen
DropdownMenuItem(
text = { Text(text = stringResource(downloadUnviewed)) },
onClick = {
onDownloadClicked(DownloadAction.UNVIEWED_ITEMS)
onDismissRequest()
},
)
if (includeDownloadAllOption) {
listOfNotNull(
DownloadAction.NEXT_1_ITEM to pluralStringResource(downloadAmount, 1, 1),
DownloadAction.NEXT_5_ITEMS to pluralStringResource(downloadAmount, 5, 5),
DownloadAction.NEXT_10_ITEMS to pluralStringResource(downloadAmount, 10, 10),
DownloadAction.NEXT_25_ITEMS to pluralStringResource(downloadAmount, 25, 25),
DownloadAction.UNVIEWED_ITEMS to stringResource(downloadUnviewed),
(DownloadAction.ALL_ITEMS 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_ITEMS)
onDownloadClicked(downloadAction)
onDismissRequest()
},
)

View file

@ -1,96 +0,0 @@
package eu.kanade.presentation.entries
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")
}
}
},
)
}

View file

@ -4,7 +4,7 @@ enum class DownloadAction {
NEXT_1_ITEM,
NEXT_5_ITEMS,
NEXT_10_ITEMS,
CUSTOM,
NEXT_25_ITEMS,
UNVIEWED_ITEMS,
ALL_ITEMS,
}

View file

@ -40,6 +40,7 @@ import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.core.view.updatePadding
import coil.imageLoader
import coil.request.CachePolicy
import coil.request.ImageRequest
import coil.size.Size
import eu.kanade.presentation.components.DropdownMenu
@ -162,6 +163,7 @@ fun AnimeCoverDialog(
val request = ImageRequest.Builder(view.context)
.data(coverDataProvider())
.size(Size.ORIGINAL)
.memoryCachePolicy(CachePolicy.DISABLED)
.target { drawable ->
// Copy bitmap in case it came from memory cache
// Because SSIV needs to thoroughly read the image

View file

@ -40,6 +40,7 @@ import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.core.view.updatePadding
import coil.imageLoader
import coil.request.CachePolicy
import coil.request.ImageRequest
import coil.size.Size
import eu.kanade.presentation.components.DropdownMenu
@ -162,6 +163,7 @@ fun MangaCoverDialog(
val request = ImageRequest.Builder(view.context)
.data(coverDataProvider())
.size(Size.ORIGINAL)
.memoryCachePolicy(CachePolicy.DISABLED)
.target { drawable ->
// Copy bitmap in case it came from memory cache
// Because SSIV needs to thoroughly read the image

View file

@ -550,11 +550,11 @@ class AnimeLibraryUpdateJob(private val context: Context, workerParams: WorkerPa
val interval = prefInterval ?: preferences.libraryUpdateInterval().get()
if (interval > 0) {
val restrictions = preferences.libraryUpdateDeviceRestriction().get()
val constraints = Constraints.Builder()
.setRequiredNetworkType(if (DEVICE_NETWORK_NOT_METERED in restrictions) { NetworkType.UNMETERED } else { NetworkType.CONNECTED })
.setRequiresCharging(DEVICE_CHARGING in restrictions)
.setRequiresBatteryNotLow(DEVICE_BATTERY_NOT_LOW in restrictions)
.build()
val constraints = Constraints(
requiredNetworkType = if (DEVICE_NETWORK_NOT_METERED in restrictions) { NetworkType.UNMETERED } else { NetworkType.CONNECTED },
requiresCharging = DEVICE_CHARGING in restrictions,
requiresBatteryNotLow = DEVICE_BATTERY_NOT_LOW in restrictions,
)
val request = PeriodicWorkRequestBuilder<AnimeLibraryUpdateJob>(
interval.toLong(),

View file

@ -549,17 +549,11 @@ class MangaLibraryUpdateJob(private val context: Context, workerParams: WorkerPa
val interval = prefInterval ?: preferences.libraryUpdateInterval().get()
if (interval > 0) {
val restrictions = preferences.libraryUpdateDeviceRestriction().get()
val constraints = Constraints.Builder()
.setRequiredNetworkType(
if (DEVICE_NETWORK_NOT_METERED in restrictions) {
NetworkType.UNMETERED
} else {
NetworkType.CONNECTED
},
)
.setRequiresCharging(DEVICE_CHARGING in restrictions)
.setRequiresBatteryNotLow(DEVICE_BATTERY_NOT_LOW in restrictions)
.build()
val constraints = Constraints(
requiredNetworkType = if (DEVICE_NETWORK_NOT_METERED in restrictions) { NetworkType.UNMETERED } else { NetworkType.CONNECTED },
requiresCharging = DEVICE_CHARGING in restrictions,
requiresBatteryNotLow = DEVICE_BATTERY_NOT_LOW in restrictions,
)
val request = PeriodicWorkRequestBuilder<MangaLibraryUpdateJob>(
interval.toLong(),

View file

@ -37,9 +37,9 @@ class AppUpdateJob(private val context: Context, workerParams: WorkerParameters)
return
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val constraints = Constraints(
requiredNetworkType = NetworkType.CONNECTED,
)
val request = PeriodicWorkRequestBuilder<AppUpdateJob>(
7,

View file

@ -71,9 +71,9 @@ class AnimeExtensionUpdateJob(private val context: Context, workerParams: Worker
val preferences = Injekt.get<BasePreferences>()
val autoUpdateJob = forceAutoUpdateJob ?: preferences.automaticExtUpdates().get()
if (autoUpdateJob) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val constraints = Constraints(
requiredNetworkType = NetworkType.CONNECTED,
)
val request = PeriodicWorkRequestBuilder<AnimeExtensionUpdateJob>(
2,

View file

@ -71,9 +71,9 @@ class MangaExtensionUpdateJob(private val context: Context, workerParams: Worker
val preferences = Injekt.get<BasePreferences>()
val autoUpdateJob = forceAutoUpdateJob ?: preferences.automaticExtUpdates().get()
if (autoUpdateJob) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val constraints = Constraints(
requiredNetworkType = NetworkType.CONNECTED,
)
val request = PeriodicWorkRequestBuilder<MangaExtensionUpdateJob>(
2,

View file

@ -39,7 +39,6 @@ import eu.kanade.presentation.components.DuplicateAnimeDialog
import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.NavigatorAdaptiveSheet
import eu.kanade.presentation.entries.DeleteItemsDialog
import eu.kanade.presentation.entries.DownloadCustomAmountDialog
import eu.kanade.presentation.entries.EditCoverAction
import eu.kanade.presentation.entries.anime.AnimeScreen
import eu.kanade.presentation.entries.anime.EpisodeSettingsDialog
@ -189,18 +188,6 @@ class AnimeScreen(
isManga = false,
)
}
is AnimeInfoScreenModel.Dialog.DownloadCustomAmount -> {
DownloadCustomAmountDialog(
maxAmount = dialog.max,
onDismissRequest = onDismissRequest,
onConfirm = { amount ->
val episodesToDownload = screenModel.getUnseenEpisodesSorted().take(amount)
if (episodesToDownload.isNotEmpty()) {
screenModel.startDownload(episodes = episodesToDownload, startNow = false)
}
},
)
}
is AnimeInfoScreenModel.Dialog.DuplicateAnime -> DuplicateAnimeDialog(
onDismissRequest = onDismissRequest,
onConfirm = { screenModel.toggleFavorite(onRemoved = {}, checkDuplicate = false) },

View file

@ -82,7 +82,7 @@ class AnimeInfoScreenModel(
private val isFromSource: Boolean,
private val downloadPreferences: DownloadPreferences = Injekt.get(),
private val libraryPreferences: LibraryPreferences = Injekt.get(),
private val uiPreferences: UiPreferences = Injekt.get(),
uiPreferences: UiPreferences = Injekt.get(),
private val trackPreferences: TrackPreferences = Injekt.get(),
internal val playerPreferences: PlayerPreferences = Injekt.get(),
private val trackManager: TrackManager = Injekt.get(),
@ -364,7 +364,7 @@ class AnimeInfoScreenModel(
/**
* Returns true if the anime has any downloads.
*/
fun hasDownloads(): Boolean {
private fun hasDownloads(): Boolean {
val anime = successState?.anime ?: return false
return downloadManager.getDownloadCount(anime) > 0
}
@ -542,7 +542,7 @@ class AnimeInfoScreenModel(
return successState.episodes.getNextUnseen(successState.anime)
}
fun getUnseenEpisodes(): List<Episode> {
private fun getUnseenEpisodes(): List<Episode> {
return successState?.processedEpisodes
?.filter { (episode, dlStatus) -> !episode.seen && dlStatus == AnimeDownload.State.NOT_DOWNLOADED }
?.map { it.episode }
@ -550,13 +550,13 @@ class AnimeInfoScreenModel(
?: emptyList()
}
fun getUnseenEpisodesSorted(): List<Episode> {
private fun getUnseenEpisodesSorted(): List<Episode> {
val anime = successState?.anime ?: return emptyList()
val episodes = getUnseenEpisodes().sortedWith(getEpisodeSort(anime))
return if (anime.sortDescending()) episodes.reversed() else episodes
}
fun startDownload(
private fun startDownload(
episodes: List<Episode>,
startNow: Boolean,
) {
@ -616,10 +616,8 @@ class AnimeInfoScreenModel(
DownloadAction.NEXT_1_ITEM -> getUnseenEpisodesSorted().take(1)
DownloadAction.NEXT_5_ITEMS -> getUnseenEpisodesSorted().take(5)
DownloadAction.NEXT_10_ITEMS -> getUnseenEpisodesSorted().take(10)
DownloadAction.CUSTOM -> {
showDownloadCustomDialog()
return
}
DownloadAction.NEXT_25_ITEMS -> getUnseenEpisodesSorted().take(25)
DownloadAction.UNVIEWED_ITEMS -> getUnseenEpisodes()
DownloadAction.ALL_ITEMS -> successState?.episodes?.map { it.episode }
}
@ -628,7 +626,7 @@ class AnimeInfoScreenModel(
}
}
fun cancelDownload(episodeId: Long) {
private fun cancelDownload(episodeId: Long) {
val activeDownload = downloadManager.getQueuedDownloadOrNull(episodeId) ?: return
downloadManager.cancelQueuedDownloads(listOf(activeDownload))
updateDownloadState(activeDownload.apply { status = AnimeDownload.State.NOT_DOWNLOADED })
@ -922,7 +920,6 @@ class AnimeInfoScreenModel(
data class ChangeCategory(val anime: Anime, val initialSelection: List<CheckboxState<Category>>) : Dialog()
data class DeleteEpisodes(val episodes: List<Episode>) : Dialog()
data class DuplicateAnime(val anime: Anime, val duplicate: Anime) : Dialog()
data class DownloadCustomAmount(val max: Int) : Dialog()
object ChangeAnimeSkipIntro : Dialog()
object SettingsSheet : Dialog()
object TrackSheet : Dialog()
@ -937,15 +934,6 @@ class AnimeInfoScreenModel(
}
}
}
private fun showDownloadCustomDialog() {
val max = processedEpisodes?.count() ?: return
mutableState.update { state ->
when (state) {
AnimeScreenState.Loading -> state
is AnimeScreenState.Success -> state.copy(dialog = Dialog.DownloadCustomAmount(max))
}
}
}
fun showDeleteEpisodeDialog(chapters: List<Episode>) {
mutableState.update { state ->

View file

@ -29,7 +29,6 @@ import eu.kanade.presentation.components.DuplicateMangaDialog
import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.NavigatorAdaptiveSheet
import eu.kanade.presentation.entries.DeleteItemsDialog
import eu.kanade.presentation.entries.DownloadCustomAmountDialog
import eu.kanade.presentation.entries.EditCoverAction
import eu.kanade.presentation.entries.manga.ChapterSettingsDialog
import eu.kanade.presentation.entries.manga.MangaScreen
@ -164,18 +163,6 @@ class MangaScreen(
isManga = true,
)
}
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) },

View file

@ -84,8 +84,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 trackPreferences: TrackPreferences = Injekt.get(),
private val trackManager: TrackManager = Injekt.get(),
private val downloadManager: MangaDownloadManager = Injekt.get(),
@ -125,8 +125,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()))
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()
@ -372,7 +372,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
}
@ -545,7 +545,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()
}
@ -557,19 +557,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 == MangaDownload.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,
) {
@ -628,19 +628,17 @@ class MangaInfoScreenModel(
DownloadAction.NEXT_1_ITEM -> getUnreadChaptersSorted().take(1)
DownloadAction.NEXT_5_ITEMS -> getUnreadChaptersSorted().take(5)
DownloadAction.NEXT_10_ITEMS -> getUnreadChaptersSorted().take(10)
DownloadAction.CUSTOM -> {
showDownloadCustomDialog()
return
}
DownloadAction.NEXT_25_ITEMS -> getUnreadChaptersSorted().take(25)
DownloadAction.UNVIEWED_ITEMS -> getUnreadChapters()
DownloadAction.ALL_ITEMS -> 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 = MangaDownload.State.NOT_DOWNLOADED })
@ -930,7 +928,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()
@ -945,16 +942,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) {

View file

@ -457,18 +457,8 @@ class AnimeLibraryScreenModel(
DownloadAction.NEXT_1_ITEM -> downloadUnseenEpisodes(animes, 1)
DownloadAction.NEXT_5_ITEMS -> downloadUnseenEpisodes(animes, 5)
DownloadAction.NEXT_10_ITEMS -> downloadUnseenEpisodes(animes, 10)
DownloadAction.NEXT_25_ITEMS -> downloadUnseenEpisodes(animes, 25)
DownloadAction.UNVIEWED_ITEMS -> downloadUnseenEpisodes(animes, null)
DownloadAction.CUSTOM -> {
mutableState.update { state ->
state.copy(
dialog = Dialog.DownloadCustomAmount(
animes,
selection.maxOf { it.unseenCount }.toInt(),
),
)
}
return
}
else -> {}
}
clearSelection()
@ -480,7 +470,7 @@ class AnimeLibraryScreenModel(
* @param animes the list of anime.
* @param amount the amount to queue or null to queue all
*/
fun downloadUnseenEpisodes(animes: List<Anime>, amount: Int?) {
private fun downloadUnseenEpisodes(animes: List<Anime>, amount: Int?) {
coroutineScope.launchNonCancellable {
animes.forEach { anime ->
val episodes = getNextEpisodes.await(anime.id)
@ -702,7 +692,6 @@ class AnimeLibraryScreenModel(
sealed class Dialog {
data class ChangeCategory(val anime: List<Anime>, val initialSelection: List<CheckboxState<Category>>) : Dialog()
data class DeleteAnime(val anime: List<Anime>) : Dialog()
data class DownloadCustomAmount(val anime: List<Anime>, val max: Int) : Dialog()
}
@Immutable

View file

@ -40,7 +40,6 @@ import eu.kanade.presentation.components.EmptyScreenAction
import eu.kanade.presentation.components.LibraryBottomActionMenu
import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.entries.DownloadCustomAmountDialog
import eu.kanade.presentation.library.LibraryToolbar
import eu.kanade.presentation.library.anime.AnimeLibraryContent
import eu.kanade.presentation.util.Tab
@ -261,16 +260,6 @@ object AnimeLibraryTab : Tab {
isManga = false,
)
}
is AnimeLibraryScreenModel.Dialog.DownloadCustomAmount -> {
DownloadCustomAmountDialog(
maxAmount = dialog.max,
onDismissRequest = onDismissRequest,
onConfirm = { amount ->
screenModel.downloadUnseenEpisodes(dialog.anime, amount)
screenModel.clearSelection()
},
)
}
null -> {}
}

View file

@ -457,18 +457,8 @@ class MangaLibraryScreenModel(
DownloadAction.NEXT_1_ITEM -> downloadUnreadChapters(mangas, 1)
DownloadAction.NEXT_5_ITEMS -> downloadUnreadChapters(mangas, 5)
DownloadAction.NEXT_10_ITEMS -> downloadUnreadChapters(mangas, 10)
DownloadAction.NEXT_25_ITEMS -> downloadUnreadChapters(mangas, 25)
DownloadAction.UNVIEWED_ITEMS -> downloadUnreadChapters(mangas, null)
DownloadAction.CUSTOM -> {
mutableState.update { state ->
state.copy(
dialog = Dialog.DownloadCustomAmount(
mangas,
selection.maxOf { it.unreadCount }.toInt(),
),
)
}
return
}
else -> {}
}
clearSelection()
@ -480,7 +470,7 @@ class MangaLibraryScreenModel(
* @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)
@ -702,7 +692,6 @@ class MangaLibraryScreenModel(
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

View file

@ -39,7 +39,6 @@ import eu.kanade.presentation.components.EmptyScreenAction
import eu.kanade.presentation.components.LibraryBottomActionMenu
import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.entries.DownloadCustomAmountDialog
import eu.kanade.presentation.library.LibraryToolbar
import eu.kanade.presentation.library.manga.MangaLibraryContent
import eu.kanade.presentation.util.Tab
@ -248,16 +247,6 @@ object MangaLibraryTab : Tab {
isManga = true,
)
}
is MangaLibraryScreenModel.Dialog.DownloadCustomAmount -> {
DownloadCustomAmountDialog(
maxAmount = dialog.max,
onDismissRequest = onDismissRequest,
onConfirm = { amount ->
screenModel.downloadUnreadChapters(dialog.manga, amount)
screenModel.clearSelection()
},
)
}
null -> {}
}

View file

@ -1,12 +1,12 @@
[versions]
agp_version = "7.4.1"
lifecycle_version = "2.5.1"
lifecycle_version = "2.6.0-beta01"
[libraries]
gradle = { module = "com.android.tools.build:gradle", version.ref = "agp_version" }
annotation = "androidx.annotation:annotation:1.5.0"
appcompat = "androidx.appcompat:appcompat:1.6.0"
appcompat = "androidx.appcompat:appcompat:1.6.1"
biometricktx = "androidx.biometric:biometric-ktx:1.2.0-alpha05"
constraintlayout = "androidx.constraintlayout:constraintlayout:2.1.4"
coordinatorlayout = "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
@ -21,11 +21,11 @@ lifecycle-common = { module = "androidx.lifecycle:lifecycle-common", version.ref
lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version.ref = "lifecycle_version" }
lifecycle-runtimektx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle_version" }
work-runtime = "androidx.work:work-runtime-ktx:2.8.0-rc01"
work-runtime = "androidx.work:work-runtime-ktx:2.8.0"
guava = "com.google.guava:guava:31.1-android"
paging-runtime = "androidx.paging:paging-runtime:3.1.1"
paging-compose = "androidx.paging:paging-compose:1.0.0-alpha17"
paging-compose = "androidx.paging:paging-compose:1.0.0-alpha18"
benchmark-macro = "androidx.benchmark:benchmark-macro-junit4:1.1.1"
test-ext = "androidx.test.ext:junit-ktx:1.1.5"

View file

@ -1,5 +1,5 @@
[versions]
compiler = "1.4.0"
compiler = "1.4.2"
compose-bom = "2023.01.00"
accompanist = "0.28.0"
@ -16,9 +16,9 @@ material3-core = { module = "androidx.compose.material3:material3" }
material-icons = { module = "androidx.compose.material:material-icons-extended" }
# Here until M3's swipeable became public https://issuetracker.google.com/issues/234640556
# Using alpha version for PullRefresh fix
# Using newer version for PullRefresh fix
# TODO: use default version after next Compose BOM is released
material-core = { module = "androidx.compose.material:material", version = "1.4.0-alpha05" }
material-core = { module = "androidx.compose.material:material", version = "1.4.0-beta01" }
accompanist-webview = { module = "com.google.accompanist:accompanist-webview", version.ref = "accompanist" }
accompanist-flowlayout = { module = "com.google.accompanist:accompanist-flowlayout", version.ref = "accompanist" }

View file

@ -1,5 +1,6 @@
[versions]
kotlin_version = "1.8.0"
kotlin_version = "1.8.10"
# TODO: 1.4.1 introduces an issue with cached serializers; see https://github.com/Kotlin/kotlinx.serialization/issues/2065
serialization_version = "1.4.0"
xml_serialization_version = "0.84.3"
@ -11,9 +12,8 @@ coroutines-bom = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-bom", vers
coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core" }
coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android" }
# TODO: 1.4.1 introduces an issue with cached serializers; see https://github.com/Kotlin/kotlinx.serialization/issues/2065
serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version = "1.4.0" }
serialization-json-okio = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json-okio", version = "1.4.0" }
serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization_version" }
serialization-json-okio = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json-okio", version.ref = "serialization_version" }
serialization-protobuf = { module = "org.jetbrains.kotlinx:kotlinx-serialization-protobuf", version.ref = "serialization_version" }
serialization-xml-core = { module = "io.github.pdvrieze.xmlutil:core-android", version.ref = "xml_serialization_version" }
serialization-xml = { module = "io.github.pdvrieze.xmlutil:serialization-android", version.ref = "xml_serialization_version" }

View file

@ -61,7 +61,7 @@ flexible-adapter-ui = "com.github.arkon.FlexibleAdapter:flexible-adapter-ui:c801
photoview = "com.github.chrisbanes:PhotoView:2.3.0"
directionalviewpager = "com.github.tachiyomiorg:DirectionalViewPager:1.0.0"
insetter = "dev.chrisbanes.insetter:insetter:0.6.1"
cascade = "me.saket.cascade:cascade-compose:2.0.0-beta1"
cascade = "me.saket.cascade:cascade-compose:2.0.0-rc01"
wheelpicker = "com.github.commandiron:WheelPickerCompose:1.0.11"
materialmotion-core = "io.github.fornewid:material-motion-compose-core:0.10.4"

View file

@ -171,9 +171,10 @@
<string name="download_paused">Paused</string>
<string name="show_episode_number">Episode number</string>
<string name="sort_by_episode_number">By episode number</string>
<string name="download_1_episode">Next episode</string>
<string name="download_5_episodes">Next 5 episodes</string>
<string name="download_10_episodes">Next 10 episodes</string>
<plurals name="download_amount_anime">
<item quantity="one">Next episode</item>
<item quantity="other">Next %d episode</item>
</plurals>
<string name="download_unseen">Unseen</string>
<string name="confirm_delete_episodes">Are you sure you want to delete the selected episodes?</string>
<string name="also_set_chapter_settings_for_library">Also apply to all manga in my library</string>

View file

@ -631,11 +631,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_manga">
<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>