This commit is contained in:
Horis
2023-12-17 18:17:06 +08:00
parent 7787f8a40f
commit 38e4868a0a
3 changed files with 59 additions and 26 deletions
@@ -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 = ''")
@@ -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)
} }
} }
@@ -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 -> for (bookSource in hasBookUrlPattern) {
if (bookUrl.matches(bookSource.bookUrlPattern!!.toRegex())) { try {
source = bookSource if (bookUrl.matches(bookSource.bookUrlPattern!!.toRegex())) {
return@forEach source = bookSource
break
}
} catch (_: Exception) {
} }
} }
} }
source?.let { bookSource -> val bookSource = source ?: continue
val book = Book( val book = Book(
bookUrl = bookUrl, bookUrl = bookUrl,
origin = bookSource.bookSourceUrl, origin = bookSource.bookSourceUrl,
originName = bookSource.bookSourceName originName = bookSource.bookSourceName
) )
WebBook.getBookInfo(this, bookSource, book) kotlin.runCatching {
.onSuccess(IO) { WebBook.getBookInfoAwait(bookSource, book)
it.order = appDb.bookDao.minOrder - 1 }.onSuccess {
it.save() it.order = appDb.bookDao.minOrder - 1
successCount++ it.save()
}.onError { successCount++
throw it 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("格式不对")
} }