pull/48/head
kunfei 5 years ago
parent 8260ba9a34
commit 72331a5423
  1. 4
      app/src/main/java/io/legado/app/constant/Action.kt
  2. 2
      app/src/main/java/io/legado/app/constant/Bus.kt
  3. 1
      app/src/main/java/io/legado/app/help/http/AjaxWebView.kt
  4. 123
      app/src/main/java/io/legado/app/service/AudioPlayService.kt
  5. 32
      app/src/main/java/io/legado/app/service/help/AudioPlay.kt
  6. 30
      app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt
  7. 149
      app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt
  8. 6
      app/src/main/res/layout/activity_audio_play.xml

@ -12,4 +12,8 @@ object Action {
const val nextParagraph = "nextParagraph" const val nextParagraph = "nextParagraph"
const val upTtsSpeechRate = "upTtsSpeechRate" const val upTtsSpeechRate = "upTtsSpeechRate"
const val adjustProgress = "adjustProgress" const val adjustProgress = "adjustProgress"
const val prev = "prev"
const val next = "next"
const val moveTo = "moveTo"
const val init = "init"
} }

@ -14,7 +14,7 @@ object Bus {
const val UP_CONFIG = "upConfig" const val UP_CONFIG = "upConfig"
const val OPEN_CHAPTER = "openChapter" const val OPEN_CHAPTER = "openChapter"
const val REPLACE = "replace" const val REPLACE = "replace"
const val AUDIO_NEXT = "audioNext" const val AUDIO_SUB_TITLE = "audioSubTitle"
const val AUDIO_STATE = "audioState" const val AUDIO_STATE = "audioState"
const val AUDIO_PROGRESS = "audioProgress" const val AUDIO_PROGRESS = "audioProgress"
const val AUDIO_SIZE = "audioSize" const val AUDIO_SIZE = "audioSize"

@ -197,6 +197,7 @@ class AjaxWebView {
return@evaluateJavascript return@evaluateJavascript
} }
retry++ retry++
handler.removeCallbacks(this)
handler.postDelayed(this, 1000) handler.postDelayed(this, 1000)
} }
} }

