Horis 1 год назад
Родитель
Сommit
5b9a685b1d

+ 5 - 8
app/src/main/AndroidManifest.xml

@@ -340,7 +340,11 @@
         <activity
         <activity
             android:name=".ui.association.VerificationCodeActivity"
             android:name=".ui.association.VerificationCodeActivity"
             android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
             android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
-            android:exported="true"
+            android:theme="@style/AppTheme.Transparent" />
+        <!-- 跳转确认 -->
+        <activity
+            android:name=".ui.association.OpenUrlConfirmActivity"
+            android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
             android:theme="@style/AppTheme.Transparent" />
             android:theme="@style/AppTheme.Transparent" />
         <!-- 打开文件 -->
         <!-- 打开文件 -->
         <activity
         <activity
@@ -433,13 +437,6 @@
             </intent-filter>
             </intent-filter>
         </activity>
         </activity>
 
 
-        <activity
-            android:name=".ui.javascript.ConfirmationDialogActivity"
-            android:theme="@style/Theme.Translucent.NoTitleBar"
-            android:excludeFromRecents="true"
-            android:taskAffinity=""
-            android:launchMode="singleInstance"/>
-
         <service
         <service
             android:name=".service.CheckSourceService"
             android:name=".service.CheckSourceService"
             android:foregroundServiceType="dataSync" />
             android:foregroundServiceType="dataSync" />

+ 8 - 19
app/src/main/java/io/legado/app/help/JsExtensions.kt

@@ -1,6 +1,5 @@
 package io.legado.app.help
 package io.legado.app.help
 
 
-import android.content.Intent
 import android.net.Uri
 import android.net.Uri
 import android.webkit.WebSettings
 import android.webkit.WebSettings
 import androidx.annotation.Keep
 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.Debug
 import io.legado.app.model.analyzeRule.AnalyzeUrl
 import io.legado.app.model.analyzeRule.AnalyzeUrl
 import io.legado.app.model.analyzeRule.QueryTTF
 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.ArchiveUtils
 import io.legado.app.utils.ChineseUtils
 import io.legado.app.utils.ChineseUtils
 import io.legado.app.utils.EncoderUtils
 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.readBytes
 import io.legado.app.utils.readText
 import io.legado.app.utils.readText
 import io.legado.app.utils.stackTraceStr
 import io.legado.app.utils.stackTraceStr
+import io.legado.app.utils.startActivity
 import io.legado.app.utils.toStringArray
 import io.legado.app.utils.toStringArray
 import io.legado.app.utils.toastOnUi
 import io.legado.app.utils.toastOnUi
 import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.Dispatchers.IO
@@ -966,23 +966,12 @@ interface JsExtensions : JsEncodeUtils {
 
 
     // 新增 mimeType 参数,默认为 null(保持兼容性)
     // 新增 mimeType 参数,默认为 null(保持兼容性)
     fun openUrl(url: String, mimeType: String? = 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<OpenUrlConfirmActivity> {
+            putExtra("uri", url)
+            putExtra("mimeType", mimeType)
+            putExtra("sourceOrigin", source.getKey())
+            putExtra("sourceName", source.getTag())
         }
         }
     }
     }
 
 

+ 23 - 0
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<ActivityTranslucenceBinding>() {
+
+    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()
+    }
+
+}

+ 130 - 0
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<OpenUrlConfirmViewModel>()
+
+    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()
+    }
+
+}

+ 38 - 0
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()
+        }
+    }
+
+}

+ 0 - 72
app/src/main/java/io/legado/app/ui/javascript/ConfirmationDialogActivity.kt

@@ -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<TextView>(R.id.message)
-        val toolbar = findViewById<Toolbar>(R.id.tool_bar)
-        val btnNegative = findViewById<AccentTextView>(R.id.btn_negative)
-        val btnPositive = findViewById<AccentTextView>(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()
-    }
-}

+ 0 - 57
app/src/main/res/layout/confirmation_dialog.xml

@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="#80000000"
-    android:padding="16dp">
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:background="@drawable/shape_card_view"
-        android:orientation="vertical">
-
-        <androidx.appcompat.widget.Toolbar
-            android:id="@+id/tool_bar"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:theme="?attr/actionBarStyle"
-            app:popupTheme="@style/AppTheme.PopupOverlay"
-            app:title="跳转确认"
-            app:titleTextAppearance="@style/ToolbarTitleX" />
-
-        <TextView
-            android:id="@+id/message"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:padding="16dp"
-            android:textSize="16sp"
-            android:textAppearance="?attr/textAppearanceBodyMedium"
-            android:textColor="@color/primaryText" />
-
-        <com.google.android.flexbox.FlexboxLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:padding="8dp"
-            app:flexDirection="row"
-            app:justifyContent="flex_end">
-
-            <io.legado.app.ui.widget.text.AccentTextView
-                android:id="@+id/btn_negative"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:padding="16dp"
-                android:text="@string/cancel"/>
-
-            <io.legado.app.ui.widget.text.AccentTextView
-                android:id="@+id/btn_positive"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:padding="16dp"
-                android:text="@string/ok"/>
-
-        </com.google.android.flexbox.FlexboxLayout>
-    </LinearLayout>
-</FrameLayout>

+ 47 - 0
app/src/main/res/layout/dialog_open_url_confirm.xml

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/shape_card_view"
+    android:orientation="vertical">
+
+    <androidx.appcompat.widget.Toolbar
+        android:id="@+id/tool_bar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:theme="?attr/actionBarStyle"
+        app:popupTheme="@style/AppTheme.PopupOverlay"
+        app:title="跳转确认"
+        app:titleTextAppearance="@style/ToolbarTitle" />
+
+    <TextView
+        android:id="@+id/message"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="16dp"
+        android:textColor="@color/primaryText"
+        android:textSize="16sp" />
+
+    <com.google.android.flexbox.FlexboxLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:flexDirection="row"
+        app:justifyContent="flex_end">
+
+        <io.legado.app.ui.widget.text.AccentTextView
+            android:id="@+id/btn_negative"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:padding="16dp"
+            android:text="@string/cancel" />
+
+        <io.legado.app.ui.widget.text.AccentTextView
+            android:id="@+id/btn_positive"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:padding="16dp"
+            android:text="@string/ok" />
+
+    </com.google.android.flexbox.FlexboxLayout>
+</LinearLayout>

+ 17 - 0
app/src/main/res/menu/open_url_confirm.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:ignore="AlwaysShowAction">
+
+    <item
+        android:id="@+id/menu_disable_source"
+        android:title="@string/disable_source"
+        app:showAsAction="never" />
+
+    <item
+        android:id="@+id/menu_delete_source"
+        android:title="@string/delete_source"
+        app:showAsAction="never" />
+
+</menu>

+ 0 - 2
app/src/main/res/values/strings.xml

@@ -1185,6 +1185,4 @@
     <string name="theme_config">主题配置</string>
     <string name="theme_config">主题配置</string>
     <string name="menu_download_after">Download the chapter after</string>
     <string name="menu_download_after">Download the chapter after</string>
     <string name="menu_download_all">Download all chapter</string>
     <string name="menu_download_all">Download all chapter</string>
-    <string name="error_occurred" translatable="false">打开失败</string>
-    <string name="confirmation_message" translatable="false">%s正在请求跳转外部链接/应用,是否跳转?</string>
 </resources>
 </resources>

+ 0 - 17
app/src/main/res/values/styles.xml

@@ -127,21 +127,4 @@
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_width">wrap_content</item>
     </style>
     </style>
 
 
-    <!-- 基础透明主题 -->
-    <style name="Theme.Translucent" parent="Theme.AppCompat.Light.NoActionBar">
-        <item name="android:windowBackground">@android:color/transparent</item>
-        <item name="android:windowIsTranslucent">true</item>
-        <item name="android:windowNoTitle">true</item>
-    </style>
-
-    <!-- 无标题栏变体 -->
-    <style name="Theme.Translucent.NoTitleBar" parent="Theme.Translucent">
-        <item name="windowNoTitle">true</item>
-    </style>
-
-    <style name="ToolbarTitleX" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Title">
-        <item name="android:textSize">20sp</item>
-        <item name="android:textColor">@color/primaryText</item>
-    </style>
-
 </resources>
 </resources>