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 059b9b508..b2d4fe8e9 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt @@ -124,6 +124,7 @@ fun MangaScreen( onMergedSettingsClicked: () -> Unit, onMergeClicked: () -> Unit, onMergeWithAnotherClicked: () -> Unit, + onOpenPagePreview: (Int) -> Unit, onMorePreviewsClicked: () -> Unit, // SY <-- @@ -165,6 +166,7 @@ fun MangaScreen( onMergedSettingsClicked = onMergedSettingsClicked, onMergeClicked = onMergeClicked, onMergeWithAnotherClicked = onMergeWithAnotherClicked, + onOpenPagePreview = onOpenPagePreview, onMorePreviewsClicked = onMorePreviewsClicked, // SY <-- onMultiBookmarkClicked = onMultiBookmarkClicked, @@ -202,6 +204,7 @@ fun MangaScreen( onMergedSettingsClicked = onMergedSettingsClicked, onMergeClicked = onMergeClicked, onMergeWithAnotherClicked = onMergeWithAnotherClicked, + onOpenPagePreview = onOpenPagePreview, onMorePreviewsClicked = onMorePreviewsClicked, // SY <-- onMultiBookmarkClicked = onMultiBookmarkClicked, @@ -246,6 +249,7 @@ private fun MangaScreenSmallImpl( onMergedSettingsClicked: () -> Unit, onMergeClicked: () -> Unit, onMergeWithAnotherClicked: () -> Unit, + onOpenPagePreview: (Int) -> Unit, onMorePreviewsClicked: () -> Unit, // SY <-- @@ -460,7 +464,11 @@ private fun MangaScreenSmallImpl( key = MangaScreenItem.CHAPTER_PREVIEW, contentType = MangaScreenItem.CHAPTER_PREVIEW, ) { - PagePreviews(state.pagePreviewsState, onMorePreviewsClicked) + PagePreviews( + pagePreviewState = state.pagePreviewsState, + onOpenPage = onOpenPagePreview, + onMorePreviewsClicked = onMorePreviewsClicked, + ) } } // SY <-- @@ -519,6 +527,7 @@ fun MangaScreenLargeImpl( onMergedSettingsClicked: () -> Unit, onMergeClicked: () -> Unit, onMergeWithAnotherClicked: () -> Unit, + onOpenPagePreview: (Int) -> Unit, onMorePreviewsClicked: () -> Unit, // SY <-- @@ -695,7 +704,11 @@ fun MangaScreenLargeImpl( ) } if (state.pagePreviewsState !is PagePreviewState.Unused) { - PagePreviews(state.pagePreviewsState, onMorePreviewsClicked) + PagePreviews( + pagePreviewState = state.pagePreviewsState, + onOpenPage = onOpenPagePreview, + onMorePreviewsClicked = onMorePreviewsClicked, + ) } // SY <-- } diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/PagePreviews.kt b/app/src/main/java/eu/kanade/presentation/manga/components/PagePreviews.kt index 9fbff606d..b7757f1b1 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/components/PagePreviews.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/components/PagePreviews.kt @@ -1,5 +1,6 @@ package eu.kanade.presentation.manga.components +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxWithConstraints @@ -29,7 +30,11 @@ import eu.kanade.tachiyomi.ui.manga.PagePreviewState import exh.util.floor @Composable -fun PagePreviews(pagePreviewState: PagePreviewState, onMorePreviewsClicked: () -> Unit) { +fun PagePreviews( + pagePreviewState: PagePreviewState, + onOpenPage: (Int) -> Unit, + onMorePreviewsClicked: () -> Unit, +) { when (pagePreviewState) { PagePreviewState.Loading -> { Box(modifier = Modifier.height(60.dp).fillMaxWidth(), contentAlignment = Alignment.Center) { @@ -52,6 +57,7 @@ fun PagePreviews(pagePreviewState: PagePreviewState, onMorePreviewsClicked: () - PagePreview( modifier = Modifier.weight(1F), page = page, + onOpenPage = onOpenPage, ) } } @@ -70,9 +76,11 @@ fun PagePreviews(pagePreviewState: PagePreviewState, onMorePreviewsClicked: () - fun PagePreview( modifier: Modifier, page: PagePreview, + onOpenPage: (Int) -> Unit, ) { Column( modifier + .clickable { onOpenPage(page.index - 1) } .padding(horizontal = 8.dp, vertical = 4.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.SpaceBetween, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt index 325eaccd3..a65ee753b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt @@ -192,6 +192,7 @@ class MangaController : FullComposeController { onMergedSettingsClicked = this::openMergedSettingsDialog, onMergeClicked = this::openSmartSearch, onMergeWithAnotherClicked = this::mergeWithAnother, + onOpenPagePreview = this::openPagePreview, onMorePreviewsClicked = this::openMorePagePreviews, // SY <-- onMultiBookmarkClicked = presenter::bookmarkChapters, @@ -369,6 +370,13 @@ class MangaController : FullComposeController { val manga = presenter.manga ?: return router.pushController(PagePreviewController(manga.id)) } + + private fun openPagePreview(page: Int) { + val chapter = presenter.getNextUnreadChapter() ?: return + activity?.run { + startActivity(ReaderActivity.newIntent(this, chapter.mangaId, chapter.id, page)) + } + } // SY <-- // EXH --> diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index c459c1879..d9a1df39a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -127,10 +127,13 @@ class ReaderActivity : BaseRxActivity() { companion object { - fun newIntent(context: Context, mangaId: Long?, chapterId: Long?): Intent { + fun newIntent(context: Context, mangaId: Long?, chapterId: Long?/* SY --> */, page: Int? = null/* SY <-- */): Intent { return Intent(context, ReaderActivity::class.java).apply { putExtra("manga", mangaId) putExtra("chapter", chapterId) + // SY --> + putExtra("page", page) + // SY <-- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) } } @@ -224,12 +227,15 @@ class ReaderActivity : BaseRxActivity() { if (presenter.needsInit()) { val manga = intent.extras!!.getLong("manga", -1) val chapter = intent.extras!!.getLong("chapter", -1) + // SY --> + val page = intent.extras!!.getInt("page", -1).takeUnless { it == -1 } + // SY <-- if (manga == -1L || chapter == -1L) { finish() return } NotificationReceiver.dismissNotification(this, manga.hashCode(), Notifications.ID_NEW_CHAPTERS) - presenter.init(manga, chapter) + presenter.init(manga, chapter /* SY --> */, page/* SY <-- */) } if (savedInstanceState != null) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index 853554ce7..a7674d3e8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -307,7 +307,7 @@ class ReaderPresenter( * Initializes this presenter with the given [mangaId] and [initialChapterId]. This method will * fetch the manga from the database and initialize the initial chapter. */ - fun init(mangaId: Long, initialChapterId: Long) { + fun init(mangaId: Long, initialChapterId: Long /* SY --> */, page: Int?/* SY <-- */) { if (!needsInit()) return presenterScope.launchIO { @@ -321,7 +321,7 @@ class ReaderPresenter( null } withUIContext { - init(manga.toDbManga(), initialChapterId, metadata) + init(manga.toDbManga(), initialChapterId, metadata, page) } // SY <-- } catch (e: Throwable) { @@ -334,7 +334,7 @@ class ReaderPresenter( * Initializes this presenter with the given [manga] and [initialChapterId]. This method will * set the chapter loader, view subscriptions and trigger an initial load. */ - private fun init(manga: Manga, initialChapterId: Long /* SY --> */, metadata: RaisedSearchMetadata?/* SY <-- */) { + private fun init(manga: Manga, initialChapterId: Long /* SY --> */, metadata: RaisedSearchMetadata?, page: Int?/* SY <-- */) { if (!needsInit()) return this.manga = manga @@ -359,7 +359,7 @@ class ReaderPresenter( activeChapterSubscription?.unsubscribe() activeChapterSubscription = Observable .fromCallable { chapterList.first { chapterId == it.chapter.id } } - .flatMap { getLoadObservable(loader!!, it) } + .flatMap { getLoadObservable(loader!!, it /* SY --> */, page/* SY <-- */) } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeFirst( @@ -402,8 +402,11 @@ class ReaderPresenter( private fun getLoadObservable( loader: ChapterLoader, chapter: ReaderChapter, + // SY --> + page: Int? = null, + // SY <-- ): Observable { - return loader.loadChapter(chapter) + return loader.loadChapter(chapter /* SY --> */, page/* SY <-- */) .andThen( Observable.fromCallable { val chapterPos = chapterList.indexOf(chapter) @@ -535,7 +538,7 @@ class ReaderPresenter( selectedChapter.chapter.read = true // SY --> if (manga?.isEhBasedManga() == true) { - launchIO { + presenterScope.launchNonCancellable { chapterList .filter { it.chapter.source_order > selectedChapter.chapter.source_order } .onEach { @@ -733,7 +736,7 @@ class ReaderPresenter( fun toggleBookmark(chapterId: Long, bookmarked: Boolean) { val chapter = chapterList.find { it.chapter.id == chapterId }?.chapter ?: return chapter.bookmark = bookmarked - launchIO { + presenterScope.launchNonCancellable { updateChapter.await( ChapterUpdate( id = chapter.id!!.toLong(), diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt index 28e95ed15..1f4950164 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt @@ -33,14 +33,14 @@ class ChapterLoader( private val sourceManager: SourceManager, private val mergedReferences: List, private val mergedManga: Map, -// SY <-- + // SY <-- ) { /** * Returns a completable that assigns the page loader and loads the its pages. It just * completes if the chapter is already loaded. */ - fun loadChapter(chapter: ReaderChapter): Completable { + fun loadChapter(chapter: ReaderChapter /* SY --> */, page: Int? = null/* SY <-- */): Completable { if (chapterIsReady(chapter)) { return Completable.complete() } @@ -71,9 +71,9 @@ class ChapterLoader( // otherwise use the requested page. if (!chapter.chapter.read /* --> EH */ || readerPrefs .preserveReadingPosition() - .get() // <-- EH + .get() || page != null // <-- EH ) { - chapter.requestedPage = chapter.chapter.last_page_read + chapter.requestedPage = /* SY --> */ page ?: /* SY <-- */ chapter.chapter.last_page_read } } .toCompletable() diff --git a/app/src/main/java/exh/pagepreview/PagePreviewController.kt b/app/src/main/java/exh/pagepreview/PagePreviewController.kt index 0e0baad2a..604aa1942 100644 --- a/app/src/main/java/exh/pagepreview/PagePreviewController.kt +++ b/app/src/main/java/exh/pagepreview/PagePreviewController.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.core.os.bundleOf import eu.kanade.tachiyomi.ui.base.controller.FullComposeController +import eu.kanade.tachiyomi.ui.reader.ReaderActivity import exh.pagepreview.components.PagePreviewScreen class PagePreviewController : FullComposeController { @@ -24,12 +25,20 @@ class PagePreviewController : FullComposeController { state = presenter.state.collectAsState().value, pageDialogOpen = presenter.pageDialogOpen, onPageSelected = presenter::moveToPage, + onOpenPage = this::openPage, onOpenPageDialog = { presenter.pageDialogOpen = true }, onDismissPageDialog = { presenter.pageDialogOpen = false }, navigateUp = router::popCurrentController, ) } + fun openPage(page: Int) { + val state = presenter.state.value as? PagePreviewState.Success ?: return + activity?.run { + startActivity(ReaderActivity.newIntent(this, state.manga.id, state.chapter.id, page)) + } + } + companion object { const val MANGA_ID = "manga_id" } diff --git a/app/src/main/java/exh/pagepreview/PagePreviewPresenter.kt b/app/src/main/java/exh/pagepreview/PagePreviewPresenter.kt index 74e057a3a..11281f4f7 100644 --- a/app/src/main/java/exh/pagepreview/PagePreviewPresenter.kt +++ b/app/src/main/java/exh/pagepreview/PagePreviewPresenter.kt @@ -4,6 +4,8 @@ import android.os.Bundle import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue +import eu.kanade.domain.chapter.model.Chapter +import eu.kanade.domain.history.interactor.GetNextUnreadChapters import eu.kanade.domain.manga.interactor.GetManga import eu.kanade.domain.manga.interactor.GetPagePreviews import eu.kanade.domain.manga.model.Manga @@ -12,7 +14,6 @@ import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.util.lang.launchIO -import eu.kanade.tachiyomi.util.system.logcat import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch @@ -26,6 +27,7 @@ class PagePreviewPresenter( private val mangaId: Long, private val getPagePreviews: GetPagePreviews = Injekt.get(), private val getManga: GetManga = Injekt.get(), + private val getNextUnreadChapters: GetNextUnreadChapters = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(), ) : BasePresenter() { @@ -41,6 +43,13 @@ class PagePreviewPresenter( presenterScope.launchIO { val manga = getManga.await(mangaId)!! + val chapter = getNextUnreadChapters.await(mangaId).firstOrNull() + if (chapter == null) { + _state.update { + PagePreviewState.Error(Exception("No chapters found")) + } + return@launchIO + } val source = sourceManager.getOrStub(manga.source) page .onEach { page -> @@ -59,6 +68,7 @@ class PagePreviewPresenter( previews.hasNextPage, previews.pageCount, manga, + chapter, source, ) } @@ -67,7 +77,7 @@ class PagePreviewPresenter( pagePreviews = previews.pagePreviews, hasNextPage = previews.hasNextPage, pageCount = previews.pageCount, - ).also { logcat { page.toString() } } + ) } } GetPagePreviews.Result.Unused -> Unit @@ -96,6 +106,7 @@ sealed class PagePreviewState { val hasNextPage: Boolean, val pageCount: Int?, val manga: Manga, + val chapter: Chapter, val source: Source, ) : PagePreviewState() diff --git a/app/src/main/java/exh/pagepreview/components/PagePreviewScreen.kt b/app/src/main/java/exh/pagepreview/components/PagePreviewScreen.kt index bcd845268..db519b52a 100644 --- a/app/src/main/java/exh/pagepreview/components/PagePreviewScreen.kt +++ b/app/src/main/java/exh/pagepreview/components/PagePreviewScreen.kt @@ -48,6 +48,7 @@ fun PagePreviewScreen( state: PagePreviewState, pageDialogOpen: Boolean, onPageSelected: (Int) -> Unit, + onOpenPage: (Int) -> Unit, onOpenPageDialog: () -> Unit, onDismissPageDialog: () -> Unit, navigateUp: () -> Unit, @@ -89,6 +90,7 @@ fun PagePreviewScreen( PagePreview( modifier = Modifier.weight(1F), page = page, + onOpenPage = onOpenPage, ) } }