Display total chapters on duplicates list items (#1963)
(cherry picked from commit 12abd9938b7c235d6a1c02391624703476c1f339) # Conflicts: # CHANGELOG.md # app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt # data/src/main/java/tachiyomi/data/manga/MangaMapper.kt
This commit is contained in:
parent
f1aed0d8b9
commit
5e0f730159
@ -3,6 +3,7 @@ package eu.kanade.presentation.manga
|
|||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
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.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
@ -63,10 +64,14 @@ import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
|
|||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
||||||
import tachiyomi.domain.source.model.StubSource
|
import tachiyomi.domain.source.model.StubSource
|
||||||
import tachiyomi.domain.source.service.SourceManager
|
import tachiyomi.domain.source.service.SourceManager
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
|
import tachiyomi.presentation.core.components.Badge
|
||||||
|
import tachiyomi.presentation.core.components.BadgeGroup
|
||||||
import tachiyomi.presentation.core.components.material.padding
|
import tachiyomi.presentation.core.components.material.padding
|
||||||
|
import tachiyomi.presentation.core.i18n.pluralStringResource
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
import tachiyomi.presentation.core.util.secondaryItemAlpha
|
import tachiyomi.presentation.core.util.secondaryItemAlpha
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
@ -74,7 +79,7 @@ import uy.kohesive.injekt.api.get
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DuplicateMangaDialog(
|
fun DuplicateMangaDialog(
|
||||||
duplicates: List<Manga>,
|
duplicates: List<MangaWithChapterCount>,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
onConfirm: () -> Unit,
|
onConfirm: () -> Unit,
|
||||||
onOpenManga: (manga: Manga) -> Unit,
|
onOpenManga: (manga: Manga) -> Unit,
|
||||||
@ -118,14 +123,14 @@ fun DuplicateMangaDialog(
|
|||||||
) {
|
) {
|
||||||
items(
|
items(
|
||||||
items = duplicates,
|
items = duplicates,
|
||||||
key = { it.id },
|
key = { it.manga.id },
|
||||||
) {
|
) {
|
||||||
DuplicateMangaListItem(
|
DuplicateMangaListItem(
|
||||||
manga = it,
|
duplicate = it,
|
||||||
getSource = { sourceManager.getOrStub(it.source) },
|
getSource = { sourceManager.getOrStub(it.manga.source) },
|
||||||
onMigrate = { onMigrate(it) },
|
onMigrate = { onMigrate(it.manga) },
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
onOpenManga = { onOpenManga(it) },
|
onOpenManga = { onOpenManga(it.manga) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,13 +170,14 @@ fun DuplicateMangaDialog(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DuplicateMangaListItem(
|
private fun DuplicateMangaListItem(
|
||||||
manga: Manga,
|
duplicate: MangaWithChapterCount,
|
||||||
getSource: () -> Source,
|
getSource: () -> Source,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
onOpenManga: () -> Unit,
|
onOpenManga: () -> Unit,
|
||||||
onMigrate: () -> Unit,
|
onMigrate: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val source = getSource()
|
val source = getSource()
|
||||||
|
val manga = duplicate.manga
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(MangaCardWidth)
|
.width(MangaCardWidth)
|
||||||
@ -186,6 +192,7 @@ private fun DuplicateMangaListItem(
|
|||||||
)
|
)
|
||||||
.padding(MaterialTheme.padding.small),
|
.padding(MaterialTheme.padding.small),
|
||||||
) {
|
) {
|
||||||
|
Box {
|
||||||
MangaCover.Book(
|
MangaCover.Book(
|
||||||
data = ImageRequest.Builder(LocalContext.current)
|
data = ImageRequest.Builder(LocalContext.current)
|
||||||
.data(manga)
|
.data(manga)
|
||||||
@ -193,6 +200,22 @@ private fun DuplicateMangaListItem(
|
|||||||
.build(),
|
.build(),
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
)
|
)
|
||||||
|
BadgeGroup(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(4.dp)
|
||||||
|
.align(Alignment.TopStart),
|
||||||
|
) {
|
||||||
|
Badge(
|
||||||
|
color = MaterialTheme.colorScheme.secondary,
|
||||||
|
textColor = MaterialTheme.colorScheme.onSecondary,
|
||||||
|
text = pluralStringResource(
|
||||||
|
MR.plurals.manga_num_chapters,
|
||||||
|
duplicate.chapterCount.toInt(),
|
||||||
|
duplicate.chapterCount,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(MaterialTheme.padding.extraSmall))
|
Spacer(modifier = Modifier.height(MaterialTheme.padding.extraSmall))
|
||||||
|
|
||||||
@ -292,7 +315,7 @@ private fun MangaDetailRow(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun getMaximumMangaCardHeight(duplicates: List<Manga>): Dp {
|
private fun getMaximumMangaCardHeight(duplicates: List<MangaWithChapterCount>): Dp {
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
val typography = MaterialTheme.typography
|
val typography = MaterialTheme.typography
|
||||||
val textMeasurer = rememberTextMeasurer()
|
val textMeasurer = rememberTextMeasurer()
|
||||||
@ -320,7 +343,7 @@ private fun getMaximumMangaCardHeight(duplicates: List<Manga>): Dp {
|
|||||||
) {
|
) {
|
||||||
duplicates.fastMaxOfOrNull {
|
duplicates.fastMaxOfOrNull {
|
||||||
calculateMangaCardHeight(
|
calculateMangaCardHeight(
|
||||||
manga = it,
|
manga = it.manga,
|
||||||
density = density,
|
density = density,
|
||||||
typography = typography,
|
typography = typography,
|
||||||
textMeasurer = textMeasurer,
|
textMeasurer = textMeasurer,
|
||||||
|
@ -65,6 +65,7 @@ import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga
|
|||||||
import tachiyomi.domain.manga.interactor.GetFlatMetadataById
|
import tachiyomi.domain.manga.interactor.GetFlatMetadataById
|
||||||
import tachiyomi.domain.manga.interactor.GetManga
|
import tachiyomi.domain.manga.interactor.GetManga
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
||||||
import tachiyomi.domain.manga.model.toMangaUpdate
|
import tachiyomi.domain.manga.model.toMangaUpdate
|
||||||
import tachiyomi.domain.source.interactor.DeleteSavedSearchById
|
import tachiyomi.domain.source.interactor.DeleteSavedSearchById
|
||||||
import tachiyomi.domain.source.interactor.GetRemoteManga
|
import tachiyomi.domain.source.interactor.GetRemoteManga
|
||||||
@ -393,7 +394,7 @@ open class BrowseSourceScreenModel(
|
|||||||
.orEmpty()
|
.orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getDuplicateLibraryManga(manga: Manga): List<Manga> {
|
suspend fun getDuplicateLibraryManga(manga: Manga): List<MangaWithChapterCount> {
|
||||||
return getDuplicateLibraryManga.invoke(manga)
|
return getDuplicateLibraryManga.invoke(manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,7 +445,7 @@ open class BrowseSourceScreenModel(
|
|||||||
sealed interface Dialog {
|
sealed interface Dialog {
|
||||||
data object Filter : Dialog
|
data object Filter : Dialog
|
||||||
data class RemoveManga(val manga: Manga) : Dialog
|
data class RemoveManga(val manga: Manga) : Dialog
|
||||||
data class AddDuplicateManga(val manga: Manga, val duplicates: List<Manga>) : Dialog
|
data class AddDuplicateManga(val manga: Manga, val duplicates: List<MangaWithChapterCount>) : Dialog
|
||||||
data class ChangeMangaCategory(
|
data class ChangeMangaCategory(
|
||||||
val manga: Manga,
|
val manga: Manga,
|
||||||
val initialSelection: ImmutableList<CheckboxState.State<Category>>,
|
val initialSelection: ImmutableList<CheckboxState.State<Category>>,
|
||||||
|
@ -40,6 +40,7 @@ import tachiyomi.domain.library.service.LibraryPreferences
|
|||||||
import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga
|
import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga
|
||||||
import tachiyomi.domain.manga.interactor.GetManga
|
import tachiyomi.domain.manga.interactor.GetManga
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
||||||
import tachiyomi.domain.source.service.SourceManager
|
import tachiyomi.domain.source.service.SourceManager
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
@ -246,7 +247,7 @@ class HistoryScreenModel(
|
|||||||
sealed interface Dialog {
|
sealed interface Dialog {
|
||||||
data object DeleteAll : Dialog
|
data object DeleteAll : Dialog
|
||||||
data class Delete(val history: HistoryWithRelations) : Dialog
|
data class Delete(val history: HistoryWithRelations) : Dialog
|
||||||
data class DuplicateManga(val manga: Manga, val duplicates: List<Manga>) : Dialog
|
data class DuplicateManga(val manga: Manga, val duplicates: List<MangaWithChapterCount>) : Dialog
|
||||||
data class ChangeCategory(
|
data class ChangeCategory(
|
||||||
val manga: Manga,
|
val manga: Manga,
|
||||||
val initialSelection: ImmutableList<CheckboxState<Category>>,
|
val initialSelection: ImmutableList<CheckboxState<Category>>,
|
||||||
|
@ -125,6 +125,7 @@ import tachiyomi.domain.manga.interactor.UpdateMergedSettings
|
|||||||
import tachiyomi.domain.manga.model.CustomMangaInfo
|
import tachiyomi.domain.manga.model.CustomMangaInfo
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.manga.model.MangaUpdate
|
import tachiyomi.domain.manga.model.MangaUpdate
|
||||||
|
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
||||||
import tachiyomi.domain.manga.model.MergeMangaSettingsUpdate
|
import tachiyomi.domain.manga.model.MergeMangaSettingsUpdate
|
||||||
import tachiyomi.domain.manga.model.MergedMangaReference
|
import tachiyomi.domain.manga.model.MergedMangaReference
|
||||||
import tachiyomi.domain.manga.model.applyFilter
|
import tachiyomi.domain.manga.model.applyFilter
|
||||||
@ -1653,7 +1654,7 @@ class MangaScreenModel(
|
|||||||
val initialSelection: ImmutableList<CheckboxState<Category>>,
|
val initialSelection: ImmutableList<CheckboxState<Category>>,
|
||||||
) : Dialog
|
) : Dialog
|
||||||
data class DeleteChapters(val chapters: List<Chapter>) : Dialog
|
data class DeleteChapters(val chapters: List<Chapter>) : Dialog
|
||||||
data class DuplicateManga(val manga: Manga, val duplicates: List<Manga>) : Dialog
|
data class DuplicateManga(val manga: Manga, val duplicates: List<MangaWithChapterCount>) : Dialog
|
||||||
|
|
||||||
/* SY -->
|
/* SY -->
|
||||||
data class Migrate(val newManga: Manga, val oldManga: Manga) : Dialog
|
data class Migrate(val newManga: Manga, val oldManga: Manga) : Dialog
|
||||||
|
@ -3,6 +3,7 @@ package tachiyomi.data.manga
|
|||||||
import eu.kanade.tachiyomi.source.model.UpdateStrategy
|
import eu.kanade.tachiyomi.source.model.UpdateStrategy
|
||||||
import tachiyomi.domain.library.model.LibraryManga
|
import tachiyomi.domain.library.model.LibraryManga
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
||||||
import tachiyomi.view.LibraryView
|
import tachiyomi.view.LibraryView
|
||||||
|
|
||||||
object MangaMapper {
|
object MangaMapper {
|
||||||
@ -143,6 +144,71 @@ object MangaMapper {
|
|||||||
lastRead = lastRead,
|
lastRead = lastRead,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun mapMangaWithChapterCount(
|
||||||
|
id: Long,
|
||||||
|
source: Long,
|
||||||
|
url: String,
|
||||||
|
artist: String?,
|
||||||
|
author: String?,
|
||||||
|
description: String?,
|
||||||
|
genre: List<String>?,
|
||||||
|
title: String,
|
||||||
|
status: Long,
|
||||||
|
thumbnailUrl: String?,
|
||||||
|
favorite: Boolean,
|
||||||
|
lastUpdate: Long?,
|
||||||
|
nextUpdate: Long?,
|
||||||
|
initialized: Boolean,
|
||||||
|
viewerFlags: Long,
|
||||||
|
chapterFlags: Long,
|
||||||
|
coverLastModified: Long,
|
||||||
|
dateAdded: Long,
|
||||||
|
// SY -->
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
|
filteredScanlators: String?,
|
||||||
|
// SY <--
|
||||||
|
updateStrategy: UpdateStrategy,
|
||||||
|
calculateInterval: Long,
|
||||||
|
lastModifiedAt: Long,
|
||||||
|
favoriteModifiedAt: Long?,
|
||||||
|
version: Long,
|
||||||
|
isSyncing: Long,
|
||||||
|
notes: String,
|
||||||
|
totalCount: Long,
|
||||||
|
): MangaWithChapterCount = MangaWithChapterCount(
|
||||||
|
manga = mapManga(
|
||||||
|
id,
|
||||||
|
source,
|
||||||
|
url,
|
||||||
|
artist,
|
||||||
|
author,
|
||||||
|
description,
|
||||||
|
genre,
|
||||||
|
title,
|
||||||
|
status,
|
||||||
|
thumbnailUrl,
|
||||||
|
favorite,
|
||||||
|
lastUpdate,
|
||||||
|
nextUpdate,
|
||||||
|
initialized,
|
||||||
|
viewerFlags,
|
||||||
|
chapterFlags,
|
||||||
|
coverLastModified,
|
||||||
|
dateAdded,
|
||||||
|
// SY -->
|
||||||
|
null,
|
||||||
|
// SY <--
|
||||||
|
updateStrategy,
|
||||||
|
calculateInterval,
|
||||||
|
lastModifiedAt,
|
||||||
|
favoriteModifiedAt,
|
||||||
|
version,
|
||||||
|
isSyncing,
|
||||||
|
notes,
|
||||||
|
),
|
||||||
|
chapterCount = totalCount,
|
||||||
|
)
|
||||||
|
|
||||||
fun mapLibraryView(libraryView: LibraryView): LibraryManga {
|
fun mapLibraryView(libraryView: LibraryView): LibraryManga {
|
||||||
return LibraryManga(
|
return LibraryManga(
|
||||||
manga = Manga(
|
manga = Manga(
|
||||||
|
@ -11,6 +11,7 @@ import tachiyomi.data.UpdateStrategyColumnAdapter
|
|||||||
import tachiyomi.domain.library.model.LibraryManga
|
import tachiyomi.domain.library.model.LibraryManga
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.manga.model.MangaUpdate
|
import tachiyomi.domain.manga.model.MangaUpdate
|
||||||
|
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
||||||
import tachiyomi.domain.manga.repository.MangaRepository
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
@ -73,9 +74,9 @@ class MangaRepositoryImpl(
|
|||||||
return handler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, MangaMapper::mapManga) }
|
return handler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, MangaMapper::mapManga) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getDuplicateLibraryManga(id: Long, title: String): List<Manga> {
|
override suspend fun getDuplicateLibraryManga(id: Long, title: String): List<MangaWithChapterCount> {
|
||||||
return handler.awaitList {
|
return handler.awaitList {
|
||||||
mangasQueries.getDuplicateLibraryManga(title, id, MangaMapper::mapManga)
|
mangasQueries.getDuplicateLibraryManga(id, title, MangaMapper::mapMangaWithChapterCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,11 +117,33 @@ WHERE favorite = 1
|
|||||||
AND source = :sourceId;
|
AND source = :sourceId;
|
||||||
|
|
||||||
getDuplicateLibraryManga:
|
getDuplicateLibraryManga:
|
||||||
|
WITH
|
||||||
|
duplicates AS (
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM mangas
|
FROM mangas
|
||||||
WHERE favorite = 1
|
WHERE favorite = 1
|
||||||
|
AND _id != :id
|
||||||
AND lower(title) LIKE '%' || lower(:title) || '%'
|
AND lower(title) LIKE '%' || lower(:title) || '%'
|
||||||
AND _id != :id;
|
),
|
||||||
|
chapter_counts AS (
|
||||||
|
SELECT
|
||||||
|
M._id AS manga_id,
|
||||||
|
count(*) AS chapter_count
|
||||||
|
FROM duplicates M
|
||||||
|
JOIN chapters C
|
||||||
|
ON M._id = C.manga_id
|
||||||
|
LEFT JOIN excluded_scanlators ES
|
||||||
|
ON C.manga_id = ES.manga_id
|
||||||
|
AND C.scanlator = ES.scanlator
|
||||||
|
WHERE ES.scanlator IS NULL
|
||||||
|
GROUP BY M._id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
M.*,
|
||||||
|
coalesce(CC.chapter_count, 0) AS chapter_count
|
||||||
|
FROM duplicates M
|
||||||
|
LEFT JOIN chapter_counts CC
|
||||||
|
ON M._id = CC.manga_id;
|
||||||
|
|
||||||
getUpcomingManga:
|
getUpcomingManga:
|
||||||
SELECT *
|
SELECT *
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package tachiyomi.domain.manga.interactor
|
package tachiyomi.domain.manga.interactor
|
||||||
|
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
||||||
import tachiyomi.domain.manga.repository.MangaRepository
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class GetDuplicateLibraryManga(
|
class GetDuplicateLibraryManga(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend operator fun invoke(manga: Manga): List<Manga> {
|
suspend operator fun invoke(manga: Manga): List<MangaWithChapterCount> {
|
||||||
return mangaRepository.getDuplicateLibraryManga(manga.id, manga.title.lowercase())
|
return mangaRepository.getDuplicateLibraryManga(manga.id, manga.title.lowercase())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package tachiyomi.domain.manga.model
|
||||||
|
|
||||||
|
data class MangaWithChapterCount(
|
||||||
|
val manga: Manga,
|
||||||
|
val chapterCount: Long,
|
||||||
|
)
|
@ -4,6 +4,7 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import tachiyomi.domain.library.model.LibraryManga
|
import tachiyomi.domain.library.model.LibraryManga
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.manga.model.MangaUpdate
|
import tachiyomi.domain.manga.model.MangaUpdate
|
||||||
|
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
||||||
|
|
||||||
interface MangaRepository {
|
interface MangaRepository {
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ interface MangaRepository {
|
|||||||
|
|
||||||
fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>>
|
fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>>
|
||||||
|
|
||||||
suspend fun getDuplicateLibraryManga(id: Long, title: String): List<Manga>
|
suspend fun getDuplicateLibraryManga(id: Long, title: String): List<MangaWithChapterCount>
|
||||||
|
|
||||||
suspend fun getUpcomingManga(statuses: Set<Long>): Flow<List<Manga>>
|
suspend fun getUpcomingManga(statuses: Set<Long>): Flow<List<Manga>>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user