Fix the collapse issues

Add fontFamily options
This commit is contained in:
chen08209
2024-10-26 16:52:10 +08:00
parent 25764fc4d3
commit c94f64cf78
21 changed files with 489 additions and 141 deletions

Binary file not shown.

View File

@@ -158,10 +158,12 @@ func getRawConfigWithId(id string) *config.RawConfig {
} }
mapping["path"] = filepath.Join(getProfileProvidersPath(id), value) mapping["path"] = filepath.Join(getProfileProvidersPath(id), value)
if configParams.TestURL != nil { if configParams.TestURL != nil {
hc := mapping["health-check"].(map[string]any) if mapping["health-check"] != nil {
if hc != nil { hc := mapping["health-check"].(map[string]any)
if hc["url"] != nil { if hc != nil {
hc["url"] = *configParams.TestURL if hc["url"] != nil {
hc["url"] = *configParams.TestURL
}
} }
} }
} }

View File

@@ -163,9 +163,10 @@ class ApplicationState extends State<Application> {
child: Selector2<AppState, Config, ApplicationSelectorState>( child: Selector2<AppState, Config, ApplicationSelectorState>(
selector: (_, appState, config) => ApplicationSelectorState( selector: (_, appState, config) => ApplicationSelectorState(
locale: config.appSetting.locale, locale: config.appSetting.locale,
themeMode: config.themeMode, themeMode: config.themeProps.themeMode,
primaryColor: config.primaryColor, primaryColor: config.themeProps.primaryColor,
prueBlack: config.prueBlack, prueBlack: config.themeProps.prueBlack,
fontFamily: config.themeProps.fontFamily,
), ),
builder: (_, state, child) { builder: (_, state, child) {
return DynamicColorBuilder( return DynamicColorBuilder(
@@ -199,6 +200,7 @@ class ApplicationState extends State<Application> {
themeMode: state.themeMode, themeMode: state.themeMode,
theme: ThemeData( theme: ThemeData(
useMaterial3: true, useMaterial3: true,
fontFamily: state.fontFamily.value,
pageTransitionsTheme: _pageTransitionsTheme, pageTransitionsTheme: _pageTransitionsTheme,
colorScheme: _getAppColorScheme( colorScheme: _getAppColorScheme(
brightness: Brightness.light, brightness: Brightness.light,
@@ -208,6 +210,7 @@ class ApplicationState extends State<Application> {
), ),
darkTheme: ThemeData( darkTheme: ThemeData(
useMaterial3: true, useMaterial3: true,
fontFamily: state.fontFamily.value,
pageTransitionsTheme: _pageTransitionsTheme, pageTransitionsTheme: _pageTransitionsTheme,
colorScheme: _getAppColorScheme( colorScheme: _getAppColorScheme(
brightness: Brightness.dark, brightness: Brightness.dark,

View File

@@ -29,5 +29,4 @@ export 'scroll.dart';
export 'icons.dart'; export 'icons.dart';
export 'http.dart'; export 'http.dart';
export 'keyboard.dart'; export 'keyboard.dart';
export 'network.dart'; export 'network.dart';
export 'font.dart';

View File

@@ -1,3 +0,0 @@
class Fonts{
static String get twEmoji => "Twemoji";
}

View File

@@ -162,3 +162,14 @@ enum ProxiesIconStyle {
none, none,
icon, icon,
} }
enum FontFamily {
system(),
miSans("MiSans"),
twEmoji("Twemoji"),
icon("Icons");
final String? value;
const FontFamily([this.value]);
}

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart'; import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/state.dart'; import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart'; import 'package:fl_clash/widgets/widgets.dart';
@@ -69,7 +70,7 @@ class _NetworkDetectionState extends State<NetworkDetection> {
} }
_clearSetTimeoutTimer() { _clearSetTimeoutTimer() {
if(_setTimeoutTimer != null){ if (_setTimeoutTimer != null) {
_setTimeoutTimer?.cancel(); _setTimeoutTimer?.cancel();
_setTimeoutTimer = null; _setTimeoutTimer = null;
} }
@@ -155,7 +156,7 @@ class _NetworkDetectionState extends State<NetworkDetection> {
.textTheme .textTheme
.titleLarge .titleLarge
?.copyWith( ?.copyWith(
fontFamily: Fonts.twEmoji, fontFamily: FontFamily.twEmoji.value,
), ),
), ),
) )

View File

@@ -1,4 +1,5 @@
import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart'; import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/state.dart'; import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -18,6 +19,16 @@ class ThemeModeItem {
}); });
} }
class FontFamilyItem {
final FontFamily fontFamily;
final String label;
const FontFamilyItem({
required this.fontFamily,
required this.label,
});
}
class ThemeFragment extends StatelessWidget { class ThemeFragment extends StatelessWidget {
const ThemeFragment({super.key}); const ThemeFragment({super.key});
@@ -92,7 +103,11 @@ class _ThemeColorsBoxState extends State<ThemeColorsBox> {
return CommonCard( return CommonCard(
isSelected: isSelected, isSelected: isSelected,
onPressed: () { onPressed: () {
globalState.appController.config.themeMode = themeModeItem.themeMode; final appController = globalState.appController;
appController.config.themeProps =
appController.config.themeProps.copyWith(
themeMode: themeModeItem.themeMode,
);
}, },
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
@@ -125,11 +140,45 @@ class _ThemeColorsBoxState extends State<ThemeColorsBox> {
isSelected: isSelected, isSelected: isSelected,
primaryColor: color, primaryColor: color,
onPressed: () { onPressed: () {
globalState.appController.config.primaryColor = color?.value; final appController = globalState.appController;
appController.config.themeProps =
appController.config.themeProps.copyWith(
primaryColor: color?.value,
);
}, },
); );
} }
Widget _fontFamilyCheckBox({
bool? isSelected,
required FontFamilyItem fontFamilyItem,
}) {
return CommonCard(
isSelected: isSelected,
onPressed: () {
final appController = globalState.appController;
appController.config.themeProps =
appController.config.themeProps.copyWith(
fontFamily: fontFamilyItem.fontFamily,
);
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Flexible(
child: Text(
fontFamilyItem.label,
),
),
],
),
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
List<ThemeModeItem> themeModeItems = [ List<ThemeModeItem> themeModeItems = [
@@ -158,15 +207,59 @@ class _ThemeColorsBoxState extends State<ThemeColorsBox> {
Colors.yellowAccent, Colors.yellowAccent,
Colors.purple, Colors.purple,
]; ];
List<FontFamilyItem> fontFamilyItems = [
FontFamilyItem(
label: appLocalizations.systemFont,
fontFamily: FontFamily.system,
),
const FontFamilyItem(
label: "MiSans",
fontFamily: FontFamily.miSans,
),
];
return Column( return Column(
children: [ children: [
ItemCard(
info: Info(
label: appLocalizations.fontFamily,
iconData: Icons.text_fields,
),
child: Container(
margin: const EdgeInsets.only(
left: 16,
right: 16,
),
height: 48,
child: Selector<Config, FontFamily>(
selector: (_, config) => config.themeProps.fontFamily,
builder: (_, fontFamily, __) {
return ListView.separated(
scrollDirection: Axis.horizontal,
itemBuilder: (_, index) {
final fontFamilyItem = fontFamilyItems[index];
return _fontFamilyCheckBox(
isSelected: fontFamily == fontFamilyItem.fontFamily,
fontFamilyItem: fontFamilyItem,
);
},
separatorBuilder: (_, __) {
return const SizedBox(
width: 16,
);
},
itemCount: fontFamilyItems.length,
);
},
),
),
),
ItemCard( ItemCard(
info: Info( info: Info(
label: appLocalizations.themeMode, label: appLocalizations.themeMode,
iconData: Icons.brightness_high, iconData: Icons.brightness_high,
), ),
child: Selector<Config, ThemeMode>( child: Selector<Config, ThemeMode>(
selector: (_, config) => config.themeMode, selector: (_, config) => config.themeProps.themeMode,
builder: (_, themeMode, __) { builder: (_, themeMode, __) {
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
@@ -204,7 +297,7 @@ class _ThemeColorsBoxState extends State<ThemeColorsBox> {
), ),
height: 88, height: 88,
child: Selector<Config, int?>( child: Selector<Config, int?>(
selector: (_, config) => config.primaryColor, selector: (_, config) => config.themeProps.primaryColor,
builder: (_, currentPrimaryColor, __) { builder: (_, currentPrimaryColor, __) {
return ListView.separated( return ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
@@ -229,7 +322,7 @@ class _ThemeColorsBoxState extends State<ThemeColorsBox> {
Padding( Padding(
padding: const EdgeInsets.symmetric(vertical: 16), padding: const EdgeInsets.symmetric(vertical: 16),
child: Selector<Config, bool>( child: Selector<Config, bool>(
selector: (_, config) => config.prueBlack, selector: (_, config) => config.themeProps.prueBlack,
builder: (_, value, ___) { builder: (_, value, ___) {
return ListItem.switchItem( return ListItem.switchItem(
leading: Icon( leading: Icon(
@@ -238,63 +331,19 @@ class _ThemeColorsBoxState extends State<ThemeColorsBox> {
), ),
title: Text(appLocalizations.prueBlackMode), title: Text(appLocalizations.prueBlackMode),
delegate: SwitchDelegate( delegate: SwitchDelegate(
value: value, value: value,
onChanged: (value) { onChanged: (value) {
globalState.appController.config.prueBlack = value; final appController = globalState.appController;
}), appController.config.themeProps =
appController.config.themeProps.copyWith(
prueBlack: value,
);
},
),
); );
}, },
), ),
), ),
// Padding(
// padding: const EdgeInsets.symmetric(vertical: 16),
// child: Selector<Config, bool>(
// selector: (_, config) => config.scaleProps.custom,
// builder: (_, value, ___) {
// return ListItem.switchItem(
// leading: Icon(
// Icons.format_size_sharp,
// color: context.colorScheme.primary,
// ),
// title: const Text("自定义字体大小"),
// delegate: SwitchDelegate(
// value: value,
// onChanged: (value) {
// globalState.appController.config.scaleProps =
// globalState.appController.config.scaleProps.copyWith(
// custom: value,
// );
// },
// ),
// );
// },
// ),
// ),
// SizedBox(
// height: 20,
// child: Selector<Config, ScaleProps>(
// selector: (_, config) => config.scaleProps,
// builder: (_, props, ___) {
// return AbsorbPointer(
// absorbing: !props.custom,
// child: DisabledMask(
// status: !props.custom,
// child: Slider(
// value: props.scale,
// min: 0.8,
// max: 1.2,
// onChanged: (value) {
// globalState.appController.config.scaleProps =
// globalState.appController.config.scaleProps.copyWith(
// scale: value,
// );
// },
// ),
// ),
// );
// },
// ),
// ),
const SizedBox( const SizedBox(
height: 64, height: 64,
), ),

View File

@@ -320,5 +320,7 @@
"iconConfiguration": "Icon configuration", "iconConfiguration": "Icon configuration",
"noData": "No data", "noData": "No data",
"adminAutoLaunch": "Admin auto launch", "adminAutoLaunch": "Admin auto launch",
"adminAutoLaunchDesc": "Boot up by using admin mode" "adminAutoLaunchDesc": "Boot up by using admin mode",
"fontFamily": "FontFamily",
"systemFont": "System font"
} }

View File

@@ -320,5 +320,7 @@
"iconConfiguration": "图片配置", "iconConfiguration": "图片配置",
"noData": "暂无数据", "noData": "暂无数据",
"adminAutoLaunch": "管理员自启动", "adminAutoLaunch": "管理员自启动",
"adminAutoLaunchDesc": "使用管理员模式开机自启动" "adminAutoLaunchDesc": "使用管理员模式开机自启动",
"fontFamily": "字体",
"systemFont": "系统字体"
} }

View File

@@ -192,6 +192,7 @@ class MessageLookup extends MessageLookupByLibrary {
"findProcessMode": MessageLookupByLibrary.simpleMessage("Find process"), "findProcessMode": MessageLookupByLibrary.simpleMessage("Find process"),
"findProcessModeDesc": MessageLookupByLibrary.simpleMessage( "findProcessModeDesc": MessageLookupByLibrary.simpleMessage(
"There is a risk of flashback after opening"), "There is a risk of flashback after opening"),
"fontFamily": MessageLookupByLibrary.simpleMessage("FontFamily"),
"fourColumns": MessageLookupByLibrary.simpleMessage("Four columns"), "fourColumns": MessageLookupByLibrary.simpleMessage("Four columns"),
"general": MessageLookupByLibrary.simpleMessage("General"), "general": MessageLookupByLibrary.simpleMessage("General"),
"generalDesc": "generalDesc":
@@ -425,6 +426,7 @@ class MessageLookup extends MessageLookupByLibrary {
"style": MessageLookupByLibrary.simpleMessage("Style"), "style": MessageLookupByLibrary.simpleMessage("Style"),
"submit": MessageLookupByLibrary.simpleMessage("Submit"), "submit": MessageLookupByLibrary.simpleMessage("Submit"),
"sync": MessageLookupByLibrary.simpleMessage("Sync"), "sync": MessageLookupByLibrary.simpleMessage("Sync"),
"systemFont": MessageLookupByLibrary.simpleMessage("System font"),
"systemProxy": MessageLookupByLibrary.simpleMessage("System proxy"), "systemProxy": MessageLookupByLibrary.simpleMessage("System proxy"),
"systemProxyDesc": MessageLookupByLibrary.simpleMessage( "systemProxyDesc": MessageLookupByLibrary.simpleMessage(
"Attach HTTP proxy to VpnService"), "Attach HTTP proxy to VpnService"),

View File

@@ -155,6 +155,7 @@ class MessageLookup extends MessageLookupByLibrary {
"findProcessMode": MessageLookupByLibrary.simpleMessage("查找进程"), "findProcessMode": MessageLookupByLibrary.simpleMessage("查找进程"),
"findProcessModeDesc": "findProcessModeDesc":
MessageLookupByLibrary.simpleMessage("开启后存在闪退风险"), MessageLookupByLibrary.simpleMessage("开启后存在闪退风险"),
"fontFamily": MessageLookupByLibrary.simpleMessage("字体"),
"fourColumns": MessageLookupByLibrary.simpleMessage("四列"), "fourColumns": MessageLookupByLibrary.simpleMessage("四列"),
"general": MessageLookupByLibrary.simpleMessage("基础"), "general": MessageLookupByLibrary.simpleMessage("基础"),
"generalDesc": MessageLookupByLibrary.simpleMessage("覆写基础设置"), "generalDesc": MessageLookupByLibrary.simpleMessage("覆写基础设置"),
@@ -339,6 +340,7 @@ class MessageLookup extends MessageLookupByLibrary {
"style": MessageLookupByLibrary.simpleMessage("风格"), "style": MessageLookupByLibrary.simpleMessage("风格"),
"submit": MessageLookupByLibrary.simpleMessage("提交"), "submit": MessageLookupByLibrary.simpleMessage("提交"),
"sync": MessageLookupByLibrary.simpleMessage("同步"), "sync": MessageLookupByLibrary.simpleMessage("同步"),
"systemFont": MessageLookupByLibrary.simpleMessage("系统字体"),
"systemProxy": MessageLookupByLibrary.simpleMessage("系统代理"), "systemProxy": MessageLookupByLibrary.simpleMessage("系统代理"),
"systemProxyDesc": "systemProxyDesc":
MessageLookupByLibrary.simpleMessage("为VpnService附加HTTP代理"), MessageLookupByLibrary.simpleMessage("为VpnService附加HTTP代理"),

View File

@@ -3269,6 +3269,26 @@ class AppLocalizations {
args: [], args: [],
); );
} }
/// `FontFamily`
String get fontFamily {
return Intl.message(
'FontFamily',
name: 'fontFamily',
desc: '',
args: [],
);
}
/// `System font`
String get systemFont {
return Intl.message(
'System font',
name: 'systemFont',
desc: '',
args: [],
);
}
} }
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> { class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> {

View File

@@ -141,6 +141,35 @@ class ProxiesStyle with _$ProxiesStyle {
json == null ? defaultProxiesStyle : _$ProxiesStyleFromJson(json); json == null ? defaultProxiesStyle : _$ProxiesStyleFromJson(json);
} }
const defaultThemeProps = ThemeProps();
@freezed
class ThemeProps with _$ThemeProps {
const factory ThemeProps({
@Default(0xFF795548) int? primaryColor,
@Default(ThemeMode.system) ThemeMode themeMode,
@Default(false) bool prueBlack,
@Default(FontFamily.system) FontFamily fontFamily,
}) = _ThemeProps;
factory ThemeProps.fromJson(Map<String, Object?> json) => _$ThemePropsFromJson(json);
factory ThemeProps.realFromJson(Map<String, Object?>? json) {
if (json == null) {
return Platform.isWindows
? defaultThemeProps.copyWith(fontFamily: FontFamily.miSans)
: defaultThemeProps;
}
try {
return ThemeProps.fromJson(json);
} catch (_) {
return Platform.isWindows
? defaultThemeProps.copyWith(fontFamily: FontFamily.miSans)
: defaultThemeProps;
}
}
}
const defaultCustomFontSizeScale = 1.0; const defaultCustomFontSizeScale = 1.0;
@JsonSerializable() @JsonSerializable()
@@ -148,13 +177,11 @@ class Config extends ChangeNotifier {
AppSetting _appSetting; AppSetting _appSetting;
List<Profile> _profiles; List<Profile> _profiles;
String? _currentProfileId; String? _currentProfileId;
ThemeMode _themeMode;
int? _primaryColor;
bool _isAccessControl; bool _isAccessControl;
AccessControl _accessControl; AccessControl _accessControl;
DAV? _dav; DAV? _dav;
WindowProps _windowProps; WindowProps _windowProps;
bool _prueBlack; ThemeProps _themeProps;
VpnProps _vpnProps; VpnProps _vpnProps;
DesktopProps _desktopProps; DesktopProps _desktopProps;
bool _overrideDns; bool _overrideDns;
@@ -163,18 +190,16 @@ class Config extends ChangeNotifier {
Config() Config()
: _profiles = [], : _profiles = [],
_themeMode = ThemeMode.system,
_primaryColor = defaultPrimaryColor.value,
_isAccessControl = false, _isAccessControl = false,
_accessControl = const AccessControl(), _accessControl = const AccessControl(),
_windowProps = const WindowProps(), _windowProps = const WindowProps(),
_prueBlack = false,
_vpnProps = defaultVpnProps, _vpnProps = defaultVpnProps,
_desktopProps = const DesktopProps(), _desktopProps = const DesktopProps(),
_overrideDns = false, _overrideDns = false,
_appSetting = defaultAppSetting, _appSetting = defaultAppSetting,
_hotKeyActions = [], _hotKeyActions = [],
_proxiesStyle = defaultProxiesStyle; _proxiesStyle = defaultProxiesStyle,
_themeProps = defaultThemeProps;
@JsonKey(fromJson: AppSetting.realFromJson) @JsonKey(fromJson: AppSetting.realFromJson)
AppSetting get appSetting => _appSetting; AppSetting get appSetting => _appSetting;
@@ -305,25 +330,6 @@ class Config extends ChangeNotifier {
} }
} }
@JsonKey(defaultValue: ThemeMode.system)
ThemeMode get themeMode => _themeMode;
set themeMode(ThemeMode value) {
if (_themeMode != value) {
_themeMode = value;
notifyListeners();
}
}
int? get primaryColor => _primaryColor;
set primaryColor(int? value) {
if (_primaryColor != value) {
_primaryColor = value;
notifyListeners();
}
}
@JsonKey(defaultValue: false) @JsonKey(defaultValue: false)
bool get isAccessControl { bool get isAccessControl {
if (!Platform.isAndroid) return false; if (!Platform.isAndroid) return false;
@@ -355,18 +361,6 @@ class Config extends ChangeNotifier {
} }
} }
@JsonKey(defaultValue: false)
bool get prueBlack {
return _prueBlack;
}
set prueBlack(bool value) {
if (_prueBlack != value) {
_prueBlack = value;
notifyListeners();
}
}
WindowProps get windowProps => _windowProps; WindowProps get windowProps => _windowProps;
set windowProps(WindowProps value) { set windowProps(WindowProps value) {
@@ -427,6 +421,16 @@ class Config extends ChangeNotifier {
} }
} }
@JsonKey(fromJson: ThemeProps.realFromJson)
ThemeProps get themeProps => _themeProps;
set themeProps(ThemeProps value) {
if (_themeProps != value) {
_themeProps = value;
notifyListeners();
}
}
updateOrAddHotKeyAction(HotKeyAction hotKeyAction) { updateOrAddHotKeyAction(HotKeyAction hotKeyAction) {
final index = final index =
_hotKeyActions.indexWhere((item) => item.action == hotKeyAction.action); _hotKeyActions.indexWhere((item) => item.action == hotKeyAction.action);
@@ -455,11 +459,9 @@ class Config extends ChangeNotifier {
_appSetting = config._appSetting; _appSetting = config._appSetting;
_currentProfileId = config._currentProfileId; _currentProfileId = config._currentProfileId;
_dav = config._dav; _dav = config._dav;
_themeMode = config._themeMode;
_primaryColor = config._primaryColor;
_isAccessControl = config._isAccessControl; _isAccessControl = config._isAccessControl;
_accessControl = config._accessControl; _accessControl = config._accessControl;
_prueBlack = config._prueBlack; _themeProps = config._themeProps;
_windowProps = config._windowProps; _windowProps = config._windowProps;
_proxiesStyle = config._proxiesStyle; _proxiesStyle = config._proxiesStyle;
_vpnProps = config._vpnProps; _vpnProps = config._vpnProps;

View File

@@ -1541,3 +1541,212 @@ abstract class _ProxiesStyle implements ProxiesStyle {
_$$ProxiesStyleImplCopyWith<_$ProxiesStyleImpl> get copyWith => _$$ProxiesStyleImplCopyWith<_$ProxiesStyleImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
ThemeProps _$ThemePropsFromJson(Map<String, dynamic> json) {
return _ThemeProps.fromJson(json);
}
/// @nodoc
mixin _$ThemeProps {
int? get primaryColor => throw _privateConstructorUsedError;
ThemeMode get themeMode => throw _privateConstructorUsedError;
bool get prueBlack => throw _privateConstructorUsedError;
FontFamily get fontFamily => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$ThemePropsCopyWith<ThemeProps> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ThemePropsCopyWith<$Res> {
factory $ThemePropsCopyWith(
ThemeProps value, $Res Function(ThemeProps) then) =
_$ThemePropsCopyWithImpl<$Res, ThemeProps>;
@useResult
$Res call(
{int? primaryColor,
ThemeMode themeMode,
bool prueBlack,
FontFamily fontFamily});
}
/// @nodoc
class _$ThemePropsCopyWithImpl<$Res, $Val extends ThemeProps>
implements $ThemePropsCopyWith<$Res> {
_$ThemePropsCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
@pragma('vm:prefer-inline')
@override
$Res call({
Object? primaryColor = freezed,
Object? themeMode = null,
Object? prueBlack = null,
Object? fontFamily = null,
}) {
return _then(_value.copyWith(
primaryColor: freezed == primaryColor
? _value.primaryColor
: primaryColor // ignore: cast_nullable_to_non_nullable
as int?,
themeMode: null == themeMode
? _value.themeMode
: themeMode // ignore: cast_nullable_to_non_nullable
as ThemeMode,
prueBlack: null == prueBlack
? _value.prueBlack
: prueBlack // ignore: cast_nullable_to_non_nullable
as bool,
fontFamily: null == fontFamily
? _value.fontFamily
: fontFamily // ignore: cast_nullable_to_non_nullable
as FontFamily,
) as $Val);
}
}
/// @nodoc
abstract class _$$ThemePropsImplCopyWith<$Res>
implements $ThemePropsCopyWith<$Res> {
factory _$$ThemePropsImplCopyWith(
_$ThemePropsImpl value, $Res Function(_$ThemePropsImpl) then) =
__$$ThemePropsImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{int? primaryColor,
ThemeMode themeMode,
bool prueBlack,
FontFamily fontFamily});
}
/// @nodoc
class __$$ThemePropsImplCopyWithImpl<$Res>
extends _$ThemePropsCopyWithImpl<$Res, _$ThemePropsImpl>
implements _$$ThemePropsImplCopyWith<$Res> {
__$$ThemePropsImplCopyWithImpl(
_$ThemePropsImpl _value, $Res Function(_$ThemePropsImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? primaryColor = freezed,
Object? themeMode = null,
Object? prueBlack = null,
Object? fontFamily = null,
}) {
return _then(_$ThemePropsImpl(
primaryColor: freezed == primaryColor
? _value.primaryColor
: primaryColor // ignore: cast_nullable_to_non_nullable
as int?,
themeMode: null == themeMode
? _value.themeMode
: themeMode // ignore: cast_nullable_to_non_nullable
as ThemeMode,
prueBlack: null == prueBlack
? _value.prueBlack
: prueBlack // ignore: cast_nullable_to_non_nullable
as bool,
fontFamily: null == fontFamily
? _value.fontFamily
: fontFamily // ignore: cast_nullable_to_non_nullable
as FontFamily,
));
}
}
/// @nodoc
@JsonSerializable()
class _$ThemePropsImpl implements _ThemeProps {
const _$ThemePropsImpl(
{this.primaryColor = 0xFF795548,
this.themeMode = ThemeMode.system,
this.prueBlack = false,
this.fontFamily = FontFamily.system});
factory _$ThemePropsImpl.fromJson(Map<String, dynamic> json) =>
_$$ThemePropsImplFromJson(json);
@override
@JsonKey()
final int? primaryColor;
@override
@JsonKey()
final ThemeMode themeMode;
@override
@JsonKey()
final bool prueBlack;
@override
@JsonKey()
final FontFamily fontFamily;
@override
String toString() {
return 'ThemeProps(primaryColor: $primaryColor, themeMode: $themeMode, prueBlack: $prueBlack, fontFamily: $fontFamily)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ThemePropsImpl &&
(identical(other.primaryColor, primaryColor) ||
other.primaryColor == primaryColor) &&
(identical(other.themeMode, themeMode) ||
other.themeMode == themeMode) &&
(identical(other.prueBlack, prueBlack) ||
other.prueBlack == prueBlack) &&
(identical(other.fontFamily, fontFamily) ||
other.fontFamily == fontFamily));
}
@JsonKey(ignore: true)
@override
int get hashCode =>
Object.hash(runtimeType, primaryColor, themeMode, prueBlack, fontFamily);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$ThemePropsImplCopyWith<_$ThemePropsImpl> get copyWith =>
__$$ThemePropsImplCopyWithImpl<_$ThemePropsImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$ThemePropsImplToJson(
this,
);
}
}
abstract class _ThemeProps implements ThemeProps {
const factory _ThemeProps(
{final int? primaryColor,
final ThemeMode themeMode,
final bool prueBlack,
final FontFamily fontFamily}) = _$ThemePropsImpl;
factory _ThemeProps.fromJson(Map<String, dynamic> json) =
_$ThemePropsImpl.fromJson;
@override
int? get primaryColor;
@override
ThemeMode get themeMode;
@override
bool get prueBlack;
@override
FontFamily get fontFamily;
@override
@JsonKey(ignore: true)
_$$ThemePropsImplCopyWith<_$ThemePropsImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -14,16 +14,12 @@ Config _$ConfigFromJson(Map<String, dynamic> json) => Config()
.toList() ?? .toList() ??
[] []
..currentProfileId = json['currentProfileId'] as String? ..currentProfileId = json['currentProfileId'] as String?
..themeMode = $enumDecodeNullable(_$ThemeModeEnumMap, json['themeMode']) ??
ThemeMode.system
..primaryColor = (json['primaryColor'] as num?)?.toInt()
..isAccessControl = json['isAccessControl'] as bool? ?? false ..isAccessControl = json['isAccessControl'] as bool? ?? false
..accessControl = ..accessControl =
AccessControl.fromJson(json['accessControl'] as Map<String, dynamic>) AccessControl.fromJson(json['accessControl'] as Map<String, dynamic>)
..dav = json['dav'] == null ..dav = json['dav'] == null
? null ? null
: DAV.fromJson(json['dav'] as Map<String, dynamic>) : DAV.fromJson(json['dav'] as Map<String, dynamic>)
..prueBlack = json['prueBlack'] as bool? ?? false
..windowProps = ..windowProps =
WindowProps.fromJson(json['windowProps'] as Map<String, dynamic>?) WindowProps.fromJson(json['windowProps'] as Map<String, dynamic>?)
..vpnProps = VpnProps.fromJson(json['vpnProps'] as Map<String, dynamic>?) ..vpnProps = VpnProps.fromJson(json['vpnProps'] as Map<String, dynamic>?)
@@ -35,32 +31,26 @@ Config _$ConfigFromJson(Map<String, dynamic> json) => Config()
.toList() ?? .toList() ??
[] []
..proxiesStyle = ..proxiesStyle =
ProxiesStyle.fromJson(json['proxiesStyle'] as Map<String, dynamic>?); ProxiesStyle.fromJson(json['proxiesStyle'] as Map<String, dynamic>?)
..themeProps =
ThemeProps.realFromJson(json['themeProps'] as Map<String, Object?>?);
Map<String, dynamic> _$ConfigToJson(Config instance) => <String, dynamic>{ Map<String, dynamic> _$ConfigToJson(Config instance) => <String, dynamic>{
'appSetting': instance.appSetting, 'appSetting': instance.appSetting,
'profiles': instance.profiles, 'profiles': instance.profiles,
'currentProfileId': instance.currentProfileId, 'currentProfileId': instance.currentProfileId,
'themeMode': _$ThemeModeEnumMap[instance.themeMode]!,
'primaryColor': instance.primaryColor,
'isAccessControl': instance.isAccessControl, 'isAccessControl': instance.isAccessControl,
'accessControl': instance.accessControl, 'accessControl': instance.accessControl,
'dav': instance.dav, 'dav': instance.dav,
'prueBlack': instance.prueBlack,
'windowProps': instance.windowProps, 'windowProps': instance.windowProps,
'vpnProps': instance.vpnProps, 'vpnProps': instance.vpnProps,
'desktopProps': instance.desktopProps, 'desktopProps': instance.desktopProps,
'overrideDns': instance.overrideDns, 'overrideDns': instance.overrideDns,
'hotKeyActions': instance.hotKeyActions, 'hotKeyActions': instance.hotKeyActions,
'proxiesStyle': instance.proxiesStyle, 'proxiesStyle': instance.proxiesStyle,
'themeProps': instance.themeProps,
}; };
const _$ThemeModeEnumMap = {
ThemeMode.system: 'system',
ThemeMode.light: 'light',
ThemeMode.dark: 'dark',
};
_$AppSettingImpl _$$AppSettingImplFromJson(Map<String, dynamic> json) => _$AppSettingImpl _$$AppSettingImplFromJson(Map<String, dynamic> json) =>
_$AppSettingImpl( _$AppSettingImpl(
locale: json['locale'] as String?, locale: json['locale'] as String?,
@@ -241,3 +231,35 @@ const _$ProxyCardTypeEnumMap = {
ProxyCardType.shrink: 'shrink', ProxyCardType.shrink: 'shrink',
ProxyCardType.min: 'min', ProxyCardType.min: 'min',
}; };
_$ThemePropsImpl _$$ThemePropsImplFromJson(Map<String, dynamic> json) =>
_$ThemePropsImpl(
primaryColor: (json['primaryColor'] as num?)?.toInt() ?? 0xFF795548,
themeMode: $enumDecodeNullable(_$ThemeModeEnumMap, json['themeMode']) ??
ThemeMode.system,
prueBlack: json['prueBlack'] as bool? ?? false,
fontFamily:
$enumDecodeNullable(_$FontFamilyEnumMap, json['fontFamily']) ??
FontFamily.system,
);
Map<String, dynamic> _$$ThemePropsImplToJson(_$ThemePropsImpl instance) =>
<String, dynamic>{
'primaryColor': instance.primaryColor,
'themeMode': _$ThemeModeEnumMap[instance.themeMode]!,
'prueBlack': instance.prueBlack,
'fontFamily': _$FontFamilyEnumMap[instance.fontFamily]!,
};
const _$ThemeModeEnumMap = {
ThemeMode.system: 'system',
ThemeMode.light: 'light',
ThemeMode.dark: 'dark',
};
const _$FontFamilyEnumMap = {
FontFamily.system: 'system',
FontFamily.miSans: 'miSans',
FontFamily.twEmoji: 'twEmoji',
FontFamily.icon: 'icon',
};

View File

@@ -772,6 +772,7 @@ mixin _$ApplicationSelectorState {
ThemeMode? get themeMode => throw _privateConstructorUsedError; ThemeMode? get themeMode => throw _privateConstructorUsedError;
int? get primaryColor => throw _privateConstructorUsedError; int? get primaryColor => throw _privateConstructorUsedError;
bool get prueBlack => throw _privateConstructorUsedError; bool get prueBlack => throw _privateConstructorUsedError;
FontFamily get fontFamily => throw _privateConstructorUsedError;
@JsonKey(ignore: true) @JsonKey(ignore: true)
$ApplicationSelectorStateCopyWith<ApplicationSelectorState> get copyWith => $ApplicationSelectorStateCopyWith<ApplicationSelectorState> get copyWith =>
@@ -788,7 +789,8 @@ abstract class $ApplicationSelectorStateCopyWith<$Res> {
{String? locale, {String? locale,
ThemeMode? themeMode, ThemeMode? themeMode,
int? primaryColor, int? primaryColor,
bool prueBlack}); bool prueBlack,
FontFamily fontFamily});
} }
/// @nodoc /// @nodoc
@@ -809,6 +811,7 @@ class _$ApplicationSelectorStateCopyWithImpl<$Res,
Object? themeMode = freezed, Object? themeMode = freezed,
Object? primaryColor = freezed, Object? primaryColor = freezed,
Object? prueBlack = null, Object? prueBlack = null,
Object? fontFamily = null,
}) { }) {
return _then(_value.copyWith( return _then(_value.copyWith(
locale: freezed == locale locale: freezed == locale
@@ -827,6 +830,10 @@ class _$ApplicationSelectorStateCopyWithImpl<$Res,
? _value.prueBlack ? _value.prueBlack
: prueBlack // ignore: cast_nullable_to_non_nullable : prueBlack // ignore: cast_nullable_to_non_nullable
as bool, as bool,
fontFamily: null == fontFamily
? _value.fontFamily
: fontFamily // ignore: cast_nullable_to_non_nullable
as FontFamily,
) as $Val); ) as $Val);
} }
} }
@@ -844,7 +851,8 @@ abstract class _$$ApplicationSelectorStateImplCopyWith<$Res>
{String? locale, {String? locale,
ThemeMode? themeMode, ThemeMode? themeMode,
int? primaryColor, int? primaryColor,
bool prueBlack}); bool prueBlack,
FontFamily fontFamily});
} }
/// @nodoc /// @nodoc
@@ -864,6 +872,7 @@ class __$$ApplicationSelectorStateImplCopyWithImpl<$Res>
Object? themeMode = freezed, Object? themeMode = freezed,
Object? primaryColor = freezed, Object? primaryColor = freezed,
Object? prueBlack = null, Object? prueBlack = null,
Object? fontFamily = null,
}) { }) {
return _then(_$ApplicationSelectorStateImpl( return _then(_$ApplicationSelectorStateImpl(
locale: freezed == locale locale: freezed == locale
@@ -882,6 +891,10 @@ class __$$ApplicationSelectorStateImplCopyWithImpl<$Res>
? _value.prueBlack ? _value.prueBlack
: prueBlack // ignore: cast_nullable_to_non_nullable : prueBlack // ignore: cast_nullable_to_non_nullable
as bool, as bool,
fontFamily: null == fontFamily
? _value.fontFamily
: fontFamily // ignore: cast_nullable_to_non_nullable
as FontFamily,
)); ));
} }
} }
@@ -893,7 +906,8 @@ class _$ApplicationSelectorStateImpl implements _ApplicationSelectorState {
{required this.locale, {required this.locale,
required this.themeMode, required this.themeMode,
required this.primaryColor, required this.primaryColor,
required this.prueBlack}); required this.prueBlack,
required this.fontFamily});
@override @override
final String? locale; final String? locale;
@@ -903,10 +917,12 @@ class _$ApplicationSelectorStateImpl implements _ApplicationSelectorState {
final int? primaryColor; final int? primaryColor;
@override @override
final bool prueBlack; final bool prueBlack;
@override
final FontFamily fontFamily;
@override @override
String toString() { String toString() {
return 'ApplicationSelectorState(locale: $locale, themeMode: $themeMode, primaryColor: $primaryColor, prueBlack: $prueBlack)'; return 'ApplicationSelectorState(locale: $locale, themeMode: $themeMode, primaryColor: $primaryColor, prueBlack: $prueBlack, fontFamily: $fontFamily)';
} }
@override @override
@@ -920,12 +936,14 @@ class _$ApplicationSelectorStateImpl implements _ApplicationSelectorState {
(identical(other.primaryColor, primaryColor) || (identical(other.primaryColor, primaryColor) ||
other.primaryColor == primaryColor) && other.primaryColor == primaryColor) &&
(identical(other.prueBlack, prueBlack) || (identical(other.prueBlack, prueBlack) ||
other.prueBlack == prueBlack)); other.prueBlack == prueBlack) &&
(identical(other.fontFamily, fontFamily) ||
other.fontFamily == fontFamily));
} }
@override @override
int get hashCode => int get hashCode => Object.hash(
Object.hash(runtimeType, locale, themeMode, primaryColor, prueBlack); runtimeType, locale, themeMode, primaryColor, prueBlack, fontFamily);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@@ -940,7 +958,8 @@ abstract class _ApplicationSelectorState implements ApplicationSelectorState {
{required final String? locale, {required final String? locale,
required final ThemeMode? themeMode, required final ThemeMode? themeMode,
required final int? primaryColor, required final int? primaryColor,
required final bool prueBlack}) = _$ApplicationSelectorStateImpl; required final bool prueBlack,
required final FontFamily fontFamily}) = _$ApplicationSelectorStateImpl;
@override @override
String? get locale; String? get locale;
@@ -951,6 +970,8 @@ abstract class _ApplicationSelectorState implements ApplicationSelectorState {
@override @override
bool get prueBlack; bool get prueBlack;
@override @override
FontFamily get fontFamily;
@override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$ApplicationSelectorStateImplCopyWith<_$ApplicationSelectorStateImpl> _$$ApplicationSelectorStateImplCopyWith<_$ApplicationSelectorStateImpl>
get copyWith => throw _privateConstructorUsedError; get copyWith => throw _privateConstructorUsedError;

View File

@@ -55,6 +55,7 @@ class ApplicationSelectorState with _$ApplicationSelectorState {
required ThemeMode? themeMode, required ThemeMode? themeMode,
required int? primaryColor, required int? primaryColor,
required bool prueBlack, required bool prueBlack,
required FontFamily fontFamily,
}) = _ApplicationSelectorState; }) = _ApplicationSelectorState;
} }

