From 556b2ee844a37c351a8b83bc6b28a1a3834455da Mon Sep 17 00:00:00 2001 From: cc_du Date: Thu, 6 Aug 2026 23:37:32 +0800 Subject: [PATCH 1/2] feat: add Start/Stop app shortcuts alongside toggle --- .../com/follow/clash/plugins/AppPlugin.kt | 40 ++++++++++++++----- lib/plugins/app.dart | 6 ++- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/android/app/src/main/kotlin/com/follow/clash/plugins/AppPlugin.kt b/android/app/src/main/kotlin/com/follow/clash/plugins/AppPlugin.kt index e562051f8c..5d56d11d85 100644 --- a/android/app/src/main/kotlin/com/follow/clash/plugins/AppPlugin.kt +++ b/android/app/src/main/kotlin/com/follow/clash/plugins/AppPlugin.kt @@ -134,7 +134,11 @@ class AppPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, ActivityAware } "initShortcuts" -> { - initShortcuts(call.arguments as String) + val labels = call.arguments + if (labels is Map<*, *>) { + @Suppress("UNCHECKED_CAST") + initShortcuts(labels as Map) + } result.success(true) } @@ -190,21 +194,35 @@ class AppPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, ActivityAware } } - private fun initShortcuts(label: String) { - val shortcut = with(ShortcutInfoCompat.Builder(GlobalState.application, "toggle")) { - setShortLabel(label) - setIcon( + private fun initShortcuts(labels: Map) { + val startLabel = labels["start"] ?: "Start" + val stopLabel = labels["stop"] ?: "Stop" + val toggleLabel = labels["toggle"] ?: return + val shortcuts = listOf( + buildShortcut("start", startLabel, QuickAction.START), + buildShortcut("stop", stopLabel, QuickAction.STOP), + buildShortcut("toggle", toggleLabel, QuickAction.TOGGLE), + ) + ShortcutManagerCompat.setDynamicShortcuts( + GlobalState.application, shortcuts + ) + } + + private fun buildShortcut( + id: String, + label: String, + action: QuickAction, + ): ShortcutInfoCompat { + return ShortcutInfoCompat.Builder(GlobalState.application, id) + .setShortLabel(label) + .setIcon( IconCompat.createWithResource( GlobalState.application, R.mipmap.ic_launcher_round, ) ) - setIntent(QuickAction.TOGGLE.quickIntent) - build() - } - ShortcutManagerCompat.setDynamicShortcuts( - GlobalState.application, listOf(shortcut) - ) + .setIntent(action.quickIntent) + .build() } private fun tip(message: String?) { diff --git a/lib/plugins/app.dart b/lib/plugins/app.dart index 612b7cc40e..db9437a50f 100644 --- a/lib/plugins/app.dart +++ b/lib/plugins/app.dart @@ -78,7 +78,11 @@ class App { Future initShortcuts() async { return methodChannel.invokeMethod( 'initShortcuts', - currentAppLocalizations.toggle, + { + 'start': currentAppLocalizations.start, + 'stop': currentAppLocalizations.stop, + 'toggle': currentAppLocalizations.toggle, + }, ); } From 347d00be9ca50b9087011ad1b92534acf467a26a Mon Sep 17 00:00:00 2001 From: cc_du Date: Fri, 7 Aug 2026 00:21:15 +0800 Subject: [PATCH 2/2] Add icon for shortcuts --- .../com/follow/clash/plugins/AppPlugin.kt | 24 +++++++++++++++---- .../main/res/drawable/ic_shortcut_start.xml | 16 +++++++++++++ .../main/res/drawable/ic_shortcut_stop.xml | 16 +++++++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 android/app/src/main/res/drawable/ic_shortcut_start.xml create mode 100644 android/app/src/main/res/drawable/ic_shortcut_stop.xml diff --git a/android/app/src/main/kotlin/com/follow/clash/plugins/AppPlugin.kt b/android/app/src/main/kotlin/com/follow/clash/plugins/AppPlugin.kt index 5d56d11d85..8805c19053 100644 --- a/android/app/src/main/kotlin/com/follow/clash/plugins/AppPlugin.kt +++ b/android/app/src/main/kotlin/com/follow/clash/plugins/AppPlugin.kt @@ -199,9 +199,24 @@ class AppPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, ActivityAware val stopLabel = labels["stop"] ?: "Stop" val toggleLabel = labels["toggle"] ?: return val shortcuts = listOf( - buildShortcut("start", startLabel, QuickAction.START), - buildShortcut("stop", stopLabel, QuickAction.STOP), - buildShortcut("toggle", toggleLabel, QuickAction.TOGGLE), + buildShortcut( + id = "start", + label = startLabel, + action = QuickAction.START, + iconRes = R.drawable.ic_shortcut_start, + ), + buildShortcut( + id = "stop", + label = stopLabel, + action = QuickAction.STOP, + iconRes = R.drawable.ic_shortcut_stop, + ), + buildShortcut( + id = "toggle", + label = toggleLabel, + action = QuickAction.TOGGLE, + iconRes = R.mipmap.ic_launcher_round, + ), ) ShortcutManagerCompat.setDynamicShortcuts( GlobalState.application, shortcuts @@ -212,13 +227,14 @@ class AppPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, ActivityAware id: String, label: String, action: QuickAction, + iconRes: Int, ): ShortcutInfoCompat { return ShortcutInfoCompat.Builder(GlobalState.application, id) .setShortLabel(label) .setIcon( IconCompat.createWithResource( GlobalState.application, - R.mipmap.ic_launcher_round, + iconRes, ) ) .setIntent(action.quickIntent) diff --git a/android/app/src/main/res/drawable/ic_shortcut_start.xml b/android/app/src/main/res/drawable/ic_shortcut_start.xml new file mode 100644 index 0000000000..9bbfdd1146 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_shortcut_start.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/ic_shortcut_stop.xml b/android/app/src/main/res/drawable/ic_shortcut_stop.xml new file mode 100644 index 0000000000..5e26e69ed8 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_shortcut_stop.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file