Skip to content

Commit

Permalink
update: 托盘菜单可切换代理模式
Browse files Browse the repository at this point in the history
  • Loading branch information
mapleafgo committed May 6, 2023
1 parent 61b1a26 commit 200362e
Show file tree
Hide file tree
Showing 16 changed files with 149 additions and 353 deletions.
2 changes: 1 addition & 1 deletion lib/app/app_widget.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:asuka/asuka.dart';
import 'package:flutter/material.dart' hide MenuItem;
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_modular/flutter_modular.dart';

Expand Down
121 changes: 61 additions & 60 deletions lib/app/pages/index/index_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import 'package:asuka/asuka.dart';
import 'package:clash_for_flutter/app/bean/profile_url_bean.dart';
import 'package:clash_for_flutter/app/component/drawer_component.dart';
import 'package:clash_for_flutter/app/component/loading_component.dart';
import 'package:clash_for_flutter/app/enum/type_enum.dart';
import 'package:clash_for_flutter/app/source/global_config.dart';
import 'package:clash_for_flutter/app/source/request.dart';
import 'package:clash_for_flutter/app/utils/constants.dart';
import 'package:flutter/material.dart' hide MenuItem;
import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:mobx/mobx.dart';
import 'package:protocol_handler/protocol_handler.dart';
import 'package:tray_manager/tray_manager.dart';
import 'package:system_tray/system_tray.dart';
import 'package:window_manager/window_manager.dart';

