Horis 2 ani în urmă
părinte
comite
0b79704b7b

+ 9 - 1
app/src/main/java/io/legado/app/data/dao/BookDao.kt

@@ -1,6 +1,11 @@
 package io.legado.app.data.dao
 
-import androidx.room.*
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Update
 import io.legado.app.constant.BookType
 import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookGroup
@@ -79,6 +84,9 @@ interface BookDao {
     @Query("SELECT * FROM books WHERE bookUrl = :bookUrl")
     fun getBook(bookUrl: String): Book?
 
+    @Query("SELECT * FROM books WHERE bookUrl = :bookUrl")
+    fun getBookFlow(bookUrl: String): Flow<Book?>
+
     @Query("SELECT * FROM books WHERE name = :name and author = :author")
     fun getBook(name: String, author: String): Book?
 

+ 6 - 0
app/src/main/java/io/legado/app/model/ReadBook.kt

@@ -19,6 +19,7 @@ import io.legado.app.model.webBook.WebBook
 import io.legado.app.service.BaseReadAloudService
 import io.legado.app.ui.book.read.page.entities.TextChapter
 import io.legado.app.ui.book.read.page.provider.ChapterProvider
+import io.legado.app.utils.LogUtils
 import io.legado.app.utils.stackTraceStr
 import io.legado.app.utils.toastOnUi
 import kotlinx.coroutines.CoroutineScope
@@ -208,6 +209,7 @@ object ReadBook : CoroutineScope by MainScope() {
             prevTextChapter = curTextChapter
             curTextChapter = nextTextChapter
             nextTextChapter = null
+            LogUtils.d("moveToNextChapter", "title ${curTextChapter?.chapter?.title}")
             if (curTextChapter == null) {
                 AppLog.putDebug("moveToNextChapter-章节未加载,开始加载")
                 callBack?.upContent()
@@ -238,6 +240,7 @@ object ReadBook : CoroutineScope by MainScope() {
             nextTextChapter = curTextChapter
             curTextChapter = prevTextChapter
             prevTextChapter = null
+            LogUtils.d("moveToPrevChapter", "title ${curTextChapter?.chapter?.title}")
             if (curTextChapter == null) {
                 callBack?.upContent()
                 loadContent(durChapterIndex, upContent, resetPageOffset = false)
@@ -535,7 +538,10 @@ object ReadBook : CoroutineScope by MainScope() {
                         book.getUseReplaceRule()
                     )
                 }
+                LogUtils.d("saveRead", "dur ${book.durChapterTitle}")
             }
+            LogUtils.d("bookDao", "saveRead update latest ${book.latestChapterTitle}")
+            LogUtils.d("bookDao", "saveRead update dur ${book.durChapterTitle}")
             appDb.bookDao.update(book)
         }
     }

+ 45 - 1
app/src/main/java/io/legado/app/ui/about/AboutFragment.kt

@@ -10,11 +10,27 @@ import androidx.preference.Preference
 import androidx.preference.PreferenceFragmentCompat
 import io.legado.app.R
 import io.legado.app.constant.AppConst.appInfo
+import io.legado.app.constant.AppLog
 import io.legado.app.help.AppUpdate
+import io.legado.app.help.config.AppConfig
+import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.ui.widget.dialog.TextDialog
 import io.legado.app.ui.widget.dialog.WaitDialog
-import io.legado.app.utils.*
+import io.legado.app.utils.FileDoc
+import io.legado.app.utils.createFileIfNotExist
+import io.legado.app.utils.createFolderIfNotExist
+import io.legado.app.utils.delete
+import io.legado.app.utils.find
+import io.legado.app.utils.list
+import io.legado.app.utils.openInputStream
+import io.legado.app.utils.openOutputStream
+import io.legado.app.utils.openUrl
+import io.legado.app.utils.sendMail
+import io.legado.app.utils.sendToClip
+import io.legado.app.utils.showDialogFragment
+import io.legado.app.utils.toastOnUi
 import splitties.init.appCtx
+import java.io.File
 
 class AboutFragment : PreferenceFragmentCompat() {
 
@@ -44,6 +60,7 @@ class AboutFragment : PreferenceFragmentCompat() {
             "privacyPolicy" -> showMdFile(getString(R.string.privacy_policy), "privacyPolicy.md")
             "gzGzh" -> requireContext().sendToClip(getString(R.string.legado_gzh))
             "crashLog" -> showDialogFragment<CrashLogsDialog>()
+            "saveLog" -> saveLog()
         }
         return super.onPreferenceTreeClick(preference)
     }
@@ -99,4 +116,31 @@ class AboutFragment : PreferenceFragmentCompat() {
         return false
     }
 
+    private fun saveLog() {
+        Coroutine.async {
+            val backupPath = AppConfig.backupPath ?: let {
+                toastOnUi("未设置备份目录")
+                return@async
+            }
+            val files = FileDoc.fromFile(File(appCtx.externalCacheDir, "logs")).list()
+            if (files.isNullOrEmpty()) {
+                toastOnUi("没有日志")
+                return@async
+            }
+            val doc = FileDoc.fromUri(Uri.parse(backupPath), true)
+            doc.find("logs")?.delete()
+            val logsDoc = doc.createFolderIfNotExist("logs")
+            files.forEach { file ->
+                file.openInputStream().getOrNull()?.use { input ->
+                    logsDoc.createFileIfNotExist(file.name).openOutputStream().getOrNull()?.use {
+                        input.copyTo(it)
+                    }
+                }
+            }
+            toastOnUi("已保存至备份目录")
+        }.onError {
+            AppLog.put("保存日志出错\n${it.localizedMessage}", it, true)
+        }
+    }
+
 }

