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
485 lines
8.7 KiB
Dart
485 lines
8.7 KiB
Dart
// ignore_for_file: constant_identifier_names
|
|
|
|
import 'dart:io';
|
|
|
|
import 'package:fl_clash/fragments/dashboard/widgets/widgets.dart';
|
|
import 'package:fl_clash/widgets/widgets.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
import 'package:hotkey_manager/hotkey_manager.dart';
|
|
|
|
enum SupportPlatform {
|
|
Windows,
|
|
MacOS,
|
|
Linux,
|
|
Android;
|
|
|
|
static SupportPlatform get currentPlatform {
|
|
if (Platform.isWindows) {
|
|
return SupportPlatform.Windows;
|
|
} else if (Platform.isMacOS) {
|
|
return SupportPlatform.MacOS;
|
|
} else if (Platform.isLinux) {
|
|
return SupportPlatform.Linux;
|
|
} else if (Platform.isAndroid) {
|
|
return SupportPlatform.Android;
|
|
}
|
|
throw "invalid platform";
|
|
}
|
|
}
|
|
|
|
const desktopPlatforms = [
|
|
SupportPlatform.Linux,
|
|
SupportPlatform.MacOS,
|
|
SupportPlatform.Windows,
|
|
];
|
|
|
|
enum GroupType {
|
|
Selector,
|
|
URLTest,
|
|
Fallback,
|
|
LoadBalance,
|
|
Relay;
|
|
|
|
static GroupType parseProfileType(String type) {
|
|
return switch (type) {
|
|
"url-test" => URLTest,
|
|
"select" => Selector,
|
|
"fallback" => Fallback,
|
|
"load-balance" => LoadBalance,
|
|
"relay" => Relay,
|
|
String() => throw UnimplementedError(),
|
|
};
|
|
}
|
|
}
|
|
|
|
enum GroupName { GLOBAL, Proxy, Auto, Fallback }
|
|
|
|
extension GroupTypeExtension on GroupType {
|
|
static List<String> get valueList => GroupType.values
|
|
.map(
|
|
(e) => e.toString().split(".").last,
|
|
)
|
|
.toList();
|
|
|
|
bool get isComputedSelected {
|
|
return [GroupType.URLTest, GroupType.Fallback].contains(this);
|
|
}
|
|
|
|
static GroupType? getGroupType(String value) {
|
|
final index = GroupTypeExtension.valueList.indexOf(value);
|
|
if (index == -1) return null;
|
|
return GroupType.values[index];
|
|
}
|
|
|
|
String get value => GroupTypeExtension.valueList[index];
|
|
}
|
|
|
|
enum UsedProxy { GLOBAL, DIRECT, REJECT }
|
|
|
|
extension UsedProxyExtension on UsedProxy {
|
|
static List<String> get valueList => UsedProxy.values
|
|
.map(
|
|
(e) => e.toString().split(".").last,
|
|
)
|
|
.toList();
|
|
|
|
String get value => UsedProxyExtension.valueList[index];
|
|
}
|
|
|
|
enum Mode { rule, global, direct }
|
|
|
|
enum ViewMode { mobile, laptop, desktop }
|
|
|
|
enum LogLevel {
|
|
debug,
|
|
info,
|
|
warning,
|
|
error,
|
|
silent,
|
|
app,
|
|
}
|
|
|
|
enum TransportProtocol { udp, tcp }
|
|
|
|
enum TrafficUnit { B, KB, MB, GB, TB }
|
|
|
|
enum NavigationItemMode { mobile, desktop, more }
|
|
|
|
enum Network { tcp, udp }
|
|
|
|
enum ProxiesSortType { none, delay, name }
|
|
|
|
enum TunStack { gvisor, system, mixed }
|
|
|
|
enum AccessControlMode { acceptSelected, rejectSelected }
|
|
|
|
enum AccessSortType { none, name, time }
|
|
|
|
enum ProfileType { file, url }
|
|
|
|
enum ResultType { success, error }
|
|
|
|
enum AppMessageType {
|
|
log,
|
|
delay,
|
|
request,
|
|
loaded,
|
|
}
|
|
|
|
enum InvokeMessageType {
|
|
protect,
|
|
process,
|
|
}
|
|
|
|
enum FindProcessMode { always, off }
|
|
|
|
enum RecoveryOption {
|
|
all,
|
|
onlyProfiles,
|
|
}
|
|
|
|
enum ChipType { action, delete }
|
|
|
|
enum CommonCardType { plain, filled }
|
|
//
|
|
// extension CommonCardTypeExt on CommonCardType {
|
|
// CommonCardType get variant => CommonCardType.plain;
|
|
// }
|
|
|
|
enum ProxiesType { tab, list }
|
|
|
|
enum ProxiesLayout { loose, standard, tight }
|
|
|
|
enum ProxyCardType { expand, shrink, min }
|
|
|
|
enum DnsMode {
|
|
normal,
|
|
@JsonValue("fake-ip")
|
|
fakeIp,
|
|
@JsonValue("redir-host")
|
|
redirHost,
|
|
hosts
|
|
}
|
|
|
|
enum ExternalControllerStatus {
|
|
@JsonValue("")
|
|
close,
|
|
@JsonValue("127.0.0.1:9090")
|
|
open
|
|
}
|
|
|
|
enum KeyboardModifier {
|
|
alt([
|
|
PhysicalKeyboardKey.altLeft,
|
|
PhysicalKeyboardKey.altRight,
|
|
]),
|
|
capsLock([
|
|
PhysicalKeyboardKey.capsLock,
|
|
]),
|
|
control([
|
|
PhysicalKeyboardKey.controlLeft,
|
|
PhysicalKeyboardKey.controlRight,
|
|
]),
|
|
fn([
|
|
PhysicalKeyboardKey.fn,
|
|
]),
|
|
meta([
|
|
PhysicalKeyboardKey.metaLeft,
|
|
PhysicalKeyboardKey.metaRight,
|
|
]),
|
|
shift([
|
|
PhysicalKeyboardKey.shiftLeft,
|
|
PhysicalKeyboardKey.shiftRight,
|
|
]);
|
|
|
|
final List<PhysicalKeyboardKey> physicalKeys;
|
|
|
|
const KeyboardModifier(this.physicalKeys);
|
|
}
|
|
|
|
extension KeyboardModifierExt on KeyboardModifier {
|
|
HotKeyModifier toHotKeyModifier() {
|
|
return switch (this) {
|
|
KeyboardModifier.alt => HotKeyModifier.alt,
|
|
KeyboardModifier.capsLock => HotKeyModifier.capsLock,
|
|
KeyboardModifier.control => HotKeyModifier.control,
|
|
KeyboardModifier.fn => HotKeyModifier.fn,
|
|
KeyboardModifier.meta => HotKeyModifier.meta,
|
|
KeyboardModifier.shift => HotKeyModifier.shift,
|
|
};
|
|
}
|
|
}
|
|
|
|
enum HotAction {
|
|
start,
|
|
view,
|
|
mode,
|
|
proxy,
|
|
tun,
|
|
}
|
|
|
|
enum ProxiesIconStyle {
|
|
standard,
|
|
none,
|
|
icon,
|
|
}
|
|
|
|
enum FontFamily {
|
|
twEmoji("Twemoji"),
|
|
jetBrainsMono("JetBrainsMono"),
|
|
icon("Icons");
|
|
|
|
final String value;
|
|
|
|
const FontFamily(this.value);
|
|
}
|
|
|
|
enum RouteMode {
|
|
bypassPrivate,
|
|
config,
|
|
}
|
|
|
|
enum ActionMethod {
|
|
message,
|
|
initClash,
|
|
getIsInit,
|
|
forceGc,
|
|
shutdown,
|
|
validateConfig,
|
|
updateConfig,
|
|
getProxies,
|
|
changeProxy,
|
|
getTraffic,
|
|
getTotalTraffic,
|
|
resetTraffic,
|
|
asyncTestDelay,
|
|
getConnections,
|
|
closeConnections,
|
|
closeConnection,
|
|
getExternalProviders,
|
|
getExternalProvider,
|
|
updateGeoData,
|
|
updateExternalProvider,
|
|
sideLoadExternalProvider,
|
|
startLog,
|
|
stopLog,
|
|
startListener,
|
|
stopListener,
|
|
getCountryCode,
|
|
getMemory,
|
|
getProfile,
|
|
crash,
|
|
|
|
///Android,
|
|
setFdMap,
|
|
setProcessMap,
|
|
setState,
|
|
startTun,
|
|
stopTun,
|
|
getRunTime,
|
|
updateDns,
|
|
getAndroidVpnOptions,
|
|
getCurrentProfileName,
|
|
}
|
|
|
|
enum AuthorizeCode { none, success, error }
|
|
|
|
enum WindowsHelperServiceStatus {
|
|
none,
|
|
presence,
|
|
running,
|
|
}
|
|
|
|
enum DebounceTag {
|
|
updateClashConfig,
|
|
updateStatus,
|
|
updateGroups,
|
|
addCheckIpNum,
|
|
applyProfile,
|
|
savePreferences,
|
|
changeProxy,
|
|
checkIp,
|
|
handleWill,
|
|
updateDelay,
|
|
vpnTip,
|
|
autoLaunch,
|
|
renderPause,
|
|
updatePageIndex,
|
|
pageChange,
|
|
proxiesTabChange,
|
|
}
|
|
|
|
enum DashboardWidget {
|
|
networkSpeed(
|
|
GridItem(
|
|
crossAxisCellCount: 8,
|
|
child: NetworkSpeed(),
|
|
),
|
|
),
|
|
outboundModeV2(
|
|
GridItem(
|
|
crossAxisCellCount: 8,
|
|
child: OutboundModeV2(),
|
|
),
|
|
),
|
|
outboundMode(
|
|
GridItem(
|
|
crossAxisCellCount: 4,
|
|
child: OutboundMode(),
|
|
),
|
|
),
|
|
trafficUsage(
|
|
GridItem(
|
|
crossAxisCellCount: 4,
|
|
child: TrafficUsage(),
|
|
),
|
|
),
|
|
networkDetection(
|
|
GridItem(
|
|
crossAxisCellCount: 4,
|
|
child: NetworkDetection(),
|
|
),
|
|
),
|
|
tunButton(
|
|
GridItem(
|
|
crossAxisCellCount: 4,
|
|
child: TUNButton(),
|
|
),
|
|
platforms: desktopPlatforms,
|
|
),
|
|
vpnButton(
|
|
GridItem(
|
|
crossAxisCellCount: 4,
|
|
child: VpnButton(),
|
|
),
|
|
platforms: [
|
|
SupportPlatform.Android,
|
|
],
|
|
),
|
|
systemProxyButton(
|
|
GridItem(
|
|
crossAxisCellCount: 4,
|
|
child: SystemProxyButton(),
|
|
),
|
|
platforms: desktopPlatforms,
|
|
),
|
|
intranetIp(
|
|
GridItem(
|
|
crossAxisCellCount: 4,
|
|
child: IntranetIP(),
|
|
),
|
|
),
|
|
memoryInfo(
|
|
GridItem(
|
|
crossAxisCellCount: 4,
|
|
child: MemoryInfo(),
|
|
),
|
|
);
|
|
|
|
final GridItem widget;
|
|
final List<SupportPlatform> platforms;
|
|
|
|
const DashboardWidget(
|
|
this.widget, {
|
|
this.platforms = SupportPlatform.values,
|
|
});
|
|
|
|
static DashboardWidget getDashboardWidget(GridItem gridItem) {
|
|
final dashboardWidgets = DashboardWidget.values;
|
|
final index = dashboardWidgets.indexWhere(
|
|
(item) => item.widget == gridItem,
|
|
);
|
|
return dashboardWidgets[index];
|
|
}
|
|
}
|
|
|
|
enum GeodataLoader {
|
|
standard,
|
|
memconservative,
|
|
}
|
|
|
|
enum PageLabel {
|
|
dashboard,
|
|
proxies,
|
|
profiles,
|
|
tools,
|
|
logs,
|
|
requests,
|
|
resources,
|
|
connections,
|
|
}
|
|
|
|
enum RuleAction {
|
|
DOMAIN("DOMAIN"),
|
|
DOMAIN_SUFFIX("DOMAIN-SUFFIX"),
|
|
DOMAIN_KEYWORD("DOMAIN-KEYWORD"),
|
|
DOMAIN_REGEX("DOMAIN-REGEX"),
|
|
GEOSITE("GEOSITE"),
|
|
IP_CIDR("IP-CIDR"),
|
|
IP_CIDR6("IP-CIDR6"),
|
|
IP_SUFFIX("IP-SUFFIX"),
|
|
IP_ASN("IP-ASN"),
|
|
GEOIP("GEOIP"),
|
|
SRC_GEOIP("SRC-GEOIP"),
|
|
SRC_IP_ASN("SRC-IP-ASN"),
|
|
SRC_IP_CIDR("SRC-IP-CIDR"),
|
|
SRC_IP_SUFFIX("SRC-IP-SUFFIX"),
|
|
DST_PORT("DST-PORT"),
|
|
SRC_PORT("SRC-PORT"),
|
|
IN_PORT("IN-PORT"),
|
|
IN_TYPE("IN-TYPE"),
|
|
IN_USER("IN-USER"),
|
|
IN_NAME("IN-NAME"),
|
|
PROCESS_PATH("PROCESS-PATH"),
|
|
PROCESS_PATH_REGEX("PROCESS-PATH-REGEX"),
|
|
PROCESS_NAME("PROCESS-NAME"),
|
|
PROCESS_NAME_REGEX("PROCESS-NAME-REGEX"),
|
|
UID("UID"),
|
|
NETWORK("NETWORK"),
|
|
DSCP("DSCP"),
|
|
RULE_SET("RULE-SET"),
|
|
AND("AND"),
|
|
OR("OR"),
|
|
NOT("NOT"),
|
|
SUB_RULE("SUB-RULE"),
|
|
MATCH("MATCH");
|
|
|
|
final String value;
|
|
|
|
const RuleAction(this.value);
|
|
}
|
|
|
|
extension RuleActionExt on RuleAction {
|
|
bool get hasParams => [
|
|
RuleAction.GEOIP,
|
|
RuleAction.IP_ASN,
|
|
RuleAction.SRC_IP_ASN,
|
|
RuleAction.IP_CIDR,
|
|
RuleAction.IP_CIDR6,
|
|
RuleAction.IP_SUFFIX,
|
|
RuleAction.RULE_SET,
|
|
].contains(this);
|
|
}
|
|
|
|
enum OverrideRuleType {
|
|
override,
|
|
added,
|
|
}
|
|
|
|
enum RuleTarget {
|
|
DIRECT,
|
|
REJECT,
|
|
}
|
|
|
|
enum RecoveryStrategy {
|
|
compatible,
|
|
override,
|
|
}
|
|
|
|
enum CacheTag {
|
|
logs,
|
|
rules,
|
|
requests,
|
|
}
|