diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0b2ad12fd..07a76c223 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -340,7 +340,11 @@ + + - - diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index b002aacb0..8d0f7ffb1 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -1,6 +1,5 @@ package io.legado.app.help -import android.content.Intent import android.net.Uri import android.webkit.WebSettings import androidx.annotation.Keep @@ -22,7 +21,7 @@ import io.legado.app.help.source.SourceVerificationHelp import io.legado.app.model.Debug import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.QueryTTF -import io.legado.app.ui.javascript.ConfirmationDialogActivity +import io.legado.app.ui.association.OpenUrlConfirmActivity import io.legado.app.utils.ArchiveUtils import io.legado.app.utils.ChineseUtils import io.legado.app.utils.EncoderUtils @@ -45,6 +44,7 @@ import io.legado.app.utils.longToastOnUi import io.legado.app.utils.readBytes import io.legado.app.utils.readText import io.legado.app.utils.stackTraceStr +import io.legado.app.utils.startActivity import io.legado.app.utils.toStringArray import io.legado.app.utils.toastOnUi import kotlinx.coroutines.Dispatchers.IO @@ -966,23 +966,12 @@ interface JsExtensions : JsEncodeUtils { // 新增 mimeType 参数,默认为 null(保持兼容性) fun openUrl(url: String, mimeType: String? = null) { - try { - val intent = Intent(appCtx, ConfirmationDialogActivity::class.java).apply { - // 同时设置 Data 和 Type(避免单独设置 data/type 导致冲突) - if (mimeType != null) { - setDataAndType(Uri.parse(url), mimeType) - } else { - data = Uri.parse(url) - } - putExtra("sourceTag", getSource()?.getTag() ?: "") - // 可选:添加 MIME 类型到 Extra 供后续逻辑使用 - putExtra("mimeType", mimeType) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - appCtx.startActivity(intent) - } catch (e: Exception) { - AppLog.put("启动跳转对话框失败", e) - appCtx.toastOnUi("启动跳转确认失败") + val source = getSource() ?: throw NoStackTraceException("openUrl source cannot be null") + appCtx.startActivity { + putExtra("uri", url) + putExtra("mimeType", mimeType) + putExtra("sourceOrigin", source.getKey()) + putExtra("sourceName", source.getTag()) } } diff --git a/app/src/main/java/io/legado/app/ui/association/OpenUrlConfirmActivity.kt b/app/src/main/java/io/legado/app/ui/association/OpenUrlConfirmActivity.kt new file mode 100644 index 000000000..ceb0978b1 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/association/OpenUrlConfirmActivity.kt @@ -0,0 +1,23 @@ +package io.legado.app.ui.association + +import android.os.Bundle +import io.legado.app.base.BaseActivity +import io.legado.app.databinding.ActivityTranslucenceBinding +import io.legado.app.utils.showDialogFragment +import io.legado.app.utils.viewbindingdelegate.viewBinding + +class OpenUrlConfirmActivity : + BaseActivity() { + + override val binding by viewBinding(ActivityTranslucenceBinding::inflate) + + override fun onActivityCreated(savedInstanceState: Bundle?) { + intent.getStringExtra("uri")?.let { + val mimeType = intent.getStringExtra("mimeType") + val sourceOrigin = intent.getStringExtra("sourceOrigin") + val sourceName = intent.getStringExtra("sourceName") + showDialogFragment(OpenUrlConfirmDialog(it, mimeType, sourceOrigin, sourceName)) + } ?: finish() + } + +} diff --git a/app/src/main/java/io/legado/app/ui/association/OpenUrlConfirmDialog.kt b/app/src/main/java/io/legado/app/ui/association/OpenUrlConfirmDialog.kt new file mode 100644 index 000000000..dbf3d443b --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/association/OpenUrlConfirmDialog.kt @@ -0,0 +1,130 @@ +package io.legado.app.ui.association + +import android.content.Intent +import android.os.Bundle +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.widget.Toolbar +import androidx.core.net.toUri +import androidx.fragment.app.viewModels +import io.legado.app.R +import io.legado.app.base.BaseDialogFragment +import io.legado.app.constant.AppLog +import io.legado.app.databinding.DialogOpenUrlConfirmBinding +import io.legado.app.lib.dialogs.alert +import io.legado.app.lib.theme.primaryColor +import io.legado.app.utils.applyTint +import io.legado.app.utils.setLayout +import io.legado.app.utils.toastOnUi +import io.legado.app.utils.viewbindingdelegate.viewBinding +import splitties.init.appCtx + +class OpenUrlConfirmDialog() : BaseDialogFragment(R.layout.dialog_open_url_confirm), + Toolbar.OnMenuItemClickListener { + + constructor( + uri: String, + mimeType: String?, + sourceOrigin: String? = null, + sourceName: String? = null + ) : this() { + arguments = Bundle().apply { + putString("uri", uri) + putString("mimeType", mimeType) + putString("sourceOrigin", sourceOrigin) + putString("sourceName", sourceName) + } + } + + val binding by viewBinding(DialogOpenUrlConfirmBinding::bind) + val viewModel by viewModels() + + override fun onStart() { + super.onStart() + setLayout(1f, ViewGroup.LayoutParams.WRAP_CONTENT) + } + + override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { + initMenu() + val arguments = arguments ?: return + viewModel.initData(arguments) + if (viewModel.uri.isBlank()) { + dismiss() + return + } + binding.toolBar.setBackgroundColor(primaryColor) + binding.toolBar.subtitle = viewModel.sourceName + initView() + } + + private fun initMenu() { + binding.toolBar.setOnMenuItemClickListener(this) + binding.toolBar.inflateMenu(R.menu.open_url_confirm) + binding.toolBar.menu.applyTint(requireContext()) + } + + private fun initView() { + binding.message.text = "${viewModel.sourceName} 正在请求跳转链接/应用,是否跳转?" + binding.btnNegative.setOnClickListener { dismiss() } + binding.btnPositive.setOnClickListener { + openUrl() + dismiss() + } + } + + private fun openUrl() { + try { + val uri = viewModel.uri.toUri() + val mimeType = viewModel.mimeType + // 创建目标 Intent 并设置类型 + val targetIntent = Intent(Intent.ACTION_VIEW).apply { + // 同时设置 Data 和 Type + if (!mimeType.isNullOrBlank()) { + setDataAndType(uri, mimeType) + } else { + data = uri + } + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + + // 验证是否有应用可以处理 + if (targetIntent.resolveActivity(appCtx.packageManager) != null) { + startActivity(targetIntent) + } else { + toastOnUi(R.string.can_not_open) + } + } catch (e: Exception) { + AppLog.put("打开链接失败", e, true) + } + } + + override fun onMenuItemClick(item: MenuItem): Boolean { + when (item.itemId) { + R.id.menu_disable_source -> { + viewModel.disableSource { + dismiss() + } + } + + R.id.menu_delete_source -> { + alert(R.string.draw) { + setMessage(getString(R.string.sure_del) + "\n" + viewModel.sourceName) + noButton() + yesButton { + viewModel.deleteSource { + dismiss() + } + } + } + } + } + return false + } + + override fun onDestroy() { + super.onDestroy() + activity?.finish() + } + +} diff --git a/app/src/main/java/io/legado/app/ui/association/OpenUrlConfirmViewModel.kt b/app/src/main/java/io/legado/app/ui/association/OpenUrlConfirmViewModel.kt new file mode 100644 index 000000000..e677fb683 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/association/OpenUrlConfirmViewModel.kt @@ -0,0 +1,38 @@ +package io.legado.app.ui.association + +import android.app.Application +import android.os.Bundle +import io.legado.app.base.BaseViewModel +import io.legado.app.data.appDb + +class OpenUrlConfirmViewModel(app: Application): BaseViewModel(app) { + + var uri = "" + var mimeType: String? = null + var sourceOrigin = "" + var sourceName = "" + + fun initData(arguments: Bundle) { + uri = arguments.getString("uri") ?: "" + mimeType = arguments.getString("mimeType") + sourceName = arguments.getString("sourceName") ?: "" + sourceOrigin = arguments.getString("sourceOrigin") ?: "" + } + + fun disableSource(block: () -> Unit) { + execute { + appDb.bookSourceDao.enable(sourceOrigin, false) + }.onSuccess { + block.invoke() + } + } + + fun deleteSource(block: () -> Unit) { + execute { + appDb.bookSourceDao.delete(sourceOrigin) + }.onSuccess { + block.invoke() + } + } + +} diff --git a/app/src/main/java/io/legado/app/ui/javascript/ConfirmationDialogActivity.kt b/app/src/main/java/io/legado/app/ui/javascript/ConfirmationDialogActivity.kt deleted file mode 100644 index e212ba2f6..000000000 --- a/app/src/main/java/io/legado/app/ui/javascript/ConfirmationDialogActivity.kt +++ /dev/null @@ -1,72 +0,0 @@ -package io.legado.app.ui.javascript - -import android.content.ActivityNotFoundException -import android.content.Intent -import android.os.Bundle -import android.widget.TextView -import androidx.appcompat.widget.Toolbar -import androidx.appcompat.app.AppCompatActivity -import io.legado.app.R -import io.legado.app.constant.AppLog -import io.legado.app.ui.widget.text.AccentTextView -import io.legado.app.utils.toastOnUi - -class ConfirmationDialogActivity : AppCompatActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.confirmation_dialog) - - val messageView = findViewById(R.id.message) - val toolbar = findViewById(R.id.tool_bar) - val btnNegative = findViewById(R.id.btn_negative) - val btnPositive = findViewById(R.id.btn_positive) - - // 获取原始 Intent 的数据和 MIME 类型 - val uri = intent?.data - val mimeType = intent?.getStringExtra("mimeType") - if (uri == null) { - finish() - return - } - - // 处理来源标签显示 - val sourceTag = intent.getStringExtra("sourceTag").takeIf { !it.isNullOrBlank() } ?: "当前来源" - messageView.text = "$sourceTag 正在请求跳转外部链接/应用,是否跳转?" - - toolbar.setNavigationOnClickListener { finish() } - btnNegative.setOnClickListener { finish() } - btnPositive.setOnClickListener { - try { - // 创建目标 Intent 并设置类型 - val targetIntent = Intent(Intent.ACTION_VIEW).apply { - // 同时设置 Data 和 Type - if (!mimeType.isNullOrBlank()) { - setDataAndType(uri, mimeType) - } else { - data = uri - } - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - - // 验证是否有应用可以处理 - if (targetIntent.resolveActivity(packageManager) != null) { - startActivity(targetIntent) - } else { - toastOnUi(R.string.can_not_open) - } - } catch (e: ActivityNotFoundException) { - toastOnUi(R.string.can_not_open) - } catch (e: Exception) { - AppLog.put("打开链接失败", e) - toastOnUi(R.string.error_occurred) - } - finish() - } - } - - override fun onBackPressed() { - super.onBackPressed() - finish() - } -} diff --git a/app/src/main/res/layout/confirmation_dialog.xml b/app/src/main/res/layout/confirmation_dialog.xml deleted file mode 100644 index b8b0b36d1..000000000 --- a/app/src/main/res/layout/confirmation_dialog.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/dialog_open_url_confirm.xml b/app/src/main/res/layout/dialog_open_url_confirm.xml new file mode 100644 index 000000000..f6e5d147b --- /dev/null +++ b/app/src/main/res/layout/dialog_open_url_confirm.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/open_url_confirm.xml b/app/src/main/res/menu/open_url_confirm.xml new file mode 100644 index 000000000..e85dbaf20 --- /dev/null +++ b/app/src/main/res/menu/open_url_confirm.xml @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 00bf22601..a67ff259a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1185,6 +1185,4 @@ 主题配置 Download the chapter after Download all chapter - 打开失败 - %s正在请求跳转外部链接/应用,是否跳转? diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 7f736e1b6..4bc8faa05 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -127,21 +127,4 @@ wrap_content - - - - - - - -