Page preview jump to page in Reader

This commit is contained in:
Jobobby04 2022-11-06 00:33:11 -04:00
parent d5ee2905ee
commit c96efe1819
9 changed files with 78 additions and 18 deletions

View File

@ -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 <--
}

View File

@ -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,

View File

@ -192,6 +192,7 @@ class MangaController : FullComposeController<MangaPresenter> {
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<MangaPresenter> {
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 -->

View File

@ -127,10 +127,13 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
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<ReaderPresenter>() {
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) {

View File

@ -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<ViewerChapters> {
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(),

View File

@ -33,14 +33,14 @@ class ChapterLoader(
private val sourceManager: SourceManager,
private val mergedReferences: List<MergedMangaReference>,
private val mergedManga: Map<Long, Manga>,
// 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()

View File

@ -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<PagePreviewPresenter> {
@ -24,12 +25,20 @@ class PagePreviewController : FullComposeController<PagePreviewPresenter> {
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"
}

View File

@ -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<PagePreviewController>() {
@ -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()

View File

@ -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,
)
}
}