View File

@@ -427,7 +427,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
Animation<double> secondaryAnimation, Animation<double> secondaryAnimation,
) { ) {
return Selector<Config, ThemeMode>( return Selector<Config, ThemeMode>(
selector: (_, config) => config.themeMode, selector: (_, config) => config.themeProps.themeMode,
builder: (_, __, ___) { builder: (_, __, ___) {
_colorTween = _getColorTween( _colorTween = _getColorTween(
transitionType: transitionType, transitionType: transitionType,

View File

@@ -1,4 +1,4 @@
import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/enum/enum.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:emoji_regex/emoji_regex.dart'; import 'package:emoji_regex/emoji_regex.dart';
@@ -63,7 +63,7 @@ class EmojiText extends StatelessWidget {
TextSpan( TextSpan(
text:match.group(0), text:match.group(0),
style: style?.copyWith( style: style?.copyWith(
fontFamily: Fonts.twEmoji, fontFamily: FontFamily.twEmoji.value,
), ),
), ),
); );

View File

@@ -1,7 +1,7 @@
name: fl_clash name: fl_clash
description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free. description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free.
publish_to: 'none' publish_to: 'none'
version: 0.8.65+202410261 version: 0.8.66+202410262
environment: environment:
sdk: '>=3.1.0 <4.0.0' sdk: '>=3.1.0 <4.0.0'
@@ -72,6 +72,9 @@ flutter:
- family: Twemoji - family: Twemoji
fonts: fonts:
- asset: assets/fonts/Twemoji.Mozilla.ttf - asset: assets/fonts/Twemoji.Mozilla.ttf
- family: MiSans
fonts:
- asset: assets/fonts/MiSans-Regular.ttf
- family: Icons - family: Icons
fonts: fonts:
- asset: assets/fonts/Icons.ttf - asset: assets/fonts/Icons.ttf