This commit is contained in:
Horis
2025-03-09 20:39:34 +08:00
parent e62d5b926a
commit 0b18832803
5 changed files with 54 additions and 46 deletions
@@ -27,9 +27,11 @@ import io.legado.app.utils.getPrefString
import io.legado.app.utils.isJson import io.legado.app.utils.isJson
import io.legado.app.utils.removePref import io.legado.app.utils.removePref
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File import java.io.File
import kotlin.coroutines.coroutineContext
/** /**
* webDav初始化会访问网络,不要放到主线程 * webDav初始化会访问网络,不要放到主线程
@@ -217,9 +219,8 @@ object AppWebDav {
WebDav(putUrl, it).upload(byteArray, "text/plain") WebDav(putUrl, it).upload(byteArray, "text/plain")
} }
} catch (e: Exception) { } catch (e: Exception) {
val msg = "WebDav导出\n${e.localizedMessage}" coroutineContext.ensureActive()
AppLog.put(msg, e) AppLog.put("WebDav导出失败\n${e.localizedMessage}", e, true)
appCtx.toastOnUi(msg)
} }
} }
@@ -232,9 +233,8 @@ object AppWebDav {
WebDav(putUrl, it).upload(uri, "text/plain") WebDav(putUrl, it).upload(uri, "text/plain")
} }
} catch (e: Exception) { } catch (e: Exception) {
val msg = "WebDav导出\n${e.localizedMessage}" coroutineContext.ensureActive()
AppLog.put(msg, e) AppLog.put("WebDav导出失败\n${e.localizedMessage}", e, true)
appCtx.toastOnUi(msg)
} }
} }
@@ -249,6 +249,7 @@ object AppWebDav {
WebDav(url, authorization).upload(json.toByteArray(), "application/json") WebDav(url, authorization).upload(json.toByteArray(), "application/json")
book.syncTime = System.currentTimeMillis() book.syncTime = System.currentTimeMillis()
} catch (e: Exception) { } catch (e: Exception) {
coroutineContext.ensureActive()
AppLog.put("上传进度失败\n${e.localizedMessage}", e) AppLog.put("上传进度失败\n${e.localizedMessage}", e)
} }
} }
@@ -263,6 +264,7 @@ object AppWebDav {
WebDav(url, authorization).upload(json.toByteArray(), "application/json") WebDav(url, authorization).upload(json.toByteArray(), "application/json")
onSuccess?.invoke() onSuccess?.invoke()
} catch (e: Exception) { } catch (e: Exception) {
coroutineContext.ensureActive()
AppLog.put("上传进度失败\n${e.localizedMessage}", e) AppLog.put("上传进度失败\n${e.localizedMessage}", e)
} }
} }
@@ -289,6 +291,7 @@ object AppWebDav {
} }
} }
}.onFailure { }.onFailure {
coroutineContext.ensureActive()
AppLog.put("获取书籍进度失败\n${it.localizedMessage}", it) AppLog.put("获取书籍进度失败\n${it.localizedMessage}", it)
} }
} }
@@ -227,6 +227,8 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
} }
} }
addRecyclerViewPreloader(AppConfig.mangaPreDownloadNum) addRecyclerViewPreloader(AppConfig.mangaPreDownloadNum)
}
binding.webtoonFrame.run {
onTouchMiddle { onTouchMiddle {
if (!binding.mangaMenu.isVisible) { if (!binding.mangaMenu.isVisible) {
binding.mangaMenu.runMenuIn() binding.mangaMenu.runMenuIn()
@@ -600,7 +602,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
} }
private fun disabledClickScroller(disable: Boolean) { private fun disabledClickScroller(disable: Boolean) {
binding.mRecyclerManga.disabledClickScroller = disable binding.webtoonFrame.disabledClickScroller = disable
} }
private fun upLayoutInDisplayCutoutMode() { private fun upLayoutInDisplayCutoutMode() {
@@ -2,6 +2,7 @@ package io.legado.app.ui.book.manga.recyclerview
import android.content.Context import android.content.Context
import android.graphics.Rect import android.graphics.Rect
import android.graphics.RectF
import android.util.AttributeSet import android.util.AttributeSet
import android.view.GestureDetector import android.view.GestureDetector
import android.view.MotionEvent import android.view.MotionEvent
@@ -33,6 +34,45 @@ class WebtoonFrame : FrameLayout {
private val recycler: WebtoonRecyclerView? private val recycler: WebtoonRecyclerView?
get() = getChildAt(0) as? WebtoonRecyclerView get() = getChildAt(0) as? WebtoonRecyclerView
private val mcRect = RectF()
private val blRect = RectF()
private val brRect = RectF()
private var mTouchMiddle: (() -> Unit)? = null
fun onTouchMiddle(init: () -> Unit) = apply { this.mTouchMiddle = init }
private var mNextPage: (() -> Unit)? = null
fun onNextPage(init: () -> Unit) = apply { this.mNextPage = init }
private var mPrevPage: (() -> Unit)? = null
fun onPrevPage(init: () -> Unit) = apply { this.mPrevPage = init }
var disabledClickScroller = false
override fun onAttachedToWindow() {
super.onAttachedToWindow()
recycler?.tapListener = { ev ->
when {
mcRect.contains(ev.rawX, ev.rawY) -> {
mTouchMiddle?.invoke()
}
blRect.contains(ev.rawX, ev.rawY) && !disabledClickScroller -> {
mPrevPage?.invoke()
}
brRect.contains(ev.rawX, ev.rawY) && !disabledClickScroller -> {
mNextPage?.invoke()
}
}
}
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
mcRect.set(width * 0.33f, height * 0.33f, width * 0.66f, height * 0.66f)
blRect.set(0f, height * 0.66f, width * 0.33f, height.toFloat())
brRect.set(width * 0.66f, height * 0.66f, width.toFloat(), height.toFloat())
}
override fun dispatchTouchEvent(ev: MotionEvent): Boolean { override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
if (!disableMangaScale) { if (!disableMangaScale) {
scaleDetector.onTouchEvent(ev) scaleDetector.onTouchEvent(ev)
@@ -38,30 +38,17 @@ class WebtoonRecyclerView @JvmOverloads constructor(
private var mNestedPreScrollListener: IComicPreScroll? = null private var mNestedPreScrollListener: IComicPreScroll? = null
private val listener = GestureListener() private val listener = GestureListener()
private val detector = Detector() private val detector = Detector()
private val mcRect = RectF()
private val blRect = RectF()
private val brRect = RectF()
var doubleTapZoom = true var doubleTapZoom = true
var tapListener: ((MotionEvent) -> Unit)? = null var tapListener: ((MotionEvent) -> Unit)? = null
var longTapListener: ((MotionEvent) -> Boolean)? = null var longTapListener: ((MotionEvent) -> Boolean)? = null
var disableMangaScaling = false var disableMangaScaling = false
var disabledClickScroller = false
private var mTouchMiddle: (() -> Unit)? = null
fun onTouchMiddle(init: () -> Unit) = apply { this.mTouchMiddle = init }
private var mNextPage: (() -> Unit)? = null
fun onNextPage(init: () -> Unit) = apply { this.mNextPage = init }
private var mPrevPage: (() -> Unit)? = null
fun onPrevPage(init: () -> Unit) = apply { this.mPrevPage = init }
override fun onMeasure(widthSpec: Int, heightSpec: Int) { override fun onMeasure(widthSpec: Int, heightSpec: Int) {
halfWidth = MeasureSpec.getSize(widthSpec) / 2 halfWidth = MeasureSpec.getSize(widthSpec) / 2
halfHeight = MeasureSpec.getSize(heightSpec) / 2 halfHeight = MeasureSpec.getSize(heightSpec) / 2
if (!heightSet) { if (!heightSet) {
originalHeight = MeasureSpec.getSize(heightSpec) originalHeight = MeasureSpec.getSize(heightSpec)
val width = MeasureSpec.getSize(widthSpec)
setClickArea(width, originalHeight)
heightSet = true heightSet = true
} }
super.onMeasure(widthSpec, heightSpec) super.onMeasure(widthSpec, heightSpec)
@@ -105,12 +92,6 @@ class WebtoonRecyclerView @JvmOverloads constructor(
return super.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow, type) return super.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow, type)
} }
private fun setClickArea(width: Int, height: Int) {
mcRect.set(width * 0.33f, height * 0.33f, width * 0.66f, height * 0.66f)
blRect.set(0f, height * 0.66f, width * 0.33f, height.toFloat())
brRect.set(width * 0.66f, height * 0.66f, width.toFloat(), height.toFloat())
}
private fun getPositionX(positionX: Float): Float { private fun getPositionX(positionX: Float): Float {
if (currentScale < 1) { if (currentScale < 1) {
return 0f return 0f
@@ -250,24 +231,7 @@ class WebtoonRecyclerView @JvmOverloads constructor(
inner class GestureListener : GestureDetectorWithLongTap.Listener() { inner class GestureListener : GestureDetectorWithLongTap.Listener() {
override fun onSingleTapConfirmed(ev: MotionEvent): Boolean { override fun onSingleTapConfirmed(ev: MotionEvent): Boolean {
when { tapListener?.invoke(ev)
mcRect.contains(ev.rawX, ev.rawY) -> {
mTouchMiddle?.invoke()
}
blRect.contains(ev.rawX, ev.rawY) && !disabledClickScroller -> {
mPrevPage?.invoke()
}
brRect.contains(ev.rawX, ev.rawY) && !disabledClickScroller-> {
mNextPage?.invoke()
}
else -> {
tapListener?.invoke(ev)
}
}
return false return false
} }
@@ -239,10 +239,10 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
if (!AppConfig.syncBookProgress) return if (!AppConfig.syncBookProgress) return
execute { execute {
AppWebDav.getBookProgress(book) AppWebDav.getBookProgress(book)
?: throw NoStackTraceException("没有进度")
}.onError { }.onError {
AppLog.put("拉取阅读进度失败《${book.name}》\n${it.localizedMessage}", it) AppLog.put("拉取阅读进度失败《${book.name}》\n${it.localizedMessage}", it)
}.onSuccess { progress -> }.onSuccess { progress ->
progress ?: return@onSuccess
if (progress.durChapterIndex < book.durChapterIndex || if (progress.durChapterIndex < book.durChapterIndex ||
(progress.durChapterIndex == book.durChapterIndex (progress.durChapterIndex == book.durChapterIndex
&& progress.durChapterPos < book.durChapterPos) && progress.durChapterPos < book.durChapterPos)
@@ -253,7 +253,6 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
AppLog.put("自动同步阅读进度成功《${book.name}》 ${progress.durChapterTitle}") AppLog.put("自动同步阅读进度成功《${book.name}》 ${progress.durChapterTitle}")
} }
} }
} }
/** /**