Horis 2 ani în urmă
părinte
comite
38e4868a0a

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

@@ -168,7 +168,7 @@ interface BookSourceDao {
     @Query("select * from book_sources where enabled = 1 and bookSourceUrl = :baseUrl")
     @Query("select * from book_sources where enabled = 1 and bookSourceUrl = :baseUrl")
     fun getBookSourceAddBook(baseUrl: String): BookSource?
     fun getBookSourceAddBook(baseUrl: String): BookSource?
 
 
-    @get:Query("select * from book_sources where enabled = 1 and trim(bookUrlPattern) <> '' and trim(bookUrlPattern) <> 'NONE'  order by enabled desc, customOrder")
+    @get:Query("select * from book_sources where enabled = 1 and trim(bookUrlPattern) <> '' and trim(bookUrlPattern) <> 'NONE' order by customOrder")
     val hasBookUrlPattern: List<BookSource>
     val hasBookUrlPattern: List<BookSource>
 
 
     @get:Query("select * from book_sources where bookSourceGroup is null or bookSourceGroup = ''")
     @get:Query("select * from book_sources where bookSourceGroup is null or bookSourceGroup = ''")

+ 22 - 2
app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt

@@ -27,6 +27,7 @@ import io.legado.app.ui.book.search.SearchActivity
 import io.legado.app.ui.file.HandleFileContract
 import io.legado.app.ui.file.HandleFileContract
 import io.legado.app.ui.main.MainFragmentInterface
 import io.legado.app.ui.main.MainFragmentInterface
 import io.legado.app.ui.main.MainViewModel
 import io.legado.app.ui.main.MainViewModel
+import io.legado.app.ui.widget.dialog.WaitDialog
 import io.legado.app.utils.*
 import io.legado.app.utils.*
 
 
 abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfViewModel>(layoutId),
 abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfViewModel>(layoutId),
@@ -66,6 +67,13 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
     abstract val groupId: Long
     abstract val groupId: Long
     abstract val books: List<Book>
     abstract val books: List<Book>
     private var groupsLiveData: LiveData<List<BookGroup>>? = null
     private var groupsLiveData: LiveData<List<BookGroup>>? = null
+    private val waitDialog by lazy {
+        WaitDialog(requireContext()).apply {
+            setOnCancelListener {
+                viewModel.addBookJob?.cancel()
+            }
+        }
+    }
 
 
     abstract fun gotoTop()
     abstract fun gotoTop()
 
 
@@ -82,7 +90,7 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
             R.id.menu_bookshelf_layout -> configBookshelf()
             R.id.menu_bookshelf_layout -> configBookshelf()
             R.id.menu_group_manage -> showDialogFragment<GroupManageDialog>()
             R.id.menu_group_manage -> showDialogFragment<GroupManageDialog>()
             R.id.menu_add_local -> startActivity<ImportBookActivity>()
             R.id.menu_add_local -> startActivity<ImportBookActivity>()
-            R.id.menu_add_url -> addBookByUrl()
+            R.id.menu_add_url -> showAddBookByUrlAlert()
             R.id.menu_bookshelf_manage -> startActivity<BookshelfManageActivity> {
             R.id.menu_bookshelf_manage -> startActivity<BookshelfManageActivity> {
                 putExtra("groupId", groupId)
                 putExtra("groupId", groupId)
             }
             }
@@ -117,8 +125,18 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
 
 
     abstract fun upSort()
     abstract fun upSort()
 
 
+    override fun observeLiveBus() {
+        viewModel.addBookProgressLiveData.observe(this) { count ->
+            if (count < 0) {
+                waitDialog.dismiss()
+            } else {
+                waitDialog.setText("添加中... ($count)")
+            }
+        }
+    }
+
     @SuppressLint("InflateParams")
     @SuppressLint("InflateParams")
-    fun addBookByUrl() {
+    fun showAddBookByUrlAlert() {
         alert(titleResource = R.string.add_book_url) {
         alert(titleResource = R.string.add_book_url) {
             val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
             val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
                 editView.hint = "url"
                 editView.hint = "url"
@@ -126,6 +144,8 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
             customView { alertBinding.root }
             customView { alertBinding.root }
             okButton {
             okButton {
                 alertBinding.editView.text?.toString()?.let {
                 alertBinding.editView.text?.toString()?.let {
+                    waitDialog.setText("添加中...")
+                    waitDialog.show()
                     viewModel.addBookByUrl(it)
                     viewModel.addBookByUrl(it)
                 }
                 }
             }
             }

+ 36 - 23
app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt

@@ -1,13 +1,16 @@
 package io.legado.app.ui.main.bookshelf
 package io.legado.app.ui.main.bookshelf
 
 
 import android.app.Application
 import android.app.Application
+import androidx.lifecycle.MutableLiveData
 import com.google.gson.stream.JsonWriter
 import com.google.gson.stream.JsonWriter
 import io.legado.app.R
 import io.legado.app.R
 import io.legado.app.base.BaseViewModel
 import io.legado.app.base.BaseViewModel
+import io.legado.app.constant.AppLog
 import io.legado.app.data.appDb
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookSource
 import io.legado.app.data.entities.BookSource
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.exception.NoStackTraceException
+import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.help.http.newCallResponseBody
 import io.legado.app.help.http.newCallResponseBody
 import io.legado.app.help.http.okHttpClient
 import io.legado.app.help.http.okHttpClient
 import io.legado.app.help.http.text
 import io.legado.app.help.http.text
@@ -20,7 +23,6 @@ import io.legado.app.utils.isAbsUrl
 import io.legado.app.utils.isJsonArray
 import io.legado.app.utils.isJsonArray
 import io.legado.app.utils.printOnDebug
 import io.legado.app.utils.printOnDebug
 import io.legado.app.utils.toastOnUi
 import io.legado.app.utils.toastOnUi
-import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.isActive
 import kotlinx.coroutines.isActive
 import java.io.File
 import java.io.File
 import java.io.FileOutputStream
 import java.io.FileOutputStream
@@ -32,10 +34,12 @@ import kotlin.collections.hashMapOf
 import kotlin.collections.set
 import kotlin.collections.set
 
 
 class BookshelfViewModel(application: Application) : BaseViewModel(application) {
 class BookshelfViewModel(application: Application) : BaseViewModel(application) {
+    val addBookProgressLiveData = MutableLiveData(-1)
+    var addBookJob: Coroutine<*>? = null
 
 
     fun addBookByUrl(bookUrls: String) {
     fun addBookByUrl(bookUrls: String) {
         var successCount = 0
         var successCount = 0
-        execute {
+        addBookJob = execute {
             val hasBookUrlPattern: List<BookSource> by lazy {
             val hasBookUrlPattern: List<BookSource> by lazy {
                 appDb.bookSourceDao.hasBookUrlPattern
                 appDb.bookSourceDao.hasBookUrlPattern
             }
             }
@@ -43,41 +47,48 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application)
             for (url in urls) {
             for (url in urls) {
                 val bookUrl = url.trim()
                 val bookUrl = url.trim()
                 if (bookUrl.isEmpty()) continue
                 if (bookUrl.isEmpty()) continue
-                if (appDb.bookDao.getBook(bookUrl) != null) continue
+                if (appDb.bookDao.getBook(bookUrl) != null) {
+                    successCount++
+                    continue
+                }
                 val baseUrl = NetworkUtils.getBaseUrl(bookUrl) ?: continue
                 val baseUrl = NetworkUtils.getBaseUrl(bookUrl) ?: continue
                 var source = appDb.bookSourceDao.getBookSourceAddBook(baseUrl)
                 var source = appDb.bookSourceDao.getBookSourceAddBook(baseUrl)
                 if (source == null) {
                 if (source == null) {
-                    hasBookUrlPattern.forEach { bookSource ->
-                        if (bookUrl.matches(bookSource.bookUrlPattern!!.toRegex())) {
-                            source = bookSource
-                            return@forEach
+                    for (bookSource in hasBookUrlPattern) {
+                        try {
+                            if (bookUrl.matches(bookSource.bookUrlPattern!!.toRegex())) {
+                                source = bookSource
+                                break
+                            }
+                        } catch (_: Exception) {
                         }
                         }
                     }
                     }
                 }
                 }
-                source?.let { bookSource ->
-                    val book = Book(
-                        bookUrl = bookUrl,
-                        origin = bookSource.bookSourceUrl,
-                        originName = bookSource.bookSourceName
-                    )
-                    WebBook.getBookInfo(this, bookSource, book)
-                        .onSuccess(IO) {
-                            it.order = appDb.bookDao.minOrder - 1
-                            it.save()
-                            successCount++
-                        }.onError {
-                            throw it
-                        }
+                val bookSource = source ?: continue
+                val book = Book(
+                    bookUrl = bookUrl,
+                    origin = bookSource.bookSourceUrl,
+                    originName = bookSource.bookSourceName
+                )
+                kotlin.runCatching {
+                    WebBook.getBookInfoAwait(bookSource, book)
+                }.onSuccess {
+                    it.order = appDb.bookDao.minOrder - 1
+                    it.save()
+                    successCount++
+                    addBookProgressLiveData.postValue(successCount)
                 }
                 }
             }
             }
         }.onSuccess {
         }.onSuccess {
             if (successCount > 0) {
             if (successCount > 0) {
                 context.toastOnUi(R.string.success)
                 context.toastOnUi(R.string.success)
             } else {
             } else {
-                context.toastOnUi("ERROR")
+                context.toastOnUi("添加网址失败")
             }
             }
         }.onError {
         }.onError {
-            context.toastOnUi(it.localizedMessage ?: "ERROR")
+            AppLog.put("添加网址出错\n${it.localizedMessage}", it, true)
+        }.onFinally {
+            addBookProgressLiveData.postValue(-1)
         }
         }
     }
     }
 
 
@@ -121,9 +132,11 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application)
                         importBookshelf(it, groupId)
                         importBookshelf(it, groupId)
                     }
                     }
                 }
                 }
+
                 text.isJsonArray() -> {
                 text.isJsonArray() -> {
                     importBookshelfByJson(text, groupId)
                     importBookshelfByJson(text, groupId)
                 }
                 }
+
                 else -> {
                 else -> {
                     throw NoStackTraceException("格式不对")
                     throw NoStackTraceException("格式不对")
                 }
                 }