Optimize change proxy Optimize network check Fix fallback issues Optimize lots of details
194 lines
5.0 KiB
Dart
194 lines
5.0 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:fl_clash/enum/enum.dart';
|
|
import 'package:fl_clash/models/models.dart';
|
|
import 'package:fl_clash/state.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:tray_manager/tray_manager.dart';
|
|
|
|
import 'app_localizations.dart';
|
|
import 'constant.dart';
|
|
import 'other.dart';
|
|
import 'window.dart';
|
|
|
|
class Tray {
|
|
Future _updateSystemTray({
|
|
required Brightness? brightness,
|
|
bool force = false,
|
|
}) async {
|
|
if (Platform.isAndroid) {
|
|
return;
|
|
}
|
|
if (Platform.isLinux || force) {
|
|
await trayManager.destroy();
|
|
}
|
|
await trayManager.setIcon(
|
|
other.getTrayIconPath(
|
|
brightness: brightness ??
|
|
WidgetsBinding.instance.platformDispatcher.platformBrightness,
|
|
),
|
|
isTemplate: true,
|
|
);
|
|
if (!Platform.isLinux) {
|
|
await trayManager.setToolTip(
|
|
appName,
|
|
);
|
|
}
|
|
}
|
|
|
|
update({
|
|
required AppState appState,
|
|
required AppFlowingState appFlowingState,
|
|
required Config config,
|
|
required ClashConfig clashConfig,
|
|
bool focus = false,
|
|
}) async {
|
|
if (Platform.isAndroid) {
|
|
return;
|
|
}
|
|
if (!Platform.isLinux) {
|
|
await _updateSystemTray(
|
|
brightness: appState.brightness,
|
|
force: focus,
|
|
);
|
|
}
|
|
List<MenuItem> menuItems = [];
|
|
final showMenuItem = MenuItem(
|
|
label: appLocalizations.show,
|
|
onClick: (_) {
|
|
window?.show();
|
|
},
|
|
);
|
|
menuItems.add(showMenuItem);
|
|
final startMenuItem = MenuItem.checkbox(
|
|
label: appFlowingState.isStart
|
|
? appLocalizations.stop
|
|
: appLocalizations.start,
|
|
onClick: (_) async {
|
|
globalState.appController.updateStart();
|
|
},
|
|
checked: false,
|
|
);
|
|
menuItems.add(startMenuItem);
|
|
menuItems.add(MenuItem.separator());
|
|
for (final mode in Mode.values) {
|
|
menuItems.add(
|
|
MenuItem.checkbox(
|
|
label: Intl.message(mode.name),
|
|
onClick: (_) {
|
|
globalState.appController.clashConfig.mode = mode;
|
|
},
|
|
checked: mode == clashConfig.mode,
|
|
),
|
|
);
|
|
}
|
|
menuItems.add(MenuItem.separator());
|
|
if (!Platform.isWindows) {
|
|
final groups = appState.currentGroups;
|
|
for (final group in groups) {
|
|
List<MenuItem> subMenuItems = [];
|
|
for (final proxy in group.all) {
|
|
subMenuItems.add(
|
|
MenuItem.checkbox(
|
|
label: proxy.name,
|
|
checked: appState.selectedMap[group.name] == proxy.name,
|
|
onClick: (_) {
|
|
final appController = globalState.appController;
|
|
appController.config.updateCurrentSelectedMap(
|
|
group.name,
|
|
proxy.name,
|
|
);
|
|
appController.changeProxy(
|
|
groupName: group.name,
|
|
proxyName: proxy.name,
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
menuItems.add(
|
|
MenuItem.submenu(
|
|
label: group.name,
|
|
submenu: Menu(
|
|
items: subMenuItems,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
if (groups.isNotEmpty) {
|
|
menuItems.add(MenuItem.separator());
|
|
}
|
|
}
|
|
if (appFlowingState.isStart) {
|
|
menuItems.add(
|
|
MenuItem.checkbox(
|
|
label: appLocalizations.tun,
|
|
onClick: (_) {
|
|
globalState.appController.updateTun();
|
|
},
|
|
checked: clashConfig.tun.enable,
|
|
),
|
|
);
|
|
menuItems.add(
|
|
MenuItem.checkbox(
|
|
label: appLocalizations.systemProxy,
|
|
onClick: (_) {
|
|
globalState.appController.updateSystemProxy();
|
|
},
|
|
checked: config.networkProps.systemProxy,
|
|
),
|
|
);
|
|
menuItems.add(MenuItem.separator());
|
|
}
|
|
final autoStartMenuItem = MenuItem.checkbox(
|
|
label: appLocalizations.autoLaunch,
|
|
onClick: (_) async {
|
|
globalState.appController.updateAutoLaunch();
|
|
},
|
|
checked: config.appSetting.autoLaunch,
|
|
);
|
|
final copyEnvVarMenuItem = MenuItem(
|
|
label: appLocalizations.copyEnvVar,
|
|
onClick: (_) async {
|
|
await _copyEnv(clashConfig.mixedPort);
|
|
},
|
|
);
|
|
menuItems.add(autoStartMenuItem);
|
|
menuItems.add(copyEnvVarMenuItem);
|
|
menuItems.add(MenuItem.separator());
|
|
final exitMenuItem = MenuItem(
|
|
label: appLocalizations.exit,
|
|
onClick: (_) async {
|
|
await globalState.appController.handleExit();
|
|
},
|
|
);
|
|
menuItems.add(exitMenuItem);
|
|
final menu = Menu(items: menuItems);
|
|
await trayManager.setContextMenu(menu);
|
|
if (Platform.isLinux) {
|
|
await _updateSystemTray(
|
|
brightness: appState.brightness,
|
|
force: focus,
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> _copyEnv(int port) async {
|
|
final url = "http://127.0.0.1:$port";
|
|
|
|
final cmdline = Platform.isWindows
|
|
? "set \$env:all_proxy=$url"
|
|
: "export all_proxy=$url";
|
|
|
|
await Clipboard.setData(
|
|
ClipboardData(
|
|
text: cmdline,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
final tray = Tray();
|