Merge remote-tracking branch 'origin/master'

This commit is contained in:
kunfei 2023-03-09 14:03:10 +08:00
commit 48902bba3f
6 changed files with 58 additions and 91 deletions

View File

@ -60,6 +60,8 @@ jobs:
VERSIONL: ${{ needs.prepare.outputs.versionL }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Clear 18PlusList.txt
run: |
echo "清空18PlusList.txt"

View File

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

View File

@ -52,8 +52,7 @@ class BookInfoActivity :
VMBaseActivity<ActivityBookInfoBinding, BookInfoViewModel>(toolBarTheme = Theme.Dark),
GroupSelectDialog.CallBack,
ChangeBookSourceDialog.CallBack,
ChangeCoverDialog.CallBack,
BookInfoViewModel.CallBack {
ChangeCoverDialog.CallBack {
private val tocActivityResult = registerForActivityResult(TocActivityResult()) {
it?.let {
@ -108,10 +107,9 @@ class BookInfoActivity :
binding.flAction.setBackgroundColor(bottomBackground)
binding.tvShelf.setTextColor(getPrimaryTextColor(ColorUtils.isColorLight(bottomBackground)))
binding.tvToc.text = getString(R.string.toc_s, getString(R.string.loading))
viewModel.callBack = this
viewModel.bookData.observe(this) { showBook(it) }
viewModel.chapterListData.observe(this) { upLoading(false, it) }
//viewModel.webFileData.observe(this) { showWebFileDownloadAlert() }
viewModel.waitDialogData.observe(this) { upWaitDialogStatus(it) }
viewModel.initData(intent)
initViewEvent()
}
@ -499,31 +497,34 @@ class BookInfoActivity :
private fun showWebFileDownloadAlert(
onClick: ((Book) -> Unit)? = null
) {
viewModel.webFileData.value?.let {
alert(titleResource = R.string.download_and_import_file) {
items<BookInfoViewModel.WebFile>(it) { _, webFile, _ ->
if (webFile.isSupported) {
/* import */
viewModel.importOrDownloadWebFile<Book>(webFile) {
onClick?.invoke(it)
}
} else {
alert(
title = getString(R.string.draw),
message = getString(R.string.file_not_supported, webFile.name)
) {
neutralButton(R.string.open_fun) {
/* download only */
viewModel.importOrDownloadWebFile<Uri>(webFile) { uri ->
openFileUri(uri, "*/*")
}
val webFiles = viewModel.webFiles
if (webFiles.isEmpty()) {
toastOnUi("Unexpected webFileData")
return
}
alert(titleResource = R.string.download_and_import_file) {
items<BookInfoViewModel.WebFile>(webFiles) { _, webFile, _ ->
if (webFile.isSupported) {
/* import */
viewModel.importOrDownloadWebFile<Book>(webFile) {
onClick?.invoke(it)
}
} else {
alert(
title = getString(R.string.draw),
message = getString(R.string.file_not_supported, webFile.name)
) {
neutralButton(R.string.open_fun) {
/* download only */
viewModel.importOrDownloadWebFile<Uri>(webFile) { uri ->
openFileUri(uri, "*/*")
}
noButton()
}
noButton()
}
}
}
} ?: toastOnUi("Unexpected webFileData")
}
}
private fun readBook(book: Book) {
@ -588,14 +589,15 @@ class BookInfoActivity :
}
}
override fun onWebFileProcessFinally() {
waitDialog.dismiss()
}
override fun onWebFileProcessStart() {
waitDialog.run {
setText("Loading.....")
show()
private fun upWaitDialogStatus(isShow: Boolean) {
val showText = "Loading....."
if (isShow) {
waitDialog.run {
setText(showText)
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.coroutine.Coroutine
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.ReadBook
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.postEvent
import io.legado.app.utils.toastOnUi
import io.legado.app.utils.runOnUI
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
class BookInfoViewModel(application: Application) : BaseViewModel(application) {
val bookData = MutableLiveData<Book>()
val chapterListData = MutableLiveData<List<BookChapter>>()
val webFileData = MutableLiveData<List<WebFile>>()
val webFiles = mutableListOf<WebFile>()
var inBookshelf = false
var bookSource: BookSource? = null
private var changeSourceCoroutine: Coroutine<*>? = null
var callBack: CallBack? = null
val waitDialogData = MutableLiveData<Boolean>()
fun initData(intent: Intent) {
execute {
@ -241,45 +238,24 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
scope: CoroutineScope = viewModelScope
) {
execute(scope) {
webFiles.clear()
val fileName = "${book.name} 作者:${book.author}"
if (book.downloadUrls.isNullOrEmpty()) {
val ruleDownloadUrls = bookSource.getBookInfoRule().downloadUrls
val content = AnalyzeUrl(book.bookUrl, source = bookSource).getStrResponse().body
val analyzeRule = AnalyzeRule(book, bookSource)
analyzeRule.setContent(content).setBaseUrl(book.bookUrl)
analyzeRule.getStringList(ruleDownloadUrls, isUrl = true)?.let {
parseDownloadUrls(it, fileName)
} ?: throw NoStackTraceException("Unexpected ruleDownloadUrls")
} else {
parseDownloadUrls(book.downloadUrls, fileName)
book.downloadUrls!!.map {
val mFileName = "${fileName}.${LocalBook.parseFileSuffix(it)}"
val isSupportedFile = AppPattern.bookFileRegex.matches(mFileName)
WebFile(it, mFileName, isSupportedFile)
}
}.onError {
context.toastOnUi("LoadWebFileError\n${it.localizedMessage}")
}.onSuccess {
webFileData.postValue(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)
webFiles.addAll(it)
}
}
fun <T> importOrDownloadWebFile(webFile: WebFile, success: ((T) -> Unit)?) {
bookSource ?: return
execute {
callBack?.run {
runOnUI {
onWebFileProcessStart()
}
}
waitDialogData.postValue(true)
if (webFile.isSupported) {
val book = LocalBook.importFileOnLine(webFile.url, webFile.name, bookSource)
changeToLocalBook(book)
@ -291,12 +267,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
}.onError {
context.toastOnUi("ImportWebFileError\n${it.localizedMessage}")
}.onFinally {
callBack?.run {
runOnUI {
onWebFileProcessFinally()
}
}
waitDialogData.postValue(false)
}
}
@ -433,9 +404,4 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
}
}
interface CallBack {
fun onWebFileProcessStart()
fun onWebFileProcessFinally()
}
}

View File

@ -34,8 +34,7 @@ import java.net.URLDecoder
/**
* rss阅读界面
*/
class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>(false),
ReadRssViewModel.CallBack {
class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>(false) {
override val binding by viewBinding(ActivityRssReadBinding::inflate)
override val viewModel by viewModels<ReadRssViewModel>()
@ -50,7 +49,8 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
viewModel.callBack = this
viewModel.upStarMenuData.observe(this) { upStarMenu() }
viewModel.upTtsMenuData.observe(this) { upTtsMenu(it) }
binding.titleBar.title = intent.getStringExtra("title")
initWebView()
initLiveData()
@ -223,7 +223,7 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
}
}
override fun upStarMenu() {
private fun upStarMenu() {
starMenuItem?.isVisible = viewModel.rssArticle != null
if (viewModel.rssStar != null) {
starMenuItem?.setIcon(R.drawable.ic_star)
@ -235,7 +235,7 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
starMenuItem?.icon?.setTintMutate(primaryTextColor)
}
override fun upTtsMenu(isPlaying: Boolean) {
private fun upTtsMenu(isPlaying: Boolean) {
launch {
if (isPlaying) {
ttsMenuItem?.setIcon(R.drawable.ic_stop_black_24dp)

View File

@ -27,13 +27,14 @@ import java.util.*
class ReadRssViewModel(application: Application) : BaseViewModel(application) {
var callBack: CallBack? = null
var rssSource: RssSource? = null
var rssArticle: RssArticle? = null
var tts: TTS? = null
val contentLiveData = MutableLiveData<String>()
val urlLiveData = MutableLiveData<AnalyzeUrl>()
var rssStar: RssStar? = null
val upTtsMenuData = MutableLiveData<Boolean>()
val upStarMenuData = MutableLiveData<Boolean>()
fun initData(intent: Intent) {
execute {
@ -72,7 +73,7 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application) {
}
}
}.onFinally {
callBack?.upStarMenu()
upStarMenuData.postValue(true)
}
}
@ -126,7 +127,7 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application) {
rssStar = it
}
}.onSuccess {
callBack?.upStarMenu()
upStarMenuData.postValue(true)
}
}
@ -196,11 +197,11 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application) {
tts = TTS().apply {
setSpeakStateListener(object : TTS.SpeakStateListener {
override fun onStart() {
callBack?.upTtsMenu(true)
upTtsMenuData.postValue(true)
}
override fun onDone() {
callBack?.upTtsMenu(false)
upTtsMenuData.postValue(false)
}
})
}
@ -213,8 +214,4 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application) {
tts?.clearTts()
}
interface CallBack {
fun upStarMenu()
fun upTtsMenu(isPlaying: Boolean)
}
}