diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt index 2c0adfd48bfa..2ce1bec082ad 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -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" diff --git a/app/src/main/java/io/legado/app/help/config/AppConfig.kt b/app/src/main/java/io/legado/app/help/config/AppConfig.kt index e1f244ea6ad6..762a1e025ad3 100644 --- a/app/src/main/java/io/legado/app/help/config/AppConfig.kt +++ b/app/src/main/java/io/legado/app/help/config/AppConfig.kt @@ -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 diff --git a/app/src/main/java/io/legado/app/model/ReadBook.kt b/app/src/main/java/io/legado/app/model/ReadBook.kt index 8ec329eb7b48..ed7ade90c1dd 100644 --- a/app/src/main/java/io/legado/app/model/ReadBook.kt +++ b/app/src/main/java/io/legado/app/model/ReadBook.kt @@ -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() + } } } } @@ -893,6 +928,8 @@ object ReadBook : CoroutineScope by MainScope() { fun notifyBookChanged() + fun sureNewProgress(progress: BookProgress) + fun cancelSelect() } diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index 92a47de4b79d..5cdbc0ce18b9 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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.* /** * 阅读界面 @@ -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?) { @@ -289,6 +250,7 @@ class ReadBookActivity : BaseReadBookActivity(), viewModel.initData(intent) false } + justInitData = true } override fun onNewIntent(intent: Intent) { @@ -318,6 +280,7 @@ class ReadBookActivity : BaseReadBookActivity(), bookChanged = false ReadBook.callBack = this viewModel.initData(intent) + justInitData = true } else { //web端阅读时,app处于阅读界面,本地记录会覆盖web保存的进度,在此处恢复 ReadBook.webBookProgress?.let { @@ -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() { @@ -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 { @@ -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 + } } } @@ -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) @@ -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() diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt index 9c863a99c917..79e11e2f9190 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt @@ -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) diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ClickActionConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ClickActionConfigDialog.kt index 3b4b590de20c..17d7da38b6fd 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ClickActionConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ClickActionConfigDialog.kt @@ -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)) ) } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt index 9a1c313ee63c..6c15dbca31fb 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt @@ -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 @@ -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 @@ -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)) }) } } @@ -726,5 +732,6 @@ class ReadView(context: Context, attrs: AttributeSet) : fun changeReplaceRuleState() fun openSearchActivity(searchWord: String?) fun upSystemUiVisibility() + fun sureNewProgress(progress: BookProgress) } } diff --git a/app/src/main/res/menu/book_read.xml b/app/src/main/res/menu/book_read.xml index ac98ea66db52..85f526aecfc3 100644 --- a/app/src/main/res/menu/book_read.xml +++ b/app/src/main/res/menu/book_read.xml @@ -65,6 +65,12 @@ android:visible="false" app:showAsAction="never" /> + + Suscripción de reglsa 添加大佬们提供的规则导入地址\n添加后点击可导入规则 Obtener progreso en la nube + Cobertura del progreso en la nube El progreso actual excede el progreso de la nube. ¿Quieres sincronizar? Progreso de lectura sincronizado Sincronizar el progreso de la lectura al entrar y salir de la pantalla de lectura + Mejora de Sincronización + 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 No se pudo marcar URL única Exportar lista de libros @@ -1129,8 +1132,10 @@ 点击书名打开详情 等待导出 默认主页 + " Sincronización del progreso exitosa" 显示快速滚动条 导出所有书的书源 + The cloud progress exceeds the current progress. Do you want to synchronize? 保留启用状态 点击预览图片 反向竖屏 diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index d373e0c5147c..8e9e8dfc557c 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -808,10 +808,13 @@ footer header Rule Subscription 添加大佬们提供的规则导入地址\n添加后点击可导入规则 - Pull the cloud progress + クラウド上の進捗状況のカバー + Cobertura do progresso na nuvem The current progress exceeds the cloud progress. Do you want to synchronize? Synchronous reading progress Synchronize reading progress when entering / exiting the reading interface + 同期強化 + ページに再入力する時(スリープ解除やバックグラウンドから復帰など)、またはネットワークが利用可能になるとクラウド進捗を同期します Failed to create bookmark Single URL Export the list of books @@ -1132,8 +1135,10 @@ 点击书名打开详情 等待导出 默认主页 + Sync progress success 显示快速滚动条 导出所有书的书源 + The cloud progress exceeds the current progress. Do you want to synchronize? 保留启用状态 点击预览图片 反向竖屏 diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index c4baf3d08e6c..3d4463de60fa 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -807,9 +807,12 @@ Assinatura de regras 添加大佬们提供的规则导入地址\n添加后点击可导入规则 Obter o progresso da nuvem + Phủ sóng tiến độ trên đám mây O progresso atual excede o progresso da nuvem. Você quer sincronizar? Progresso de leitura sincronizada Sincronizar o progresso da leitura ao entrar e sair da tela de leitura + Aprimoramento de Sincronização + Sincronizar o progresso na nuvem ao reentrar na página (por exemplo, após desligar a tela ou ao retornar do fundo) ou quando a rede estiver disponível Falha ao marcar como favorito URL única Exportar a lista de livros @@ -1132,8 +1135,10 @@ 点击书名打开详情 等待导出 默认主页 + Sincronização de progresso bem-sucedida 显示快速滚动条 导出所有书的书源 + The cloud progress exceeds the current progress. Do you want to synchronize? 保留启用状态 点击预览图片 反向竖屏 diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index f52b4898c7b1..2098aee475c7 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -808,9 +808,12 @@ Còn Quy tắc đăng ký Thêm địa chỉ nhập quy tắc do các ông chủ cung cấp\\nNhấp để nhập quy tắc sau khi thêm Kéo tiến độ đám mây + Phủ sóng tiến độ trên đám mây Tiến độ hiện tại vượt quá tiến độ đám mây. Bạn có muốn đồng bộ hóa? Tiến độ đọc đồng bộ Đồng bộ tiến độ đọc khi vào/ra khỏi giao diện đọc + Cải Tiến Đồng Bộ + Đồng bộ tiến độ trên đám mây khi quay lại trang (ví dụ: sau khi tắt màn hình, quay trở lại từ nền, v.v.) hoặc khi mạng trở nên khả dụng Không thể tạo dấu trang URL đơn Xuất bookshelf @@ -1127,9 +1130,11 @@ Còn 换源间隔 点击书名打开详情 等待导出 + " Đồng bộ hóa tiến trình thành công" 默认主页 显示快速滚动条 导出所有书的书源 + The cloud progress exceeds the current progress. Do you want to synchronize? 保留启用状态 点击预览图片 反向竖屏 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index e9e10d768fa6..15d8027d5e98 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -807,9 +807,12 @@ 規則訂閱 添加大佬們提供的規則匯入地址 添加後點擊可匯入規則 拉取雲端進度 + 覆蓋雲端進度 目前進度超過雲端進度,係咪同步? 同步閱讀進度 進入退出閱讀介面時同步閱讀進度 + 同步增強 + 重新進入頁面(熄屏、返回背景等)或者當網絡可用時同步雲端進度 建立書籤失敗 單URL 導出書單 @@ -1128,9 +1131,11 @@ 换源间隔 点击书名打开详情 等待导出 + 進度同步成功 默认主页 显示快速滚动条 导出所有书的书源 + 雲端進度超過目前進度,是否同步? 保留启用状态 点击预览图片 反向竖屏 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 72d29400b887..6996bf91699a 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -810,9 +810,12 @@ 規則訂閱 新增大佬們提供的規則匯入地址\n新增後點擊可匯入規則 拉取雲端進度 + 覆蓋雲端進度 目前進度超過雲端進度,是否同步? 同步閱讀進度 進入退出閱讀介面時同步閱讀進度 + 同步增強 + 重新進入頁面(熄屏、背景返回等)或網路變為可用時同步雲端進度 建立書籤失敗 單URL 匯出書單 @@ -1130,9 +1133,11 @@ 换源间隔 点击书名打开详情 等待导出 + 進度同步成功 默认主页 显示快速滚动条 导出所有书的书源 + 雲端進度超過目前進度,是否同步? 保留启用状态 点击预览图片 反向竖屏 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 68c42f6ac64d..a001c751eb90 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -813,9 +813,12 @@ 规则订阅 添加大佬们提供的规则导入地址\n添加后点击可导入规则 拉取云端进度 + 覆盖云端进度 当前进度超过云端进度,是否同步? 同步阅读进度 进入退出阅读界面时同步阅读进度 + 同步增强 + 重新进入页面(息屏、后台返回等)或者网络变为可用时同步云端进度 创建书签失败 单 URL 导出书单 @@ -1130,9 +1133,11 @@ 换源间隔 点击书名打开详情 等待导出 + 进度同步成功 默认主页 显示快速滚动条 导出所有书的书源 + 云端进度超过当前进度,是否同步? 保留启用状态 点击预览图片 反向竖屏 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 783d0f3e6bdb..c31a27ce4392 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -812,9 +812,14 @@ Rule Subscription Add the rule import address provided by the bosses\nClick to import rules after adding Pull the cloud progress + Overlay Cloud Progress The current progress exceeds the cloud progress. Do you want to synchronize? + The cloud progress exceeds the current progress. Do you want to synchronize? Synchronous reading progress Synchronize reading progress when entering / exiting the reading interface + Sync Enhancement + Sync cloud progress when re-entering the page (e.g., after screen off, returning from background, etc.) or when the network becomes available + Sync progress success Failed to create bookmark Single URL Export the list of books diff --git a/app/src/main/res/xml/pref_config_backup.xml b/app/src/main/res/xml/pref_config_backup.xml index b02913d7ce51..0a5d9c77f0f6 100644 --- a/app/src/main/res/xml/pref_config_backup.xml +++ b/app/src/main/res/xml/pref_config_backup.xml @@ -50,6 +50,16 @@ app:allowDividerBelow="false" app:iconSpaceReserved="false" /> + +