Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

kunfei 3 лет назад
Родитель
Сommit
82d7cc2da4

+ 4 - 0
app/src/main/java/io/legado/app/constant/BookType.kt

@@ -37,6 +37,10 @@ object BookType {
      */
     const val local = 0b100000000
 
+    /**
+     * 512 压缩包 表明书籍文件是从压缩包内解压来的
+     */
+    const val archive = 0b1000000000
 
     @Target(AnnotationTarget.VALUE_PARAMETER)
     @Retention(AnnotationRetention.SOURCE)

+ 1 - 1
app/src/main/java/io/legado/app/data/DatabaseMigrations.kt

@@ -355,7 +355,7 @@ object DatabaseMigrations {
             db.execSQL(
                 """
                 update books set type = type | ${BookType.local}
-                where origin = '${BookType.localTag}' or origin like '${BookType.webDavTag}%'
+                where origin like '${BookType.localTag}%' or origin like '${BookType.webDavTag}%'
             """.trimIndent()
             )
         }

+ 15 - 2
app/src/main/java/io/legado/app/help/book/BookExtensions.kt

@@ -55,6 +55,19 @@ val Book.isWebFile: Boolean
 val Book.isUpError: Boolean
     get() = isType(BookType.updateError)
 
+val Book.isArchive: Boolean
+    get() = isType(BookType.archive)
+
+val Book.archiveName: String?
+    get() {
+        return if (isArchive) {
+            // local_book::archive.rar
+            origin.substring(BookType.localTag.length + 2)
+        } else {
+            null
+        }
+    }
+
 fun Book.contains(word: String?): Boolean {
     if (word.isNullOrEmpty()) {
         return true
@@ -139,7 +152,7 @@ fun Book.removeLocalUriCache() {
 
 fun Book.getRemoteUrl(): String? {
     if (origin.startsWith(BookType.webDavTag)) {
-        return origin.substring(8)
+        return origin.substring(BookType.webDavTag.length)
     }
     return null
 }
@@ -175,7 +188,7 @@ fun Book.upType() {
             BookSourceType.file -> BookType.webFile
             else -> BookType.text
         }
-        if (origin == "loc_book" || origin.startsWith(BookType.webDavTag)) {
+        if (origin == BookType.localTag || origin.startsWith(BookType.webDavTag)) {
             type = type or BookType.local
         }
     }

+ 9 - 3
app/src/main/java/io/legado/app/model/localBook/LocalBook.kt

@@ -190,18 +190,24 @@ object LocalBook {
 
     /* 导入压缩包内的书籍 */
     fun importArchiveFile(
-        uri: Uri,
+        archiveFileUri: Uri,
         saveFileName: String? = null,
         filter: ((String) -> Boolean)? = null
     ): List<Book> {
-        val files = ArchiveUtils.deCompress(uri, filter = filter)
+        val archiveFileDoc = FileDoc.fromUri(archiveFileUri, false)
+        val files = ArchiveUtils.deCompress(archiveFileDoc, filter = filter)
         if (files.isEmpty()) throw NoStackTraceException(appCtx.getString(R.string.unsupport_archivefile_entry))
         return files.map {
             saveBookFile(
                     FileInputStream(it),
                     saveFileName ?: it.name
             ).let {
-                importFile(it)
+                importFile(it).apply {
+                    //附加压缩包文件名 以便判断书籍导入界面压缩包是否导入
+                    origin = "${BookType.localTag}::${archiveFileDoc.name}"
+                    addType(BookType.archive)
+                    save()
+                }
             }
         }
     }

+ 1 - 3
app/src/main/java/io/legado/app/ui/book/import/BaseImportBookActivity.kt

@@ -13,9 +13,7 @@ import io.legado.app.lib.dialogs.alert
 import io.legado.app.lib.theme.primaryTextColor
 import io.legado.app.ui.book.read.ReadBookActivity
 import io.legado.app.ui.document.HandleFileContract
-import io.legado.app.utils.applyTint
-import io.legado.app.utils.hideSoftInput
-import io.legado.app.utils.startActivity
+import io.legado.app.utils.*
 import io.legado.app.utils.viewbindingdelegate.viewBinding
 
 import kotlin.coroutines.resume

+ 18 - 2
app/src/main/java/io/legado/app/ui/book/import/local/ImportBookActivity.kt

@@ -11,6 +11,7 @@ import androidx.documentfile.provider.DocumentFile
 import androidx.recyclerview.widget.LinearLayoutManager
 import io.legado.app.R
 import io.legado.app.constant.AppConst
+import io.legado.app.constant.AppPattern
 import io.legado.app.constant.PreferKey
 import io.legado.app.data.appDb
 import io.legado.app.databinding.DialogEditTextBinding
@@ -132,7 +133,7 @@ class ImportBookActivity : BaseImportBookActivity<ImportBookViewModel>(),
             initRootDoc()
         }
         launch {
-            appDb.bookDao.flowLocalUri().conflate().collect {
+            appDb.bookDao.flowLocal().conflate().collect {
                 adapter.upBookHas(it)
             }
         }
@@ -300,6 +301,21 @@ class ImportBookActivity : BaseImportBookActivity<ImportBookViewModel>(),
         binding.selectActionBar.upCountView(adapter.selectedUris.size, adapter.checkableCount)
     }
 
-    override fun startRead(bookUrl: String) = startReadBook(bookUrl)
+    override fun startRead(fileDoc: FileDoc) {
+        if (!ArchiveUtils.isArchive(fileDoc.name)) {
+            startReadBook(fileDoc.toString())
+        } else {
+            val fileNames = ArchiveUtils.getArchiveFilesName(fileDoc) {
+                it.matches(AppPattern.bookFileRegex)
+            }
+            if (fileNames.size == 1) {
+                appDb.bookDao.getBookByFileName(fileNames[0])?.let {
+                    startReadBook(it.bookUrl)
+                }
+            } else {
+                //onArchiveFileClick(fileNames)
+            }
+        }
+    }
 
 }

+ 28 - 13
app/src/main/java/io/legado/app/ui/book/import/local/ImportBookAdapter.kt

@@ -8,7 +8,10 @@ import io.legado.app.R
 import io.legado.app.base.adapter.ItemViewHolder
 import io.legado.app.base.adapter.RecyclerAdapter
 import io.legado.app.constant.AppConst
+import io.legado.app.data.entities.Book
 import io.legado.app.databinding.ItemImportBookBinding
+import io.legado.app.help.book.archiveName
+import io.legado.app.help.book.isArchive
 import io.legado.app.utils.*
 
 
@@ -16,7 +19,7 @@ class ImportBookAdapter(context: Context, val callBack: CallBack) :
     RecyclerAdapter<FileDoc, ItemImportBookBinding>(context) {
     val selectedUris = hashSetOf<String>()
     var checkableCount = 0
-    private val bookNamesOnBookShelf = arrayListOf<String>()
+    private val bookOrArchiveNamesOnBookShelf = arrayListOf<String>()
 
     override fun getViewBinding(parent: ViewGroup): ItemImportBookBinding {
         return ItemImportBookBinding.inflate(inflater, parent, false)
@@ -41,7 +44,7 @@ class ImportBookAdapter(context: Context, val callBack: CallBack) :
                     llBrief.gone()
                     cbSelect.isChecked = false
                 } else {
-                    if (bookNamesOnBookShelf.contains(item.name)) {
+                    if (isOnBookShelf(item)) {
                         ivIcon.setImageResource(R.drawable.ic_book_has)
                         ivIcon.visible()
                         cbSelect.invisible()
@@ -67,7 +70,7 @@ class ImportBookAdapter(context: Context, val callBack: CallBack) :
             getItem(holder.layoutPosition)?.let {
                 if (it.isDir) {
                     callBack.nextDoc(it)
-                } else if (!bookNamesOnBookShelf.contains(it.name)) {
+                } else if (!isOnBookShelf(it)) {
                     if (!selectedUris.contains(it.toString())) {
                         selectedUris.add(it.toString())
                     } else {
@@ -77,18 +80,30 @@ class ImportBookAdapter(context: Context, val callBack: CallBack) :
                     callBack.upCountView()
                 } else {
                     /* 点击开始阅读 */
-                    callBack.startRead(it.toString())
+                    callBack.startRead(it)
                 }
             }
         }
     }
 
+    private fun isOnBookShelf(fileDoc: FileDoc): Boolean {
+        return bookOrArchiveNamesOnBookShelf.contains(fileDoc.name)
+    }
+
     @SuppressLint("NotifyDataSetChanged")
-    fun upBookHas(bookUrls: List<String>) {
-        bookNamesOnBookShelf.clear()
-        bookUrls.forEach {
-            val path = Uri.decode(it)
-            bookNamesOnBookShelf.add(FileUtils.getName(path))
+    fun upBookHas(books: List<Book>) {
+        bookOrArchiveNamesOnBookShelf.clear()
+        books.forEach {
+            if (it.isArchive) {
+                bookOrArchiveNamesOnBookShelf.add(
+                    it.archiveName!!
+                )
+            } else {
+                val path = Uri.decode(it.bookUrl)
+                bookOrArchiveNamesOnBookShelf.add(
+                    FileUtils.getName(path)
+                )
+            }
         }
         notifyDataSetChanged()
         upCheckableCount()
@@ -97,7 +112,7 @@ class ImportBookAdapter(context: Context, val callBack: CallBack) :
     private fun upCheckableCount() {
         checkableCount = 0
         getItems().forEach {
-            if (!it.isDir && !bookNamesOnBookShelf.contains(it.name)) {
+            if (!it.isDir && !isOnBookShelf(it)) {
                 checkableCount++
             }
         }
@@ -108,7 +123,7 @@ class ImportBookAdapter(context: Context, val callBack: CallBack) :
     fun selectAll(selectAll: Boolean) {
         if (selectAll) {
             getItems().forEach {
-                if (!it.isDir && !bookNamesOnBookShelf.contains(it.name)) {
+                if (!it.isDir && !isOnBookShelf(it)) {
                     selectedUris.add(it.toString())
                 }
             }
@@ -121,7 +136,7 @@ class ImportBookAdapter(context: Context, val callBack: CallBack) :
 
     fun revertSelection() {
         getItems().forEach {
-            if (!it.isDir && !bookNamesOnBookShelf.contains(it.name)) {
+            if (!it.isDir && !isOnBookShelf(it)) {
                 if (selectedUris.contains(it.toString())) {
                     selectedUris.remove(it.toString())
                 } else {
@@ -144,7 +159,7 @@ class ImportBookAdapter(context: Context, val callBack: CallBack) :
     interface CallBack {
         fun nextDoc(fileDoc: FileDoc)
         fun upCountView()
-        fun startRead(bookUrl: String)
+        fun startRead(fileDoc: FileDoc)
     }
 
 }