Horis пре 3 година
родитељ
комит
7b2c7e2dbe

+ 2 - 1
app/src/app/java/io/legado/app/lib/cronet/AbsCallBack.kt

@@ -124,7 +124,7 @@ abstract class AbsCallBack(
         onSuccess(response)
         onSuccess(response)
 
 
         //打印协议,用于调试
         //打印协议,用于调试
-        DebugLog.i(javaClass.simpleName, "start[${info.negotiatedProtocol}]${info.url}")
+        DebugLog.i(javaClass.simpleName, "onResponseStarted[${info.negotiatedProtocol}][${info.httpStatusCode}]${info.url}")
         if (eventListener != null) {
         if (eventListener != null) {
             eventListener.responseHeadersEnd(mCall, response)
             eventListener.responseHeadersEnd(mCall, response)
             eventListener.responseBodyStart(mCall)
             eventListener.responseBodyStart(mCall)
@@ -169,6 +169,7 @@ abstract class AbsCallBack(
     override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
     override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
         canceled.set(true)
         canceled.set(true)
         callbackResults.add(CallbackResult(CallbackStep.ON_CANCELED))
         callbackResults.add(CallbackResult(CallbackStep.ON_CANCELED))
+        //DebugLog.i(javaClass.simpleName, "cancel[${info?.negotiatedProtocol}]${info?.url}")
         eventListener?.callEnd(mCall)
         eventListener?.callEnd(mCall)
         //onError(IOException("Cronet Request Canceled"))
         //onError(IOException("Cronet Request Canceled"))
     }
     }

+ 2 - 0
app/src/app/java/io/legado/app/lib/cronet/NewCallBack.kt

@@ -3,6 +3,7 @@ package io.legado.app.lib.cronet
 import android.os.Build
 import android.os.Build
 import androidx.annotation.Keep
 import androidx.annotation.Keep
 import androidx.annotation.RequiresApi
 import androidx.annotation.RequiresApi
+import io.legado.app.utils.DebugLog
 import okhttp3.Call
 import okhttp3.Call
 import okhttp3.Request
 import okhttp3.Request
 import okhttp3.Response
 import okhttp3.Response
@@ -20,6 +21,7 @@ class NewCallBack(originalRequest: Request, mCall: Call) : AbsCallBack(originalR
     @Throws(IOException::class)
     @Throws(IOException::class)
     override fun waitForDone(urlRequest: UrlRequest): Response {
     override fun waitForDone(urlRequest: UrlRequest): Response {
         urlRequest.start()
         urlRequest.start()
+        //DebugLog.i(javaClass.simpleName, "start ${originalRequest.method} ${originalRequest.url}")
         return if (mCall.timeout().timeoutNanos() > 0) {
         return if (mCall.timeout().timeoutNanos() > 0) {
             responseFuture.get(mCall.timeout().timeoutNanos(), TimeUnit.NANOSECONDS)
             responseFuture.get(mCall.timeout().timeoutNanos(), TimeUnit.NANOSECONDS)
         } else {
         } else {

+ 17 - 6
app/src/main/java/io/legado/app/help/AppWebDav.kt

@@ -69,6 +69,9 @@ object AppWebDav {
             if (!account.isNullOrBlank() && !password.isNullOrBlank()) {
             if (!account.isNullOrBlank() && !password.isNullOrBlank()) {
                 val mAuthorization = Authorization(account, password)
                 val mAuthorization = Authorization(account, password)
                 checkAuthorization(mAuthorization)
                 checkAuthorization(mAuthorization)
+                WebDav(rootWebDavUrl, mAuthorization).makeAsDir()
+                WebDav(bookProgressUrl, mAuthorization).makeAsDir()
+                WebDav(exportsWebDavUrl, mAuthorization).makeAsDir()
                 val rootBooksUrl = "${rootWebDavUrl}books"
                 val rootBooksUrl = "${rootWebDavUrl}books"
                 defaultBookWebDav = RemoteBookWebDav(rootBooksUrl, mAuthorization)
                 defaultBookWebDav = RemoteBookWebDav(rootBooksUrl, mAuthorization)
                 authorization = mAuthorization
                 authorization = mAuthorization
@@ -78,10 +81,7 @@ object AppWebDav {
 
 
     @Throws(WebDavException::class)
     @Throws(WebDavException::class)
     private suspend fun checkAuthorization(authorization: Authorization) {
     private suspend fun checkAuthorization(authorization: Authorization) {
-        if (!WebDav(rootWebDavUrl, authorization).makeAsDir() ||
-            !WebDav(bookProgressUrl, authorization).makeAsDir() ||
-            !WebDav(exportsWebDavUrl, authorization).makeAsDir()
-        ) {
+        if (!WebDav(rootWebDavUrl, authorization).check()) {
             appCtx.removePref(PreferKey.webDavPassword)
             appCtx.removePref(PreferKey.webDavPassword)
             appCtx.toastOnUi(R.string.webdav_application_authorization_error)
             appCtx.toastOnUi(R.string.webdav_application_authorization_error)
             throw WebDavException(appCtx.getString(R.string.webdav_application_authorization_error))
             throw WebDavException(appCtx.getString(R.string.webdav_application_authorization_error))
@@ -213,7 +213,11 @@ object AppWebDav {
     }
     }
 
 
     private fun getProgressUrl(name: String, author: String): String {
     private fun getProgressUrl(name: String, author: String): String {
-        return bookProgressUrl + UrlUtil.replaceReservedChar("${name}_${author}") + ".json"
+        return bookProgressUrl + getProgressFileName(name, author)
+    }
+
+    private fun getProgressFileName(name: String, author: String): String {
+        return UrlUtil.replaceReservedChar("${name}_${author}") + ".json"
     }
     }
 
 
     /**
     /**
@@ -229,15 +233,22 @@ object AppWebDav {
                         return GSON.fromJsonObject<BookProgress>(json).getOrNull()
                         return GSON.fromJsonObject<BookProgress>(json).getOrNull()
                     }
                     }
                 }
                 }
+            }.onFailure {
+                AppLog.put("获取书籍进度失败\n${it.localizedMessage}", it)
             }
             }
         }
         }
         return null
         return null
     }
     }
 
 
     suspend fun downloadAllBookProgress() {
     suspend fun downloadAllBookProgress() {
-        authorization ?: return
+        val authorization = authorization ?: return
         if (!NetworkUtils.isAvailable()) return
         if (!NetworkUtils.isAvailable()) return
+        val bookProgressFiles = WebDav(bookProgressUrl, authorization).listFiles().map {
+            it.displayName
+        }.toHashSet()
         appDb.bookDao.all.forEach { book ->
         appDb.bookDao.all.forEach { book ->
+            val progressFileName = getProgressFileName(book.name, book.author)
+            if (!bookProgressFiles.contains(progressFileName)) return@forEach
             getBookProgress(book)?.let { bookProgress ->
             getBookProgress(book)?.let { bookProgress ->
                 if (bookProgress.durChapterIndex > book.durChapterIndex
                 if (bookProgress.durChapterIndex > book.durChapterIndex
                     || (bookProgress.durChapterIndex == book.durChapterIndex
                     || (bookProgress.durChapterIndex == book.durChapterIndex

+ 20 - 6
app/src/main/java/io/legado/app/lib/webdav/WebDav.kt

@@ -229,10 +229,24 @@ open class WebDav(
                 addHeader("Depth", "0")
                 addHeader("Depth", "0")
                 val requestBody = EXISTS.toRequestBody("application/xml".toMediaType())
                 val requestBody = EXISTS.toRequestBody("application/xml".toMediaType())
                 method("PROPFIND", requestBody)
                 method("PROPFIND", requestBody)
-            }.isSuccessful
+            }.use { it.isSuccessful }
         }.getOrDefault(false)
         }.getOrDefault(false)
     }
     }
 
 
+    /**
+     * 检查用户名密码是否有效
+     */
+    suspend fun check(): Boolean {
+        return kotlin.runCatching {
+            webDavClient.newCallResponse {
+                url(url)
+                addHeader("Depth", "0")
+                val requestBody = EXISTS.toRequestBody("application/xml".toMediaType())
+                method("PROPFIND", requestBody)
+            }.use { it.code != 401 }
+        }.getOrDefault(true)
+    }
+
     /**
     /**
      * 根据自己的URL,在远程处创建对应的文件夹
      * 根据自己的URL,在远程处创建对应的文件夹
      * @return 是否创建成功
      * @return 是否创建成功
@@ -245,7 +259,7 @@ open class WebDav(
                 webDavClient.newCallResponse {
                 webDavClient.newCallResponse {
                     url(url)
                     url(url)
                     method("MKCOL", null)
                     method("MKCOL", null)
-                }.let {
+                }.use {
                     checkResult(it)
                     checkResult(it)
                 }
                 }
             }
             }
@@ -300,7 +314,7 @@ open class WebDav(
                 webDavClient.newCallResponse {
                 webDavClient.newCallResponse {
                     url(url)
                     url(url)
                     put(fileBody)
                     put(fileBody)
-                }.let {
+                }.use {
                     checkResult(it)
                     checkResult(it)
                 }
                 }
             }
             }
@@ -320,7 +334,7 @@ open class WebDav(
                 webDavClient.newCallResponse {
                 webDavClient.newCallResponse {
                     url(url)
                     url(url)
                     put(fileBody)
                     put(fileBody)
-                }.let {
+                }.use {
                     checkResult(it)
                     checkResult(it)
                 }
                 }
             }
             }
@@ -340,7 +354,7 @@ open class WebDav(
                 webDavClient.newCallResponse {
                 webDavClient.newCallResponse {
                     url(url)
                     url(url)
                     put(fileBody)
                     put(fileBody)
-                }.let {
+                }.use {
                     checkResult(it)
                     checkResult(it)
                 }
                 }
             }
             }
@@ -371,7 +385,7 @@ open class WebDav(
             webDavClient.newCallResponse {
             webDavClient.newCallResponse {
                 url(url)
                 url(url)
                 method("DELETE", null)
                 method("DELETE", null)
-            }.let {
+            }.use {
                 checkResult(it)
                 checkResult(it)
             }
             }
         }.onFailure {
         }.onFailure {

+ 21 - 10
app/src/main/java/io/legado/app/model/ReadBook.kt

@@ -21,6 +21,7 @@ import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.MainScope
 import kotlinx.coroutines.MainScope
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
 import splitties.init.appCtx
 import splitties.init.appCtx
 import kotlin.math.min
 import kotlin.math.min
 
 
@@ -51,6 +52,9 @@ object ReadBook : CoroutineScope by MainScope() {
     /* web端阅读进度记录 */
     /* web端阅读进度记录 */
     var webBookProgress: BookProgress? = null
     var webBookProgress: BookProgress? = null
 
 
+    var preDownloadTask: Coroutine<*>? = null
+    val downloadedChapters = hashSetOf<Int>()
+
     //暂时保存跳转前进度
     //暂时保存跳转前进度
     fun saveCurrentBookProcess() {
     fun saveCurrentBookProcess() {
         if (lastBookPress != null) return //避免进度条连续跳转不能覆盖最初的进度记录
         if (lastBookPress != null) return //避免进度条连续跳转不能覆盖最初的进度记录
@@ -319,7 +323,7 @@ object ReadBook : CoroutineScope by MainScope() {
     /**
     /**
      * 下载正文
      * 下载正文
      */
      */
-    private fun downloadIndex(index: Int) {
+    private suspend fun downloadIndex(index: Int) {
         if (index < 0) return
         if (index < 0) return
         if (index > chapterSize - 1) {
         if (index > chapterSize - 1) {
             upToc()
             upToc()
@@ -331,7 +335,9 @@ object ReadBook : CoroutineScope by MainScope() {
                 appDb.bookChapterDao.getChapter(book.bookUrl, index)?.let { chapter ->
                 appDb.bookChapterDao.getChapter(book.bookUrl, index)?.let { chapter ->
                     if (BookHelp.hasContent(book, chapter)) {
                     if (BookHelp.hasContent(book, chapter)) {
                         removeLoading(chapter.index)
                         removeLoading(chapter.index)
+                        downloadedChapters.add(chapter.index)
                     } else {
                     } else {
+                        delay(1000)
                         download(this, chapter, false)
                         download(this, chapter, false)
                     }
                     }
                 } ?: removeLoading(index)
                 } ?: removeLoading(index)
@@ -482,17 +488,22 @@ object ReadBook : CoroutineScope by MainScope() {
         if (AppConfig.preDownloadNum < 2) {
         if (AppConfig.preDownloadNum < 2) {
             return
             return
         }
         }
-        Coroutine.async {
+        preDownloadTask?.cancel()
+        preDownloadTask = Coroutine.async {
             //预下载
             //预下载
-            val maxChapterIndex = durChapterIndex + AppConfig.preDownloadNum
-            for (i in durChapterIndex.plus(2)..maxChapterIndex) {
-                delay(1000)
-                downloadIndex(i)
+            launch {
+                val maxChapterIndex = min(durChapterIndex + AppConfig.preDownloadNum, chapterSize)
+                for (i in durChapterIndex.plus(2)..maxChapterIndex) {
+                    if (downloadedChapters.contains(i)) continue
+                    downloadIndex(i)
+                }
             }
             }
-            val minChapterIndex = durChapterIndex - min(5, AppConfig.preDownloadNum)
-            for (i in durChapterIndex.minus(2) downTo minChapterIndex) {
-                delay(1000)
-                downloadIndex(i)
+            launch {
+                val minChapterIndex = durChapterIndex - min(5, AppConfig.preDownloadNum)
+                for (i in durChapterIndex.minus(2) downTo minChapterIndex) {
+                    if (downloadedChapters.contains(i)) continue
+                    downloadIndex(i)
+                }
             }
             }
         }
         }
     }
     }

+ 2 - 2
app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt

@@ -143,7 +143,7 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
 
 
                 mText.isUri() -> {
                 mText.isUri() -> {
                     val uri = Uri.parse(mText)
                     val uri = Uri.parse(mText)
-                    uri.inputStream(context).getOrThrow().let {
+                    uri.inputStream(context).getOrThrow().use {
                         allSources.addAll(GSON.fromJsonArray<BookSource>(it).getOrThrow())
                         allSources.addAll(GSON.fromJsonArray<BookSource>(it).getOrThrow())
                     }
                     }
                 }
                 }
@@ -166,7 +166,7 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
             } else {
             } else {
                 url(url)
                 url(url)
             }
             }
-        }.byteStream().let {
+        }.byteStream().use {
             allSources.addAll(GSON.fromJsonArray<BookSource>(it).getOrThrow())
             allSources.addAll(GSON.fromJsonArray<BookSource>(it).getOrThrow())
         }
         }
     }
     }

+ 26 - 29
app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt

@@ -1220,30 +1220,27 @@ class ReadBookActivity : BaseReadBookActivity(),
         val previousResult = binding.searchMenu.previousSearchResult
         val previousResult = binding.searchMenu.previousSearchResult
 
 
         fun jumpToPosition() {
         fun jumpToPosition() {
-            ReadBook.curTextChapter?.let {
-                binding.searchMenu.updateSearchInfo()
-                val (pageIndex, lineIndex, charIndex, addLine, charIndex2) =
-                    viewModel.searchResultPositions(it, searchResult)
-                ReadBook.skipToPage(pageIndex) {
-                    launch {
-                        isSelectingSearchResult = true
-                        binding.readView.curPage.selectStartMoveIndex(0, lineIndex, charIndex)
-                        when (addLine) {
-                            0 -> binding.readView.curPage.selectEndMoveIndex(
-                                0,
-                                lineIndex,
-                                charIndex + viewModel.searchContentQuery.length - 1
-                            )
-                            1 -> binding.readView.curPage.selectEndMoveIndex(
-                                0, lineIndex + 1, charIndex2
-                            )
-                            //consider change page, jump to scroll position
-                            -1 -> binding.readView.curPage.selectEndMoveIndex(1, 0, charIndex2)
-                        }
-                        binding.readView.isTextSelected = true
-                        isSelectingSearchResult = false
-                    }
+            val curTextChapter = ReadBook.curTextChapter ?: return
+            binding.searchMenu.updateSearchInfo()
+            val (pageIndex, lineIndex, charIndex, addLine, charIndex2) =
+                viewModel.searchResultPositions(curTextChapter, searchResult)
+            ReadBook.skipToPage(pageIndex) {
+                isSelectingSearchResult = true
+                binding.readView.curPage.selectStartMoveIndex(0, lineIndex, charIndex)
+                when (addLine) {
+                    0 -> binding.readView.curPage.selectEndMoveIndex(
+                        0,
+                        lineIndex,
+                        charIndex + viewModel.searchContentQuery.length - 1
+                    )
+                    1 -> binding.readView.curPage.selectEndMoveIndex(
+                        0, lineIndex + 1, charIndex2
+                    )
+                    //consider change page, jump to scroll position
+                    -1 -> binding.readView.curPage.selectEndMoveIndex(1, 0, charIndex2)
                 }
                 }
+                binding.readView.isTextSelected = true
+                isSelectingSearchResult = false
             }
             }
         }
         }
 
 
@@ -1281,13 +1278,11 @@ class ReadBookActivity : BaseReadBookActivity(),
 
 
     private fun startBackupJob() {
     private fun startBackupJob() {
         backupJob?.cancel()
         backupJob?.cancel()
-        backupJob = launch {
+        backupJob = launch(IO) {
             delay(300000)
             delay(300000)
-            withContext(IO) {
-                ReadBook.book?.let {
-                    AppWebDav.uploadBookProgress(it)
-                    Backup.autoBack(this@ReadBookActivity)
-                }
+            ReadBook.book?.let {
+                AppWebDav.uploadBookProgress(it)
+                Backup.autoBack(this@ReadBookActivity)
             }
             }
         }
         }
     }
     }
@@ -1323,6 +1318,8 @@ class ReadBookActivity : BaseReadBookActivity(),
         if (ReadBook.callBack === this) {
         if (ReadBook.callBack === this) {
             ReadBook.callBack = null
             ReadBook.callBack = null
         }
         }
+        ReadBook.preDownloadTask?.cancel()
+        ReadBook.downloadedChapters.clear()
         if (!BuildConfig.DEBUG) {
         if (!BuildConfig.DEBUG) {
             Backup.autoBack(this)
             Backup.autoBack(this)
         }
         }

+ 5 - 3
app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt

@@ -1,6 +1,8 @@
 package io.legado.app.ui.book.toc
 package io.legado.app.ui.book.toc
 
 
 import android.content.Context
 import android.content.Context
+import android.os.Handler
+import android.os.Looper
 import android.view.ViewGroup
 import android.view.ViewGroup
 import androidx.recyclerview.widget.DiffUtil
 import androidx.recyclerview.widget.DiffUtil
 import io.legado.app.R
 import io.legado.app.R
@@ -19,7 +21,6 @@ import io.legado.app.utils.gone
 import io.legado.app.utils.longToastOnUi
 import io.legado.app.utils.longToastOnUi
 import io.legado.app.utils.visible
 import io.legado.app.utils.visible
 import kotlinx.coroutines.*
 import kotlinx.coroutines.*
-import kotlinx.coroutines.Dispatchers.Main
 import java.util.concurrent.ConcurrentHashMap
 import java.util.concurrent.ConcurrentHashMap
 
 
 class ChapterListAdapter(context: Context, val callback: Callback) :
 class ChapterListAdapter(context: Context, val callback: Callback) :
@@ -27,6 +28,7 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
 
 
     val cacheFileNames = hashSetOf<String>()
     val cacheFileNames = hashSetOf<String>()
     private val displayTitleMap = ConcurrentHashMap<String, String>()
     private val displayTitleMap = ConcurrentHashMap<String, String>()
+    private val handler = Handler(Looper.getMainLooper())
 
 
     override val diffItemCallback: DiffUtil.ItemCallback<BookChapter>
     override val diffItemCallback: DiffUtil.ItemCallback<BookChapter>
         get() = object : DiffUtil.ItemCallback<BookChapter>() {
         get() = object : DiffUtil.ItemCallback<BookChapter>() {
@@ -80,7 +82,7 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
                         val displayTitle = item.getDisplayTitle(replaceRules, useReplace)
                         val displayTitle = item.getDisplayTitle(replaceRules, useReplace)
                         ensureActive()
                         ensureActive()
                         displayTitleMap[item.title] = displayTitle
                         displayTitleMap[item.title] = displayTitle
-                        withContext(Main) {
+                        handler.post {
                             notifyItemChanged(i, true)
                             notifyItemChanged(i, true)
                         }
                         }
                     }
                     }
@@ -94,7 +96,7 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
                         val displayTitle = item.getDisplayTitle(replaceRules, useReplace)
                         val displayTitle = item.getDisplayTitle(replaceRules, useReplace)
                         ensureActive()
                         ensureActive()
                         displayTitleMap[item.title] = displayTitle
                         displayTitleMap[item.title] = displayTitle
-                        withContext(Main) {
+                        handler.post {
                             notifyItemChanged(i, true)
                             notifyItemChanged(i, true)
                         }
                         }
                     }
                     }

+ 7 - 0
app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt

@@ -158,6 +158,7 @@ class BackupConfigFragment : PreferenceFragment(),
                 showHelp()
                 showHelp()
                 return true
                 return true
             }
             }
+
             R.id.menu_log -> showDialogFragment<AppLogDialog>()
             R.id.menu_log -> showDialogFragment<AppLogDialog>()
         }
         }
         return false
         return false
@@ -174,6 +175,7 @@ class BackupConfigFragment : PreferenceFragment(),
     }
     }
 
 
     override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
     override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
+        context ?: return
         when (key) {
         when (key) {
             PreferKey.backupPath -> upPreferenceSummary(key, getPrefString(key))
             PreferKey.backupPath -> upPreferenceSummary(key, getPrefString(key))
             PreferKey.webDavUrl,
             PreferKey.webDavUrl,
@@ -183,6 +185,7 @@ class BackupConfigFragment : PreferenceFragment(),
                 upPreferenceSummary(key, getPrefString(key))
                 upPreferenceSummary(key, getPrefString(key))
                 viewModel.upWebDavConfig()
                 viewModel.upWebDavConfig()
             }
             }
+
             PreferKey.webDavDeviceName -> upPreferenceSummary(key, getPrefString(key))
             PreferKey.webDavDeviceName -> upPreferenceSummary(key, getPrefString(key))
         }
         }
     }
     }
@@ -196,22 +199,26 @@ class BackupConfigFragment : PreferenceFragment(),
                 } else {
                 } else {
                     preference.summary = value.toString()
                     preference.summary = value.toString()
                 }
                 }
+
             PreferKey.webDavAccount ->
             PreferKey.webDavAccount ->
                 if (value.isNullOrBlank()) {
                 if (value.isNullOrBlank()) {
                     preference.summary = getString(R.string.web_dav_account_s)
                     preference.summary = getString(R.string.web_dav_account_s)
                 } else {
                 } else {
                     preference.summary = value.toString()
                     preference.summary = value.toString()
                 }
                 }
+
             PreferKey.webDavPassword ->
             PreferKey.webDavPassword ->
                 if (value.isNullOrBlank()) {
                 if (value.isNullOrBlank()) {
                     preference.summary = getString(R.string.web_dav_pw_s)
                     preference.summary = getString(R.string.web_dav_pw_s)
                 } else {
                 } else {
                     preference.summary = "*".repeat(value.toString().length)
                     preference.summary = "*".repeat(value.toString().length)
                 }
                 }
+
             PreferKey.webDavDir -> preference.summary = when (value) {
             PreferKey.webDavDir -> preference.summary = when (value) {
                 null -> "legado"
                 null -> "legado"
                 else -> value
                 else -> value
             }
             }
+
             else -> {
             else -> {
                 if (preference is ListPreference) {
                 if (preference is ListPreference) {
                     val index = preference.findIndexOfValue(value)
                     val index = preference.findIndexOfValue(value)

+ 0 - 2
modules/web/src/components.d.ts

@@ -22,14 +22,12 @@ declare module '@vue/runtime-core' {
     ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
     ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
     ElLink: typeof import('element-plus/es')['ElLink']
     ElLink: typeof import('element-plus/es')['ElLink']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElOption: typeof import('element-plus/es')['ElOption']
-    ElPopover: typeof import('element-plus/es')['ElPopover']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElTabPane: typeof import('element-plus/es')['ElTabPane']
     ElTabPane: typeof import('element-plus/es')['ElTabPane']
     ElTabs: typeof import('element-plus/es')['ElTabs']
     ElTabs: typeof import('element-plus/es')['ElTabs']
     ElTag: typeof import('element-plus/es')['ElTag']
     ElTag: typeof import('element-plus/es')['ElTag']
     ElText: typeof import('element-plus/es')['ElText']
     ElText: typeof import('element-plus/es')['ElText']
-    ElTooltip: typeof import('element-plus/es')['ElTooltip']
     PopCatalog: typeof import('./components/PopCatalog.vue')['default']
     PopCatalog: typeof import('./components/PopCatalog.vue')['default']
     ReadSettings: typeof import('./components/ReadSettings.vue')['default']
     ReadSettings: typeof import('./components/ReadSettings.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterLink: typeof import('vue-router')['RouterLink']

+ 1 - 1
modules/web/src/components/SourceDebug.vue

@@ -27,7 +27,7 @@ const store = useSourceStore();
 const printDebug = ref("");
 const printDebug = ref("");
 const searchKey = ref("");
 const searchKey = ref("");
 
 
-watchEffect(() => {
+watch(() => store.isDebuging, () => {
   if (store.isDebuging) startDebug();
   if (store.isDebuging) startDebug();
 });
 });