Linked mangas added to manga detail screen
This commit is contained in:
parent
a5883b24b5
commit
e7f6e16eab
5 changed files with 53 additions and 2 deletions
|
@ -56,6 +56,7 @@ import eu.kanade.presentation.manga.components.MangaActionRow
|
|||
import eu.kanade.presentation.manga.components.MangaBottomActionMenu
|
||||
import eu.kanade.presentation.manga.components.MangaChapterListItem
|
||||
import eu.kanade.presentation.manga.components.MangaInfoBox
|
||||
import eu.kanade.presentation.manga.components.MangaLinkLayout
|
||||
import eu.kanade.presentation.manga.components.MangaToolbar
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.download.model.Download
|
||||
|
@ -127,6 +128,8 @@ fun MangaScreen(
|
|||
onChapterSelected: (ChapterItem, Boolean, Boolean, Boolean) -> Unit,
|
||||
onAllChapterSelected: (Boolean) -> Unit,
|
||||
onInvertSelection: () -> Unit,
|
||||
|
||||
onLinkedMangaClicked: (Long) -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val onCopyTagToClipboard: (tag: String) -> Unit = {
|
||||
|
@ -169,6 +172,7 @@ fun MangaScreen(
|
|||
onChapterSelected = onChapterSelected,
|
||||
onAllChapterSelected = onAllChapterSelected,
|
||||
onInvertSelection = onInvertSelection,
|
||||
onLinkedMangaClicked = onLinkedMangaClicked,
|
||||
)
|
||||
} else {
|
||||
MangaScreenLargeImpl(
|
||||
|
@ -204,6 +208,7 @@ fun MangaScreen(
|
|||
onChapterSelected = onChapterSelected,
|
||||
onAllChapterSelected = onAllChapterSelected,
|
||||
onInvertSelection = onInvertSelection,
|
||||
onLinkedMangaClicked = onLinkedMangaClicked,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -255,6 +260,8 @@ private fun MangaScreenSmallImpl(
|
|||
onChapterSelected: (ChapterItem, Boolean, Boolean, Boolean) -> Unit,
|
||||
onAllChapterSelected: (Boolean) -> Unit,
|
||||
onInvertSelection: () -> Unit,
|
||||
|
||||
onLinkedMangaClicked: (Long) -> Unit,
|
||||
) {
|
||||
val chapterListState = rememberLazyListState()
|
||||
|
||||
|
@ -376,6 +383,15 @@ private fun MangaScreenSmallImpl(
|
|||
)
|
||||
}
|
||||
|
||||
if (state.links.isNotEmpty()) {
|
||||
item(
|
||||
key = MangaScreenItem.LINKED_MANGAS,
|
||||
contentType = MangaScreenItem.LINKED_MANGAS,
|
||||
) {
|
||||
MangaLinkLayout(links = state.links, onLinkClicked = onLinkedMangaClicked)
|
||||
}
|
||||
}
|
||||
|
||||
item(
|
||||
key = MangaScreenItem.ACTION_ROW,
|
||||
contentType = MangaScreenItem.ACTION_ROW,
|
||||
|
@ -481,6 +497,8 @@ fun MangaScreenLargeImpl(
|
|||
onChapterSelected: (ChapterItem, Boolean, Boolean, Boolean) -> Unit,
|
||||
onAllChapterSelected: (Boolean) -> Unit,
|
||||
onInvertSelection: () -> Unit,
|
||||
|
||||
onLinkedMangaClicked: (Long) -> Unit,
|
||||
) {
|
||||
val layoutDirection = LocalLayoutDirection.current
|
||||
val density = LocalDensity.current
|
||||
|
|
|
@ -15,6 +15,7 @@ enum class EditCoverAction {
|
|||
|
||||
enum class MangaScreenItem {
|
||||
INFO_BOX,
|
||||
LINKED_MANGAS,
|
||||
ACTION_ROW,
|
||||
DESCRIPTION_WITH_TAG,
|
||||
CHAPTER_HEADER,
|
||||
|
|
|
@ -78,6 +78,7 @@ import eu.kanade.presentation.components.DropdownMenu
|
|||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import tachiyomi.domain.link.model.LinkedManga
|
||||
import tachiyomi.domain.manga.model.Manga
|
||||
import tachiyomi.presentation.core.components.material.TextButton
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
|
@ -207,6 +208,27 @@ fun MangaActionRow(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MangaLinkLayout(
|
||||
modifier: Modifier = Modifier,
|
||||
links: List<LinkedManga>,
|
||||
onLinkClicked: (Long) -> Unit,
|
||||
) {
|
||||
FlowRow(
|
||||
modifier = modifier.padding(start = 16.dp, top = 8.dp, end = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
for (link in links) {
|
||||
MangaCover.Book(
|
||||
modifier = Modifier.sizeIn(maxWidth = 48.dp),
|
||||
data = link.thumbnailUrl,
|
||||
onClick = { onLinkClicked(link.id) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ExpandableMangaDescription(
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
|
@ -131,6 +131,7 @@ class MangaScreen(
|
|||
onChapterSelected = screenModel::toggleSelection,
|
||||
onAllChapterSelected = screenModel::toggleAllSelection,
|
||||
onInvertSelection = screenModel::invertSelection,
|
||||
onLinkedMangaClicked = { navigator.push(MangaScreen(it)) },
|
||||
)
|
||||
|
||||
val onDismissRequest = { screenModel.dismissDialog() }
|
||||
|
|
|
@ -64,6 +64,8 @@ import tachiyomi.domain.chapter.model.NoChaptersException
|
|||
import tachiyomi.domain.chapter.service.getChapterSort
|
||||
import tachiyomi.domain.download.service.DownloadPreferences
|
||||
import tachiyomi.domain.library.service.LibraryPreferences
|
||||
import tachiyomi.domain.link.interactor.GetLinkedMangas
|
||||
import tachiyomi.domain.link.model.LinkedManga
|
||||
import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga
|
||||
import tachiyomi.domain.manga.interactor.GetMangaWithChapters
|
||||
import tachiyomi.domain.manga.interactor.SetMangaChapterFlags
|
||||
|
@ -99,6 +101,7 @@ class MangaInfoScreenModel(
|
|||
private val getCategories: GetCategories = Injekt.get(),
|
||||
private val getTracks: GetTracks = Injekt.get(),
|
||||
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
||||
private val getLink: GetLinkedMangas = Injekt.get(),
|
||||
val snackbarHostState: SnackbarHostState = SnackbarHostState(),
|
||||
) : StateScreenModel<MangaScreenState>(MangaScreenState.Loading) {
|
||||
|
||||
|
@ -148,14 +151,16 @@ class MangaInfoScreenModel(
|
|||
coroutineScope.launchIO {
|
||||
combine(
|
||||
getMangaAndChapters.subscribe(mangaId).distinctUntilChanged(),
|
||||
getLink.subscribe(mangaId),
|
||||
downloadCache.changes,
|
||||
downloadManager.queueState,
|
||||
) { mangaAndChapters, _, _ -> mangaAndChapters }
|
||||
.collectLatest { (manga, chapters) ->
|
||||
) { mangaAndChapters, links, _, _ -> Triple(mangaAndChapters.first, mangaAndChapters.second, links) }
|
||||
.collectLatest { (manga, chapters, links) ->
|
||||
updateSuccessState {
|
||||
it.copy(
|
||||
manga = manga,
|
||||
chapters = chapters.toChapterItems(manga),
|
||||
links = links,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -168,6 +173,8 @@ class MangaInfoScreenModel(
|
|||
val chapters = getMangaAndChapters.awaitChapters(mangaId)
|
||||
.toChapterItems(manga)
|
||||
|
||||
val links = getLink.await(mangaId)
|
||||
|
||||
if (!manga.favorite) {
|
||||
setMangaDefaultChapterFlags.await(manga)
|
||||
}
|
||||
|
@ -184,6 +191,7 @@ class MangaInfoScreenModel(
|
|||
chapters = chapters,
|
||||
isRefreshingData = needRefreshInfo || needRefreshChapter,
|
||||
dialog = null,
|
||||
links = links,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -982,6 +990,7 @@ sealed class MangaScreenState {
|
|||
val source: Source,
|
||||
val isFromSource: Boolean,
|
||||
val chapters: List<ChapterItem>,
|
||||
val links: List<LinkedManga> = emptyList(),
|
||||
val trackItems: List<TrackItem> = emptyList(),
|
||||
val isRefreshingData: Boolean = false,
|
||||
val dialog: MangaInfoScreenModel.Dialog? = null,
|
||||
|
|
Reference in a new issue