Add ability to hide transition page between chapters

This commit is contained in:
NerdNumber9 2019-04-12 22:59:49 -04:00
parent 8ccc3c8b0c
commit 8e9087226f
9 changed files with 113 additions and 25 deletions

View File

@ -178,4 +178,6 @@ object PreferenceKeys {
const val eh_autoSolveCaptchas = "eh_autosolve_captchas" const val eh_autoSolveCaptchas = "eh_autosolve_captchas"
const val eh_delegateSources = "eh_delegate_sources" const val eh_delegateSources = "eh_delegate_sources"
const val eh_showTransitionPages = "eh_show_transition_pages"
} }

View File

@ -251,4 +251,6 @@ class PreferencesHelper(val context: Context) {
fun eh_lastVersionCode() = rxPrefs.getInteger("eh_last_version_code", 0) fun eh_lastVersionCode() = rxPrefs.getInteger("eh_last_version_code", 0)
fun eh_savedSearches() = rxPrefs.getStringSet("eh_saved_searches", emptySet()) fun eh_savedSearches() = rxPrefs.getStringSet("eh_saved_searches", emptySet())
fun eh_showTransitionPages() = rxPrefs.getBoolean(Keys.eh_showTransitionPages, true)
} }

View File

@ -90,6 +90,9 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
private var autoscrollSubscription: Subscription? = null private var autoscrollSubscription: Subscription? = null
private val sourceManager: SourceManager by injectLazy() private val sourceManager: SourceManager by injectLazy()
private val prefs: PreferencesHelper by injectLazy()
val showTransitionPages by lazy { prefs.eh_showTransitionPages().getOrDefault() }
// <-- EH // <-- EH
/** /**
@ -167,9 +170,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
expand_eh_button.setImageResource(R.drawable.ic_keyboard_arrow_down_white_32dp) expand_eh_button.setImageResource(R.drawable.ic_keyboard_arrow_down_white_32dp)
} }
} }
// <-- EH
// --> EH
private fun setupAutoscroll(interval: Float) { private fun setupAutoscroll(interval: Float) {
exhSubscriptions.remove(autoscrollSubscription) exhSubscriptions.remove(autoscrollSubscription)
autoscrollSubscription = null autoscrollSubscription = null

View File

@ -32,7 +32,7 @@ import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
import java.util.Date import java.util.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
/** /**
@ -77,6 +77,10 @@ class ReaderPresenter(
*/ */
private val isLoadingAdjacentChapterRelay = BehaviorRelay.create<Boolean>() private val isLoadingAdjacentChapterRelay = BehaviorRelay.create<Boolean>()
// EXH -->
private var loadKey: String? = null
// EXH <--
/** /**
* Chapter list for the active manga. It's retrieved lazily and should be accessed for the first * Chapter list for the active manga. It's retrieved lazily and should be accessed for the first
* time in a background thread to avoid blocking the UI. * time in a background thread to avoid blocking the UI.
@ -211,7 +215,8 @@ class ReaderPresenter(
*/ */
private fun getLoadObservable( private fun getLoadObservable(
loader: ChapterLoader, loader: ChapterLoader,
chapter: ReaderChapter chapter: ReaderChapter,
requiredLoadKey: String? = null
): Observable<ViewerChapters> { ): Observable<ViewerChapters> {
return loader.loadChapter(chapter) return loader.loadChapter(chapter)
.andThen(Observable.fromCallable { .andThen(Observable.fromCallable {
@ -223,13 +228,20 @@ class ReaderPresenter(
}) })
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnNext { newChapters -> .doOnNext { newChapters ->
val oldChapters = viewerChaptersRelay.value
// Add new references first to avoid unnecessary recycling // Add new references first to avoid unnecessary recycling
newChapters.ref() newChapters.ref()
oldChapters?.unref()
viewerChaptersRelay.call(newChapters) // Ensure that we haven't made another load request in the meantime
if(requiredLoadKey == null || requiredLoadKey == loadKey) {
val oldChapters = viewerChaptersRelay.value
oldChapters?.unref()
viewerChaptersRelay.call(newChapters)
} else {
// Another load request has been made, our new chapters are useless :(
newChapters.unref()
}
} }
} }
@ -242,8 +254,11 @@ class ReaderPresenter(
Timber.d("Loading ${chapter.chapter.url}") Timber.d("Loading ${chapter.chapter.url}")
val newLoadKey = UUID.randomUUID().toString()
loadKey = newLoadKey
activeChapterSubscription?.unsubscribe() activeChapterSubscription?.unsubscribe()
activeChapterSubscription = getLoadObservable(loader, chapter) activeChapterSubscription = getLoadObservable(loader, chapter, newLoadKey)
.toCompletable() .toCompletable()
.onErrorComplete() .onErrorComplete()
.subscribe() .subscribe()

View File

@ -37,18 +37,18 @@ class ChapterLoader(
Timber.d("Loading pages for ${chapter.chapter.name}") Timber.d("Loading pages for ${chapter.chapter.name}")
val loader = getPageLoader(it) val loader = getPageLoader(it)
chapter.pageLoader = loader
loader.getPages().take(1).doOnNext { pages -> loader.getPages().take(1).doOnNext { pages ->
pages.forEach { it.chapter = chapter } pages.forEach { it.chapter = chapter }
} }.map { pages -> loader to pages }
} }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnNext { pages -> .doOnNext { (loader, pages) ->
if (pages.isEmpty()) { if (pages.isEmpty()) {
throw Exception("Page list is empty") throw Exception("Page list is empty")
} }
chapter.pageLoader = loader // Assign here to fix race with unref
chapter.state = ReaderChapter.State.Loaded(pages) chapter.state = ReaderChapter.State.Loaded(pages)
// If the chapter is partially read, set the starting page to the last the user read // If the chapter is partially read, set the starting page to the last the user read

View File

@ -9,6 +9,7 @@ import android.view.ViewGroup.LayoutParams
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
@ -41,6 +42,11 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
*/ */
/* [EXH] private */ var currentPage: Any? = null /* [EXH] private */ var currentPage: Any? = null
// EXH -->
private var nextChapter: ReaderChapter? = null
private var prevChapter: ReaderChapter? = null
// EXH <--
/** /**
* Viewer chapters to set when the pager enters idle mode. Otherwise, if the view was settling * Viewer chapters to set when the pager enters idle mode. Otherwise, if the view was settling
* or dragging, there'd be a noticeable and annoying jump. * or dragging, there'd be a noticeable and annoying jump.
@ -137,13 +143,21 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
Timber.d("onPageSelected: ${page.number}/${pages.size}") Timber.d("onPageSelected: ${page.number}/${pages.size}")
activity.onPageSelected(page) activity.onPageSelected(page)
if (page === pages.last()) { if (page === pages.last() || page === pages.getOrNull(pages.lastIndex - 1)) {
Timber.d("Request preload next chapter because we're at the last page") Timber.d("Request preload next chapter because we're at the last page")
val transition = adapter.items.getOrNull(position + 1) as? ChapterTransition.Next // EXH -->
if (transition?.to != null) { nextChapter?.let {
activity.requestPreloadChapter(transition.to) activity.requestPreloadChapter(it)
}
// EXH <--
}
// EXH -->
if(page === pages.first() || page === pages.getOrNull(1)) {
prevChapter?.let {
activity.requestPreloadChapter(it)
} }
} }
// EXH <--
} }
/** /**
@ -167,6 +181,11 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
* it sets the chapters immediately, otherwise they are saved and set when it becomes idle. * it sets the chapters immediately, otherwise they are saved and set when it becomes idle.
*/ */
override fun setChapters(chapters: ViewerChapters) { override fun setChapters(chapters: ViewerChapters) {
// EXH -->
nextChapter = chapters.nextChapter
prevChapter = chapters.prevChapter
// EXH <--
if (isIdle) { if (isIdle) {
setChaptersInternal(chapters) setChaptersInternal(chapters)
} else { } else {
@ -187,6 +206,12 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
val pages = chapters.currChapter.pages ?: return val pages = chapters.currChapter.pages ?: return
moveToPage(pages[chapters.currChapter.requestedPage]) moveToPage(pages[chapters.currChapter.requestedPage])
pager.visibility = View.VISIBLE pager.visibility = View.VISIBLE
} else {
// Trigger page change
val page = adapter.items.getOrNull(pager.currentItem)
if(page is ReaderPage) {
onPageSelected(page, pager.currentItem)
}
} }
} }
@ -197,7 +222,14 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
Timber.d("moveToPage") Timber.d("moveToPage")
val position = adapter.items.indexOf(page) val position = adapter.items.indexOf(page)
if (position != -1) { if (position != -1) {
pager.setCurrentItem(position, true) // EXH -->
if(position == pager.currentItem) {
// Invoke anyways to update seekbar
onPageSelected(page, position)
} else {
pager.setCurrentItem(position, true)
}
// EXH <--
} else { } else {
Timber.d("Page $page not found in adapter") Timber.d("Page $page not found in adapter")
} }

View File

@ -37,7 +37,13 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
newItems.addAll(prevPages.takeLast(2)) newItems.addAll(prevPages.takeLast(2))
} }
} }
newItems.add(ChapterTransition.Prev(chapters.currChapter, chapters.prevChapter)) // EXH -->
if(viewer.activity.showTransitionPages) {
// EXH <--
newItems.add(ChapterTransition.Prev(chapters.currChapter, chapters.prevChapter))
// EXH -->
}
// EXH <--
// Add current chapter. // Add current chapter.
val currPages = chapters.currChapter.pages val currPages = chapters.currChapter.pages
@ -46,7 +52,13 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
} }
// Add next chapter transition and pages. // Add next chapter transition and pages.
newItems.add(ChapterTransition.Next(chapters.currChapter, chapters.nextChapter)) // EXH -->
if(viewer.activity.showTransitionPages) {
// EXH <--
newItems.add(ChapterTransition.Next(chapters.currChapter, chapters.nextChapter))
// EXH -->
}
// EXH <--
if (chapters.nextChapter != null) { if (chapters.nextChapter != null) {
// Add at most two pages, because this chapter will be selected before the user can // Add at most two pages, because this chapter will be selected before the user can
// swap more pages. // swap more pages.

View File

@ -47,21 +47,22 @@ class WebtoonTransitionHolder(
gravity = Gravity.CENTER gravity = Gravity.CENTER
} }
private val layoutPaddingVertical = 48.dpToPx
private val layoutPaddingHorizontal = 32.dpToPx
init { init {
layout.layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT) layout.layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
layout.orientation = LinearLayout.VERTICAL layout.orientation = LinearLayout.VERTICAL
layout.gravity = Gravity.CENTER layout.gravity = Gravity.CENTER
val paddingVertical = 48.dpToPx
val paddingHorizontal = 32.dpToPx
layout.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical)
val childMargins = 16.dpToPx val childMargins = 16.dpToPx
val childParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply { val childParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
setMargins(0, childMargins, 0, childMargins) setMargins(0, childMargins, 0, childMargins)
} }
layout.addView(textView, childParams) if(viewer.activity.showTransitionPages) {
layout.addView(textView, childParams)
}
layout.addView(pagesContainer, childParams) layout.addView(pagesContainer, childParams)
} }
@ -88,6 +89,15 @@ class WebtoonTransitionHolder(
private fun bindNextChapterTransition(transition: ChapterTransition.Next) { private fun bindNextChapterTransition(transition: ChapterTransition.Next) {
val nextChapter = transition.to val nextChapter = transition.to
if(viewer.activity.showTransitionPages) {
layout.setPadding(
layoutPaddingHorizontal,
layoutPaddingVertical,
layoutPaddingHorizontal,
layoutPaddingVertical
)
}
textView.text = if (nextChapter != null) { textView.text = if (nextChapter != null) {
SpannableStringBuilder().apply { SpannableStringBuilder().apply {
append(context.getString(R.string.transition_finished)) append(context.getString(R.string.transition_finished))
@ -113,6 +123,13 @@ class WebtoonTransitionHolder(
private fun bindPrevChapterTransition(transition: ChapterTransition.Prev) { private fun bindPrevChapterTransition(transition: ChapterTransition.Prev) {
val prevChapter = transition.to val prevChapter = transition.to
layout.setPadding(
layoutPaddingHorizontal,
layoutPaddingVertical,
layoutPaddingHorizontal,
layoutPaddingVertical
)
textView.text = if (prevChapter != null) { textView.text = if (prevChapter != null) {
SpannableStringBuilder().apply { SpannableStringBuilder().apply {
append(context.getString(R.string.transition_current)) append(context.getString(R.string.transition_current))
@ -174,7 +191,9 @@ class WebtoonTransitionHolder(
setText(R.string.transition_pages_loading) setText(R.string.transition_pages_loading)
} }
pagesContainer.addView(progress) if(viewer.activity.showTransitionPages) {
pagesContainer.addView(progress)
}
pagesContainer.addView(textView) pagesContainer.addView(textView)
} }

View File

@ -148,6 +148,11 @@ class SettingsReaderController : SettingsController() {
title = "Preserve reading position on read manga" title = "Preserve reading position on read manga"
defaultValue = false defaultValue = false
} }
switchPreference {
key = Keys.eh_showTransitionPages
title = "Show transition pages between chapters"
defaultValue = true
}
// EXH <-- // EXH <--
preferenceCategory { preferenceCategory {
titleRes = R.string.pager_viewer titleRes = R.string.pager_viewer