pull/1319/head
gedoor 3 years ago
parent 04c02c1120
commit 878635559f
  1. 2
      app/src/main/java/io/legado/app/model/Exceptions.kt
  2. 8
      app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
  3. 4
      app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt
  4. 18
      app/src/main/java/io/legado/app/model/webBook/WebBook.kt
  5. 5
      app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt
  6. 21
      app/src/main/java/io/legado/app/ui/book/audio/AudioPlayViewModel.kt
  7. 18
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt
  8. 5
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  9. 18
      app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt
  10. 5
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  11. 114
      app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt
  12. 2
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt

@ -1,5 +1,7 @@
package io.legado.app.model
class AppException(msg: String) : Exception(msg)
/**
* 内容为空
*/

@ -9,6 +9,7 @@ import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
import io.legado.app.help.AppConfig
import io.legado.app.help.BookHelp
import io.legado.app.model.AppException
import io.legado.app.utils.*
import splitties.init.appCtx
import java.io.File
@ -22,8 +23,9 @@ object LocalBook {
FileUtils.createFolderIfNotExist(appCtx.externalFiles, folderName)
}
@Throws(Exception::class)
fun getChapterList(book: Book): ArrayList<BookChapter> {
return when {
val chapters = when {
book.isEpub() -> {
EpubFile.getChapterList(book)
}
@ -34,6 +36,10 @@ object LocalBook {
TextFile().analyze(book)
}
}
if (chapters.isEmpty()) {
throw AppException("目录为空")
}
return chapters
}
fun getContext(book: Book, chapter: BookChapter): String? {

@ -6,6 +6,7 @@ import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.rule.TocRule
import io.legado.app.model.AppException
import io.legado.app.model.Debug
import io.legado.app.model.analyzeRule.AnalyzeRule
import io.legado.app.model.analyzeRule.AnalyzeUrl
@ -97,6 +98,9 @@ object BookChapterList {
}
}
}
if (chapterList.isEmpty()) {
throw AppException("目录为空")
}
//去重
if (!reverse) {
chapterList.reverse()

@ -23,19 +23,19 @@ object WebBook {
bookSources: List<BookSource>,
name: String,
author: String
): Book? {
bookSources.forEach { bookSource ->
): Pair<BookSource, Book>? {
bookSources.forEach { source ->
kotlin.runCatching {
if (!scope.isActive) return null
searchBookAwait(scope, bookSource, name).firstOrNull {
searchBookAwait(scope, source, name).firstOrNull {
it.name == name && it.author == author
}?.let {
return if (it.tocUrl.isBlank()) {
if (!scope.isActive) return null
getBookInfoAwait(scope, bookSource, it.toBook())
} else {
it.toBook()
}?.let { searchBook ->
if (!scope.isActive) return null
var book = searchBook.toBook()
if (book.tocUrl.isBlank()) {
book = getBookInfoAwait(scope, source, book)
}
return Pair(source, book)
}
}
}

@ -18,6 +18,7 @@ import io.legado.app.constant.EventBus
import io.legado.app.constant.Status
import io.legado.app.constant.Theme
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookSource
import io.legado.app.databinding.ActivityAudioPlayBinding
import io.legado.app.help.BlurTransformation
import io.legado.app.help.glide.ImageLoader
@ -193,8 +194,8 @@ class AudioPlayActivity :
override val oldBook: Book?
get() = AudioPlay.book
override fun changeTo(book: Book) {
viewModel.changeTo(book)
override fun changeTo(source: BookSource, book: Book) {
viewModel.changeTo(source, book)
}
override fun finish() {

@ -8,6 +8,7 @@ import io.legado.app.constant.EventBus
import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.BookSource
import io.legado.app.help.BookHelp
import io.legado.app.model.AudioPlay
import io.legado.app.model.webBook.WebBook
@ -90,24 +91,24 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
}
}
fun changeTo(book1: Book) {
fun changeTo(source: BookSource, book: Book) {
execute {
var oldTocSize: Int = book1.totalChapterNum
var oldTocSize: Int = book.totalChapterNum
AudioPlay.book?.let {
oldTocSize = it.totalChapterNum
book1.order = it.order
book.order = it.order
appDb.bookDao.delete(it)
}
appDb.bookDao.insert(book1)
AudioPlay.book = book1
AudioPlay.bookSource = appDb.bookSourceDao.getBookSource(book1.origin)
if (book1.tocUrl.isEmpty()) {
loadBookInfo(book1) { upChangeDurChapterIndex(book1, oldTocSize, it) }
appDb.bookDao.insert(book)
AudioPlay.book = book
AudioPlay.bookSource = source
if (book.tocUrl.isEmpty()) {
loadBookInfo(book) { upChangeDurChapterIndex(book, oldTocSize, it) }
} else {
loadChapterList(book1) { upChangeDurChapterIndex(book1, oldTocSize, it) }
loadChapterList(book) { upChangeDurChapterIndex(book, oldTocSize, it) }
}
}.onFinally {
postEvent(EventBus.SOURCE_CHANGED, book1.bookUrl)
postEvent(EventBus.SOURCE_CHANGED, book.bookUrl)
}
}

@ -16,6 +16,7 @@ import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey
import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.DialogChangeSourceBinding
import io.legado.app.help.AppConfig
@ -228,11 +229,16 @@ class ChangeSourceDialog : BaseDialogFragment(),
}
private fun changeSource(searchBook: SearchBook) {
val book = searchBook.toBook()
book.upInfoFromOld(callBack?.oldBook)
callBack?.changeTo(book)
searchBook.time = System.currentTimeMillis()
viewModel.updateSource(searchBook)
try {
val book = searchBook.toBook()
book.upInfoFromOld(callBack?.oldBook)
val source = appDb.bookSourceDao.getBookSource(book.origin)
callBack?.changeTo(source!!, book)
searchBook.time = System.currentTimeMillis()
viewModel.updateSource(searchBook)
} catch (e: Exception) {
toastOnUi("换源失败\n${e.localizedMessage}")
}
}
/**
@ -272,7 +278,7 @@ class ChangeSourceDialog : BaseDialogFragment(),
interface CallBack {
val oldBook: Book?
fun changeTo(book: Book)
fun changeTo(source: BookSource, book: Book)
}
}

@ -20,6 +20,7 @@ import io.legado.app.constant.Theme
import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.BookSource
import io.legado.app.databinding.ActivityBookInfoBinding
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.BlurTransformation
@ -435,9 +436,9 @@ class BookInfoActivity :
override val oldBook: Book?
get() = viewModel.bookData.value
override fun changeTo(book: Book) {
override fun changeTo(source: BookSource, book: Book) {
upLoading(true)
viewModel.changeTo(book)
viewModel.changeTo(source, book)
}
override fun coverChangeTo(coverUrl: String) {

@ -51,7 +51,11 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
private fun setBook(book: Book) {
durChapterIndex = book.durChapterIndex
bookData.postValue(book)
initBookSource(book)
bookSource = if (book.isLocalBook()) {
null
} else {
appDb.bookSourceDao.getBookSource(book.origin)
}
if (book.tocUrl.isEmpty()) {
loadBookInfo(book)
} else {
@ -64,14 +68,6 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
}
}
private fun initBookSource(book: Book) {
bookSource = if (book.isLocalBook()) {
null
} else {
appDb.bookSourceDao.getBookSource(book.origin)
}
}
fun loadBookInfo(
book: Book, canReName: Boolean = true,
changeDruChapterIndex: ((chapters: List<BookChapter>) -> Unit)? = null,
@ -149,7 +145,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
}
}
fun changeTo(newBook: Book) {
fun changeTo(source: BookSource, newBook: Book) {
execute {
var oldTocSize: Int = newBook.totalChapterNum
if (inBookshelf) {
@ -159,7 +155,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
}
}
bookData.postValue(newBook)
initBookSource(newBook)
bookSource = source
if (newBook.tocUrl.isEmpty()) {
loadBookInfo(newBook, false) {
upChangeDurChapterIndex(newBook, oldTocSize, it)

@ -20,6 +20,7 @@ import io.legado.app.constant.Status
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.BookProgress
import io.legado.app.data.entities.BookSource
import io.legado.app.help.ReadBookConfig
import io.legado.app.help.ReadTipConfig
import io.legado.app.help.storage.AppWebDav
@ -642,8 +643,8 @@ class ReadBookActivity : ReadBookBaseActivity(),
override val oldBook: Book?
get() = ReadBook.book
override fun changeTo(book: Book) {
viewModel.changeTo(book)
override fun changeTo(source: BookSource, book: Book) {
viewModel.changeTo(source, book)
}
override fun showActionMenu() {

@ -8,8 +8,8 @@ import io.legado.app.base.BaseViewModel
import io.legado.app.constant.EventBus
import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.BookProgress
import io.legado.app.data.entities.BookSource
import io.legado.app.help.AppConfig
import io.legado.app.help.BookHelp
import io.legado.app.help.ContentProcessor
@ -101,26 +101,22 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
}
}
private fun loadBookInfo(
book: Book,
changeDruChapterIndex: ((chapters: List<BookChapter>) -> Unit)? = null,
) {
private fun loadBookInfo(book: Book) {
if (book.isLocalBook()) {
loadChapterList(book, changeDruChapterIndex)
loadChapterList(book)
} else {
ReadBook.bookSource?.let {
WebBook.getBookInfo(viewModelScope, it, book, canReName = false)
ReadBook.bookSource?.let { source ->
WebBook.getBookInfo(viewModelScope, source, book, canReName = false)
.onSuccess {
loadChapterList(book, changeDruChapterIndex)
loadChapterList(book)
}.onError {
ReadBook.upMsg("详情页出错: ${it.localizedMessage}")
}
}
}
}
fun loadChapterList(
book: Book,
changeDruChapterIndex: ((chapters: List<BookChapter>) -> Unit)? = null,
) {
fun loadChapterList(book: Book) {
if (book.isLocalBook()) {
execute {
LocalBook.getChapterList(book).let {
@ -128,12 +124,8 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
appDb.bookChapterDao.insert(*it.toTypedArray())
appDb.bookDao.update(book)
ReadBook.chapterSize = it.size
if (it.isEmpty()) {
ReadBook.upMsg(context.getString(R.string.error_load_toc))
} else {
ReadBook.upMsg(null)
ReadBook.loadContent(resetPageOffset = true)
}
ReadBook.upMsg(null)
ReadBook.loadContent(resetPageOffset = true)
}
}.onError {
ReadBook.upMsg("LoadTocError:${it.localizedMessage}")
@ -142,19 +134,11 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
ReadBook.bookSource?.let {
WebBook.getChapterList(viewModelScope, it, book)
.onSuccess(IO) { cList ->
if (cList.isNotEmpty()) {
if (changeDruChapterIndex == null) {
appDb.bookChapterDao.insert(*cList.toTypedArray())
appDb.bookDao.update(book)
ReadBook.chapterSize = cList.size
ReadBook.upMsg(null)
ReadBook.loadContent(resetPageOffset = true)
} else {
changeDruChapterIndex(cList)
}
} else {
ReadBook.upMsg(context.getString(R.string.error_load_toc))
}
appDb.bookChapterDao.insert(*cList.toTypedArray())
appDb.bookDao.update(book)
ReadBook.chapterSize = cList.size
ReadBook.upMsg(null)
ReadBook.loadContent(resetPageOffset = true)
}.onError {
ReadBook.upMsg(context.getString(R.string.error_load_toc))
}
@ -183,23 +167,32 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
}
}
fun changeTo(newBook: Book) {
fun changeTo(source: BookSource, book: Book) {
execute {
val oldTocSize: Int = ReadBook.book?.totalChapterNum ?: newBook.totalChapterNum
ReadBook.upMsg(null)
ReadBook.resetData(newBook)
ReadBook.callBack?.upContent()
if (newBook.tocUrl.isEmpty()) {
loadBookInfo(newBook) {
upChangeDurChapterIndex(newBook, oldTocSize, it)
}
} else {
loadChapterList(newBook) {
upChangeDurChapterIndex(newBook, oldTocSize, it)
}
ReadBook.upMsg(context.getString(R.string.loading))
if (book.tocUrl.isEmpty()) {
WebBook.getBookInfoAwait(this, source, book)
}
val chapters = WebBook.getChapterListAwait(this, source, book)
ReadBook.book!!.let { oldBook ->
book.durChapterIndex = BookHelp.getDurChapter(
oldBook.durChapterIndex,
oldBook.totalChapterNum,
oldBook.durChapterTitle,
chapters
)
book.durChapterTitle = chapters[ReadBook.durChapterIndex].title
oldBook.changeTo(book)
}
appDb.bookChapterDao.insert(*chapters.toTypedArray())
ReadBook.resetData(book)
ReadBook.upMsg(null)
ReadBook.loadContent(resetPageOffset = true)
}.onError {
context.toastOnUi("换源失败\n${it.localizedMessage}")
ReadBook.upMsg(null)
}.onFinally {
postEvent(EventBus.SOURCE_CHANGED, newBook.bookUrl)
postEvent(EventBus.SOURCE_CHANGED, book.bookUrl)
}
}
@ -207,13 +200,10 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
if (!AppConfig.autoChangeSource) return
execute {
val sources = appDb.bookSourceDao.allTextEnabled
val book = WebBook.preciseSearch(this, sources, name, author)
if (book != null) {
book.upInfoFromOld(ReadBook.book)
changeTo(book)
} else {
throw Exception("自动换源失败")
}
WebBook.preciseSearch(this, sources, name, author)?.let {
it.second.upInfoFromOld(ReadBook.book)
changeTo(it.first, it.second)
} ?: throw Exception("自动换源失败")
}.onStart {
ReadBook.upMsg(context.getString(R.string.source_auto_changing))
}.onError {
@ -223,24 +213,6 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
}
}
private fun upChangeDurChapterIndex(book: Book, oldTocSize: Int, chapters: List<BookChapter>) {
execute {
ReadBook.durChapterIndex = BookHelp.getDurChapter(
book.durChapterIndex,
oldTocSize,
book.durChapterTitle,
chapters
)
book.durChapterIndex = ReadBook.durChapterIndex
book.durChapterTitle = chapters[ReadBook.durChapterIndex].title
appDb.bookDao.update(book)
appDb.bookChapterDao.insert(*chapters.toTypedArray())
ReadBook.chapterSize = chapters.size
ReadBook.upMsg(null)
ReadBook.loadContent(resetPageOffset = true)
}
}
fun openChapter(index: Int, durChapterPos: Int = 0, success: (() -> Unit)? = null) {
ReadBook.clearTextChapter()
ReadBook.callBack?.upContent()

@ -112,7 +112,7 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application)
val name = it["name"] ?: ""
val author = it["author"] ?: ""
if (name.isNotEmpty() && appDb.bookDao.getBook(name, author) == null) {
val book = WebBook.preciseSearch(this, bookSources, name, author)
val book = WebBook.preciseSearch(this, bookSources, name, author)?.second
book?.let {
if (groupId > 0) {
book.group = groupId

Loading…
Cancel
Save