class IndexPage extends StatefulWidget {
Expand All @@ -21,20 +21,22 @@ class IndexPage extends StatefulWidget {
State<IndexPage> createState() => _IndexPageState();
}

class _IndexPageState extends State<IndexPage>
with TrayListener, WindowListener, ProtocolListener, WidgetsBindingObserver {
class _IndexPageState extends State<IndexPage> with WindowListener, ProtocolListener, WidgetsBindingObserver {
final _config = Modular.get<GlobalConfig>();
final _request = Modular.get<Request>();
final PageController _page = PageController();
late final ReactionDisposer _disposeSystemProxy;
final SystemTray systemTray = SystemTray();

@override
void initState() {
_disposeSystemProxy = reaction(
reaction(
(_) => _config.systemProxy,
(status) => trayMenuChange(status),
(status) => trayMenuChange(isChecked: status, mode: _config.clashConfig.mode!),
);
reaction(
(_) => _config.clashConfig.mode,
(mode) => trayMenuChange(isChecked: _config.systemProxy, mode: mode!),
);
trayManager.addListener(this);
windowManager.addListener(this);
protocolHandler.addListener(this);
WidgetsBinding.instance.addObserver(this);
Expand All @@ -45,71 +47,70 @@ class _IndexPageState extends State<IndexPage>

Future<void> _init() async {
await windowManager.setPreventClose(true);
await trayManager.setIcon(
Platform.isWindows ? 'assets/icon.ico' : 'assets/logo_64.png',
systemTray.initSystemTray(
iconPath: Platform.isWindows ? 'assets/icon.ico' : 'assets/logo_64.png',
toolTip: "ClashForFlutter",
);
trayMenuChange(_config.systemProxy);
trayManager.setToolTip("ClashForFlutter").catchError((_) {});
trayMenuChange(isChecked: _config.systemProxy, mode: _config.clashConfig.mode ?? Mode.Rule);
systemTray.registerSystemTrayEventHandler((e) {
if (e == kSystemTrayEventClick) {
windowManager.show();
} else if (e == kSystemTrayEventRightClick) {
systemTray.popUpContextMenu();
}
});
}

@override
void dispose() {
trayManager.removeListener(this);
windowManager.removeListener(this);
protocolHandler.removeListener(this);
WidgetsBinding.instance.removeObserver(this);
_disposeSystemProxy();
super.dispose();
}

void trayMenuChange(bool isChecked) async {
List<MenuItem> items = [
MenuItem(
key: SystrayMenuKeys.systrayWinKey,
label: '显示窗口',
),
MenuItem.separator(),
MenuItem.checkbox(
key: SystrayMenuKeys.systrayProxyKey,
label: '代理',
void trayMenuChange({required bool isChecked, required Mode mode}) async {
final menu = Menu();
await menu.buildFrom([
MenuItemLabel(label: "显示窗口", onClicked: (_) => windowManager.show()),
MenuSeparator(),
MenuItemCheckbox(
label: "代理",
checked: isChecked,
onClicked: (b) async {
if (b.checked) {
await _config.closeProxy();
} else {
await _config.openProxy();
}
},
),
MenuItem(
key: SystrayMenuKeys.systrayExitKey,
label: '退出',
),
];
await trayManager.setContextMenu(Menu(items: items));
}

@override
void onTrayIconMouseDown() {
windowManager.show();
}

@override
void onTrayIconRightMouseDown() {
trayManager.popUpContextMenu();
}

@override
void onTrayMenuItemClick(MenuItem menuItem) async {
switch (menuItem.key) {
case SystrayMenuKeys.systrayWinKey:
windowManager.show();
break;
case SystrayMenuKeys.systrayProxyKey:
if (menuItem.checked!) {
SubMenu(label: "模式", children: [
MenuItemCheckbox(
checked: mode == Mode.Rule,
label: Mode.Rule.value,
onClicked: (_) => _config.setState(mode: Mode.Rule),
),
MenuItemCheckbox(
checked: mode == Mode.Global,
label: Mode.Global.value,
onClicked: (_) => _config.setState(mode: Mode.Global),
),
MenuItemCheckbox(
checked: mode == Mode.Direct,
label: Mode.Direct.value,
onClicked: (_) => _config.setState(mode: Mode.Direct),
),
]),
MenuItemLabel(
label: "退出",
onClicked: (_) async {
await _config.closeProxy();
} else {
await _config.openProxy();
}
break;
case SystrayMenuKeys.systrayExitKey:
await _config.closeProxy();
windowManager.close().then((_) => windowManager.destroy());
break;
}
windowManager.close().then((_) => windowManager.destroy());
},
),
]);
await systemTray.setContextMenu(menu);
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@ import 'package:dart_json_mapper/dart_json_mapper.dart';
@JsonSerializable()
class ProxieShow {
String name;
String? subTitle;
String? now;
String? type;
String subTitle;
int delay;

ProxieShow({
required this.name,
required this.delay,
this.subTitle,
this.now,
this.type,
required this.subTitle,
});
}
20 changes: 2 additions & 18 deletions lib/app/pages/proxys/model/proxys_model.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import 'package:clash_for_flutter/app/bean/group_bean.dart';
import 'package:clash_for_flutter/app/bean/provider_bean.dart';
import 'package:clash_for_flutter/app/bean/proxy_bean.dart';
import 'package:clash_for_flutter/app/bean/proxie_show_bean.dart';
import 'package:clash_for_flutter/app/enum/type_enum.dart';
import 'package:mobx/mobx.dart';

Expand All @@ -19,33 +16,20 @@ abstract class ProxysModelBase with Store {
@observable
SortType sortType = SortType.Default;

@observable
List<dynamic> all = [];

/// 代理列表
@observable
var proxies = <Proxy>[];
@observable
var providers = <String, Provider>{};
@observable
var proxiesMap = <String, List<ProxieShow>>{};
Map<String, dynamic> proxiesMap = {};

@action
setState({
Group? global,
SortType? sortType,
List<dynamic>? all,
List<Group>? groups,
List<Proxy>? proxies,
Map<String, Provider>? providers,
Map<String, List<ProxieShow>>? proxiesMap,
Map<String, dynamic>? proxiesMap,
}) {
if (global != null) this.global = global;
if (sortType != null) this.sortType = sortType;
if (all != null) this.all = all;
if (groups != null) this.groups = groups;
if (proxies != null) this.proxies = proxies;
if (providers != null) this.providers = providers;
if (proxiesMap != null) this.proxiesMap = proxiesMap;
}
}
62 changes: 3 additions & 59 deletions lib/app/pages/proxys/model/proxys_model.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 200362e

Please sign in to comment.