mirror of
https://github.com/MetaCubeX/ClashMetaForAndroid.git
synced 2024-11-16 13:32:37 +08:00
Refactor: refactor design structure
This commit is contained in:
parent
603cec113c
commit
4a8b6b2704
|
@ -70,10 +70,6 @@ subprojects {
|
|||
versionName = buildVersionName
|
||||
versionCode = buildVersionCode
|
||||
|
||||
if (!isApp) {
|
||||
consumerProguardFiles("consumer-rules.pro")
|
||||
}
|
||||
|
||||
resValue("string", "release_name", "v$buildVersionName")
|
||||
resValue("integer", "release_code", "$buildVersionCode")
|
||||
|
||||
|
@ -82,6 +78,10 @@ subprojects {
|
|||
abiFilters("arm64-v8a", "armeabi-v7a", "x86", "x86_64")
|
||||
}
|
||||
}
|
||||
|
||||
if (!isApp) {
|
||||
consumerProguardFiles("consumer-rules.pro")
|
||||
}
|
||||
}
|
||||
|
||||
if (isApp) {
|
||||
|
@ -108,6 +108,8 @@ subprojects {
|
|||
dimension = defaultDimension
|
||||
versionNameSuffix = ".foss"
|
||||
|
||||
buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"false\")")
|
||||
|
||||
if (isApp) {
|
||||
applicationIdSuffix = ".foss"
|
||||
}
|
||||
|
@ -116,6 +118,8 @@ subprojects {
|
|||
dimension = defaultDimension
|
||||
versionNameSuffix = ".premium"
|
||||
|
||||
buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"true\")")
|
||||
|
||||
val trackFile = rootProject.file("track.properties")
|
||||
if (trackFile.exists()) {
|
||||
val track = Properties().apply {
|
||||
|
|
|
@ -1,399 +0,0 @@
|
|||
package com.github.kr328.clash.design
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import com.github.kr328.clash.core.model.ConfigurationOverride
|
||||
import com.github.kr328.clash.core.model.LogMessage
|
||||
import com.github.kr328.clash.core.model.TunnelState
|
||||
import com.github.kr328.clash.design.adapter.SideloadProviderAdapter
|
||||
import com.github.kr328.clash.design.databinding.DesignSettingsOverideBinding
|
||||
import com.github.kr328.clash.design.databinding.DialogPreferenceListBinding
|
||||
import com.github.kr328.clash.design.dialog.FullScreenDialog
|
||||
import com.github.kr328.clash.design.model.AppInfo
|
||||
import com.github.kr328.clash.design.preference.*
|
||||
import com.github.kr328.clash.design.util.*
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
class OverrideSettingsDesign(
|
||||
context: Context,
|
||||
configuration: ConfigurationOverride
|
||||
) : Design<OverrideSettingsDesign.Request>(context) {
|
||||
enum class Request {
|
||||
ResetOverride, EditSideloadGeoip
|
||||
}
|
||||
|
||||
private val binding = DesignSettingsOverideBinding
|
||||
.inflate(context.layoutInflater, context.root, false)
|
||||
|
||||
override val root: View
|
||||
get() = binding.root
|
||||
|
||||
suspend fun requestResetConfirm(): Boolean {
|
||||
return suspendCancellableCoroutine { ctx ->
|
||||
val dialog = MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.reset_override_settings)
|
||||
.setMessage(R.string.reset_override_settings_message)
|
||||
.setPositiveButton(R.string.ok) { _, _ -> ctx.resume(true) }
|
||||
.setNegativeButton(R.string.cancel) { _, _ -> }
|
||||
.show()
|
||||
|
||||
dialog.setOnDismissListener {
|
||||
if (!ctx.isCompleted)
|
||||
ctx.resume(false)
|
||||
}
|
||||
|
||||
ctx.invokeOnCancellation {
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun requestSelectSideload(initial: String, apps: List<AppInfo>): String =
|
||||
withContext(Dispatchers.Main) {
|
||||
suspendCancellableCoroutine { ctx ->
|
||||
val binding = DialogPreferenceListBinding
|
||||
.inflate(context.layoutInflater, context.root, false)
|
||||
val adapter = SideloadProviderAdapter(context, apps, initial)
|
||||
val dialog = FullScreenDialog(context)
|
||||
|
||||
dialog.setContentView(binding.root)
|
||||
|
||||
binding.surface = dialog.surface
|
||||
|
||||
binding.titleView.text = context.getString(R.string.sideload_geoip)
|
||||
|
||||
binding.newView.visibility = View.INVISIBLE
|
||||
|
||||
binding.mainList.applyLinearAdapter(context, adapter)
|
||||
|
||||
binding.resetView.setOnClickListener {
|
||||
ctx.resume("")
|
||||
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
binding.cancelView.setOnClickListener {
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
binding.okView.setOnClickListener {
|
||||
ctx.resume(adapter.selectedPackageName)
|
||||
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
dialog.setOnDismissListener {
|
||||
if (!ctx.isCompleted)
|
||||
ctx.resume(initial)
|
||||
}
|
||||
|
||||
dialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
binding.self = this
|
||||
|
||||
binding.activityBarLayout.applyFrom(context)
|
||||
|
||||
binding.scrollRoot.bindAppBarElevation(binding.activityBarLayout)
|
||||
|
||||
val booleanValues: Array<Boolean?> = arrayOf(
|
||||
null,
|
||||
true,
|
||||
false
|
||||
)
|
||||
val booleanValuesText: Array<Int> = arrayOf(
|
||||
R.string.dont_modify,
|
||||
R.string.enabled,
|
||||
R.string.disabled
|
||||
)
|
||||
|
||||
val screen = preferenceScreen(context) {
|
||||
category(R.string.general)
|
||||
|
||||
editableText(
|
||||
value = configuration::httpPort,
|
||||
adapter = NullableTextAdapter.Port,
|
||||
title = R.string.http_port,
|
||||
placeholder = R.string.dont_modify,
|
||||
empty = R.string.disabled,
|
||||
)
|
||||
|
||||
editableText(
|
||||
value = configuration::socksPort,
|
||||
adapter = NullableTextAdapter.Port,
|
||||
title = R.string.socks_port,
|
||||
placeholder = R.string.dont_modify,
|
||||
empty = R.string.disabled,
|
||||
)
|
||||
|
||||
editableText(
|
||||
value = configuration::redirectPort,
|
||||
adapter = NullableTextAdapter.Port,
|
||||
title = R.string.redirect_port,
|
||||
placeholder = R.string.dont_modify,
|
||||
empty = R.string.disabled,
|
||||
)
|
||||
|
||||
editableText(
|
||||
value = configuration::tproxyPort,
|
||||
adapter = NullableTextAdapter.Port,
|
||||
title = R.string.tproxy_port,
|
||||
placeholder = R.string.dont_modify,
|
||||
empty = R.string.disabled,
|
||||
)
|
||||
|
||||
editableText(
|
||||
value = configuration::mixedPort,
|
||||
adapter = NullableTextAdapter.Port,
|
||||
title = R.string.mixed_port,
|
||||
placeholder = R.string.dont_modify,
|
||||
empty = R.string.disabled,
|
||||
)
|
||||
|
||||
editableTextList(
|
||||
value = configuration::authentication,
|
||||
adapter = TextAdapter.String,
|
||||
title = R.string.authentication,
|
||||
placeholder = R.string.dont_modify,
|
||||
)
|
||||
|
||||
selectableList(
|
||||
value = configuration::allowLan,
|
||||
values = booleanValues,
|
||||
valuesText = booleanValuesText,
|
||||
title = R.string.allow_lan,
|
||||
)
|
||||
|
||||
selectableList(
|
||||
value = configuration::ipv6,
|
||||
values = booleanValues,
|
||||
valuesText = booleanValuesText,
|
||||
title = R.string.ipv6,
|
||||
)
|
||||
|
||||
editableText(
|
||||
value = configuration::bindAddress,
|
||||
adapter = NullableTextAdapter.String,
|
||||
title = R.string.bind_address,
|
||||
placeholder = R.string.dont_modify,
|
||||
empty = R.string.default_
|
||||
)
|
||||
|
||||
selectableList(
|
||||
value = configuration::mode,
|
||||
values = arrayOf(
|
||||
null,
|
||||
TunnelState.Mode.Direct,
|
||||
TunnelState.Mode.Global,
|
||||
TunnelState.Mode.Rule,
|
||||
),
|
||||
valuesText = arrayOf(
|
||||
R.string.dont_modify,
|
||||
R.string.direct_mode,
|
||||
R.string.global_mode,
|
||||
R.string.rule_mode,
|
||||
),
|
||||
title = R.string.mode
|
||||
)
|
||||
|
||||
selectableList(
|
||||
value = configuration::logLevel,
|
||||
values = arrayOf(
|
||||
null,
|
||||
LogMessage.Level.Info,
|
||||
LogMessage.Level.Warning,
|
||||
LogMessage.Level.Error,
|
||||
LogMessage.Level.Debug,
|
||||
LogMessage.Level.Silent,
|
||||
),
|
||||
valuesText = arrayOf(
|
||||
R.string.dont_modify,
|
||||
R.string.info,
|
||||
R.string.warning,
|
||||
R.string.error,
|
||||
R.string.debug,
|
||||
R.string.silent,
|
||||
),
|
||||
title = R.string.log_level,
|
||||
)
|
||||
|
||||
editableTextMap(
|
||||
value = configuration::hosts,
|
||||
keyAdapter = TextAdapter.String,
|
||||
valueAdapter = TextAdapter.String,
|
||||
title = R.string.hosts,
|
||||
placeholder = R.string.dont_modify,
|
||||
)
|
||||
|
||||
clickable(
|
||||
title = R.string.sideload_geoip,
|
||||
summary = R.string.sideload_geoip_summary
|
||||
) {
|
||||
clicked {
|
||||
requests.trySend(Request.EditSideloadGeoip)
|
||||
}
|
||||
}
|
||||
|
||||
category(R.string.dns)
|
||||
|
||||
val dnsDependencies: MutableList<Preference> = mutableListOf()
|
||||
|
||||
val dns = selectableList(
|
||||
value = configuration.dns::enable,
|
||||
values = arrayOf(
|
||||
null,
|
||||
true,
|
||||
false
|
||||
),
|
||||
valuesText = arrayOf(
|
||||
R.string.dont_modify,
|
||||
R.string.force_enable,
|
||||
R.string.use_built_in,
|
||||
),
|
||||
title = R.string.strategy
|
||||
) {
|
||||
listener = OnChangedListener {
|
||||
if (configuration.dns.enable == false) {
|
||||
dnsDependencies.forEach {
|
||||
it.enabled = false
|
||||
}
|
||||
} else {
|
||||
dnsDependencies.forEach {
|
||||
it.enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editableText(
|
||||
value = configuration.dns::listen,
|
||||
adapter = NullableTextAdapter.String,
|
||||
title = R.string.listen,
|
||||
placeholder = R.string.dont_modify,
|
||||
empty = R.string.disabled,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
selectableList(
|
||||
value = configuration.app::appendSystemDns,
|
||||
values = booleanValues,
|
||||
valuesText = booleanValuesText,
|
||||
title = R.string.append_system_dns,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
selectableList(
|
||||
value = configuration.dns::ipv6,
|
||||
values = booleanValues,
|
||||
valuesText = booleanValuesText,
|
||||
title = R.string.ipv6,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
selectableList(
|
||||
value = configuration.dns::useHosts,
|
||||
values = booleanValues,
|
||||
valuesText = booleanValuesText,
|
||||
title = R.string.use_hosts,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
selectableList(
|
||||
value = configuration.dns::enhancedMode,
|
||||
values = arrayOf(
|
||||
null,
|
||||
ConfigurationOverride.DnsEnhancedMode.None,
|
||||
ConfigurationOverride.DnsEnhancedMode.FakeIp,
|
||||
ConfigurationOverride.DnsEnhancedMode.Mapping
|
||||
),
|
||||
valuesText = arrayOf(
|
||||
R.string.dont_modify,
|
||||
R.string.disabled,
|
||||
R.string.fakeip,
|
||||
R.string.mapping
|
||||
),
|
||||
title = R.string.enhanced_mode,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
editableTextList(
|
||||
value = configuration.dns::nameServer,
|
||||
adapter = TextAdapter.String,
|
||||
title = R.string.name_server,
|
||||
placeholder = R.string.dont_modify,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
editableTextList(
|
||||
value = configuration.dns::fallback,
|
||||
adapter = TextAdapter.String,
|
||||
title = R.string.fallback,
|
||||
placeholder = R.string.dont_modify,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
editableTextList(
|
||||
value = configuration.dns::defaultServer,
|
||||
adapter = TextAdapter.String,
|
||||
title = R.string.default_name_server,
|
||||
placeholder = R.string.dont_modify,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
editableTextList(
|
||||
value = configuration.dns::fakeIpFilter,
|
||||
adapter = TextAdapter.String,
|
||||
title = R.string.fakeip_filter,
|
||||
placeholder = R.string.dont_modify,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
selectableList(
|
||||
value = configuration.dns.fallbackFilter::geoIp,
|
||||
values = booleanValues,
|
||||
valuesText = booleanValuesText,
|
||||
title = R.string.geoip_fallback,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
editableTextList(
|
||||
value = configuration.dns.fallbackFilter::domain,
|
||||
adapter = TextAdapter.String,
|
||||
title = R.string.domain_fallback,
|
||||
placeholder = R.string.dont_modify,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
editableTextList(
|
||||
value = configuration.dns.fallbackFilter::ipcidr,
|
||||
adapter = TextAdapter.String,
|
||||
title = R.string.ipcidr_fallback,
|
||||
placeholder = R.string.dont_modify,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
editableTextMap(
|
||||
value = configuration.dns::nameserverPolicy,
|
||||
keyAdapter = TextAdapter.String,
|
||||
valueAdapter = TextAdapter.String,
|
||||
title = R.string.name_server_policy,
|
||||
placeholder = R.string.dont_modify,
|
||||
configure = dnsDependencies::add,
|
||||
)
|
||||
|
||||
dns.listener?.onChanged()
|
||||
}
|
||||
|
||||
binding.content.addView(screen.root)
|
||||
}
|
||||
|
||||
fun requestClear() {
|
||||
requests.trySend(Request.ResetOverride)
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
package com.github.kr328.clash.design.component
|
||||
|
||||
import android.content.Context
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import com.github.kr328.clash.core.model.ProxySort
|
||||
import com.github.kr328.clash.core.model.TunnelState
|
||||
import com.github.kr328.clash.design.ProxyDesign
|
||||
import com.github.kr328.clash.design.R
|
||||
import com.github.kr328.clash.design.store.UiStore
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
|
||||
class ProxyMenu(
|
||||
context: Context,
|
||||
menuView: View,
|
||||
mode: TunnelState.Mode?,
|
||||
private val uiStore: UiStore,
|
||||
private val requests: Channel<ProxyDesign.Request>,
|
||||
private val updateConfig: () -> Unit,
|
||||
) : PopupMenu.OnMenuItemClickListener {
|
||||
private val menu = PopupMenu(context, menuView)
|
||||
|
||||
fun show() {
|
||||
menu.show()
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||
item.isChecked = !item.isChecked
|
||||
|
||||
when (item.itemId) {
|
||||
R.id.not_selectable -> {
|
||||
uiStore.proxyExcludeNotSelectable = item.isChecked
|
||||
|
||||
requests.trySend(ProxyDesign.Request.ReLaunch)
|
||||
}
|
||||
R.id.single -> {
|
||||
uiStore.proxySingleLine = true
|
||||
|
||||
updateConfig()
|
||||
|
||||
requests.trySend(ProxyDesign.Request.ReloadAll)
|
||||
}
|
||||
R.id.multiple -> {
|
||||
uiStore.proxySingleLine = false
|
||||
|
||||
updateConfig()
|
||||
|
||||
requests.trySend(ProxyDesign.Request.ReloadAll)
|
||||
}
|
||||
R.id.default_ -> {
|
||||
uiStore.proxySort = ProxySort.Default
|
||||
|
||||
requests.trySend(ProxyDesign.Request.ReloadAll)
|
||||
}
|
||||
R.id.name -> {
|
||||
uiStore.proxySort = ProxySort.Title
|
||||
|
||||
requests.trySend(ProxyDesign.Request.ReloadAll)
|
||||
}
|
||||
R.id.delay -> {
|
||||
uiStore.proxySort = ProxySort.Delay
|
||||
|
||||
requests.trySend(ProxyDesign.Request.ReloadAll)
|
||||
}
|
||||
R.id.dont_modify -> {
|
||||
requests.trySend(ProxyDesign.Request.PatchMode(null))
|
||||
}
|
||||
R.id.direct_mode -> {
|
||||
requests.trySend(ProxyDesign.Request.PatchMode(TunnelState.Mode.Direct))
|
||||
}
|
||||
R.id.global_mode -> {
|
||||
requests.trySend(ProxyDesign.Request.PatchMode(TunnelState.Mode.Global))
|
||||
}
|
||||
R.id.rule_mode -> {
|
||||
requests.trySend(ProxyDesign.Request.PatchMode(TunnelState.Mode.Rule))
|
||||
}
|
||||
else -> return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
init {
|
||||
menu.menuInflater.inflate(R.menu.menu_proxy, menu.menu)
|
||||
|
||||
menu.menu.apply {
|
||||
findItem(R.id.not_selectable).isChecked = uiStore.proxyExcludeNotSelectable
|
||||
|
||||
if (uiStore.proxySingleLine) {
|
||||
findItem(R.id.single).isChecked = true
|
||||
} else {
|
||||
findItem(R.id.multiple).isChecked = true
|
||||
}
|
||||
|
||||
when (uiStore.proxySort) {
|
||||
ProxySort.Default -> findItem(R.id.default_).isChecked = true
|
||||
ProxySort.Title -> findItem(R.id.name).isChecked = true
|
||||
ProxySort.Delay -> findItem(R.id.delay).isChecked = true
|
||||
}
|
||||
|
||||
when (mode) {
|
||||
null -> findItem(R.id.dont_modify).isChecked = true
|
||||
TunnelState.Mode.Direct -> findItem(R.id.direct_mode).isChecked = true
|
||||
TunnelState.Mode.Global -> findItem(R.id.global_mode).isChecked = true
|
||||
TunnelState.Mode.Rule -> findItem(R.id.rule_mode).isChecked = true
|
||||
TunnelState.Mode.Script -> throw IllegalStateException("invalid mode")
|
||||
}
|
||||
}
|
||||
|
||||
menu.setOnMenuItemClickListener(this)
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:title="@string/filter">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/not_selectable"
|
||||
android:checkable="true"
|
||||
android:title="@string/not_selectable" />
|
||||
</menu>
|
||||
</item>
|
||||
<item android:title="@string/mode">
|
||||
<menu>
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/dont_modify"
|
||||
android:title="@string/dont_modify" />
|
||||
<item
|
||||
android:id="@+id/direct_mode"
|
||||
android:title="@string/direct_mode" />
|
||||
<item
|
||||
android:id="@+id/global_mode"
|
||||
android:title="@string/global_mode" />
|
||||
<item
|
||||
android:id="@+id/rule_mode"
|
||||
android:title="@string/rule_mode" />
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
<item android:title="@string/layout">
|
||||
<menu>
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/single"
|
||||
android:title="@string/single" />
|
||||
<item
|
||||
android:id="@+id/multiple"
|
||||
android:title="@string/multiple" />
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
<item android:title="@string/sort">
|
||||
<menu>
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/default_"
|
||||
android:title="@string/default_" />
|
||||
<item
|
||||
android:id="@+id/name"
|
||||
android:title="@string/name" />
|
||||
<item
|
||||
android:id="@+id/delay"
|
||||
android:title="@string/delay" />
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
</menu>
|
|
@ -47,6 +47,17 @@ class HelpDesign(
|
|||
|
||||
category(R.string.feedback)
|
||||
|
||||
if (BuildConfig.PREMIUM) {
|
||||
clickable(
|
||||
title = R.string.google_play,
|
||||
summary = R.string.google_play_url
|
||||
) {
|
||||
clicked {
|
||||
openLink(Uri.parse(context.getString(R.string.google_play_url)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clickable(
|
||||
title = R.string.github_issues,
|
||||
summary = R.string.github_issues_url
|
||||
|
@ -56,23 +67,25 @@ class HelpDesign(
|
|||
}
|
||||
}
|
||||
|
||||
category(R.string.sources)
|
||||
if (!BuildConfig.PREMIUM) {
|
||||
category(R.string.sources)
|
||||
|
||||
clickable(
|
||||
title = R.string.clash_for_android,
|
||||
summary = R.string.github_url
|
||||
) {
|
||||
clicked {
|
||||
openLink(Uri.parse(context.getString(R.string.github_url)))
|
||||
clickable(
|
||||
title = R.string.clash_for_android,
|
||||
summary = R.string.github_url
|
||||
) {
|
||||
clicked {
|
||||
openLink(Uri.parse(context.getString(R.string.github_url)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clickable(
|
||||
title = R.string.clash_core,
|
||||
summary = R.string.clash_core_url
|
||||
) {
|
||||
clicked {
|
||||
openLink(Uri.parse(context.getString(R.string.clash_core_url)))
|
||||
clickable(
|
||||
title = R.string.clash_core,
|
||||
summary = R.string.clash_core_url
|
||||
) {
|
||||
clicked {
|
||||
openLink(Uri.parse(context.getString(R.string.clash_core_url)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -185,24 +185,43 @@ class OverrideSettingsDesign(
|
|||
empty = R.string.default_
|
||||
)
|
||||
|
||||
selectableList(
|
||||
value = configuration::mode,
|
||||
values = arrayOf(
|
||||
null,
|
||||
TunnelState.Mode.Direct,
|
||||
TunnelState.Mode.Global,
|
||||
TunnelState.Mode.Rule,
|
||||
TunnelState.Mode.Script
|
||||
),
|
||||
valuesText = arrayOf(
|
||||
R.string.dont_modify,
|
||||
R.string.direct_mode,
|
||||
R.string.global_mode,
|
||||
R.string.rule_mode,
|
||||
R.string.script_mode
|
||||
),
|
||||
title = R.string.mode
|
||||
)
|
||||
if (BuildConfig.PREMIUM) {
|
||||
selectableList(
|
||||
value = configuration::mode,
|
||||
values = arrayOf(
|
||||
null,
|
||||
TunnelState.Mode.Direct,
|
||||
TunnelState.Mode.Global,
|
||||
TunnelState.Mode.Rule,
|
||||
TunnelState.Mode.Script
|
||||
),
|
||||
valuesText = arrayOf(
|
||||
R.string.dont_modify,
|
||||
R.string.direct_mode,
|
||||
R.string.global_mode,
|
||||
R.string.rule_mode,
|
||||
R.string.script_mode
|
||||
),
|
||||
title = R.string.mode
|
||||
)
|
||||
} else {
|
||||
selectableList(
|
||||
value = configuration::mode,
|
||||
values = arrayOf(
|
||||
null,
|
||||
TunnelState.Mode.Direct,
|
||||
TunnelState.Mode.Global,
|
||||
TunnelState.Mode.Rule
|
||||
),
|
||||
valuesText = arrayOf(
|
||||
R.string.dont_modify,
|
||||
R.string.direct_mode,
|
||||
R.string.global_mode,
|
||||
R.string.rule_mode
|
||||
),
|
||||
title = R.string.mode
|
||||
)
|
||||
}
|
||||
|
||||
selectableList(
|
||||
value = configuration::logLevel,
|
|
@ -6,6 +6,7 @@ import android.view.View
|
|||
import androidx.appcompat.widget.PopupMenu
|
||||
import com.github.kr328.clash.core.model.ProxySort
|
||||
import com.github.kr328.clash.core.model.TunnelState
|
||||
import com.github.kr328.clash.design.BuildConfig
|
||||
import com.github.kr328.clash.design.ProxyDesign
|
||||
import com.github.kr328.clash.design.R
|
||||
import com.github.kr328.clash.design.store.UiStore
|
||||
|
@ -88,6 +89,8 @@ class ProxyMenu(
|
|||
menu.menuInflater.inflate(R.menu.menu_proxy, menu.menu)
|
||||
|
||||
menu.menu.apply {
|
||||
findItem(R.id.script_mode).isVisible = BuildConfig.PREMIUM
|
||||
|
||||
findItem(R.id.not_selectable).isChecked = uiStore.proxyExcludeNotSelectable
|
||||
|
||||
if (uiStore.proxySingleLine) {
|
|
@ -1,84 +0,0 @@
|
|||
package com.github.kr328.clash.design
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.view.View
|
||||
import com.github.kr328.clash.common.compat.preferredLocale
|
||||
import com.github.kr328.clash.design.databinding.DesignSettingsCommonBinding
|
||||
import com.github.kr328.clash.design.preference.category
|
||||
import com.github.kr328.clash.design.preference.clickable
|
||||
import com.github.kr328.clash.design.preference.preferenceScreen
|
||||
import com.github.kr328.clash.design.preference.tips
|
||||
import com.github.kr328.clash.design.util.applyFrom
|
||||
import com.github.kr328.clash.design.util.bindAppBarElevation
|
||||
import com.github.kr328.clash.design.util.layoutInflater
|
||||
import com.github.kr328.clash.design.util.root
|
||||
|
||||
class HelpDesign(
|
||||
context: Context,
|
||||
openLink: (Uri) -> Unit,
|
||||
) : Design<Unit>(context) {
|
||||
private val binding = DesignSettingsCommonBinding
|
||||
.inflate(context.layoutInflater, context.root, false)
|
||||
|
||||
override val root: View
|
||||
get() = binding.root
|
||||
|
||||
init {
|
||||
binding.surface = surface
|
||||
|
||||
binding.activityBarLayout.applyFrom(context)
|
||||
|
||||
binding.scrollRoot.bindAppBarElevation(binding.activityBarLayout)
|
||||
|
||||
val screen = preferenceScreen(context) {
|
||||
tips(R.string.tips_help)
|
||||
|
||||
category(R.string.document)
|
||||
|
||||
clickable(
|
||||
title = R.string.clash_wiki,
|
||||
summary = R.string.clash_wiki_url
|
||||
) {
|
||||
clicked {
|
||||
openLink(Uri.parse(context.getString(R.string.clash_wiki_url)))
|
||||
}
|
||||
}
|
||||
|
||||
category(R.string.feedback)
|
||||
|
||||
clickable(
|
||||
title = R.string.github_issues,
|
||||
summary = R.string.github_issues_url
|
||||
) {
|
||||
clicked {
|
||||
openLink(Uri.parse(context.getString(R.string.github_issues_url)))
|
||||
}
|
||||
}
|
||||
|
||||
clickable(
|
||||
title = R.string.google_play,
|
||||
summary = R.string.google_play_url
|
||||
) {
|
||||
clicked {
|
||||
openLink(Uri.parse(context.getString(R.string.google_play_url)))
|
||||
}
|
||||
}
|
||||
|
||||
if (context.resources.configuration.preferredLocale.language == "zh") {
|
||||
category(R.string.donate)
|
||||
|
||||
clickable(
|
||||
title = R.string.donate,
|
||||
summary = R.string.donate_url
|
||||
) {
|
||||
clicked {
|
||||
openLink(Uri.parse(context.getString(R.string.donate_url)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binding.content.addView(screen.root)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user