@ -20,11 +20,15 @@ import io.legado.app.constant.Action
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.constant.Bus import io.legado.app.constant.Bus
import io.legado.app.constant.Status import io.legado.app.constant.Status
import io.legado.app.data.entities.BookChapter
import io.legado.app.help.BookHelp
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.AudioPlay
import io.legado.app.utils.LogUtils import io.legado.app.utils.LogUtils
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
@ -72,14 +76,16 @@ class AudioPlayService : BaseService(),
intent?.action?.let { action -> intent?.action?.let { action ->
when (action) { when (action) {
Action.play -> { Action.play -> {
title = intent.getStringExtra("title") ?: "" AudioPlay.book?.let {
subtitle = intent.getStringExtra("subtitle") ?: "" title = it.name
position = intent.getIntExtra("position", 0) position = it.durChapterPos
url = intent.getStringExtra("url") loadContent(it.durChapterIndex)
play() }
} }
Action.pause -> pause(true) Action.pause -> pause(true)
Action.resume -> resume() Action.resume -> resume()
Action.prev -> moveToPrev()
Action.next -> moveToNext()
Action.addTimer -> addTimer() Action.addTimer -> addTimer()
Action.setTimer -> setTimer(intent.getIntExtra("minute", 0)) Action.setTimer -> setTimer(intent.getIntExtra("minute", 0))
Action.adjustProgress -> adjustProgress(intent.getIntExtra("position", position)) Action.adjustProgress -> adjustProgress(intent.getIntExtra("position", position))
@ -102,6 +108,7 @@ class AudioPlayService : BaseService(),
} }
private fun play() { private fun play() {
postEvent(Bus.AUDIO_SUB_TITLE, subtitle)
upNotification() upNotification()
if (requestFocus()) { if (requestFocus()) {
try { try {
@ -176,7 +183,7 @@ class AudioPlayService : BaseService(),
*/ */
override fun onCompletion(mp: MediaPlayer?) { override fun onCompletion(mp: MediaPlayer?) {
handler.removeCallbacks(mpRunnable) handler.removeCallbacks(mpRunnable)
postEvent(Bus.AUDIO_NEXT, 1) moveToNext()
} }
private fun setTimer(minute: Int) { private fun setTimer(minute: Int) {
@ -207,6 +214,110 @@ class AudioPlayService : BaseService(),
handler.postDelayed(mpRunnable, 1000) handler.postDelayed(mpRunnable, 1000)
} }
private fun loadContent(index: Int) {
AudioPlay.book?.let { book ->
if (addLoading(index)) {
launch(IO) {
App.db.bookChapterDao().getChapter(book.bookUrl, index)?.let { chapter ->
BookHelp.getContent(book, chapter)?.let {
contentLoadFinish(chapter, it)
removeLoading(chapter.index)
} ?: download(chapter)
} ?: removeLoading(index)
}
}
}
}
private fun download(chapter: BookChapter) {
AudioPlay.book?.let { book ->
AudioPlay.webBook?.getContent(book, chapter, scope = this)
?.onSuccess(IO) { content ->
if (content.isNullOrEmpty()) {
contentLoadFinish(chapter, 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 (AudioPlay.loadingChapters.contains(index)) return false
AudioPlay.loadingChapters.add(index)
return true
}
}
private fun removeLoading(index: Int) {
synchronized(this) {
AudioPlay.loadingChapters.remove(index)
}
}
/**
*
*/
private fun contentLoadFinish(chapter: BookChapter, content: String) {
if (chapter.index == AudioPlay.durChapterIndex) {
subtitle = chapter.title
url = content
play()
}
}
fun moveToPrev() {
if (AudioPlay.durChapterIndex > 0) {
AudioPlay.durChapterIndex--
AudioPlay.durPageIndex = 0
AudioPlay.book?.durChapterIndex = AudioPlay.durChapterIndex
saveRead()
position = 0
loadContent(AudioPlay.durChapterIndex)
}
}
fun moveToNext() {
if (AudioPlay.durChapterIndex < AudioPlay.chapterSize - 1) {
AudioPlay.durChapterIndex++
AudioPlay.durPageIndex = 0
AudioPlay.book?.durChapterIndex = AudioPlay.durChapterIndex
saveRead()
position = 0
loadContent(AudioPlay.durChapterIndex)
} else {
stopSelf()
}
}
private fun saveRead() {
launch(IO) {
AudioPlay.book?.let { book ->
book.lastCheckCount = 0
book.durChapterTime = System.currentTimeMillis()
book.durChapterIndex = AudioPlay.durChapterIndex
book.durChapterPos = AudioPlay.durPageIndex
App.db.bookDao().update(book)
}
}
}
fun saveProgress() {
launch(IO) {
AudioPlay.book?.let {
App.db.bookDao().upProgress(it.bookUrl, AudioPlay.durPageIndex)
}
}
}
/** /**
* 定时 * 定时
*/ */

@ -7,7 +7,6 @@ import io.legado.app.constant.Action
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.model.WebBook import io.legado.app.model.WebBook
import io.legado.app.service.AudioPlayService import io.legado.app.service.AudioPlayService
import io.legado.app.ui.audio.AudioPlayViewModel
object AudioPlay { object AudioPlay {
var titleData = MutableLiveData<String>() var titleData = MutableLiveData<String>()
@ -15,19 +14,14 @@ object AudioPlay {
var book: Book? = null var book: Book? = null
var inBookshelf = false var inBookshelf = false
var chapterSize = 0 var chapterSize = 0
var callBack: AudioPlayViewModel.CallBack? = null
var durChapterIndex = 0 var durChapterIndex = 0
var durPageIndex = 0 var durPageIndex = 0
var webBook: WebBook? = null var webBook: WebBook? = null
val loadingChapters = arrayListOf<Int>() val loadingChapters = arrayListOf<Int>()
fun play(context: Context, title: String?, subtitle: String, url: String, position: Int) { fun play(context: Context) {
val intent = Intent(context, AudioPlayService::class.java) val intent = Intent(context, AudioPlayService::class.java)
intent.action = Action.play intent.action = Action.play
intent.putExtra("title", title)
intent.putExtra("subtitle", subtitle)
intent.putExtra("url", url)
intent.putExtra("position", position)
context.startService(intent) context.startService(intent)
} }
@ -63,4 +57,28 @@ object AudioPlay {
context.startService(intent) context.startService(intent)
} }
} }
fun prev(context: Context) {
if (AudioPlayService.isRun) {
val intent = Intent(context, AudioPlayService::class.java)
intent.action = Action.prev
context.startService(intent)
}
}
fun next(context: Context) {
if (AudioPlayService.isRun) {
val intent = Intent(context, AudioPlayService::class.java)
intent.action = Action.next
context.startService(intent)
}
}
fun moveTo(context: Context, index: Int) {
if (AudioPlayService.isRun) {
val intent = Intent(context, AudioPlayService::class.java)
intent.action = Action.moveTo
context.startService(intent)
}
}
} }

@ -13,7 +13,6 @@ import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.Bus import io.legado.app.constant.Bus
import io.legado.app.constant.Status import io.legado.app.constant.Status
import io.legado.app.data.entities.BookChapter
import io.legado.app.help.BlurTransformation import io.legado.app.help.BlurTransformation
import io.legado.app.help.ImageLoader import io.legado.app.help.ImageLoader
import io.legado.app.help.storage.Backup import io.legado.app.help.storage.Backup
@ -35,8 +34,7 @@ import org.jetbrains.anko.sdk27.listeners.onLongClick
import org.jetbrains.anko.startActivity import org.jetbrains.anko.startActivity
import org.jetbrains.anko.startActivityForResult import org.jetbrains.anko.startActivityForResult
class AudioPlayActivity : VMBaseActivity<AudioPlayViewModel>(R.layout.activity_audio_play), class AudioPlayActivity : VMBaseActivity<AudioPlayViewModel>(R.layout.activity_audio_play) {
AudioPlayViewModel.CallBack {
override val viewModel: AudioPlayViewModel override val viewModel: AudioPlayViewModel
get() = getViewModel(AudioPlayViewModel::class.java) get() = getViewModel(AudioPlayViewModel::class.java)
@ -62,10 +60,10 @@ class AudioPlayActivity : VMBaseActivity<AudioPlayViewModel>(R.layout.activity_a
true true
} }
iv_skip_next.onClick { iv_skip_next.onClick {
viewModel.moveToNext() AudioPlay.next(this)
} }
iv_skip_previous.onClick { iv_skip_previous.onClick {
viewModel.moveToPrev() AudioPlay.prev(this)
} }
player_progress.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { player_progress.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
@ -113,21 +111,10 @@ class AudioPlayActivity : VMBaseActivity<AudioPlayViewModel>(R.layout.activity_a
when (status) { when (status) {
Status.PLAY -> AudioPlay.pause(this) Status.PLAY -> AudioPlay.pause(this)
Status.PAUSE -> AudioPlay.resume(this) Status.PAUSE -> AudioPlay.resume(this)
else -> viewModel.loadContent(AudioPlay.durChapterIndex) else -> AudioPlay.play(this)
} }
} }
override fun contentLoadFinish(bookChapter: BookChapter, content: String) {
AudioPlay.play(
this,
AudioPlay.book?.name,
bookChapter.title,
content,
AudioPlay.durPageIndex
)
viewModel.loadContent(AudioPlay.durChapterIndex + 1)
}
override fun finish() { override fun finish() {
AudioPlay.book?.let { AudioPlay.book?.let {
if (!AudioPlay.inBookshelf) { if (!AudioPlay.inBookshelf) {
@ -160,7 +147,7 @@ class AudioPlayActivity : VMBaseActivity<AudioPlayViewModel>(R.layout.activity_a
when (requestCode) { when (requestCode) {
requestCodeChapter -> data?.getIntExtra("index", AudioPlay.durChapterIndex)?.let { requestCodeChapter -> data?.getIntExtra("index", AudioPlay.durChapterIndex)?.let {
if (it != AudioPlay.durChapterIndex) { if (it != AudioPlay.durChapterIndex) {
viewModel.loadContent(it) AudioPlay.moveTo(this, it)
} }
} }
} }
@ -171,9 +158,6 @@ class AudioPlayActivity : VMBaseActivity<AudioPlayViewModel>(R.layout.activity_a
observeEvent<Boolean>(Bus.AUDIO_PLAY_BUTTON) { observeEvent<Boolean>(Bus.AUDIO_PLAY_BUTTON) {
playButton() playButton()
} }
observeEvent<Int>(Bus.AUDIO_NEXT) {
viewModel.moveToNext()
}
observeEvent<Int>(Bus.AUDIO_STATE) { observeEvent<Int>(Bus.AUDIO_STATE) {
status = it status = it
if (status == Status.PLAY) { if (status == Status.PLAY) {
@ -186,12 +170,14 @@ class AudioPlayActivity : VMBaseActivity<AudioPlayViewModel>(R.layout.activity_a
AudioPlay.durPageIndex = it AudioPlay.durPageIndex = it
if (!adjustProgress) player_progress.progress = it if (!adjustProgress) player_progress.progress = it
tv_dur_time.text = DateFormatUtils.format(it.toLong(), "mm:ss") tv_dur_time.text = DateFormatUtils.format(it.toLong(), "mm:ss")
viewModel.saveProgress()
} }
observeEventSticky<Int>(Bus.AUDIO_SIZE) { observeEventSticky<Int>(Bus.AUDIO_SIZE) {
player_progress.max = it player_progress.max = it
tv_all_time.text = DateFormatUtils.format(it.toLong(), "mm:ss") tv_all_time.text = DateFormatUtils.format(it.toLong(), "mm:ss")
} }
observeEventSticky<String>(Bus.AUDIO_SUB_TITLE) {
tv_sub_title.text = it
}
} }
} }

@ -10,16 +10,6 @@ import io.legado.app.data.entities.BookChapter
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.model.WebBook import io.legado.app.model.WebBook
import io.legado.app.service.help.AudioPlay import io.legado.app.service.help.AudioPlay
import io.legado.app.service.help.AudioPlay.book
import io.legado.app.service.help.AudioPlay.callBack
import io.legado.app.service.help.AudioPlay.chapterSize
import io.legado.app.service.help.AudioPlay.coverData
import io.legado.app.service.help.AudioPlay.durChapterIndex
import io.legado.app.service.help.AudioPlay.durPageIndex
import io.legado.app.service.help.AudioPlay.inBookshelf
import io.legado.app.service.help.AudioPlay.loadingChapters
import io.legado.app.service.help.AudioPlay.titleData
import io.legado.app.service.help.AudioPlay.webBook
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -27,20 +17,20 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
fun initData(intent: Intent) { fun initData(intent: Intent) {
execute { execute {
inBookshelf = intent.getBooleanExtra("inBookshelf", true) AudioPlay.inBookshelf = intent.getBooleanExtra("inBookshelf", true)
val bookUrl = intent.getStringExtra("bookUrl") val bookUrl = intent.getStringExtra("bookUrl")
book = if (!bookUrl.isNullOrEmpty()) { AudioPlay.book = if (!bookUrl.isNullOrEmpty()) {
App.db.bookDao().getBook(bookUrl) App.db.bookDao().getBook(bookUrl)
} else { } else {
App.db.bookDao().lastReadBook App.db.bookDao().lastReadBook
} }
book?.let { book -> AudioPlay.book?.let { book ->
titleData.postValue(book.name) AudioPlay.titleData.postValue(book.name)
coverData.postValue(book.getDisplayCover()) AudioPlay.coverData.postValue(book.getDisplayCover())
durChapterIndex = book.durChapterIndex AudioPlay.durChapterIndex = book.durChapterIndex
durPageIndex = book.durChapterPos AudioPlay.durPageIndex = book.durChapterPos
App.db.bookSourceDao().getBookSource(book.origin)?.let { App.db.bookSourceDao().getBookSource(book.origin)?.let {
webBook = WebBook(it) AudioPlay.webBook = WebBook(it)
} }
val count = App.db.bookChapterDao().getChapterCount(book.bookUrl) val count = App.db.bookChapterDao().getChapterCount(book.bookUrl)
if (count == 0) { if (count == 0) {
@ -50,10 +40,10 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
loadChapterList(book) loadChapterList(book)
} }
} else { } else {
if (durChapterIndex > count - 1) { if (AudioPlay.durChapterIndex > count - 1) {
durChapterIndex = count - 1 AudioPlay.durChapterIndex = count - 1
} }
chapterSize = count AudioPlay.chapterSize = count
} }
} }
saveRead() saveRead()
@ -65,7 +55,7 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
changeDruChapterIndex: ((chapters: List<BookChapter>) -> Unit)? = null changeDruChapterIndex: ((chapters: List<BookChapter>) -> Unit)? = null
) { ) {
execute { execute {
webBook?.getBookInfo(book, this) AudioPlay.webBook?.getBookInfo(book, this)
?.onSuccess { ?.onSuccess {
loadChapterList(book, changeDruChapterIndex) loadChapterList(book, changeDruChapterIndex)
} }
@ -77,12 +67,12 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
changeDruChapterIndex: ((chapters: List<BookChapter>) -> Unit)? = null changeDruChapterIndex: ((chapters: List<BookChapter>) -> Unit)? = null
) { ) {
execute { execute {
webBook?.getChapterList(book, this) AudioPlay.webBook?.getChapterList(book, this)
?.onSuccess(Dispatchers.IO) { cList -> ?.onSuccess(Dispatchers.IO) { cList ->
if (!cList.isNullOrEmpty()) { if (!cList.isNullOrEmpty()) {
if (changeDruChapterIndex == null) { if (changeDruChapterIndex == null) {
App.db.bookChapterDao().insert(*cList.toTypedArray()) App.db.bookChapterDao().insert(*cList.toTypedArray())
chapterSize = cList.size AudioPlay.chapterSize = cList.size
} else { } else {
changeDruChapterIndex(cList) changeDruChapterIndex(cList)
} }
@ -95,74 +85,18 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
} }
} }
fun loadContent(index: Int) {
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(chapter: BookChapter) {
book?.let { book ->
webBook?.getContent(book, chapter, scope = this)
?.onSuccess(Dispatchers.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 (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) {
if (chapter.index == durChapterIndex) {
callBack?.contentLoadFinish(chapter, content)
}
}
fun changeTo(book1: Book) { fun changeTo(book1: Book) {
execute { execute {
book?.let { AudioPlay.book?.let {
App.db.bookDao().delete(it.bookUrl) App.db.bookDao().delete(it.bookUrl)
} }
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
} }
App.db.bookDao().insert(book1) App.db.bookDao().insert(book1)
book = book1 AudioPlay.book = book1
App.db.bookSourceDao().getBookSource(book1.origin)?.let { App.db.bookSourceDao().getBookSource(book1.origin)?.let {
webBook = WebBook(it) AudioPlay.webBook = WebBook(it)
} }
if (book1.tocUrl.isEmpty()) { if (book1.tocUrl.isEmpty()) {
loadBookInfo(book1) { upChangeDurChapterIndex(book1, it) } loadBookInfo(book1) { upChangeDurChapterIndex(book1, it) }
@ -174,64 +108,34 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
private fun upChangeDurChapterIndex(book: Book, chapters: List<BookChapter>) { private fun upChangeDurChapterIndex(book: Book, chapters: List<BookChapter>) {
execute { execute {
durChapterIndex = BookHelp.getDurChapterIndexByChapterTitle( AudioPlay.durChapterIndex = BookHelp.getDurChapterIndexByChapterTitle(
book.durChapterTitle, book.durChapterTitle,
book.durChapterIndex, book.durChapterIndex,
chapters chapters
) )
book.durChapterIndex = durChapterIndex book.durChapterIndex = AudioPlay.durChapterIndex
book.durChapterTitle = chapters[durChapterIndex].title book.durChapterTitle = chapters[AudioPlay.durChapterIndex].title
App.db.bookDao().update(book) App.db.bookDao().update(book)
App.db.bookChapterDao().insert(*chapters.toTypedArray()) App.db.bookChapterDao().insert(*chapters.toTypedArray())
chapterSize = chapters.size AudioPlay.chapterSize = chapters.size
}
}
fun moveToPrev() {
if (durChapterIndex > 0) {
durChapterIndex--
durPageIndex = 0
book?.durChapterIndex = durChapterIndex
saveRead()
loadContent(durChapterIndex)
}
}
fun moveToNext() {
if (durChapterIndex < chapterSize - 1) {
durChapterIndex++
durPageIndex = 0
book?.durChapterIndex = durChapterIndex
saveRead()
loadContent(durChapterIndex)
} else {
AudioPlay.stop(context)
} }
} }
private fun saveRead() { private fun saveRead() {
execute { execute {
book?.let { book -> AudioPlay.book?.let { book ->
book.lastCheckCount = 0 book.lastCheckCount = 0
book.durChapterTime = System.currentTimeMillis() book.durChapterTime = System.currentTimeMillis()
book.durChapterIndex = durChapterIndex book.durChapterIndex = AudioPlay.durChapterIndex
book.durChapterPos = durPageIndex book.durChapterPos = AudioPlay.durPageIndex
App.db.bookDao().update(book) App.db.bookDao().update(book)
} }
} }
} }
fun saveProgress() {
execute {
book?.let {
App.db.bookDao().upProgress(it.bookUrl, durPageIndex)
}
}
}
fun removeFromBookshelf(success: (() -> Unit)?) { fun removeFromBookshelf(success: (() -> Unit)?) {
execute { execute {
book?.let { AudioPlay.book?.let {
App.db.bookDao().delete(it.bookUrl) App.db.bookDao().delete(it.bookUrl)
} }
}.onSuccess { }.onSuccess {
@ -239,7 +143,4 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
} }
} }
interface CallBack {
fun contentLoadFinish(bookChapter: BookChapter, content: String)
}
} }

@ -42,6 +42,12 @@
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar" /> app:layout_constraintTop_toBottomOf="@+id/title_bar" />
<TextView
android:id="@+id/tv_sub_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/ll_player_progress" />
<LinearLayout <LinearLayout
android:id="@+id/ll_player_progress" android:id="@+id/ll_player_progress"
android:layout_width="match_parent" android:layout_width="match_parent"

Loading…
Cancel
Save