Files
MWClash/lib/models/config.dart
chen08209 676f2d058a Add windows server mode start process verify
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
2025-05-01 00:02:29 +08:00

256 lines
7.5 KiB
Dart

// ignore_for_file: invalid_annotation_target
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'models.dart';
part 'generated/config.freezed.dart';
part 'generated/config.g.dart';
const defaultBypassDomain = [
"*zhihu.com",
"*zhimg.com",
"*jd.com",
"100ime-iat-api.xfyun.cn",
"*360buyimg.com",
"localhost",
"*.local",
"127.*",
"10.*",
"172.16.*",
"172.17.*",
"172.18.*",
"172.19.*",
"172.2*",
"172.30.*",
"172.31.*",
"192.168.*"
];
const defaultAppSettingProps = AppSettingProps();
const defaultVpnProps = VpnProps();
const defaultNetworkProps = NetworkProps();
const defaultProxiesStyle = ProxiesStyle();
const defaultWindowProps = WindowProps();
const defaultAccessControl = AccessControl();
final defaultThemeProps = ThemeProps(
primaryColor: defaultPrimaryColor,
);
const List<DashboardWidget> defaultDashboardWidgets = [
DashboardWidget.networkSpeed,
DashboardWidget.systemProxyButton,
DashboardWidget.tunButton,
DashboardWidget.outboundMode,
DashboardWidget.networkDetection,
DashboardWidget.trafficUsage,
DashboardWidget.intranetIp,
];
List<DashboardWidget> dashboardWidgetsSafeFormJson(
List<dynamic>? dashboardWidgets,
) {
try {
return dashboardWidgets
?.map((e) => $enumDecode(_$DashboardWidgetEnumMap, e))
.toList() ??
defaultDashboardWidgets;
} catch (_) {
return defaultDashboardWidgets;
}
}
@freezed
class AppSettingProps with _$AppSettingProps {
const factory AppSettingProps({
String? locale,
@Default(defaultDashboardWidgets)
@JsonKey(fromJson: dashboardWidgetsSafeFormJson)
List<DashboardWidget> dashboardWidgets,
@Default(false) bool onlyStatisticsProxy,
@Default(false) bool autoLaunch,
@Default(false) bool silentLaunch,
@Default(false) bool autoRun,
@Default(false) bool openLogs,
@Default(true) bool closeConnections,
@Default(defaultTestUrl) String testUrl,
@Default(true) bool isAnimateToPage,
@Default(true) bool autoCheckUpdate,
@Default(false) bool showLabel,
@Default(false) bool disclaimerAccepted,
@Default(true) bool minimizeOnExit,
@Default(false) bool hidden,
@Default(false) bool developerMode,
@Default(RecoveryStrategy.compatible) RecoveryStrategy recoveryStrategy,
}) = _AppSettingProps;
factory AppSettingProps.fromJson(Map<String, Object?> json) =>
_$AppSettingPropsFromJson(json);
factory AppSettingProps.safeFromJson(Map<String, Object?>? json) {
return json == null
? defaultAppSettingProps
: AppSettingProps.fromJson(json);
}
}
@freezed
class AccessControl with _$AccessControl {
const factory AccessControl({
@Default(false) bool enable,
@Default(AccessControlMode.rejectSelected) AccessControlMode mode,
@Default([]) List<String> acceptList,
@Default([]) List<String> rejectList,
@Default(AccessSortType.none) AccessSortType sort,
@Default(true) bool isFilterSystemApp,
@Default(true) bool isFilterNonInternetApp,
}) = _AccessControl;
factory AccessControl.fromJson(Map<String, Object?> json) =>
_$AccessControlFromJson(json);
}
extension AccessControlExt on AccessControl {
List<String> get currentList => switch (mode) {
AccessControlMode.acceptSelected => acceptList,
AccessControlMode.rejectSelected => rejectList,
};
}
@freezed
class WindowProps with _$WindowProps {
const factory WindowProps({
@Default(750) double width,
@Default(600) double height,
double? top,
double? left,
}) = _WindowProps;
factory WindowProps.fromJson(Map<String, Object?>? json) =>
json == null ? const WindowProps() : _$WindowPropsFromJson(json);
}
@freezed
class VpnProps with _$VpnProps {
const factory VpnProps({
@Default(true) bool enable,
@Default(true) bool systemProxy,
@Default(false) bool ipv6,
@Default(true) bool allowBypass,
@Default(defaultAccessControl) AccessControl accessControl,
}) = _VpnProps;
factory VpnProps.fromJson(Map<String, Object?>? json) =>
json == null ? defaultVpnProps : _$VpnPropsFromJson(json);
}
@freezed
class NetworkProps with _$NetworkProps {
const factory NetworkProps({
@Default(true) bool systemProxy,
@Default(defaultBypassDomain) List<String> bypassDomain,
@Default(RouteMode.bypassPrivate) RouteMode routeMode,
}) = _NetworkProps;
factory NetworkProps.fromJson(Map<String, Object?>? json) =>
json == null ? const NetworkProps() : _$NetworkPropsFromJson(json);
}
@freezed
class ProxiesStyle with _$ProxiesStyle {
const factory ProxiesStyle({
@Default(ProxiesType.tab) ProxiesType type,
@Default(ProxiesSortType.none) ProxiesSortType sortType,
@Default(ProxiesLayout.standard) ProxiesLayout layout,
@Default(ProxiesIconStyle.standard) ProxiesIconStyle iconStyle,
@Default(ProxyCardType.expand) ProxyCardType cardType,
@Default({}) Map<String, String> iconMap,
}) = _ProxiesStyle;
factory ProxiesStyle.fromJson(Map<String, Object?>? json) =>
json == null ? defaultProxiesStyle : _$ProxiesStyleFromJson(json);
}
@freezed
class TextScale with _$TextScale {
const factory TextScale({
@Default(false) enable,
@Default(1.0) scale,
}) = _TextScale;
factory TextScale.fromJson(Map<String, Object?> json) =>
_$TextScaleFromJson(json);
}
@freezed
class ThemeProps with _$ThemeProps {
const factory ThemeProps({
int? primaryColor,
@Default(defaultPrimaryColors) List<int> primaryColors,
@Default(ThemeMode.dark) ThemeMode themeMode,
@Default(DynamicSchemeVariant.content) DynamicSchemeVariant schemeVariant,
@Default(false) bool pureBlack,
@Default(TextScale()) TextScale textScale,
}) = _ThemeProps;
factory ThemeProps.fromJson(Map<String, Object?> json) =>
_$ThemePropsFromJson(json);
factory ThemeProps.safeFromJson(Map<String, Object?>? json) {
if (json == null) {
return defaultThemeProps;
}
try {
return ThemeProps.fromJson(json);
} catch (_) {
return defaultThemeProps;
}
}
}
@freezed
class Config with _$Config {
const factory Config({
@JsonKey(fromJson: AppSettingProps.safeFromJson)
@Default(defaultAppSettingProps)
AppSettingProps appSetting,
@Default([]) List<Profile> profiles,
@Default([]) List<HotKeyAction> hotKeyActions,
String? currentProfileId,
@Default(false) bool overrideDns,
DAV? dav,
@Default(defaultNetworkProps) NetworkProps networkProps,
@Default(defaultVpnProps) VpnProps vpnProps,
@JsonKey(fromJson: ThemeProps.safeFromJson) required ThemeProps themeProps,
@Default(defaultProxiesStyle) ProxiesStyle proxiesStyle,
@Default(defaultWindowProps) WindowProps windowProps,
@Default(defaultClashConfig) ClashConfig patchClashConfig,
}) = _Config;
factory Config.fromJson(Map<String, Object?> json) => _$ConfigFromJson(json);
factory Config.compatibleFromJson(Map<String, Object?> json) {
try {
final accessControlMap = json["accessControl"];
final isAccessControl = json["isAccessControl"];
if (accessControlMap != null) {
(accessControlMap as Map)["enable"] = isAccessControl;
if (json["vpnProps"] != null) {
(json["vpnProps"] as Map)["accessControl"] = accessControlMap;
}
}
} catch (_) {}
return Config.fromJson(json);
}
}
extension ConfigExt on Config {
Profile? get currentProfile {
return profiles.getProfile(currentProfileId);
}
}