Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions app/src/main/java/com/github/kr328/clash/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,16 @@ import kotlinx.coroutines.selects.select
import kotlinx.coroutines.withContext
import java.util.concurrent.TimeUnit
import com.github.kr328.clash.design.R
import com.github.kr328.clash.core.model.TunnelState
import com.github.kr328.clash.core.Clash

class MainActivity : BaseActivity<MainDesign>() {
private val modeMap = mapOf(
MainDesign.Request.ToggleDirectMode to TunnelState.Mode.Direct,
MainDesign.Request.ToggleGlobalMode to TunnelState.Mode.Global,
MainDesign.Request.ToggleRuleMode to TunnelState.Mode.Rule
)

override suspend fun main() {
val design = MainDesign(this)

Expand Down Expand Up @@ -53,6 +61,16 @@ class MainActivity : BaseActivity<MainDesign>() {
else
design.startClash()
}
in modeMap.keys -> {
design.showModeSwitchTips()
withClash {
val o = queryOverride(Clash.OverrideSlot.Session)

o.mode = modeMap[it]!!

patchOverride(Clash.OverrideSlot.Session, o)
}
}
MainDesign.Request.OpenProxy ->
startActivity(ProxyActivity::class.intent)
MainDesign.Request.OpenProfiles ->
Expand All @@ -72,6 +90,8 @@ class MainActivity : BaseActivity<MainDesign>() {
startActivity(HelpActivity::class.intent)
MainDesign.Request.OpenAbout ->
design.showAbout(queryAppVersionName())

else -> {}
}
}
if (clashRunning) {
Expand Down
30 changes: 30 additions & 0 deletions design/src/main/java/com/github/kr328/clash/design/MainDesign.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.github.kr328.clash.design

import android.content.Context
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import com.github.kr328.clash.core.model.TunnelState
import com.github.kr328.clash.core.util.trafficTotal
Expand All @@ -16,6 +17,9 @@ import kotlinx.coroutines.withContext
class MainDesign(context: Context) : Design<MainDesign.Request>(context) {
enum class Request {
ToggleStatus,
ToggleDirectMode,
ToggleGlobalMode,
ToggleRuleMode,
OpenProxy,
OpenProfiles,
OpenProviders,
Expand Down Expand Up @@ -57,6 +61,16 @@ class MainDesign(context: Context) : Design<MainDesign.Request>(context) {
TunnelState.Mode.Rule -> context.getString(R.string.rule_mode)
else -> context.getString(R.string.rule_mode)
}
val viewId = when (mode) {
TunnelState.Mode.Direct -> R.id.btnDirect
TunnelState.Mode.Global -> R.id.btnGlobal
TunnelState.Mode.Rule -> R.id.btnRule
else -> View.NO_ID
}
// 避免重复设置导致死循环
if (binding.toggleGroup.checkedButtonId != viewId) {
binding.toggleGroup.check(viewId)
}
}
}

Expand All @@ -78,11 +92,27 @@ class MainDesign(context: Context) : Design<MainDesign.Request>(context) {
}
}

suspend fun showModeSwitchTips() {
withContext(Dispatchers.Main) {
Toast.makeText(context, R.string.mode_switch_tips, Toast.LENGTH_LONG).show()
}
}

init {
binding.self = this

binding.colorClashStarted = context.resolveThemedColor(com.google.android.material.R.attr.colorPrimary)
binding.colorClashStopped = context.resolveThemedColor(R.attr.colorClashStopped)
binding.toggleGroup.addOnButtonCheckedListener { _, checkedId, isChecked ->
if (isChecked) {
when (checkedId) {
R.id.btnDirect -> requests.trySend(Request.ToggleDirectMode)
R.id.btnGlobal -> requests.trySend(Request.ToggleGlobalMode)
R.id.btnRule -> requests.trySend(Request.ToggleRuleMode)
}
}
}

}

fun request(request: Request) {
Expand Down
36 changes: 36 additions & 0 deletions design/src/main/res/layout/design_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,42 @@
app:subtext="@{mode}"
app:text="@string/proxy" />

<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/toggleGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:visibility="@{clashRunning ? View.VISIBLE : View.GONE}"
app:checkedButton="@+id/btnRule"
app:selectionRequired="true"
app:singleSelection="true"> <!-- 默认选中项 -->

<com.google.android.material.button.MaterialButton
android:id="@+id/btnRule"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/rule_mode" />

<com.google.android.material.button.MaterialButton
android:id="@+id/btnGlobal"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/global_mode" />

<com.google.android.material.button.MaterialButton
android:id="@+id/btnDirect"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/direct_mode" />

</com.google.android.material.button.MaterialButtonToggleGroup>

<com.github.kr328.clash.design.view.LargeActionCard
android:layout_width="match_parent"
android:layout_height="wrap_content"
Expand Down