Skip to content

Commit

Permalink
同步进度功能补充 (#4352)
Browse files Browse the repository at this point in the history
* 进度同步补充:
在初始阅读界面时拉取云端进度 --> 初始阅读界面保留原有拉取逻辑,除此之外的阅读界面处于已恢复状态时执行同步云端进度,若云端进度快于本地则弹窗提醒是否同步
无 --> 监听到网络切换到有网环境时执行同步云端进度,若云端进度快于本地则弹窗提醒是否同步
页面进入已暂停状态时上传阅读进度 --> 页面进入已暂停状态时执行同步云端进度

以上新增的同步云端进度逻辑为:如果本地进度快于服务器进度或者没有进度则进行上传,如果慢与服务器进度则返回云端进度按需执行

* 点击区域增加同步阅读进度功能

* 阅读界面初始化同步逻辑修改

* merge

* merge

* merge

* 增加覆盖云端进度

* merge

* merge

* 多次弹窗问题修改

* 补充的同步功能增加配置开关

* Revert "优化"

This reverts commit d51d0f8.

* merge

---------

Co-authored-by: mozhu <lcl_em@163.com>
  • Loading branch information
liaochuan and mozhu authored Nov 15, 2024
1 parent c1c0142 commit be862ab
Show file tree
Hide file tree
Showing 17 changed files with 161 additions and 57 deletions.
1 change: 1 addition & 0 deletions app/src/main/java/io/legado/app/constant/PreferKey.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ object PreferKey {
const val importKeepGroup = "importKeepGroup"
const val screenOrientation = "screenOrientation"
const val syncBookProgress = "syncBookProgress"
const val syncBookProgressPlus = "syncBookProgressPlus"
const val cronet = "Cronet"
const val antiAlias = "antiAlias"
const val bitmapCacheSize = "bitmapCacheSize"
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/io/legado/app/help/config/AppConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,8 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {

val syncBookProgress get() = appCtx.getPrefBoolean(PreferKey.syncBookProgress, true)

val syncBookProgressPlus get() = appCtx.getPrefBoolean(PreferKey.syncBookProgressPlus, false)

val mediaButtonOnExit get() = appCtx.getPrefBoolean("mediaButtonOnExit", true)

val readAloudByMediaButton
Expand Down
39 changes: 38 additions & 1 deletion app/src/main/java/io/legado/app/model/ReadBook.kt
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,47 @@ object ReadBook : CoroutineScope by MainScope() {
nextTextChapter?.clearSearchResult()
}

fun uploadProgress() {
fun uploadProgress(successAction: (() -> Unit)? = null) {
book?.let {
launch(IO) {
AppWebDav.uploadBookProgress(it)
ensureActive()
it.update()
successAction?.invoke()
}
}
}

/**
* 同步阅读进度
* 如果当前进度快于服务器进度或者没有进度进行上传,如果慢与服务器进度则执行传入动作
*/
fun syncProgress(
newProgressAction: ((progress: BookProgress) -> Unit)? = null,
uploadSuccessAction: (() -> Unit)? = null,
syncSuccessAction: (() -> Unit)? = null) {
if (!AppConfig.syncBookProgress) return
book?.let {
Coroutine.async {
AppWebDav.getBookProgress(it)
}.onError {
AppLog.put("拉取阅读进度失败", it)
}.onSuccess { progress ->
if (progress == null || progress.durChapterIndex < it.durChapterIndex ||
(progress.durChapterIndex == it.durChapterIndex
&& progress.durChapterPos < it.durChapterPos)) {
// 服务器没有进度或者进度比服务器快,上传现有进度
Coroutine.async {
AppWebDav.uploadBookProgress(BookProgress(it), uploadSuccessAction)
it.save()
}
} else if (progress.durChapterIndex > it.durChapterIndex ||
progress.durChapterPos > it.durChapterPos) {
// 进度比服务器慢,执行传入动作
newProgressAction?.invoke(progress)
} else {
syncSuccessAction?.invoke()
}
}
}
}
Expand Down Expand Up @@ -893,6 +928,8 @@ object ReadBook : CoroutineScope by MainScope() {

fun notifyBookChanged()

fun sureNewProgress(progress: BookProgress)

fun cancelSelect()
}

Expand Down
102 changes: 49 additions & 53 deletions app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,10 @@ import android.content.res.Configuration
import android.net.Uri
import android.os.Bundle
import android.os.Looper
import android.view.Gravity
import android.view.InputDevice
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.view.MotionEvent
import android.view.View
import android.view.*
import androidx.activity.addCallback
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.PopupMenu
import androidx.core.view.get
import androidx.core.view.isVisible
Expand All @@ -24,12 +19,7 @@ import androidx.lifecycle.lifecycleScope
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
import io.legado.app.BuildConfig
import io.legado.app.R
import io.legado.app.constant.AppConst
import io.legado.app.constant.AppLog
import io.legado.app.constant.BookType
import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey
import io.legado.app.constant.Status
import io.legado.app.constant.*
import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
Expand All @@ -39,14 +29,7 @@ import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.AppWebDav
import io.legado.app.help.IntentData
import io.legado.app.help.TTS
import io.legado.app.help.book.BookHelp
import io.legado.app.help.book.ContentProcessor
import io.legado.app.help.book.isAudio
import io.legado.app.help.book.isEpub
import io.legado.app.help.book.isLocal
import io.legado.app.help.book.isLocalTxt
import io.legado.app.help.book.isMobi
import io.legado.app.help.book.removeType
import io.legado.app.help.book.*
import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.ReadBookConfig
import io.legado.app.help.config.ReadTipConfig
Expand All @@ -59,6 +42,7 @@ import io.legado.app.lib.theme.accentColor
import io.legado.app.model.ReadAloud
import io.legado.app.model.ReadBook
import io.legado.app.model.analyzeRule.AnalyzeRule
import io.legado.app.receiver.NetworkChangedListener
import io.legado.app.model.localBook.EpubFile
import io.legado.app.model.localBook.MobiFile
import io.legado.app.receiver.TimeBatteryReceiver
Expand All @@ -69,7 +53,7 @@ import io.legado.app.ui.book.bookmark.BookmarkDialog
import io.legado.app.ui.book.changesource.ChangeBookSourceDialog
import io.legado.app.ui.book.changesource.ChangeChapterSourceDialog
import io.legado.app.ui.book.info.BookInfoActivity
import io.legado.app.ui.book.read.config.AutoReadDialog
import io.legado.app.ui.book.read.config.*
import io.legado.app.ui.book.read.config.BgTextConfigDialog.Companion.BG_COLOR
import io.legado.app.ui.book.read.config.BgTextConfigDialog.Companion.TEXT_COLOR
import io.legado.app.ui.book.read.config.MoreConfigDialog
Expand All @@ -96,38 +80,10 @@ import io.legado.app.ui.replace.ReplaceRuleActivity
import io.legado.app.ui.replace.edit.ReplaceEditActivity
import io.legado.app.ui.widget.PopupAction
import io.legado.app.ui.widget.dialog.PhotoDialog
import io.legado.app.utils.ACache
import io.legado.app.utils.Debounce
import io.legado.app.utils.LogUtils
import io.legado.app.utils.StartActivityContract
import io.legado.app.utils.applyOpenTint
import io.legado.app.utils.buildMainHandler
import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.getPrefString
import io.legado.app.utils.hexString
import io.legado.app.utils.iconItemOnLongClick
import io.legado.app.utils.invisible
import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.isTrue
import io.legado.app.utils.launch
import io.legado.app.utils.navigationBarGravity
import io.legado.app.utils.observeEvent
import io.legado.app.utils.observeEventSticky
import io.legado.app.utils.postEvent
import io.legado.app.utils.showDialogFragment
import io.legado.app.utils.showHelp
import io.legado.app.utils.startActivity
import io.legado.app.utils.sysScreenOffTime
import io.legado.app.utils.throttle
import io.legado.app.utils.toastOnUi
import io.legado.app.utils.visible
import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.*

/**
* 阅读界面
Expand Down Expand Up @@ -245,6 +201,11 @@ class ReadBookActivity : BaseReadBookActivity(),

//恢复跳转前进度对话框的交互结果
private var confirmRestoreProcess: Boolean? = null
private val networkChangedListener by lazy {
NetworkChangedListener(this)
}
private var justInitData: Boolean = false
private var syncDialog: AlertDialog? = null

@SuppressLint("ClickableViewAccessibility")
override fun onActivityCreated(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -289,6 +250,7 @@ class ReadBookActivity : BaseReadBookActivity(),
viewModel.initData(intent)
false
}
justInitData = true
}

override fun onNewIntent(intent: Intent) {
Expand Down Expand Up @@ -318,6 +280,7 @@ class ReadBookActivity : BaseReadBookActivity(),
bookChanged = false
ReadBook.callBack = this
viewModel.initData(intent)
justInitData = true
} else {
//web端阅读时,app处于阅读界面,本地记录会覆盖web保存的进度,在此处恢复
ReadBook.webBookProgress?.let {
Expand All @@ -329,6 +292,14 @@ class ReadBookActivity : BaseReadBookActivity(),
registerReceiver(timeBatteryReceiver, timeBatteryReceiver.filter)
binding.readView.upTime()
screenOffTimerStart()
// 网络监听,当从无网切换到网络环境时同步进度(注意注册的同时就会收到监听,因此界面激活时无需重复执行同步操作)
networkChangedListener.register()
networkChangedListener.onNetworkChanged = {
// 当网络是可用状态且无需初始化时同步进度(初始化中已有同步进度逻辑)
if (AppConfig.syncBookProgressPlus && NetworkUtils.isAvailable() && !justInitData) {
ReadBook.syncProgress({progress -> sureNewProgress(progress)}, null)
}
}
}

override fun onPause() {
Expand All @@ -339,9 +310,15 @@ class ReadBookActivity : BaseReadBookActivity(),
unregisterReceiver(timeBatteryReceiver)
upSystemUiVisibility()
if (!BuildConfig.DEBUG) {
ReadBook.uploadProgress()
if (AppConfig.syncBookProgressPlus) {
ReadBook.syncProgress()
} else {
ReadBook.uploadProgress()
}
Backup.autoBack(this)
}
justInitData = false
networkChangedListener.unRegister()
}

override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
Expand Down Expand Up @@ -408,6 +385,9 @@ class ReadBookActivity : BaseReadBookActivity(),
menu.findItem(R.id.menu_get_progress)?.isVisible = withContext(IO) {
AppWebDav.isOk
}
menu.findItem(R.id.menu_cover_progress)?.isVisible = withContext(IO) {
AppWebDav.isOk
}
}
}

Expand Down Expand Up @@ -551,6 +531,10 @@ class ReadBookActivity : BaseReadBookActivity(),
}
}

R.id.menu_cover_progress -> ReadBook.book?.let {
ReadBook.uploadProgress({ toastOnUi(R.string.upload_book_success) })
}

R.id.menu_same_title_removed -> {
ReadBook.book?.let {
val contentProcessor = ContentProcessor.get(it)
Expand Down Expand Up @@ -1499,6 +1483,18 @@ class ReadBookActivity : BaseReadBookActivity(),
}
}

override fun sureNewProgress(progress: BookProgress) {
syncDialog?.dismiss()
syncDialog = alert(R.string.get_book_progress) {
setMessage(R.string.cloud_progress_exceeds_current)
okButton {
ReadBook.setProgress(progress)
ReadBook.saveRead()
}
noButton()
}
}

override fun finish() {
val book = ReadBook.book ?: return super.finish()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,11 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
// 有章节跳转不同步阅读进度
ReadBook.chapterChanged = false
} else if (!isSameBook || !BaseReadAloudService.isRun) {
syncBookProgress(book)
if (AppConfig.syncBookProgressPlus) {
ReadBook.syncProgress({ progress -> ReadBook.callBack?.sureNewProgress(progress) }, null)
} else {
syncBookProgress(book)
}
}
if (!book.isLocal && ReadBook.bookSource == null) {
autoChangeSource(book.name, book.author)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class ClickActionConfigDialog : BaseDialogFragment(R.layout.dialog_click_action_
Pair(8, getString(R.string.edit_content)),
Pair(9, getString(R.string.replace_state_change)),
Pair(10, getString(R.string.chapter_list)),
Pair(11, getString(R.string.search_content))
Pair(11, getString(R.string.search_content)),
Pair(12, getString(R.string.sync_book_progress_t))
)
}

Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import android.view.MotionEvent
import android.view.ViewConfiguration
import android.view.WindowInsets
import android.widget.FrameLayout
import io.legado.app.R
import io.legado.app.constant.PageAnim
import io.legado.app.data.entities.BookProgress
import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.ReadBookConfig
import io.legado.app.model.ReadAloud
Expand All @@ -34,6 +36,7 @@ import io.legado.app.ui.book.read.page.provider.TextPageFactory
import io.legado.app.utils.activity
import io.legado.app.utils.canvasrecorder.pools.BitmapPool
import io.legado.app.utils.invisible
import io.legado.app.utils.longToastOnUi
import io.legado.app.utils.showDialogFragment
import io.legado.app.utils.throttle
import java.text.BreakIterator
Expand Down Expand Up @@ -434,6 +437,9 @@ class ReadView(context: Context, attrs: AttributeSet) :
9 -> callBack.changeReplaceRuleState()
10 -> callBack.openChapterList()
11 -> callBack.openSearchActivity(null)
12 -> ReadBook.syncProgress({progress -> callBack.sureNewProgress(progress)},
{ context.longToastOnUi(context.getString(R.string.upload_book_success)) },
{ context.longToastOnUi(context.getString(R.string.sync_book_progress_success)) })
}
}

Expand Down Expand Up @@ -726,5 +732,6 @@ class ReadView(context: Context, attrs: AttributeSet) :
fun changeReplaceRuleState()
fun openSearchActivity(searchWord: String?)
fun upSystemUiVisibility()
fun sureNewProgress(progress: BookProgress)
}
}
6 changes: 6 additions & 0 deletions app/src/main/res/menu/book_read.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@
android:visible="false"
app:showAsAction="never" />

<item
android:id="@+id/menu_cover_progress"
android:title="@string/cover_book_progress"
android:visible="false"
app:showAsAction="never" />

<item
android:id="@+id/menu_reverse_content"
android:title="@string/reverse_content"
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values-es-rES/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -806,9 +806,12 @@
<string name="rule_subscription">Suscripción de reglsa</string>
<string name="rule_sub_empty_msg">添加大佬们提供的规则导入地址\n添加后点击可导入规则</string>
<string name="get_book_progress">Obtener progreso en la nube</string>
<string name="cover_book_progress">Cobertura del progreso en la nube</string>
<string name="current_progress_exceeds_cloud">El progreso actual excede el progreso de la nube. ¿Quieres sincronizar?</string>
<string name="sync_book_progress_t">Progreso de lectura sincronizado</string>
<string name="sync_book_progress_s">Sincronizar el progreso de la lectura al entrar y salir de la pantalla de lectura</string>
<string name="sync_book_progress_plus_t">Mejora de Sincronización</string>
<string name="sync_book_progress_plus_s">Sincronizar el progreso en la nube al volver a entrar en la página (por ejemplo, tras apagar la pantalla o al regresar desde el fondo) o cuando la red esté disponible</string>
<string name="create_bookmark_error">No se pudo marcar</string>
<string name="single_url">URL única</string>
<string name="export_bookshelf">Exportar lista de libros</string>
Expand Down Expand Up @@ -1129,8 +1132,10 @@
<string name="open_book_info_by_click_title">点击书名打开详情</string>
<string name="export_wait">等待导出</string>
<string name="default_home_page">默认主页</string>
<string name="sync_book_progress_success">" Sincronización del progreso exitosa"</string>
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
<string name="export_all_use_book_source">导出所有书的书源</string>
<string name="cloud_progress_exceeds_current">The cloud progress exceeds the current progress. Do you want to synchronize?</string>
<string name="keep_enable">保留启用状态</string>
<string name="preview_image_by_click">点击预览图片</string>
<string name="screen_portrait_reversed">反向竖屏</string>
Expand Down
Loading

0 comments on commit be862ab

Please sign in to comment.