From cf5f9c6674c24776f4eda9c2ea12e6dbd2ab582f Mon Sep 17 00:00:00 2001 From: HapeLee <1321903405@qq.com> Date: Wed, 24 Dec 2025 00:41:01 +0800 Subject: [PATCH] =?UTF-8?q?[=E4=BC=98=E5=8C=96]=20=E6=BC=AB=E7=94=BB?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=89=A9=E5=B1=95=20#496?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/manga/ReadMangaActivity.kt | 100 ++++++++++++++++++ .../app/ui/book/manga/ReadMangaViewModel.kt | 26 +++++ .../io/legado/app/ui/book/read/MangaMenu.kt | 29 ++++- 3 files changed, 154 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaActivity.kt b/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaActivity.kt index 2f74e89a0..186262ec8 100644 --- a/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaActivity.kt @@ -11,6 +11,7 @@ import android.view.MenuItem import android.view.WindowManager import android.view.animation.LinearInterpolator import androidx.activity.addCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.appcompat.app.AlertDialog import androidx.core.view.doOnLayout @@ -29,22 +30,33 @@ import com.jaredrummler.android.colorpicker.ColorPickerDialogListener import io.legado.app.BuildConfig import io.legado.app.R import io.legado.app.base.VMBaseActivity +import io.legado.app.constant.AppLog import io.legado.app.constant.BookType 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.databinding.ActivityMangaBinding 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.isLocal import io.legado.app.help.book.removeType 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.lib.dialogs.SelectItem import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.selector 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.ui.book.changesource.ChangeBookSourceDialog 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.read.MangaMenu 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.browser.WebViewActivity +import io.legado.app.ui.login.SourceLoginActivity import io.legado.app.ui.widget.number.NumberPickerDialog import io.legado.app.ui.widget.recycler.LoadMoreView 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.fromJsonObject 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.showDialogFragment +import io.legado.app.utils.startActivity import io.legado.app.utils.toastOnUi import io.legado.app.utils.toggleSystemBar import io.legado.app.utils.viewbindingdelegate.viewBinding @@ -135,6 +153,17 @@ class ReadMangaActivity : VMBaseActivity { + 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 { + 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) + } + } + } + /** * 菜单 */ diff --git a/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaViewModel.kt b/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaViewModel.kt index 9fb27ecee..cccdedd7d 100644 --- a/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaViewModel.kt @@ -24,6 +24,7 @@ import io.legado.app.help.book.removeType import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.config.AppConfig import io.legado.app.help.coroutine.Coroutine +import io.legado.app.model.ReadBook import io.legado.app.model.ReadManga import io.legado.app.model.localBook.LocalBook 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 { ReadManga.bookSource?.let { val oldBook = book.copy() diff --git a/app/src/main/java/io/legado/app/ui/book/read/MangaMenu.kt b/app/src/main/java/io/legado/app/ui/book/read/MangaMenu.kt index d305f44e9..465effd89 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/MangaMenu.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/MangaMenu.kt @@ -7,6 +7,7 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.view.animation.Animation import android.widget.FrameLayout +import androidx.appcompat.widget.PopupMenu import androidx.core.view.isGone import androidx.core.view.isVisible 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 callBack: CallBack get() = activity as CallBack 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 { loadAnimation(context, R.anim.anim_readbook_top_in) } @@ -207,11 +224,17 @@ class MangaMenu @JvmOverloads constructor( } true } + tvBookName.setOnClickListener{ + callBack.openBookInfoActivity() + } tvChapterName.setOnClickListener(chapterViewClickListener) tvChapterName.setOnLongClickListener(chapterViewLongClickListener) tvChapterUrl.setOnClickListener(chapterViewClickListener) tvChapterUrl.setOnLongClickListener(chapterViewLongClickListener) - + tvSourceAction.setOnLongClickListener { + sourceMenu.show() + true + } tvNext.setOnClickListener { ReadManga.moveToNextChapter(true) } @@ -282,6 +305,10 @@ class MangaMenu @JvmOverloads constructor( fun showFooterConfig() fun showScrollModeDialog() fun onAutoPageToggle2() + fun showLogin() + fun payAction() + fun openSourceEditActivity() + fun disableSource() } }