[skip ci] fix: bookInfo viewModel hold activity

This commit is contained in:
Xwite 2023-03-09 13:42:42 +08:00
parent 1834afe309
commit 1b6ec86984
3 changed files with 45 additions and 76 deletions

View File

@ -151,7 +151,7 @@ object BookInfo {
coroutineContext.ensureActive() coroutineContext.ensureActive()
Debug.log(bookSource.bookSourceUrl, "┌获取文件下载链接") Debug.log(bookSource.bookSourceUrl, "┌获取文件下载链接")
book.downloadUrls = analyzeRule.getStringList(infoRule.downloadUrls, isUrl = true) book.downloadUrls = analyzeRule.getStringList(infoRule.downloadUrls, isUrl = true)
if (book.downloadUrls == null) { if (book.downloadUrls.isNullOrEmpty()) {
Debug.log(bookSource.bookSourceUrl, "") Debug.log(bookSource.bookSourceUrl, "")
throw NoStackTraceException("下载链接为空") throw NoStackTraceException("下载链接为空")
} else { } else {

View File

@ -52,8 +52,7 @@ class BookInfoActivity :
VMBaseActivity<ActivityBookInfoBinding, BookInfoViewModel>(toolBarTheme = Theme.Dark), VMBaseActivity<ActivityBookInfoBinding, BookInfoViewModel>(toolBarTheme = Theme.Dark),
GroupSelectDialog.CallBack, GroupSelectDialog.CallBack,
ChangeBookSourceDialog.CallBack, ChangeBookSourceDialog.CallBack,
ChangeCoverDialog.CallBack, ChangeCoverDialog.CallBack {
BookInfoViewModel.CallBack {
private val tocActivityResult = registerForActivityResult(TocActivityResult()) { private val tocActivityResult = registerForActivityResult(TocActivityResult()) {
it?.let { it?.let {
@ -111,7 +110,7 @@ class BookInfoActivity :
viewModel.callBack = this viewModel.callBack = this
viewModel.bookData.observe(this) { showBook(it) } viewModel.bookData.observe(this) { showBook(it) }
viewModel.chapterListData.observe(this) { upLoading(false, it) } viewModel.chapterListData.observe(this) { upLoading(false, it) }
//viewModel.webFileData.observe(this) { showWebFileDownloadAlert() } viewModel.waitDialogData.observe(this) { upWaitDialogStatus(it) }
viewModel.initData(intent) viewModel.initData(intent)
initViewEvent() initViewEvent()
} }
@ -499,31 +498,34 @@ class BookInfoActivity :
private fun showWebFileDownloadAlert( private fun showWebFileDownloadAlert(
onClick: ((Book) -> Unit)? = null onClick: ((Book) -> Unit)? = null
) { ) {
viewModel.webFileData.value?.let { val webFiles = viewModel.webFiles
alert(titleResource = R.string.download_and_import_file) { if (webFiles.isEmpty()) {
items<BookInfoViewModel.WebFile>(it) { _, webFile, _ -> toastOnUi("Unexpected webFileData")
if (webFile.isSupported) { return
/* import */ }
viewModel.importOrDownloadWebFile<Book>(webFile) { alert(titleResource = R.string.download_and_import_file) {
onClick?.invoke(it) items<BookInfoViewModel.WebFile>(webFiles) { _, webFile, _ ->
} if (webFile.isSupported) {
} else { /* import */
alert( viewModel.importOrDownloadWebFile<Book>(webFile) {
title = getString(R.string.draw), onClick?.invoke(it)
message = getString(R.string.file_not_supported, webFile.name) }
) { } else {
neutralButton(R.string.open_fun) { alert(
/* download only */ title = getString(R.string.draw),
viewModel.importOrDownloadWebFile<Uri>(webFile) { uri -> message = getString(R.string.file_not_supported, webFile.name)
openFileUri(uri, "*/*") ) {
} neutralButton(R.string.open_fun) {
/* download only */
viewModel.importOrDownloadWebFile<Uri>(webFile) { uri ->
openFileUri(uri, "*/*")
} }
noButton()
} }
noButton()
} }
} }
} }
} ?: toastOnUi("Unexpected webFileData") }
} }
private fun readBook(book: Book) { private fun readBook(book: Book) {
@ -588,14 +590,15 @@ class BookInfoActivity :
} }
} }
override fun onWebFileProcessFinally() { private fun upWaitDialogStatus(isShow: Boolean) {
waitDialog.dismiss() val showText = "Loading....."
} if (isShow) {
waitDialog.run {
override fun onWebFileProcessStart() { setText(showText)
waitDialog.run { show()
setText("Loading.....") }
show() } else {
waitDialog.dismiss()
} }
} }

View File

@ -21,8 +21,6 @@ import io.legado.app.help.AppWebDav
import io.legado.app.help.book.* import io.legado.app.help.book.*
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.lib.webdav.ObjectNotFoundException import io.legado.app.lib.webdav.ObjectNotFoundException
import io.legado.app.model.analyzeRule.AnalyzeRule
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.model.BookCover import io.legado.app.model.BookCover
import io.legado.app.model.ReadBook import io.legado.app.model.ReadBook
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook
@ -30,18 +28,17 @@ import io.legado.app.model.webBook.WebBook
import io.legado.app.utils.isContentScheme import io.legado.app.utils.isContentScheme
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import io.legado.app.utils.runOnUI
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
class BookInfoViewModel(application: Application) : BaseViewModel(application) { class BookInfoViewModel(application: Application) : BaseViewModel(application) {
val bookData = MutableLiveData<Book>() val bookData = MutableLiveData<Book>()
val chapterListData = MutableLiveData<List<BookChapter>>() val chapterListData = MutableLiveData<List<BookChapter>>()
val webFileData = MutableLiveData<List<WebFile>>() val webFiles = mutableListOf<WebFile>()
var inBookshelf = false var inBookshelf = false
var bookSource: BookSource? = null var bookSource: BookSource? = null
private var changeSourceCoroutine: Coroutine<*>? = null private var changeSourceCoroutine: Coroutine<*>? = null
var callBack: CallBack? = null val waitDialogData = MutableLiveData<Boolean>()
fun initData(intent: Intent) { fun initData(intent: Intent) {
execute { execute {
@ -241,45 +238,24 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
scope: CoroutineScope = viewModelScope scope: CoroutineScope = viewModelScope
) { ) {
execute(scope) { execute(scope) {
webFiles.clear()
val fileName = "${book.name} 作者:${book.author}" val fileName = "${book.name} 作者:${book.author}"
if (book.downloadUrls.isNullOrEmpty()) { book.downloadUrls!!.map {
val ruleDownloadUrls = bookSource.getBookInfoRule().downloadUrls val mFileName = "${fileName}.${LocalBook.parseFileSuffix(it)}"
val content = AnalyzeUrl(book.bookUrl, source = bookSource).getStrResponse().body val isSupportedFile = AppPattern.bookFileRegex.matches(mFileName)
val analyzeRule = AnalyzeRule(book, bookSource) WebFile(it, mFileName, isSupportedFile)
analyzeRule.setContent(content).setBaseUrl(book.bookUrl)
analyzeRule.getStringList(ruleDownloadUrls, isUrl = true)?.let {
parseDownloadUrls(it, fileName)
} ?: throw NoStackTraceException("Unexpected ruleDownloadUrls")
} else {
parseDownloadUrls(book.downloadUrls, fileName)
} }
}.onError { }.onError {
context.toastOnUi("LoadWebFileError\n${it.localizedMessage}") context.toastOnUi("LoadWebFileError\n${it.localizedMessage}")
}.onSuccess { }.onSuccess {
webFileData.postValue(it) webFiles.addAll(it)
}
}
private fun parseDownloadUrls(
downloadUrls: List<String>?,
fileName: String
): List<WebFile>? {
val urls = downloadUrls
return urls?.map {
val mFileName = "${fileName}.${LocalBook.parseFileSuffix(it)}"
val isSupportedFile = AppPattern.bookFileRegex.matches(mFileName)
WebFile(it, mFileName, isSupportedFile)
} }
} }
fun <T> importOrDownloadWebFile(webFile: WebFile, success: ((T) -> Unit)?) { fun <T> importOrDownloadWebFile(webFile: WebFile, success: ((T) -> Unit)?) {
bookSource ?: return bookSource ?: return
execute { execute {
callBack?.run { waitDialogData.postValue(true)
runOnUI {
onWebFileProcessStart()
}
}
if (webFile.isSupported) { if (webFile.isSupported) {
val book = LocalBook.importFileOnLine(webFile.url, webFile.name, bookSource) val book = LocalBook.importFileOnLine(webFile.url, webFile.name, bookSource)
changeToLocalBook(book) changeToLocalBook(book)
@ -291,12 +267,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
}.onError { }.onError {
context.toastOnUi("ImportWebFileError\n${it.localizedMessage}") context.toastOnUi("ImportWebFileError\n${it.localizedMessage}")
}.onFinally { }.onFinally {
callBack?.run { waitDialogData.postValue(false)
runOnUI {
onWebFileProcessFinally()
}
}
} }
} }
@ -433,9 +404,4 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
} }
} }
interface CallBack {
fun onWebFileProcessStart()
fun onWebFileProcessFinally()
}
} }