Clean up library download chapters logic
We can probably clean up the same logic in the manga controller at some point too, but that stuff's messy. Also fixes the spacing issue that the new icon introduced.
This commit is contained in:
parent
50b17d5d34
commit
33e90d6449
@ -94,7 +94,7 @@ class DomainModule : InjektModule {
|
|||||||
addFactory { GetLibraryManga(get()) }
|
addFactory { GetLibraryManga(get()) }
|
||||||
addFactory { GetMangaWithChapters(get(), get()) }
|
addFactory { GetMangaWithChapters(get(), get()) }
|
||||||
addFactory { GetManga(get()) }
|
addFactory { GetManga(get()) }
|
||||||
addFactory { GetNextUnreadChapters(get(), get(), get(), get()) }
|
addFactory { GetNextUnreadChapters(get(), get(), get()) }
|
||||||
addFactory { ResetViewerFlags(get()) }
|
addFactory { ResetViewerFlags(get()) }
|
||||||
addFactory { SetMangaChapterFlags(get()) }
|
addFactory { SetMangaChapterFlags(get()) }
|
||||||
addFactory { SetMangaDefaultChapterFlags(get(), get(), get()) }
|
addFactory { SetMangaDefaultChapterFlags(get(), get(), get()) }
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
package eu.kanade.domain.history.interactor
|
package eu.kanade.domain.history.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.chapter.interactor.GetChapter
|
|
||||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
import eu.kanade.domain.chapter.model.Chapter
|
||||||
import eu.kanade.domain.history.repository.HistoryRepository
|
import eu.kanade.domain.history.repository.HistoryRepository
|
||||||
import eu.kanade.domain.manga.interactor.GetManga
|
import eu.kanade.domain.manga.interactor.GetManga
|
||||||
import eu.kanade.tachiyomi.util.chapter.getChapterSort
|
import eu.kanade.tachiyomi.util.chapter.getChapterSort
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
class GetNextUnreadChapters(
|
class GetNextUnreadChapters(
|
||||||
private val getChapter: GetChapter,
|
|
||||||
private val getChapterByMangaId: GetChapterByMangaId,
|
private val getChapterByMangaId: GetChapterByMangaId,
|
||||||
private val getManga: GetManga,
|
private val getManga: GetManga,
|
||||||
private val historyRepository: HistoryRepository,
|
private val historyRepository: HistoryRepository,
|
||||||
@ -19,15 +18,16 @@ class GetNextUnreadChapters(
|
|||||||
return await(history.mangaId, history.chapterId).firstOrNull()
|
return await(history.mangaId, history.chapterId).firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun await(mangaId: Long, chapterId: Long): List<Chapter> {
|
suspend fun await(mangaId: Long): List<Chapter> {
|
||||||
val chapter = getChapter.await(chapterId) ?: return emptyList()
|
|
||||||
val manga = getManga.await(mangaId) ?: return emptyList()
|
val manga = getManga.await(mangaId) ?: return emptyList()
|
||||||
|
return getChapterByMangaId.await(mangaId)
|
||||||
val chapters = getChapterByMangaId.await(mangaId)
|
|
||||||
.sortedWith(getChapterSort(manga, sortDescending = false))
|
.sortedWith(getChapterSort(manga, sortDescending = false))
|
||||||
val currChapterIndex = chapters.indexOfFirst { chapter.id == it.id }
|
|
||||||
return chapters
|
|
||||||
.subList(currChapterIndex, chapters.size)
|
|
||||||
.filterNot { it.read }
|
.filterNot { it.read }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun await(mangaId: Long, fromChapterId: Long): List<Chapter> {
|
||||||
|
val unreadChapters = await(mangaId)
|
||||||
|
val currChapterIndex = unreadChapters.indexOfFirst { it.id == fromChapterId }
|
||||||
|
return unreadChapters.subList(max(0, currChapterIndex), unreadChapters.size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import androidx.compose.animation.shrinkVertically
|
|||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
@ -174,6 +173,7 @@ private fun RowScope.Button(
|
|||||||
toConfirm: Boolean,
|
toConfirm: Boolean,
|
||||||
onLongClick: () -> Unit,
|
onLongClick: () -> Unit,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
|
content: (@Composable () -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
val animatedWeight by animateFloatAsState(if (toConfirm) 2f else 1f)
|
val animatedWeight by animateFloatAsState(if (toConfirm) 2f else 1f)
|
||||||
Column(
|
Column(
|
||||||
@ -205,6 +205,7 @@ private fun RowScope.Button(
|
|||||||
style = MaterialTheme.typography.labelSmall,
|
style = MaterialTheme.typography.labelSmall,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
content?.invoke()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,15 +275,14 @@ fun LibraryBottomActionMenu(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (onDownloadClicked != null) {
|
if (onDownloadClicked != null) {
|
||||||
Box {
|
|
||||||
var downloadExpanded by remember { mutableStateOf(false) }
|
var downloadExpanded by remember { mutableStateOf(false) }
|
||||||
this@Row.Button(
|
Button(
|
||||||
title = stringResource(R.string.action_download),
|
title = stringResource(R.string.action_download),
|
||||||
icon = Icons.Outlined.Download,
|
icon = Icons.Outlined.Download,
|
||||||
toConfirm = confirm[3],
|
toConfirm = confirm[3],
|
||||||
onLongClick = { onLongClickItem(3) },
|
onLongClick = { onLongClickItem(3) },
|
||||||
onClick = { downloadExpanded = !downloadExpanded },
|
onClick = { downloadExpanded = !downloadExpanded },
|
||||||
)
|
) {
|
||||||
val onDismissRequest = { downloadExpanded = false }
|
val onDismissRequest = { downloadExpanded = false }
|
||||||
DownloadDropdownMenu(
|
DownloadDropdownMenu(
|
||||||
expanded = downloadExpanded,
|
expanded = downloadExpanded,
|
||||||
|
@ -28,7 +28,6 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import eu.kanade.presentation.components.AppStateBanners
|
import eu.kanade.presentation.components.AppStateBanners
|
||||||
import eu.kanade.presentation.components.DownloadDropdownMenu
|
import eu.kanade.presentation.components.DownloadDropdownMenu
|
||||||
import eu.kanade.presentation.components.DropdownMenu
|
|
||||||
import eu.kanade.presentation.components.OverflowMenu
|
import eu.kanade.presentation.components.OverflowMenu
|
||||||
import eu.kanade.presentation.manga.DownloadAction
|
import eu.kanade.presentation.manga.DownloadAction
|
||||||
import eu.kanade.presentation.theme.active
|
import eu.kanade.presentation.theme.active
|
||||||
|
@ -17,10 +17,9 @@ import eu.kanade.domain.base.BasePreferences
|
|||||||
import eu.kanade.domain.category.interactor.GetCategories
|
import eu.kanade.domain.category.interactor.GetCategories
|
||||||
import eu.kanade.domain.category.interactor.SetMangaCategories
|
import eu.kanade.domain.category.interactor.SetMangaCategories
|
||||||
import eu.kanade.domain.category.model.Category
|
import eu.kanade.domain.category.model.Category
|
||||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
|
||||||
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
|
||||||
import eu.kanade.domain.chapter.model.toDbChapter
|
import eu.kanade.domain.chapter.model.toDbChapter
|
||||||
|
import eu.kanade.domain.history.interactor.GetNextUnreadChapters
|
||||||
import eu.kanade.domain.library.model.LibraryManga
|
import eu.kanade.domain.library.model.LibraryManga
|
||||||
import eu.kanade.domain.library.model.LibrarySort
|
import eu.kanade.domain.library.model.LibrarySort
|
||||||
import eu.kanade.domain.library.model.sort
|
import eu.kanade.domain.library.model.sort
|
||||||
@ -40,13 +39,11 @@ import eu.kanade.tachiyomi.data.cache.CoverCache
|
|||||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadCache
|
import eu.kanade.tachiyomi.data.download.DownloadCache
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
import eu.kanade.tachiyomi.util.chapter.getChapterSort
|
|
||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
||||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||||
@ -81,7 +78,7 @@ class LibraryPresenter(
|
|||||||
private val getLibraryManga: GetLibraryManga = Injekt.get(),
|
private val getLibraryManga: GetLibraryManga = Injekt.get(),
|
||||||
private val getTracksPerManga: GetTracksPerManga = Injekt.get(),
|
private val getTracksPerManga: GetTracksPerManga = Injekt.get(),
|
||||||
private val getCategories: GetCategories = Injekt.get(),
|
private val getCategories: GetCategories = Injekt.get(),
|
||||||
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
private val getNextUnreadChapters: GetNextUnreadChapters = Injekt.get(),
|
||||||
private val setReadStatus: SetReadStatus = Injekt.get(),
|
private val setReadStatus: SetReadStatus = Injekt.get(),
|
||||||
private val updateManga: UpdateManga = Injekt.get(),
|
private val updateManga: UpdateManga = Injekt.get(),
|
||||||
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
||||||
@ -404,25 +401,6 @@ class LibraryPresenter(
|
|||||||
return mangaCategories.flatten().distinct().subtract(common)
|
return mangaCategories.flatten().distinct().subtract(common)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shouldDownloadChapter(manga: Manga, chapter: Chapter): Boolean {
|
|
||||||
val activeDownload = downloadManager.queue.find { chapter.id == it.chapter.id }
|
|
||||||
val downloaded = downloadManager.isChapterDownloaded(chapter.name, chapter.scanlator, manga.title, manga.source)
|
|
||||||
val state = when {
|
|
||||||
activeDownload != null -> activeDownload.status
|
|
||||||
downloaded -> Download.State.DOWNLOADED
|
|
||||||
else -> Download.State.NOT_DOWNLOADED
|
|
||||||
}
|
|
||||||
return state == Download.State.NOT_DOWNLOADED
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getNotDownloadedUnreadChapters(manga: Manga): List<Chapter> {
|
|
||||||
return getChapterByMangaId.await(manga.id)
|
|
||||||
.filter { chapter ->
|
|
||||||
!chapter.read && shouldDownloadChapter(manga, chapter)
|
|
||||||
}
|
|
||||||
.sortedWith(getChapterSort(manga, sortDescending = false))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queues the amount specified of unread chapters from the list of mangas given.
|
* Queues the amount specified of unread chapters from the list of mangas given.
|
||||||
*
|
*
|
||||||
@ -432,10 +410,19 @@ class LibraryPresenter(
|
|||||||
fun downloadUnreadChapters(mangas: List<Manga>, amount: Int?) {
|
fun downloadUnreadChapters(mangas: List<Manga>, amount: Int?) {
|
||||||
presenterScope.launchNonCancellable {
|
presenterScope.launchNonCancellable {
|
||||||
mangas.forEach { manga ->
|
mangas.forEach { manga ->
|
||||||
val chapters = getNotDownloadedUnreadChapters(manga)
|
val chapters = getNextUnreadChapters.await(manga.id)
|
||||||
|
.filterNot { chapter ->
|
||||||
|
downloadManager.queue.any { chapter.id == it.chapter.id } ||
|
||||||
|
downloadManager.isChapterDownloaded(
|
||||||
|
chapter.name,
|
||||||
|
chapter.scanlator,
|
||||||
|
manga.title,
|
||||||
|
manga.source,
|
||||||
|
)
|
||||||
|
}
|
||||||
.let { if (amount != null) it.take(amount) else it }
|
.let { if (amount != null) it.take(amount) else it }
|
||||||
.map { it.toDbChapter() }
|
|
||||||
downloadManager.downloadChapters(manga, chapters)
|
downloadManager.downloadChapters(manga, chapters.map { it.toDbChapter() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user