From e7f6e16eababaf0baecf2aedc06f57f61ccefe25 Mon Sep 17 00:00:00 2001 From: Gfadebayo Date: Fri, 28 Jul 2023 16:00:06 +0100 Subject: [PATCH] Linked mangas added to manga detail screen --- .../kanade/presentation/manga/MangaScreen.kt | 18 +++++++++++++++ .../manga/MangaScreenConstants.kt | 1 + .../manga/components/MangaInfoHeader.kt | 22 +++++++++++++++++++ .../kanade/tachiyomi/ui/manga/MangaScreen.kt | 1 + .../tachiyomi/ui/manga/MangaScreenModel.kt | 13 +++++++++-- 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt index 2a1c9882a6..3b3e14ac3b 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt @@ -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 diff --git a/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt b/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt index 22a6664d0b..f473e58b90 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt @@ -15,6 +15,7 @@ enum class EditCoverAction { enum class MangaScreenItem { INFO_BOX, + LINKED_MANGAS, ACTION_ROW, DESCRIPTION_WITH_TAG, CHAPTER_HEADER, diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt b/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt index a66861a227..987b418202 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt @@ -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, + 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, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt index 33244db67e..7550911a66 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt @@ -131,6 +131,7 @@ class MangaScreen( onChapterSelected = screenModel::toggleSelection, onAllChapterSelected = screenModel::toggleAllSelection, onInvertSelection = screenModel::invertSelection, + onLinkedMangaClicked = { navigator.push(MangaScreen(it)) }, ) val onDismissRequest = { screenModel.dismissDialog() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt index cb8a6e5274..c29bd7644e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt @@ -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.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, + val links: List = emptyList(), val trackItems: List = emptyList(), val isRefreshingData: Boolean = false, val dialog: MangaInfoScreenModel.Dialog? = null,