mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
replace subscription with job in PagerPageHolder
also more fixes to the auto shifting
This commit is contained in:
parent
d93f9d6a45
commit
6872616db5
4 changed files with 109 additions and 115 deletions
|
@ -208,6 +208,8 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
|
||||||
private var indexChapterToShift: Long? = null
|
private var indexChapterToShift: Long? = null
|
||||||
|
|
||||||
private var lastCropRes = 0
|
private var lastCropRes = 0
|
||||||
|
var manuallyShiftedPages = false
|
||||||
|
private set
|
||||||
|
|
||||||
val isSplitScreen: Boolean
|
val isSplitScreen: Boolean
|
||||||
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInMultiWindowMode
|
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInMultiWindowMode
|
||||||
|
@ -593,6 +595,7 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_shift_double_page -> {
|
R.id.action_shift_double_page -> {
|
||||||
shiftDoublePages()
|
shiftDoublePages()
|
||||||
|
manuallyShiftedPages = true
|
||||||
}
|
}
|
||||||
else -> return super.onOptionsItemSelected(item)
|
else -> return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
@ -600,12 +603,13 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shiftDoublePages(forceShift: Boolean? = null, page: ReaderPage? = null) {
|
fun shiftDoublePages(forceShift: Boolean? = null, page: ReaderPage? = null) {
|
||||||
(viewer as? PagerViewer)?.config?.let { config ->
|
(viewer as? PagerViewer)?.let { pViewer ->
|
||||||
if (forceShift == config.shiftDoublePage) return
|
if (forceShift == pViewer.config.shiftDoublePage) return
|
||||||
config.shiftDoublePage = !config.shiftDoublePage
|
if (page != null && pViewer.getShiftedPage() == page) return
|
||||||
|
pViewer.config.shiftDoublePage = !pViewer.config.shiftDoublePage
|
||||||
viewModel.state.value.viewerChapters?.let {
|
viewModel.state.value.viewerChapters?.let {
|
||||||
(viewer as? PagerViewer)?.updateShifting(page)
|
pViewer.updateShifting(page)
|
||||||
(viewer as? PagerViewer)?.setChaptersDoubleShift(it)
|
pViewer.setChaptersDoubleShift(it)
|
||||||
invalidateOptionsMenu()
|
invalidateOptionsMenu()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -821,6 +825,7 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
|
||||||
|
|
||||||
binding.chaptersSheet.shiftPageButton.setOnClickListener {
|
binding.chaptersSheet.shiftPageButton.setOnClickListener {
|
||||||
shiftDoublePages()
|
shiftDoublePages()
|
||||||
|
manuallyShiftedPages = true
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.readerNav.leftChapter.setOnClickListener { loadAdjacentChapter(false) }
|
binding.readerNav.leftChapter.setOnClickListener { loadAdjacentChapter(false) }
|
||||||
|
@ -1303,6 +1308,9 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
|
||||||
binding.chaptersSheet.root.sheetBehavior.isCollapsed() -> View.VISIBLE
|
binding.chaptersSheet.root.sheetBehavior.isCollapsed() -> View.VISIBLE
|
||||||
else -> View.INVISIBLE
|
else -> View.INVISIBLE
|
||||||
}
|
}
|
||||||
|
if (lastShiftDoubleState == null) {
|
||||||
|
manuallyShiftedPages = false
|
||||||
|
}
|
||||||
lastShiftDoubleState = null
|
lastShiftDoubleState = null
|
||||||
viewer?.setChapters(viewerChapters)
|
viewer?.setChapters(viewerChapters)
|
||||||
intentPageNumber?.let { moveToPageIndex(it) }
|
intentPageNumber?.let { moveToPageIndex(it) }
|
||||||
|
|
|
@ -33,22 +33,21 @@ import eu.kanade.tachiyomi.util.system.bottomCutoutInset
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
import eu.kanade.tachiyomi.util.system.isInNightMode
|
import eu.kanade.tachiyomi.util.system.isInNightMode
|
||||||
|
import eu.kanade.tachiyomi.util.system.launchIO
|
||||||
import eu.kanade.tachiyomi.util.system.launchUI
|
import eu.kanade.tachiyomi.util.system.launchUI
|
||||||
import eu.kanade.tachiyomi.util.system.topCutoutInset
|
import eu.kanade.tachiyomi.util.system.topCutoutInset
|
||||||
|
import eu.kanade.tachiyomi.util.system.withIOContext
|
||||||
|
import eu.kanade.tachiyomi.util.system.withUIContext
|
||||||
import eu.kanade.tachiyomi.util.view.backgroundColor
|
import eu.kanade.tachiyomi.util.view.backgroundColor
|
||||||
import eu.kanade.tachiyomi.util.view.isVisibleOnScreen
|
import eu.kanade.tachiyomi.util.view.isVisibleOnScreen
|
||||||
import eu.kanade.tachiyomi.widget.ViewPagerAdapter
|
import eu.kanade.tachiyomi.widget.ViewPagerAdapter
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Dispatchers.Default
|
import kotlinx.coroutines.Dispatchers.Default
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.MainScope
|
import kotlinx.coroutines.MainScope
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import rx.Observable
|
|
||||||
import rx.Subscription
|
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
|
||||||
import rx.schedulers.Schedulers
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
@ -117,10 +116,10 @@ class PagerPageHolder(
|
||||||
private var extraProgressJob: Job? = null
|
private var extraProgressJob: Job? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscription used to read the header of the image. This is needed in order to instantiate
|
* Job used to read the header of the image. This is needed in order to instantiate
|
||||||
* the appropiate image view depending if the image is animated (GIF).
|
* the appropriate image view depending if the image is animated (GIF).
|
||||||
*/
|
*/
|
||||||
private var readImageHeaderSubscription: Subscription? = null
|
private var readImageHeaderJob: Job? = null
|
||||||
|
|
||||||
private var status = Page.State.READY
|
private var status = Page.State.READY
|
||||||
private var extraStatus = Page.State.READY
|
private var extraStatus = Page.State.READY
|
||||||
|
@ -197,7 +196,7 @@ class PagerPageHolder(
|
||||||
cancelLoadJob(1)
|
cancelLoadJob(1)
|
||||||
cancelProgressJob(2)
|
cancelProgressJob(2)
|
||||||
cancelLoadJob(2)
|
cancelLoadJob(2)
|
||||||
unsubscribeReadImageHeader()
|
cancelReadImageHeader()
|
||||||
(pageView as? SubsamplingScaleImageView)?.setOnImageEventListener(null)
|
(pageView as? SubsamplingScaleImageView)?.setOnImageEventListener(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,9 +441,9 @@ class PagerPageHolder(
|
||||||
/**
|
/**
|
||||||
* Unsubscribes from the read image header subscription.
|
* Unsubscribes from the read image header subscription.
|
||||||
*/
|
*/
|
||||||
private fun unsubscribeReadImageHeader() {
|
private fun cancelReadImageHeader() {
|
||||||
readImageHeaderSubscription?.unsubscribe()
|
readImageHeaderJob?.cancel()
|
||||||
readImageHeaderSubscription = null
|
readImageHeaderJob = null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -487,40 +486,35 @@ class PagerPageHolder(
|
||||||
retryButton?.isVisible = false
|
retryButton?.isVisible = false
|
||||||
decodeErrorLayout?.isVisible = false
|
decodeErrorLayout?.isVisible = false
|
||||||
|
|
||||||
unsubscribeReadImageHeader()
|
cancelReadImageHeader()
|
||||||
val streamFn = page.stream ?: return
|
val streamFn = page.stream ?: return
|
||||||
val streamFn2 = extraPage?.stream
|
val streamFn2 = extraPage?.stream
|
||||||
|
|
||||||
var openStream: InputStream? = null
|
var openStream: InputStream? = null
|
||||||
|
|
||||||
readImageHeaderSubscription = Observable
|
readImageHeaderJob = scope.launchIO {
|
||||||
.fromCallable {
|
try {
|
||||||
val stream = streamFn().buffered(16)
|
val stream = streamFn().buffered(16)
|
||||||
|
|
||||||
val stream2 = streamFn2?.invoke()?.buffered(16)
|
val stream2 = streamFn2?.invoke()?.buffered(16)
|
||||||
openStream = this@PagerPageHolder.mergeOrSplitPages(stream, stream2)
|
openStream = this@PagerPageHolder.mergeOrSplitPages(stream, stream2)
|
||||||
ImageUtil.isAnimatedAndSupported(stream) ||
|
val isAnimated = ImageUtil.isAnimatedAndSupported(stream) ||
|
||||||
if (stream2 != null) ImageUtil.isAnimatedAndSupported(stream2) else false
|
(stream2?.let { ImageUtil.isAnimatedAndSupported(stream2) } ?: false)
|
||||||
}
|
withUIContext {
|
||||||
.subscribeOn(Schedulers.io())
|
if (!isAnimated) {
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
if (viewer.config.readerTheme >= 2) {
|
||||||
.doOnNext { isAnimated ->
|
val bgType = getBGType(viewer.config.readerTheme, context)
|
||||||
if (!isAnimated) {
|
if (page.bg != null && page.bgType == bgType) {
|
||||||
if (viewer.config.readerTheme >= 2) {
|
setImage(openStream!!, false, imageConfig)
|
||||||
if (page.bg != null &&
|
pageView?.background = page.bg
|
||||||
page.bgType == getBGType(viewer.config.readerTheme, context) + item.hashCode()
|
}
|
||||||
) {
|
// if the user switches to automatic when pages are already cached, the bg needs to be loaded
|
||||||
setImage(openStream!!, false, imageConfig)
|
else {
|
||||||
pageView?.background = page.bg
|
val bytesArray = openStream!!.readBytes()
|
||||||
}
|
val bytesStream = bytesArray.inputStream()
|
||||||
// if the user switches to automatic when pages are already cached, the bg needs to be loaded
|
setImage(bytesStream, false, imageConfig)
|
||||||
else {
|
closeStreams(bytesStream)
|
||||||
val bytesArray = openStream!!.readBytes()
|
|
||||||
val bytesStream = bytesArray.inputStream()
|
|
||||||
setImage(bytesStream, false, imageConfig)
|
|
||||||
bytesStream.close()
|
|
||||||
|
|
||||||
scope.launchUI {
|
|
||||||
try {
|
try {
|
||||||
pageView?.background = setBG(bytesArray)
|
pageView?.background = setBG(bytesArray)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -528,36 +522,26 @@ class PagerPageHolder(
|
||||||
pageView?.background = ColorDrawable(Color.WHITE)
|
pageView?.background = ColorDrawable(Color.WHITE)
|
||||||
} finally {
|
} finally {
|
||||||
page.bg = pageView?.background
|
page.bg = pageView?.background
|
||||||
page.bgType = getBGType(
|
page.bgType = bgType
|
||||||
viewer.config.readerTheme,
|
|
||||||
context,
|
|
||||||
) + item.hashCode()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setImage(openStream!!, false, imageConfig)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setImage(openStream!!, false, imageConfig)
|
setImage(openStream!!, true, imageConfig)
|
||||||
}
|
if (viewer.config.readerTheme >= 2 && page.bg != null) {
|
||||||
} else {
|
pageView?.background = page.bg
|
||||||
setImage(openStream!!, true, imageConfig)
|
}
|
||||||
if (viewer.config.readerTheme >= 2 && page.bg != null) {
|
|
||||||
pageView?.background = page.bg
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (_: Exception) {
|
||||||
// Keep the Rx stream alive to close the input stream only when unsubscribed
|
|
||||||
.flatMap { Observable.never<Unit>() }
|
|
||||||
.doOnUnsubscribe {
|
|
||||||
try {
|
try {
|
||||||
openStream?.close()
|
openStream?.let { closeStreams(it) }
|
||||||
} catch (_: Exception) {}
|
} catch (_: Exception) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.doOnError {
|
}
|
||||||
try {
|
|
||||||
openStream?.close()
|
|
||||||
} catch (_: Exception) {}
|
|
||||||
}
|
|
||||||
.subscribe({}, {})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val imageConfig: Config
|
private val imageConfig: Config
|
||||||
|
@ -716,18 +700,16 @@ class PagerPageHolder(
|
||||||
return decodeLayout
|
return decodeLayout
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mergeOrSplitPages(imageStream: InputStream, imageStream2: InputStream?): InputStream {
|
private suspend fun mergeOrSplitPages(imageStream: InputStream, imageStream2: InputStream?): InputStream {
|
||||||
if (ImageUtil.isAnimatedAndSupported(imageStream)) {
|
if (ImageUtil.isAnimatedAndSupported(imageStream)) {
|
||||||
imageStream.reset()
|
withContext(Dispatchers.IO) { imageStream.reset() }
|
||||||
if (page.longPage == null) {
|
if (page.longPage == null) {
|
||||||
page.longPage = true
|
page.longPage = true
|
||||||
if (viewer.config.splitPages || imageStream2 != null) {
|
if (viewer.config.splitPages || imageStream2 != null) {
|
||||||
splitDoublePages()
|
splitDoublePages()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope.launchUI {
|
withUIContext { progressBar.completeAndFadeOut() }
|
||||||
progressBar.completeAndFadeOut()
|
|
||||||
}
|
|
||||||
return imageStream
|
return imageStream
|
||||||
}
|
}
|
||||||
if (page.longPage == true && viewer.config.splitPages) {
|
if (page.longPage == true && viewer.config.splitPages) {
|
||||||
|
@ -735,7 +717,7 @@ class PagerPageHolder(
|
||||||
val imageBitmap = try {
|
val imageBitmap = try {
|
||||||
BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
|
BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
imageStream.close()
|
closeStreams(imageStream)
|
||||||
Timber.e("Cannot split page ${e.message}")
|
Timber.e("Cannot split page ${e.message}")
|
||||||
return imageBytes.inputStream()
|
return imageBytes.inputStream()
|
||||||
}
|
}
|
||||||
|
@ -756,7 +738,7 @@ class PagerPageHolder(
|
||||||
val imageBitmap = try {
|
val imageBitmap = try {
|
||||||
BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
|
BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
imageStream.close()
|
closeStreams(imageStream)
|
||||||
page.longPage = true
|
page.longPage = true
|
||||||
splitDoublePages()
|
splitDoublePages()
|
||||||
Timber.e("Cannot split page ${e.message}")
|
Timber.e("Cannot split page ${e.message}")
|
||||||
|
@ -765,7 +747,7 @@ class PagerPageHolder(
|
||||||
val height = imageBitmap.height
|
val height = imageBitmap.height
|
||||||
val width = imageBitmap.width
|
val width = imageBitmap.width
|
||||||
return if (height < width) {
|
return if (height < width) {
|
||||||
imageStream.close()
|
closeStreams(imageStream)
|
||||||
page.longPage = true
|
page.longPage = true
|
||||||
splitDoublePages()
|
splitDoublePages()
|
||||||
val isLTR = (viewer !is R2LPagerViewer).xor(viewer.config.invertDoublePages)
|
val isLTR = (viewer !is R2LPagerViewer).xor(viewer.config.invertDoublePages)
|
||||||
|
@ -790,8 +772,7 @@ class PagerPageHolder(
|
||||||
val imageBitmap = try {
|
val imageBitmap = try {
|
||||||
BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
|
BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
imageStream2.close()
|
closeStreams(imageStream, imageStream2)
|
||||||
imageStream.close()
|
|
||||||
page.fullPage = true
|
page.fullPage = true
|
||||||
splitDoublePages()
|
splitDoublePages()
|
||||||
Timber.e("Cannot combine pages ${e.message}")
|
Timber.e("Cannot combine pages ${e.message}")
|
||||||
|
@ -802,8 +783,7 @@ class PagerPageHolder(
|
||||||
val width = imageBitmap.width
|
val width = imageBitmap.width
|
||||||
|
|
||||||
if (height < width) {
|
if (height < width) {
|
||||||
imageStream2.close()
|
closeStreams(imageStream, imageStream2)
|
||||||
imageStream.close()
|
|
||||||
val oldValue = page.fullPage
|
val oldValue = page.fullPage
|
||||||
page.fullPage = true
|
page.fullPage = true
|
||||||
delayPageUpdate {
|
delayPageUpdate {
|
||||||
|
@ -827,32 +807,37 @@ class PagerPageHolder(
|
||||||
shiftDoublePages(false)
|
shiftDoublePages(false)
|
||||||
return supportHingeIfThere(imageBytes.inputStream())
|
return supportHingeIfThere(imageBytes.inputStream())
|
||||||
} else if ((page.isEndPage == true) &&
|
} else if ((page.isEndPage == true) &&
|
||||||
(if (page.index == 2) !viewer.activity.isFirstPageFull() else true)
|
(if (page.index == 2) !viewer.activity.isFirstPageFull() else true) &&
|
||||||
|
extraPage?.isEndPage != true
|
||||||
) {
|
) {
|
||||||
shiftDoublePages(true)
|
shiftDoublePages(true)
|
||||||
|
extraPage = null
|
||||||
return supportHingeIfThere(imageBytes.inputStream())
|
return supportHingeIfThere(imageBytes.inputStream())
|
||||||
}
|
}
|
||||||
|
} else if (!viewer.activity.manuallyShiftedPages && page.index == 0 && page.isEndPage == true) {
|
||||||
|
// if for some reason the first page should be by itself but its not, fix that
|
||||||
|
shiftDoublePages(true)
|
||||||
|
extraPage = null
|
||||||
|
return supportHingeIfThere(imageBytes.inputStream())
|
||||||
}
|
}
|
||||||
|
|
||||||
val imageBytes2 = imageStream2.readBytes()
|
val imageBytes2 = imageStream2.readBytes()
|
||||||
val imageBitmap2 = try {
|
val imageBitmap2 = try {
|
||||||
BitmapFactory.decodeByteArray(imageBytes2, 0, imageBytes2.size)
|
BitmapFactory.decodeByteArray(imageBytes2, 0, imageBytes2.size)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
imageStream2.close()
|
closeStreams(imageStream, imageStream2)
|
||||||
imageStream.close()
|
|
||||||
extraPage?.fullPage = true
|
extraPage?.fullPage = true
|
||||||
page.isolatedPage = true
|
page.isolatedPage = true
|
||||||
splitDoublePages()
|
splitDoublePages()
|
||||||
Timber.e("Cannot combine pages ${e.message}")
|
Timber.e("Cannot combine pages ${e.message}")
|
||||||
return supportHingeIfThere(imageBytes.inputStream())
|
return supportHingeIfThere(imageBytes.inputStream())
|
||||||
}
|
}
|
||||||
scope.launchUI { progressBar.setProgress(97) }
|
withUIContext { progressBar.setProgress(97) }
|
||||||
val height2 = imageBitmap2.height
|
val height2 = imageBitmap2.height
|
||||||
val width2 = imageBitmap2.width
|
val width2 = imageBitmap2.width
|
||||||
|
|
||||||
if (height2 < width2) {
|
if (height2 < width2) {
|
||||||
imageStream2.close()
|
closeStreams(imageStream, imageStream2)
|
||||||
imageStream.close()
|
|
||||||
extraPage?.fullPage = true
|
extraPage?.fullPage = true
|
||||||
page.isolatedPage = true
|
page.isolatedPage = true
|
||||||
splitDoublePages()
|
splitDoublePages()
|
||||||
|
@ -864,13 +849,12 @@ class PagerPageHolder(
|
||||||
Color.BLACK
|
Color.BLACK
|
||||||
}
|
}
|
||||||
|
|
||||||
imageStream.close()
|
closeStreams(imageStream, imageStream2)
|
||||||
imageStream2.close()
|
|
||||||
|
|
||||||
if (extraPage?.index == 1 && extraPage?.isStartPage == null && extraPage?.fullPage == null) {
|
if (extraPage?.index == 1 && extraPage?.isStartPage == null && extraPage?.fullPage == null) {
|
||||||
extraPage?.isStartPage = ImageUtil.isPagePadded(imageBitmap, rightSide = isLTR)
|
extraPage?.isStartPage = ImageUtil.isPagePadded(imageBitmap, rightSide = isLTR)
|
||||||
if (extraPage?.isStartPage == true) {
|
if (extraPage?.isStartPage == true) {
|
||||||
shiftDoublePages(true)
|
shiftDoublePages(true)
|
||||||
|
extraPage = null
|
||||||
return supportHingeIfThere(imageBytes.inputStream())
|
return supportHingeIfThere(imageBytes.inputStream())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -885,13 +869,13 @@ class PagerPageHolder(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun supportHingeIfThere(imageStream: InputStream): InputStream {
|
private suspend fun supportHingeIfThere(imageStream: InputStream): InputStream {
|
||||||
if (viewer.config.hingeGapSize > 0 && !ImageUtil.isAnimatedAndSupported(imageStream)) {
|
if (viewer.config.hingeGapSize > 0 && !ImageUtil.isAnimatedAndSupported(imageStream)) {
|
||||||
val imageBytes = imageStream.readBytes()
|
val imageBytes = imageStream.readBytes()
|
||||||
val imageBitmap = try {
|
val imageBitmap = try {
|
||||||
BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
|
BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
imageStream.close()
|
closeStreams(imageStream)
|
||||||
val wasNotFullPage = page.fullPage != true
|
val wasNotFullPage = page.fullPage != true
|
||||||
page.fullPage = true
|
page.fullPage = true
|
||||||
if (wasNotFullPage) {
|
if (wasNotFullPage) {
|
||||||
|
@ -917,17 +901,23 @@ class PagerPageHolder(
|
||||||
return imageStream
|
return imageStream
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shiftDoublePages(shift: Boolean) {
|
private suspend fun closeStreams(stream1: InputStream?, stream2: InputStream? = null) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
stream1?.close()
|
||||||
|
stream2?.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun shiftDoublePages(shift: Boolean) {
|
||||||
delayPageUpdate { viewer.activity.shiftDoublePages(shift) }
|
delayPageUpdate { viewer.activity.shiftDoublePages(shift) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun splitDoublePages() {
|
private suspend fun splitDoublePages() {
|
||||||
delayPageUpdate { viewer.splitDoublePages(page) }
|
delayPageUpdate { viewer.splitDoublePages(page) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun delayPageUpdate(callback: () -> Unit) {
|
private suspend fun delayPageUpdate(callback: () -> Unit) {
|
||||||
scope.launchUI {
|
withUIContext {
|
||||||
delay(100)
|
|
||||||
callback()
|
callback()
|
||||||
if (extraPage?.fullPage == true || page.fullPage == true) {
|
if (extraPage?.fullPage == true || page.fullPage == true) {
|
||||||
extraPage = null
|
extraPage = null
|
||||||
|
@ -935,13 +925,11 @@ class PagerPageHolder(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
private fun getBGType(readerTheme: Int, context: Context): Int {
|
||||||
fun getBGType(readerTheme: Int, context: Context): Int {
|
return if (readerTheme == 3) {
|
||||||
return if (readerTheme == 3) {
|
if (context.isInNightMode()) 2 else 1
|
||||||
if (context.isInNightMode()) 2 else 1
|
} else {
|
||||||
} else {
|
0 + (context.resources.configuration?.orientation ?: 0) * 10
|
||||||
0 + (context.resources.configuration?.orientation ?: 0) * 10
|
} + item.hashCode()
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,12 +167,8 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
|
||||||
(oldCurrent?.first as? ReaderPage)?.firstHalf == false
|
(oldCurrent?.first as? ReaderPage)?.firstHalf == false
|
||||||
} else {
|
} else {
|
||||||
oldCurrent?.second == current ||
|
oldCurrent?.second == current ||
|
||||||
(current.index + 1) < (
|
(current.index + 1) <
|
||||||
(
|
(((oldCurrent?.second ?: oldCurrent?.first) as? ReaderPage)?.index ?: 0)
|
||||||
oldCurrent?.second
|
|
||||||
?: oldCurrent?.first
|
|
||||||
) as? ReaderPage
|
|
||||||
)?.index ?: 0
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -647,27 +647,29 @@ object ImageUtil {
|
||||||
val right = width - left
|
val right = width - left
|
||||||
val paddedSide = if (rightSide) right else left
|
val paddedSide = if (rightSide) right else left
|
||||||
val unPaddedSide = if (!rightSide) right else left
|
val unPaddedSide = if (!rightSide) right else left
|
||||||
return (1 until 30).all {
|
return (1 until 30).count {
|
||||||
// if all of a side is padded (the left page usually has a white padding on the right when scanned)
|
// if all of a side is padded (the left page usually has a white padding on the right when scanned)
|
||||||
getPixel(paddedSide, (height * (it / 30f)).roundToInt()).isWhiteOrDark(checkWhite)
|
getPixel(paddedSide, (height * (it / 30f)).roundToInt()).isWhiteOrDark(checkWhite)
|
||||||
} && !(1 until 50).all {
|
} >= 27 && !(1 until 50).all {
|
||||||
// and if all of the other side isn't padded
|
// and if all of the other side isn't padded
|
||||||
getPixel(unPaddedSide, (height * (it / 50f)).roundToInt()).isWhiteOrDark(checkWhite)
|
getPixel(unPaddedSide, (height * (it / 50f)).roundToInt()).isWhiteOrDark(checkWhite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Bitmap.isOneSideMorePadded(rightSide: Boolean, checkWhite: Boolean): Boolean {
|
private fun Bitmap.isOneSideMorePadded(rightSide: Boolean, checkWhite: Boolean): Boolean {
|
||||||
val middle = height / 2
|
val middle = (height * 0.475).roundToInt()
|
||||||
val paddedSide: (Int) -> Int = { if (rightSide) width - it * 2 else it * 2 }
|
val middle2 = (height * 0.525).roundToInt()
|
||||||
val unPaddedSide: (Int) -> Int = { if (!rightSide) width - it * 2 else it * 2 }
|
val widthFactor = max(1, (width / 400f).roundToInt())
|
||||||
// val pixels = IntArray(100)
|
val paddedSide: (Int) -> Int = { if (!rightSide) width - it * widthFactor else it * widthFactor }
|
||||||
// getPixels(pixels, 0, 2, paddedSide(0), 0)
|
val unPaddedSide: (Int) -> Int = { if (rightSide) width - it * widthFactor else it * widthFactor }
|
||||||
return run stop@{
|
return run stop@{
|
||||||
(1 until 100).any {
|
(1 until 37).any {
|
||||||
if (!getPixel(paddedSide(it), middle).isWhiteOrDark(checkWhite)) return@stop false
|
if (!getPixel(paddedSide(it), middle).isWhiteOrDark(checkWhite)) return@stop false
|
||||||
!getPixel(unPaddedSide(it), middle).isWhiteOrDark(checkWhite)
|
if (!getPixel(paddedSide(it), middle2).isWhiteOrDark(checkWhite)) return@stop false
|
||||||
|
!getPixel(unPaddedSide(it), middle).isWhiteOrDark(checkWhite) ||
|
||||||
|
!getPixel(unPaddedSide(it), middle2).isWhiteOrDark(checkWhite)
|
||||||
}
|
}
|
||||||
} // && getPixels()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Int.isWhiteOrDark(checkWhite: Boolean): Boolean =
|
private fun Int.isWhiteOrDark(checkWhite: Boolean): Boolean =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue