mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
优化
This commit is contained in:
@@ -340,7 +340,11 @@
|
||||
<activity
|
||||
android:name=".ui.association.VerificationCodeActivity"
|
||||
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" />
|
||||
<!-- 打开文件 -->
|
||||
<activity
|
||||
@@ -433,13 +437,6 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ui.javascript.ConfirmationDialogActivity"
|
||||
android:theme="@style/Theme.Translucent.NoTitleBar"
|
||||
android:excludeFromRecents="true"
|
||||
android:taskAffinity=""
|
||||
android:launchMode="singleInstance"/>
|
||||
|
||||
<service
|
||||
android:name=".service.CheckSourceService"
|
||||
android:foregroundServiceType="dataSync" />
|
||||
|
||||
@@ -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<OpenUrlConfirmActivity> {
|
||||
putExtra("uri", url)
|
||||
putExtra("mimeType", mimeType)
|
||||
putExtra("sourceOrigin", source.getKey())
|
||||
putExtra("sourceName", source.getTag())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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
app/src/main/res/layout/dialog_open_url_confirm.xml
Normal file
47
app/src/main/res/layout/dialog_open_url_confirm.xml
Normal file
@@ -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
app/src/main/res/menu/open_url_confirm.xml
Normal file
17
app/src/main/res/menu/open_url_confirm.xml
Normal file
@@ -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>
|
||||
@@ -1185,6 +1185,4 @@
|
||||
<string name="theme_config">主题配置</string>
|
||||
<string name="menu_download_after">Download the chapter after</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>
|
||||
|
||||
@@ -127,21 +127,4 @@
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
</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>
|
||||
|
||||
Reference in New Issue
Block a user