pull/49/head
kunfei 5 years ago
parent 9729b111b3
commit f0ad1cd0d9
  1. 5
      app/src/main/java/io/legado/app/service/BaseReadAloudService.kt
  2. 137
      app/src/main/java/io/legado/app/service/help/ReadBook.kt
  3. 31
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  4. 132
      app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt

@ -24,6 +24,7 @@ import io.legado.app.help.IntentDataHelp
import io.legado.app.help.IntentHelp import io.legado.app.help.IntentHelp
import io.legado.app.help.MediaHelp import io.legado.app.help.MediaHelp
import io.legado.app.receiver.MediaButtonReceiver import io.legado.app.receiver.MediaButtonReceiver
import io.legado.app.service.help.ReadBook
import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.widget.page.TextChapter import io.legado.app.ui.widget.page.TextChapter
import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefBoolean
@ -326,6 +327,8 @@ abstract class BaseReadAloudService : BaseService(),
abstract fun aloudServicePendingIntent(actionStr: String): PendingIntent? abstract fun aloudServicePendingIntent(actionStr: String): PendingIntent?
open fun nextChapter() { open fun nextChapter() {
postEvent(Bus.TTS_TURN_PAGE, 2) if (!ReadBook.moveToNextChapter(true)) {
stopSelf()
}
} }
} }

