|
@@ -6,7 +6,6 @@ import android.content.Intent
|
|
|
import android.content.res.Configuration
|
|
import android.content.res.Configuration
|
|
|
import android.net.Uri
|
|
import android.net.Uri
|
|
|
import android.os.Bundle
|
|
import android.os.Bundle
|
|
|
-import android.os.SystemClock
|
|
|
|
|
import android.view.Gravity
|
|
import android.view.Gravity
|
|
|
import android.view.InputDevice
|
|
import android.view.InputDevice
|
|
|
import android.view.KeyEvent
|
|
import android.view.KeyEvent
|
|
@@ -93,11 +92,11 @@ import io.legado.app.ui.widget.PopupAction
|
|
|
import io.legado.app.ui.widget.dialog.PhotoDialog
|
|
import io.legado.app.ui.widget.dialog.PhotoDialog
|
|
|
import io.legado.app.ui.widget.dialog.TextDialog
|
|
import io.legado.app.ui.widget.dialog.TextDialog
|
|
|
import io.legado.app.utils.ACache
|
|
import io.legado.app.utils.ACache
|
|
|
|
|
+import io.legado.app.utils.Debounce
|
|
|
import io.legado.app.utils.LogUtils
|
|
import io.legado.app.utils.LogUtils
|
|
|
import io.legado.app.utils.StartActivityContract
|
|
import io.legado.app.utils.StartActivityContract
|
|
|
import io.legado.app.utils.SyncedRenderer
|
|
import io.legado.app.utils.SyncedRenderer
|
|
|
import io.legado.app.utils.applyOpenTint
|
|
import io.legado.app.utils.applyOpenTint
|
|
|
-import io.legado.app.utils.buildMainHandler
|
|
|
|
|
import io.legado.app.utils.getPrefBoolean
|
|
import io.legado.app.utils.getPrefBoolean
|
|
|
import io.legado.app.utils.getPrefString
|
|
import io.legado.app.utils.getPrefString
|
|
|
import io.legado.app.utils.hexString
|
|
import io.legado.app.utils.hexString
|
|
@@ -118,7 +117,6 @@ import io.legado.app.utils.toastOnUi
|
|
|
import io.legado.app.utils.visible
|
|
import io.legado.app.utils.visible
|
|
|
import kotlinx.coroutines.Dispatchers.IO
|
|
import kotlinx.coroutines.Dispatchers.IO
|
|
|
import kotlinx.coroutines.Job
|
|
import kotlinx.coroutines.Job
|
|
|
-import kotlinx.coroutines.Runnable
|
|
|
|
|
import kotlinx.coroutines.cancelChildren
|
|
import kotlinx.coroutines.cancelChildren
|
|
|
import kotlinx.coroutines.delay
|
|
import kotlinx.coroutines.delay
|
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.coroutines.launch
|
|
@@ -217,15 +215,13 @@ class ReadBookActivity : BaseReadBookActivity(),
|
|
|
override val pageFactory: TextPageFactory get() = binding.readView.pageFactory
|
|
override val pageFactory: TextPageFactory get() = binding.readView.pageFactory
|
|
|
override val headerHeight: Int get() = binding.readView.curPage.headerHeight
|
|
override val headerHeight: Int get() = binding.readView.curPage.headerHeight
|
|
|
private val menuLayoutIsVisible get() = bottomDialog > 0 || binding.readMenu.isVisible
|
|
private val menuLayoutIsVisible get() = bottomDialog > 0 || binding.readMenu.isVisible
|
|
|
- private val nextPageRunnable by lazy { Runnable { keyPage(PageDirection.NEXT) } }
|
|
|
|
|
- private val prevPageRunnable by lazy { Runnable { keyPage(PageDirection.PREV) } }
|
|
|
|
|
|
|
+ private val nextPageDebounce by lazy { Debounce { keyPage(PageDirection.NEXT) } }
|
|
|
|
|
+ private val prevPageDebounce by lazy { Debounce { keyPage(PageDirection.PREV) } }
|
|
|
private var bookChanged = false
|
|
private var bookChanged = false
|
|
|
private var pageChanged = false
|
|
private var pageChanged = false
|
|
|
private var reloadContent = false
|
|
private var reloadContent = false
|
|
|
private val autoPageRenderer by lazy { SyncedRenderer { doAutoPage(it) } }
|
|
private val autoPageRenderer by lazy { SyncedRenderer { doAutoPage(it) } }
|
|
|
private var autoPageScrollOffset = 0.0
|
|
private var autoPageScrollOffset = 0.0
|
|
|
- private val handler by lazy { buildMainHandler() }
|
|
|
|
|
- private var lastKeyPageTime = 0L
|
|
|
|
|
|
|
|
|
|
//恢复跳转前进度对话框的交互结果
|
|
//恢复跳转前进度对话框的交互结果
|
|
|
private var confirmRestoreProcess: Boolean? = null
|
|
private var confirmRestoreProcess: Boolean? = null
|
|
@@ -624,38 +620,39 @@ class ReadBookActivity : BaseReadBookActivity(),
|
|
|
if (menuLayoutIsVisible) {
|
|
if (menuLayoutIsVisible) {
|
|
|
return super.onKeyDown(keyCode, event)
|
|
return super.onKeyDown(keyCode, event)
|
|
|
}
|
|
}
|
|
|
|
|
+ val longPress = event.repeatCount > 0
|
|
|
when {
|
|
when {
|
|
|
isPrevKey(keyCode) -> {
|
|
isPrevKey(keyCode) -> {
|
|
|
- handleKeyPage(PageDirection.PREV)
|
|
|
|
|
|
|
+ handleKeyPage(PageDirection.PREV, longPress)
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
isNextKey(keyCode) -> {
|
|
isNextKey(keyCode) -> {
|
|
|
- handleKeyPage(PageDirection.NEXT)
|
|
|
|
|
|
|
+ handleKeyPage(PageDirection.NEXT, longPress)
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
when (keyCode) {
|
|
when (keyCode) {
|
|
|
- KeyEvent.KEYCODE_VOLUME_UP -> if (volumeKeyPage(PageDirection.PREV)) {
|
|
|
|
|
|
|
+ KeyEvent.KEYCODE_VOLUME_UP -> if (volumeKeyPage(PageDirection.PREV, longPress)) {
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- KeyEvent.KEYCODE_VOLUME_DOWN -> if (volumeKeyPage(PageDirection.NEXT)) {
|
|
|
|
|
|
|
+ KeyEvent.KEYCODE_VOLUME_DOWN -> if (volumeKeyPage(PageDirection.NEXT, longPress)) {
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
KeyEvent.KEYCODE_PAGE_UP -> {
|
|
KeyEvent.KEYCODE_PAGE_UP -> {
|
|
|
- handleKeyPage(PageDirection.PREV)
|
|
|
|
|
|
|
+ handleKeyPage(PageDirection.PREV, longPress)
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
KeyEvent.KEYCODE_PAGE_DOWN -> {
|
|
KeyEvent.KEYCODE_PAGE_DOWN -> {
|
|
|
- handleKeyPage(PageDirection.NEXT)
|
|
|
|
|
|
|
+ handleKeyPage(PageDirection.NEXT, longPress)
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
KeyEvent.KEYCODE_SPACE -> {
|
|
KeyEvent.KEYCODE_SPACE -> {
|
|
|
- handleKeyPage(PageDirection.NEXT)
|
|
|
|
|
|
|
+ handleKeyPage(PageDirection.NEXT, longPress)
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -669,7 +666,7 @@ class ReadBookActivity : BaseReadBookActivity(),
|
|
|
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
|
|
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
|
|
|
when (keyCode) {
|
|
when (keyCode) {
|
|
|
KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN -> {
|
|
KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN -> {
|
|
|
- if (volumeKeyPage(PageDirection.NONE)) {
|
|
|
|
|
|
|
+ if (volumeKeyPage(PageDirection.NONE, false)) {
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -852,49 +849,52 @@ class ReadBookActivity : BaseReadBookActivity(),
|
|
|
if (menuLayoutIsVisible || !AppConfig.mouseWheelPage) {
|
|
if (menuLayoutIsVisible || !AppConfig.mouseWheelPage) {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
- keyPageDebounce(direction, 200L, true)
|
|
|
|
|
|
|
+ keyPageDebounce(direction, mouseWheel = true, longPress = false)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 音量键翻页
|
|
* 音量键翻页
|
|
|
*/
|
|
*/
|
|
|
- private fun volumeKeyPage(direction: PageDirection): Boolean {
|
|
|
|
|
|
|
+ private fun volumeKeyPage(direction: PageDirection, longPress: Boolean): Boolean {
|
|
|
if (!AppConfig.volumeKeyPage) {
|
|
if (!AppConfig.volumeKeyPage) {
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
if (!AppConfig.volumeKeyPageOnPlay && BaseReadAloudService.isPlay()) {
|
|
if (!AppConfig.volumeKeyPageOnPlay && BaseReadAloudService.isPlay()) {
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
- handleKeyPage(direction)
|
|
|
|
|
|
|
+ handleKeyPage(direction, longPress)
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private fun handleKeyPage(direction: PageDirection) {
|
|
|
|
|
|
|
+ private fun handleKeyPage(direction: PageDirection, longPress: Boolean) {
|
|
|
if (AppConfig.keyPageOnLongPress || direction == PageDirection.NONE) {
|
|
if (AppConfig.keyPageOnLongPress || direction == PageDirection.NONE) {
|
|
|
keyPage(direction)
|
|
keyPage(direction)
|
|
|
} else {
|
|
} else {
|
|
|
- keyPageDebounce(direction)
|
|
|
|
|
|
|
+ keyPageDebounce(direction, longPress = longPress)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private fun keyPageDebounce(
|
|
private fun keyPageDebounce(
|
|
|
direction: PageDirection,
|
|
direction: PageDirection,
|
|
|
- delay: Long = 100L,
|
|
|
|
|
- mouseWheel: Boolean = false
|
|
|
|
|
|
|
+ mouseWheel: Boolean = false,
|
|
|
|
|
+ longPress: Boolean
|
|
|
) {
|
|
) {
|
|
|
- handler.removeCallbacks(nextPageRunnable)
|
|
|
|
|
- handler.removeCallbacks(prevPageRunnable)
|
|
|
|
|
- if (!mouseWheel) {
|
|
|
|
|
- val keyPageTime = SystemClock.uptimeMillis()
|
|
|
|
|
- val elapsed = keyPageTime - lastKeyPageTime
|
|
|
|
|
- lastKeyPageTime = keyPageTime
|
|
|
|
|
- if (elapsed < 100) {
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (longPress) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ nextPageDebounce.apply {
|
|
|
|
|
+ wait = if (mouseWheel) 200L else 600L
|
|
|
|
|
+ leading = !mouseWheel
|
|
|
|
|
+ trailing = mouseWheel
|
|
|
|
|
+ }
|
|
|
|
|
+ prevPageDebounce.apply {
|
|
|
|
|
+ wait = if (mouseWheel) 200L else 600L
|
|
|
|
|
+ leading = !mouseWheel
|
|
|
|
|
+ trailing = mouseWheel
|
|
|
}
|
|
}
|
|
|
when (direction) {
|
|
when (direction) {
|
|
|
- PageDirection.NEXT -> handler.postDelayed(nextPageRunnable, delay)
|
|
|
|
|
- PageDirection.PREV -> handler.postDelayed(prevPageRunnable, delay)
|
|
|
|
|
|
|
+ PageDirection.NEXT -> nextPageDebounce.invoke()
|
|
|
|
|
+ PageDirection.PREV -> prevPageDebounce.invoke()
|
|
|
else -> {}
|
|
else -> {}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|