+ 4 - 0
app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt

@@ -53,6 +53,7 @@ import io.legado.app.ui.widget.dialog.VariableDialog
 import io.legado.app.ui.widget.dialog.WaitDialog
 import io.legado.app.utils.ColorUtils
 import io.legado.app.utils.GSON
+import io.legado.app.utils.LogUtils
 import io.legado.app.utils.StartActivityContract
 import io.legado.app.utils.dpToPx
 import io.legado.app.utils.gone
@@ -300,6 +301,7 @@ class BookInfoActivity :
 
     private fun showBook(book: Book) = binding.run {
         showCover(book)
+        LogUtils.d("showBook", "latest ${book.latestChapterTitle}")
         tvName.text = book.name
         tvAuthor.text = getString(R.string.author_show, book.getRealAuthor())
         tvOrigin.text = getString(R.string.origin_show, book.originName)
@@ -340,6 +342,8 @@ class BookInfoActivity :
 
             else -> {
                 book?.let {
+                    LogUtils.d("upLoading", "latest ${it.latestChapterTitle}")
+                    LogUtils.d("upLoading", "dur ${it.durChapterTitle}")
                     binding.tvToc.text = getString(R.string.toc_s, it.durChapterTitle)
                     binding.tvLasted.text = getString(R.string.lasted_show, it.latestChapterTitle)
                 }

+ 21 - 6
app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt

@@ -33,12 +33,14 @@ import io.legado.app.model.analyzeRule.AnalyzeUrl
 import io.legado.app.model.localBook.LocalBook
 import io.legado.app.model.webBook.WebBook
 import io.legado.app.utils.ArchiveUtils
+import io.legado.app.utils.LogUtils
 import io.legado.app.utils.UrlUtil
 import io.legado.app.utils.isContentScheme
 import io.legado.app.utils.postEvent
 import io.legado.app.utils.toastOnUi
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.launch
 
 class BookInfoViewModel(application: Application) : BaseViewModel(application) {
     val bookData = MutableLiveData<Book>()
@@ -57,6 +59,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
             val bookUrl = intent.getStringExtra("bookUrl") ?: ""
             appDb.bookDao.getBook(name, author)?.let {
                 inBookshelf = true
+                LogUtils.d("BookInfoViewModel initData", "book ${it.name}")
                 upBook(it)
                 return@execute
             }
@@ -89,6 +92,16 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
 
     private fun upBook(book: Book) {
         execute {
+            launch {
+                appDb.bookDao.getBookFlow(book.bookUrl).collect { book ->
+                    book?.let {
+                        LogUtils.d("getBookFlow", "name ${it.name}")
+                        LogUtils.d("getBookFlow", "use replace ${it.getUseReplaceRule()}")
+                        LogUtils.d("getBookFlow", "latest ${it.latestChapterTitle}")
+                        LogUtils.d("getBookFlow", "dur ${it.durChapterTitle}")
+                    }
+                }
+            }
             bookData.postValue(book)
             upCoverByRule(book)
             bookSource = if (book.isLocal) null else
@@ -109,12 +122,14 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
     private fun upCoverByRule(book: Book) {
         execute {
             if (book.coverUrl.isNullOrBlank() && book.customCoverUrl.isNullOrBlank()) {
-                BookCover.searchCover(book)?.let { coverUrl ->
-                    book.customCoverUrl = coverUrl
-                    bookData.postValue(book)
-                    if (inBookshelf) {
-                        saveBook(book)
-                    }
+                val coverUrl = BookCover.searchCover(book)
+                if (coverUrl.isNullOrBlank()) {
+                    return@execute
+                }
+                book.customCoverUrl = coverUrl
+                bookData.postValue(book)
+                if (inBookshelf) {
+                    saveBook(book)
                 }
             }
         }

+ 1 - 0
app/src/main/res/values-es-rES/strings.xml

@@ -1140,4 +1140,5 @@
     <string name="adjust_chapter_index">调整章节位置</string>
     <string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
     <string name="key_page_on_long_press">按键长按翻页</string>
+    <string name="save_log">保存日志</string>
 </resources>

+ 1 - 0
app/src/main/res/values-ja-rJP/strings.xml

@@ -1143,4 +1143,5 @@
     <string name="adjust_chapter_index">调整章节位置</string>
     <string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
     <string name="key_page_on_long_press">按键长按翻页</string>
+    <string name="save_log">保存日志</string>
 </resources>

+ 1 - 0
app/src/main/res/values-pt-rBR/strings.xml

@@ -1143,4 +1143,5 @@
     <string name="adjust_chapter_index">调整章节位置</string>
     <string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
     <string name="key_page_on_long_press">按键长按翻页</string>
+    <string name="save_log">保存日志</string>
 </resources>

+ 1 - 0
app/src/main/res/values-vi/strings.xml

@@ -1139,4 +1139,5 @@ Còn </string>
     <string name="adjust_chapter_index">调整章节位置</string>
     <string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
     <string name="key_page_on_long_press">按键长按翻页</string>
+    <string name="save_log">保存日志</string>
 </resources>

+ 1 - 0
app/src/main/res/values-zh-rHK/strings.xml

@@ -1140,4 +1140,5 @@
     <string name="adjust_chapter_index">调整章节位置</string>
     <string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
     <string name="key_page_on_long_press">按键长按翻页</string>
+    <string name="save_log">保存日志</string>
 </resources>

+ 1 - 0
app/src/main/res/values-zh-rTW/strings.xml

@@ -1142,4 +1142,5 @@
     <string name="adjust_chapter_index">调整章节位置</string>
     <string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
     <string name="key_page_on_long_press">按键长按翻页</string>
+    <string name="save_log">保存日志</string>
 </resources>

+ 1 - 0
app/src/main/res/values-zh/strings.xml

@@ -1142,4 +1142,5 @@
     <string name="adjust_chapter_index">调整章节位置</string>
     <string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
     <string name="key_page_on_long_press">按键长按翻页</string>
+    <string name="save_log">保存日志</string>
 </resources>

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -1143,4 +1143,5 @@
     <string name="adjust_chapter_index">Adjust of chapter index</string>
     <string name="clear_webview_data_success">Cleared successfully, automatically restarts the application after 3 seconds</string>
     <string name="key_page_on_long_press">Press and hold the key to turn the page</string>
+    <string name="save_log">保存日志</string>
 </resources>

+ 5 - 0
app/src/main/res/xml/about.xml

@@ -34,6 +34,11 @@
             android:title="@string/crash_log"
             app:iconSpaceReserved="false" />
 
+        <io.legado.app.lib.prefs.Preference
+            android:key="saveLog"
+            android:title="@string/save_log"
+            app:iconSpaceReserved="false" />
+
         <io.legado.app.lib.prefs.Preference
             android:key="privacyPolicy"
             android:title="@string/privacy_policy"