@ -1,10 +1,19 @@
package io.legado.app.service.help package io.legado.app.service.help
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import io.legado.app.App
import io.legado.app.R
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
import io.legado.app.help.BookHelp
import io.legado.app.help.coroutine.Coroutine
import io.legado.app.model.WebBook import io.legado.app.model.WebBook
import io.legado.app.ui.book.read.ReadBookViewModel import io.legado.app.ui.book.read.ReadBookViewModel
import io.legado.app.ui.widget.page.TextChapter import io.legado.app.ui.widget.page.TextChapter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
object ReadBook { object ReadBook {
@ -21,7 +30,133 @@ object ReadBook {
var curTextChapter: TextChapter? = null var curTextChapter: TextChapter? = null
var nextTextChapter: TextChapter? = null var nextTextChapter: TextChapter? = null
var webBook: WebBook? = null var webBook: WebBook? = null
val loadingChapters = arrayListOf<Int>() private val loadingChapters = arrayListOf<Int>()
fun moveToNextChapter(upContent: Boolean): Boolean {
if (durChapterIndex < chapterSize - 1) {
durChapterIndex++
prevTextChapter = curTextChapter
curTextChapter = nextTextChapter
nextTextChapter = null
book?.let {
if (curTextChapter == null) {
loadContent(durChapterIndex)
} else if (upContent) {
callBack?.upContent()
}
loadContent(durChapterIndex.plus(1))
GlobalScope.launch(Dispatchers.IO) {
for (i in 2..10) {
delay(100)
download(durChapterIndex + i)
}
}
}
saveRead()
callBack?.curChapterChanged()
return true
} else {
return false
}
}
fun loadContent(index: Int) {
book?.let { book ->
if (addLoading(index)) {
Coroutine.async {
App.db.bookChapterDao().getChapter(book.bookUrl, index)?.let { chapter ->
BookHelp.getContent(book, chapter)?.let {
contentLoadFinish(chapter, it)
removeLoading(chapter.index)
} ?: download(chapter)
} ?: removeLoading(index)
}.onError {
removeLoading(index)
}
}
}
}
fun download(index: Int) {
book?.let { book ->
if (addLoading(index)) {
Coroutine.async {
App.db.bookChapterDao().getChapter(book.bookUrl, index)?.let { chapter ->
if (BookHelp.hasContent(book, chapter)) {
removeLoading(chapter.index)
} else {
download(chapter)
}
} ?: removeLoading(index)
}.onError {
removeLoading(index)
}
}
}
}
fun download(chapter: BookChapter) {
book?.let { book ->
webBook?.getContent(book, chapter)
?.onSuccess(Dispatchers.IO) { content ->
if (content.isNullOrEmpty()) {
contentLoadFinish(chapter, App.INSTANCE.getString(R.string.content_empty))
removeLoading(chapter.index)
} else {
BookHelp.saveContent(book, chapter, content)
contentLoadFinish(chapter, content)
removeLoading(chapter.index)
}
}?.onError {
contentLoadFinish(chapter, it.localizedMessage ?: "未知错误")
removeLoading(chapter.index)
}
}
}
private fun addLoading(index: Int): Boolean {
synchronized(this) {
if (loadingChapters.contains(index)) return false
loadingChapters.add(index)
return true
}
}
private fun removeLoading(index: Int) {
synchronized(this) {
loadingChapters.remove(index)
}
}
private fun contentLoadFinish(chapter: BookChapter, content: String) {
Coroutine.async {
if (chapter.index in durChapterIndex - 1..durChapterIndex + 1) {
val c = BookHelp.disposeContent(
chapter.title,
book!!.name,
webBook?.bookSource?.bookSourceUrl,
content,
book!!.useReplaceRule
)
callBack?.contentLoadFinish(chapter, c)
}
}
}
fun saveRead() {
Coroutine.async {
book?.let { book ->
book.lastCheckCount = 0
book.durChapterTime = System.currentTimeMillis()
book.durChapterIndex = durChapterIndex
book.durChapterPos = durPageIndex
curTextChapter?.let {
book.durChapterTitle = it.title
}
App.db.bookDao().update(book)
}
}
}
} }

@ -253,16 +253,16 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
* 加载章节内容 * 加载章节内容
*/ */
override fun loadContent() { override fun loadContent() {
viewModel.loadContent(ReadBook.durChapterIndex) ReadBook.loadContent(ReadBook.durChapterIndex)
viewModel.loadContent(ReadBook.durChapterIndex + 1) ReadBook.loadContent(ReadBook.durChapterIndex + 1)
viewModel.loadContent(ReadBook.durChapterIndex - 1) ReadBook.loadContent(ReadBook.durChapterIndex - 1)
} }
/** /**
* 加载章节内容, index章节序号 * 加载章节内容, index章节序号
*/ */
override fun loadContent(index: Int) { override fun loadContent(index: Int) {
viewModel.loadContent(index) ReadBook.loadContent(index)
} }
/** /**
@ -297,7 +297,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
page_view.upContent() page_view.upContent()
} }
private fun curChapterChanged() { override fun curChapterChanged() {
ReadBook.curTextChapter?.let { ReadBook.curTextChapter?.let {
tv_chapter_name.text = it.title tv_chapter_name.text = it.title
tv_chapter_name.visible() tv_chapter_name.visible()
@ -353,7 +353,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
override fun setPageIndex(pageIndex: Int) { override fun setPageIndex(pageIndex: Int) {
ReadBook.durPageIndex = pageIndex ReadBook.durPageIndex = pageIndex
viewModel.saveRead() ReadBook.saveRead()
curPageChanged() curPageChanged()
} }
@ -373,15 +373,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
* 下一页 * 下一页
*/ */
override fun moveToNextChapter(upContent: Boolean): Boolean { override fun moveToNextChapter(upContent: Boolean): Boolean {
return if (ReadBook.durChapterIndex < ReadBook.chapterSize - 1) { return ReadBook.moveToNextChapter(upContent)
ReadBook.durPageIndex = 0
viewModel.moveToNextChapter(upContent)
viewModel.saveRead()
curChapterChanged()
true
} else {
false
}
} }
/** /**
@ -391,7 +383,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
return if (ReadBook.durChapterIndex > 0) { return if (ReadBook.durChapterIndex > 0) {
ReadBook.durPageIndex = if (last) ReadBook.prevTextChapter?.lastIndex() ?: 0 else 0 ReadBook.durPageIndex = if (last) ReadBook.prevTextChapter?.lastIndex() ?: 0 else 0
viewModel.moveToPrevChapter(upContent) viewModel.moveToPrevChapter(upContent)
viewModel.saveRead() ReadBook.saveRead()
curChapterChanged() curChapterChanged()
true true
} else { } else {
@ -419,7 +411,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
ReadBook.durPageIndex = page ReadBook.durPageIndex = page
page_view.upContent() page_view.upContent()
curPageChanged() curPageChanged()
viewModel.saveRead() ReadBook.saveRead()
} }
override fun openReplaceRule() { override fun openReplaceRule() {
@ -583,10 +575,9 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
} else { } else {
ReadBook.durPageIndex = ReadBook.durPageIndex + 1 ReadBook.durPageIndex = ReadBook.durPageIndex + 1
page_view.upContent() page_view.upContent()
viewModel.saveRead() ReadBook.saveRead()
} }
} }
2 -> if (!moveToNextChapter(true)) ReadAloud.stop(this)
-1 -> { -1 -> {
if (ReadBook.durPageIndex > 0) { if (ReadBook.durPageIndex > 0) {
if (page_view.isScrollDelegate) { if (page_view.isScrollDelegate) {
@ -594,7 +585,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
} else { } else {
ReadBook.durPageIndex = ReadBook.durPageIndex - 1 ReadBook.durPageIndex = ReadBook.durPageIndex - 1
page_view.upContent() page_view.upContent()
viewModel.saveRead() ReadBook.saveRead()
} }
} else { } else {
moveToPrevChapter(true) moveToPrevChapter(true)

@ -60,7 +60,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
ReadBook.callBack?.loadContent() ReadBook.callBack?.loadContent()
} }
if (ReadBook.inBookshelf) { if (ReadBook.inBookshelf) {
saveRead() ReadBook.saveRead()
} }
} }
@ -100,27 +100,6 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
} }
} }
fun moveToNextChapter(upContent: Boolean) {
ReadBook.durChapterIndex++
ReadBook.prevTextChapter = ReadBook.curTextChapter
ReadBook.curTextChapter = ReadBook.nextTextChapter
ReadBook.nextTextChapter = null
ReadBook.book?.let {
if (ReadBook.curTextChapter == null) {
loadContent(ReadBook.durChapterIndex)
} else if (upContent) {
ReadBook.callBack?.upContent()
}
loadContent(ReadBook.durChapterIndex.plus(1))
launch(IO) {
for (i in 2..10) {
delay(100)
download(ReadBook.durChapterIndex + i)
}
}
}
}
fun moveToPrevChapter(upContent: Boolean) { fun moveToPrevChapter(upContent: Boolean) {
ReadBook.durChapterIndex-- ReadBook.durChapterIndex--
ReadBook.nextTextChapter = ReadBook.curTextChapter ReadBook.nextTextChapter = ReadBook.curTextChapter
@ -128,103 +107,20 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
ReadBook.prevTextChapter = null ReadBook.prevTextChapter = null
ReadBook.book?.let { ReadBook.book?.let {
if (ReadBook.curTextChapter == null) { if (ReadBook.curTextChapter == null) {
loadContent(ReadBook.durChapterIndex) ReadBook.loadContent(ReadBook.durChapterIndex)
} else if (upContent) { } else if (upContent) {
ReadBook.callBack?.upContent() ReadBook.callBack?.upContent()
} }
loadContent(ReadBook.durChapterIndex.minus(1)) ReadBook.loadContent(ReadBook.durChapterIndex.minus(1))
launch(IO) { launch(IO) {
for (i in -5..-2) { for (i in -5..-2) {
delay(100) delay(100)
download(ReadBook.durChapterIndex + i) ReadBook.download(ReadBook.durChapterIndex + i)
}
}
}
}
fun loadContent(index: Int) {
ReadBook.book?.let { book ->
if (addLoading(index)) {
execute {
App.db.bookChapterDao().getChapter(book.bookUrl, index)?.let { chapter ->
BookHelp.getContent(book, chapter)?.let {
contentLoadFinish(chapter, it)
removeLoading(chapter.index)
} ?: download(chapter)
} ?: removeLoading(index)
}.onError {
removeLoading(index)
}
}
}
}
private fun download(index: Int) {
ReadBook.book?.let { book ->
if (addLoading(index)) {
execute {
App.db.bookChapterDao().getChapter(book.bookUrl, index)?.let { chapter ->
if (BookHelp.hasContent(book, chapter)) {
removeLoading(chapter.index)
} else {
download(chapter)
}
} ?: removeLoading(index)
}.onError {
removeLoading(index)
} }
} }
} }
} }
private fun download(chapter: BookChapter) {
ReadBook.book?.let { book ->
ReadBook.webBook?.getContent(book, chapter, scope = this)
?.onSuccess(IO) { content ->
if (content.isNullOrEmpty()) {
contentLoadFinish(chapter, context.getString(R.string.content_empty))
removeLoading(chapter.index)
} else {
BookHelp.saveContent(book, chapter, content)
contentLoadFinish(chapter, content)
removeLoading(chapter.index)
}
}?.onError {
contentLoadFinish(chapter, it.localizedMessage ?: "未知错误")
removeLoading(chapter.index)
}
}
}
private fun addLoading(index: Int): Boolean {
synchronized(this) {
if (ReadBook.loadingChapters.contains(index)) return false
ReadBook.loadingChapters.add(index)
return true
}
}
private fun removeLoading(index: Int) {
synchronized(this) {
ReadBook.loadingChapters.remove(index)
}
}
private fun contentLoadFinish(chapter: BookChapter, content: String) {
execute {
if (chapter.index in ReadBook.durChapterIndex - 1..ReadBook.durChapterIndex + 1) {
val c = BookHelp.disposeContent(
chapter.title,
ReadBook.book!!.name,
ReadBook.webBook?.bookSource?.bookSourceUrl,
content,
ReadBook.book!!.useReplaceRule
)
ReadBook.callBack?.contentLoadFinish(chapter, c)
}
}
}
fun changeTo(book1: Book) { fun changeTo(book1: Book) {
execute { execute {
ReadBook.book?.let { ReadBook.book?.let {
@ -278,25 +174,10 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
ReadBook.durChapterIndex = index ReadBook.durChapterIndex = index
ReadBook.durPageIndex = 0 ReadBook.durPageIndex = 0
} }
saveRead() ReadBook.saveRead()
ReadBook.callBack?.loadContent() ReadBook.callBack?.loadContent()
} }
fun saveRead() {
execute {
ReadBook.book?.let { book ->
book.lastCheckCount = 0
book.durChapterTime = System.currentTimeMillis()
book.durChapterIndex = ReadBook.durChapterIndex
book.durChapterPos = ReadBook.durPageIndex
ReadBook.curTextChapter?.let {
book.durChapterTitle = it.title
}
App.db.bookDao().update(book)
}
}
}
fun removeFromBookshelf(success: (() -> Unit)?) { fun removeFromBookshelf(success: (() -> Unit)?) {
execute { execute {
ReadBook.book?.let { ReadBook.book?.let {
@ -322,7 +203,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
App.db.bookChapterDao().getChapter(book.bookUrl, ReadBook.durChapterIndex) App.db.bookChapterDao().getChapter(book.bookUrl, ReadBook.durChapterIndex)
?.let { chapter -> ?.let { chapter ->
BookHelp.delContent(book, chapter) BookHelp.delContent(book, chapter)
loadContent(ReadBook.durChapterIndex) ReadBook.loadContent(ReadBook.durChapterIndex)
} }
} }
} }
@ -336,5 +217,6 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
fun loadContent() fun loadContent()
fun contentLoadFinish(bookChapter: BookChapter, content: String) fun contentLoadFinish(bookChapter: BookChapter, content: String)
fun upContent() fun upContent()
fun curChapterChanged()
} }
} }
Loading…
Cancel
Save