Add linux deb dependencies Add backup recovery strategy select Support custom text scaling Optimize the display of different text scale Optimize windows setup experience Optimize startTun performance Optimize android tv experience Optimize default option Optimize computed text size Optimize hyperOS freeform window Add developer mode Update core Optimize more details
201 lines
5.2 KiB
Dart
201 lines
5.2 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:fl_clash/common/utils.dart';
|
|
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 '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(
|
|
utils.getTrayIconPath(
|
|
brightness: brightness ??
|
|
WidgetsBinding.instance.platformDispatcher.platformBrightness,
|
|
),
|
|
isTemplate: true,
|
|
);
|
|
if (!Platform.isLinux) {
|
|
await trayManager.setToolTip(
|
|
appName,
|
|
);
|
|
}
|
|
}
|
|
|
|
update({
|
|
required TrayState trayState,
|
|
bool focus = false,
|
|
}) async {
|
|
if (Platform.isAndroid) {
|
|
return;
|
|
}
|
|
if (!Platform.isLinux) {
|
|
await _updateSystemTray(
|
|
brightness: trayState.brightness,
|
|
force: focus,
|
|
);
|
|
}
|
|
List<MenuItem> menuItems = [];
|
|
final showMenuItem = MenuItem(
|
|
label: appLocalizations.show,
|
|
onClick: (_) {
|
|
window?.show();
|
|
},
|
|
);
|
|
menuItems.add(showMenuItem);
|
|
final startMenuItem = MenuItem.checkbox(
|
|
label: trayState.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.changeMode(mode);
|
|
},
|
|
checked: mode == trayState.mode,
|
|
),
|
|
);
|
|
}
|
|
menuItems.add(MenuItem.separator());
|
|
if (Platform.isMacOS) {
|
|
for (final group in trayState.groups) {
|
|
List<MenuItem> subMenuItems = [];
|
|
for (final proxy in group.all) {
|
|
subMenuItems.add(
|
|
MenuItem.checkbox(
|
|
label: proxy.name,
|
|
checked: trayState.selectedMap[group.name] == proxy.name,
|
|
onClick: (_) {
|
|
final appController = globalState.appController;
|
|
appController.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 (trayState.groups.isNotEmpty) {
|
|
menuItems.add(MenuItem.separator());
|
|
}
|
|
}
|
|
if (trayState.isStart) {
|
|
menuItems.add(
|
|
MenuItem.checkbox(
|
|
label: appLocalizations.tun,
|
|
onClick: (_) {
|
|
globalState.appController.updateTun();
|
|
},
|
|
checked: trayState.tunEnable,
|
|
),
|
|
);
|
|
menuItems.add(
|
|
MenuItem.checkbox(
|
|
label: appLocalizations.systemProxy,
|
|
onClick: (_) {
|
|
globalState.appController.updateSystemProxy();
|
|
},
|
|
checked: trayState.systemProxy,
|
|
),
|
|
);
|
|
menuItems.add(MenuItem.separator());
|
|
}
|
|
final autoStartMenuItem = MenuItem.checkbox(
|
|
label: appLocalizations.autoLaunch,
|
|
onClick: (_) async {
|
|
globalState.appController.updateAutoLaunch();
|
|
},
|
|
checked: trayState.autoLaunch,
|
|
);
|
|
final copyEnvVarMenuItem = MenuItem(
|
|
label: appLocalizations.copyEnvVar,
|
|
onClick: (_) async {
|
|
await _copyEnv(trayState.port);
|
|
},
|
|
);
|
|
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: trayState.brightness,
|
|
force: focus,
|
|
);
|
|
}
|
|
}
|
|
|
|
updateTrayTitle([Traffic? traffic]) async {
|
|
// if (!Platform.isMacOS) {
|
|
// return;
|
|
// }
|
|
// if (traffic == null) {
|
|
// await trayManager.setTitle("");
|
|
// } else {
|
|
// await trayManager.setTitle(
|
|
// "${traffic.up.shortShow} ↑ \n${traffic.down.shortShow} ↓",
|
|
// );
|
|
// }
|
|
}
|
|
|
|
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();
|