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
256 lines
7.5 KiB
Dart
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);
|
|
}
|
|
}
|