[优化] 漫画功能扩展 #496
This commit is contained in:
@@ -11,6 +11,7 @@ import android.view.MenuItem
|
|||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.view.animation.LinearInterpolator
|
import android.view.animation.LinearInterpolator
|
||||||
import androidx.activity.addCallback
|
import androidx.activity.addCallback
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.view.doOnLayout
|
import androidx.core.view.doOnLayout
|
||||||
@@ -29,22 +30,33 @@ import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
|
|||||||
import io.legado.app.BuildConfig
|
import io.legado.app.BuildConfig
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.base.VMBaseActivity
|
import io.legado.app.base.VMBaseActivity
|
||||||
|
import io.legado.app.constant.AppLog
|
||||||
import io.legado.app.constant.BookType
|
import io.legado.app.constant.BookType
|
||||||
import io.legado.app.constant.EventBus
|
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.Book
|
||||||
import io.legado.app.data.entities.BookChapter
|
import io.legado.app.data.entities.BookChapter
|
||||||
import io.legado.app.data.entities.BookProgress
|
import io.legado.app.data.entities.BookProgress
|
||||||
import io.legado.app.data.entities.BookSource
|
import io.legado.app.data.entities.BookSource
|
||||||
import io.legado.app.databinding.ActivityMangaBinding
|
import io.legado.app.databinding.ActivityMangaBinding
|
||||||
import io.legado.app.databinding.ViewLoadMoreBinding
|
import io.legado.app.databinding.ViewLoadMoreBinding
|
||||||
|
import io.legado.app.exception.NoStackTraceException
|
||||||
|
import io.legado.app.help.AppFreezeMonitor.handler
|
||||||
|
import io.legado.app.help.book.BookHelp
|
||||||
import io.legado.app.help.book.isImage
|
import io.legado.app.help.book.isImage
|
||||||
|
import io.legado.app.help.book.isLocal
|
||||||
import io.legado.app.help.book.removeType
|
import io.legado.app.help.book.removeType
|
||||||
import io.legado.app.help.config.AppConfig
|
import io.legado.app.help.config.AppConfig
|
||||||
|
import io.legado.app.help.coroutine.Coroutine
|
||||||
|
import io.legado.app.help.source.getSourceType
|
||||||
import io.legado.app.help.storage.Backup
|
import io.legado.app.help.storage.Backup
|
||||||
import io.legado.app.lib.dialogs.SelectItem
|
import io.legado.app.lib.dialogs.SelectItem
|
||||||
import io.legado.app.lib.dialogs.alert
|
import io.legado.app.lib.dialogs.alert
|
||||||
import io.legado.app.lib.dialogs.selector
|
import io.legado.app.lib.dialogs.selector
|
||||||
import io.legado.app.model.ReadManga
|
import io.legado.app.model.ReadManga
|
||||||
|
import io.legado.app.model.analyzeRule.AnalyzeRule
|
||||||
|
import io.legado.app.model.analyzeRule.AnalyzeRule.Companion.setChapter
|
||||||
|
import io.legado.app.model.analyzeRule.AnalyzeRule.Companion.setCoroutineContext
|
||||||
import io.legado.app.receiver.NetworkChangedListener
|
import io.legado.app.receiver.NetworkChangedListener
|
||||||
import io.legado.app.ui.book.changesource.ChangeBookSourceDialog
|
import io.legado.app.ui.book.changesource.ChangeBookSourceDialog
|
||||||
import io.legado.app.ui.book.info.BookInfoActivity
|
import io.legado.app.ui.book.info.BookInfoActivity
|
||||||
@@ -64,7 +76,10 @@ import io.legado.app.ui.book.manga.recyclerview.ScrollTimer
|
|||||||
import io.legado.app.ui.book.manga.recyclerview.WebtoonFrame
|
import io.legado.app.ui.book.manga.recyclerview.WebtoonFrame
|
||||||
import io.legado.app.ui.book.read.MangaMenu
|
import io.legado.app.ui.book.read.MangaMenu
|
||||||
import io.legado.app.ui.book.read.ReadBookActivity.Companion.RESULT_DELETED
|
import io.legado.app.ui.book.read.ReadBookActivity.Companion.RESULT_DELETED
|
||||||
|
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
|
||||||
import io.legado.app.ui.book.toc.TocActivityResult
|
import io.legado.app.ui.book.toc.TocActivityResult
|
||||||
|
import io.legado.app.ui.browser.WebViewActivity
|
||||||
|
import io.legado.app.ui.login.SourceLoginActivity
|
||||||
import io.legado.app.ui.widget.number.NumberPickerDialog
|
import io.legado.app.ui.widget.number.NumberPickerDialog
|
||||||
import io.legado.app.ui.widget.recycler.LoadMoreView
|
import io.legado.app.ui.widget.recycler.LoadMoreView
|
||||||
import io.legado.app.utils.GSON
|
import io.legado.app.utils.GSON
|
||||||
@@ -75,8 +90,11 @@ import io.legado.app.utils.fastBinarySearch
|
|||||||
import io.legado.app.utils.findCenterViewPosition
|
import io.legado.app.utils.findCenterViewPosition
|
||||||
import io.legado.app.utils.fromJsonObject
|
import io.legado.app.utils.fromJsonObject
|
||||||
import io.legado.app.utils.gone
|
import io.legado.app.utils.gone
|
||||||
|
import io.legado.app.utils.isAbsUrl
|
||||||
|
import io.legado.app.utils.isTrue
|
||||||
import io.legado.app.utils.observeEvent
|
import io.legado.app.utils.observeEvent
|
||||||
import io.legado.app.utils.showDialogFragment
|
import io.legado.app.utils.showDialogFragment
|
||||||
|
import io.legado.app.utils.startActivity
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
import io.legado.app.utils.toggleSystemBar
|
import io.legado.app.utils.toggleSystemBar
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||||
@@ -135,6 +153,17 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
|
|||||||
LinearInterpolator()
|
LinearInterpolator()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val sourceEditActivity =
|
||||||
|
registerForActivityResult(StartActivityContract(BookSourceEditActivity::class.java)) {
|
||||||
|
if (it.resultCode == RESULT_OK) {
|
||||||
|
viewModel.upBookSource {
|
||||||
|
handler.post {
|
||||||
|
binding.mangaMenu.upBookView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val loadMoreView by lazy {
|
private val loadMoreView by lazy {
|
||||||
LoadMoreView(this).apply {
|
LoadMoreView(this).apply {
|
||||||
// setBackgroundColor(getCompatColor(R.color.book_ant_10))
|
// setBackgroundColor(getCompatColor(R.color.book_ant_10))
|
||||||
@@ -565,6 +594,77 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
|
|||||||
return super.onCompatCreateOptionsMenu(menu)
|
return super.onCompatCreateOptionsMenu(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun showLogin() {
|
||||||
|
ReadManga.bookSource?.let {
|
||||||
|
startActivity<SourceLoginActivity> {
|
||||||
|
putExtra("type", "bookSource")
|
||||||
|
putExtra("key", it.bookSourceUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun payAction() {
|
||||||
|
val book = ReadManga.book ?: return
|
||||||
|
if (book.isLocal) return
|
||||||
|
val chapter = appDb.bookChapterDao.getChapter(book.bookUrl, ReadManga.durChapterIndex)
|
||||||
|
if (chapter == null) {
|
||||||
|
toastOnUi("no chapter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
alert(R.string.chapter_pay) {
|
||||||
|
setMessage(chapter.title)
|
||||||
|
yesButton {
|
||||||
|
Coroutine.async(lifecycleScope) {
|
||||||
|
val source =
|
||||||
|
ReadManga.bookSource ?: throw NoStackTraceException("no book source")
|
||||||
|
val payAction = source.getContentRule().payAction
|
||||||
|
if (payAction.isNullOrBlank()) {
|
||||||
|
throw NoStackTraceException("no pay action")
|
||||||
|
}
|
||||||
|
val analyzeRule = AnalyzeRule(book, source)
|
||||||
|
analyzeRule.setCoroutineContext(coroutineContext)
|
||||||
|
analyzeRule.setBaseUrl(chapter.url)
|
||||||
|
analyzeRule.setChapter(chapter)
|
||||||
|
analyzeRule.evalJS(payAction).toString()
|
||||||
|
}.onSuccess(IO) {
|
||||||
|
if (it.isAbsUrl()) {
|
||||||
|
startActivity<WebViewActivity> {
|
||||||
|
val bookSource = ReadManga.bookSource
|
||||||
|
putExtra("title", getString(R.string.chapter_pay))
|
||||||
|
putExtra("url", it)
|
||||||
|
putExtra("sourceOrigin", bookSource?.bookSourceUrl)
|
||||||
|
putExtra("sourceName", bookSource?.bookSourceName)
|
||||||
|
putExtra("sourceType", bookSource?.getSourceType())
|
||||||
|
}
|
||||||
|
} else if (it.isTrue()) {
|
||||||
|
//购买成功后刷新目录
|
||||||
|
ReadManga.book?.let {
|
||||||
|
ReadManga.curMangaChapter = null
|
||||||
|
BookHelp.delContent(book, chapter)
|
||||||
|
viewModel.loadChapterList(book)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.onError {
|
||||||
|
AppLog.put("执行购买操作出错\n${it.localizedMessage}", it, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
noButton()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun disableSource() {
|
||||||
|
viewModel.disableSource()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun openSourceEditActivity() {
|
||||||
|
ReadManga.bookSource?.let {
|
||||||
|
sourceEditActivity.launch {
|
||||||
|
putExtra("sourceUrl", it.bookSourceUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单
|
* 菜单
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import io.legado.app.help.book.removeType
|
|||||||
import io.legado.app.help.book.simulatedTotalChapterNum
|
import io.legado.app.help.book.simulatedTotalChapterNum
|
||||||
import io.legado.app.help.config.AppConfig
|
import io.legado.app.help.config.AppConfig
|
||||||
import io.legado.app.help.coroutine.Coroutine
|
import io.legado.app.help.coroutine.Coroutine
|
||||||
|
import io.legado.app.model.ReadBook
|
||||||
import io.legado.app.model.ReadManga
|
import io.legado.app.model.ReadManga
|
||||||
import io.legado.app.model.localBook.LocalBook
|
import io.legado.app.model.localBook.LocalBook
|
||||||
import io.legado.app.model.webBook.WebBook
|
import io.legado.app.model.webBook.WebBook
|
||||||
@@ -120,6 +121,31 @@ class ReadMangaViewModel(application: Application) : BaseViewModel(application)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun upBookSource(success: (() -> Unit)?) {
|
||||||
|
execute {
|
||||||
|
ReadManga.book?.let { book ->
|
||||||
|
ReadManga.bookSource = appDb.bookSourceDao.getBookSource(book.origin)
|
||||||
|
}
|
||||||
|
}.onSuccess {
|
||||||
|
success?.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadChapterList(book: Book) {
|
||||||
|
execute {
|
||||||
|
loadChapterListAwait(book)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun disableSource() {
|
||||||
|
execute {
|
||||||
|
ReadManga.bookSource?.let {
|
||||||
|
it.enabled = false
|
||||||
|
appDb.bookSourceDao.update(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun loadChapterListAwait(book: Book): Boolean {
|
private suspend fun loadChapterListAwait(book: Book): Boolean {
|
||||||
ReadManga.bookSource?.let {
|
ReadManga.bookSource?.let {
|
||||||
val oldBook = book.copy()
|
val oldBook = book.copy()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import android.util.AttributeSet
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.animation.Animation
|
import android.view.animation.Animation
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.google.android.material.slider.Slider
|
import com.google.android.material.slider.Slider
|
||||||
@@ -37,6 +38,22 @@ class MangaMenu @JvmOverloads constructor(
|
|||||||
private val binding = ViewMangaMenuBinding.inflate(LayoutInflater.from(context), this, true)
|
private val binding = ViewMangaMenuBinding.inflate(LayoutInflater.from(context), this, true)
|
||||||
private val callBack: CallBack get() = activity as CallBack
|
private val callBack: CallBack get() = activity as CallBack
|
||||||
var canShowMenu: Boolean = false
|
var canShowMenu: Boolean = false
|
||||||
|
|
||||||
|
private val sourceMenu by lazy {
|
||||||
|
PopupMenu(context, binding.tvSourceAction).apply {
|
||||||
|
inflate(R.menu.book_read_source)
|
||||||
|
setOnMenuItemClickListener {
|
||||||
|
when (it.itemId) {
|
||||||
|
R.id.menu_login -> callBack.showLogin()
|
||||||
|
R.id.menu_chapter_pay -> callBack.payAction()
|
||||||
|
R.id.menu_edit_source -> callBack.openSourceEditActivity()
|
||||||
|
R.id.menu_disable_source -> callBack.disableSource()
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val menuTopIn: Animation by lazy {
|
private val menuTopIn: Animation by lazy {
|
||||||
loadAnimation(context, R.anim.anim_readbook_top_in)
|
loadAnimation(context, R.anim.anim_readbook_top_in)
|
||||||
}
|
}
|
||||||
@@ -207,11 +224,17 @@ class MangaMenu @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
tvBookName.setOnClickListener{
|
||||||
|
callBack.openBookInfoActivity()
|
||||||
|
}
|
||||||
tvChapterName.setOnClickListener(chapterViewClickListener)
|
tvChapterName.setOnClickListener(chapterViewClickListener)
|
||||||
tvChapterName.setOnLongClickListener(chapterViewLongClickListener)
|
tvChapterName.setOnLongClickListener(chapterViewLongClickListener)
|
||||||
tvChapterUrl.setOnClickListener(chapterViewClickListener)
|
tvChapterUrl.setOnClickListener(chapterViewClickListener)
|
||||||
tvChapterUrl.setOnLongClickListener(chapterViewLongClickListener)
|
tvChapterUrl.setOnLongClickListener(chapterViewLongClickListener)
|
||||||
|
tvSourceAction.setOnLongClickListener {
|
||||||
|
sourceMenu.show()
|
||||||
|
true
|
||||||
|
}
|
||||||
tvNext.setOnClickListener {
|
tvNext.setOnClickListener {
|
||||||
ReadManga.moveToNextChapter(true)
|
ReadManga.moveToNextChapter(true)
|
||||||
}
|
}
|
||||||
@@ -282,6 +305,10 @@ class MangaMenu @JvmOverloads constructor(
|
|||||||
fun showFooterConfig()
|
fun showFooterConfig()
|
||||||
fun showScrollModeDialog()
|
fun showScrollModeDialog()
|
||||||
fun onAutoPageToggle2()
|
fun onAutoPageToggle2()
|
||||||
|
fun showLogin()
|
||||||
|
fun payAction()
|
||||||
|
fun openSourceEditActivity()
|
||||||
|
fun disableSource()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user