Compare commits

...

1 Commits

Author SHA1 Message Date
chen08209
196a50aaf7 Fix android tile service issues 2024-08-01 23:51:00 +08:00
18 changed files with 268 additions and 173 deletions

View File

@@ -142,6 +142,7 @@ class ApplicationState extends State<Application> {
locale: config.locale, locale: config.locale,
themeMode: config.themeMode, themeMode: config.themeMode,
primaryColor: config.primaryColor, primaryColor: config.primaryColor,
prueBlack: config.prueBlack,
), ),
builder: (_, state, child) { builder: (_, state, child) {
return DynamicColorBuilder( return DynamicColorBuilder(
@@ -180,7 +181,7 @@ class ApplicationState extends State<Application> {
brightness: Brightness.dark, brightness: Brightness.dark,
systemColorSchemes: systemColorSchemes, systemColorSchemes: systemColorSchemes,
primaryColor: state.primaryColor, primaryColor: state.primaryColor,
), ).toPrueBlack(state.prueBlack),
), ),
home: child, home: child,
); );

View File

@@ -16,4 +16,13 @@ extension ColorExtension on Color {
toLittle() { toLittle() {
return withOpacity(0.03); return withOpacity(0.03);
} }
} }
extension ColorSchemeExtension on ColorScheme {
ColorScheme toPrueBlack(bool isPrueBlack) => isPrueBlack
? copyWith(
surface: Colors.black,
background: Colors.black,
)
: this;
}

View File

@@ -89,8 +89,11 @@ class _EditProfileState extends State<EditProfile> {
}); });
} }
Future<FileInfo> _getFileInfo(path) async { Future<FileInfo?> _getFileInfo(path) async {
final file = File(path); final file = File(path);
if (!await file.exists()) {
return null;
}
final lastModified = await file.lastModified(); final lastModified = await file.lastModified();
final size = await file.length(); final size = await file.length();
return FileInfo( return FileInfo(
@@ -127,59 +130,6 @@ class _EditProfileState extends State<EditProfile> {
); );
} }
Widget _buildSubtitle() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 4,
),
ValueListenableBuilder<FileInfo?>(
valueListenable: fileInfoNotifier,
builder: (_, fileInfo, __) {
final height =
globalState.appController.measure.bodyMediumHeight + 4;
return SizedBox(
height: height,
child: FadeBox(
child: fileInfo == null
? SizedBox(
width: height,
height: height,
child: const CircularProgressIndicator(
strokeWidth: 2,
),
)
: Text(
fileInfo.desc,
),
),
);
},
),
const SizedBox(
height: 8,
),
Wrap(
runSpacing: 6,
spacing: 12,
children: [
CommonChip(
avatar: const Icon(Icons.edit),
label: appLocalizations.edit,
onPressed: _editProfileFile,
),
CommonChip(
avatar: const Icon(Icons.upload),
label: appLocalizations.upload,
onPressed: _uploadProfileFile,
),
],
),
],
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final items = [ final items = [
@@ -250,9 +200,49 @@ class _EditProfileState extends State<EditProfile> {
), ),
), ),
], ],
ListItem( ValueListenableBuilder<FileInfo?>(
title: Text(appLocalizations.profile), valueListenable: fileInfoNotifier,
subtitle: _buildSubtitle(), builder: (_, fileInfo, __) {
return FadeBox(
child: fileInfo == null
? Container()
: ListItem(
title: Text(
appLocalizations.profile,
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 4,
),
Text(
fileInfo.desc,
),
const SizedBox(
height: 8,
),
Wrap(
runSpacing: 6,
spacing: 12,
children: [
CommonChip(
avatar: const Icon(Icons.edit),
label: appLocalizations.edit,
onPressed: _editProfileFile,
),
CommonChip(
avatar: const Icon(Icons.upload),
label: appLocalizations.upload,
onPressed: _uploadProfileFile,
),
],
),
],
),
),
);
},
), ),
]; ];
return FloatLayout( return FloatLayout(

View File

@@ -189,7 +189,7 @@ class _ProfileItemState extends State<ProfileItem> {
), ),
onTab: () async { onTab: () async {
await globalState.appController.deleteProfile(widget.profile.id); await globalState.appController.deleteProfile(widget.profile.id);
if(mounted){ if (mounted) {
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
}, },
@@ -231,75 +231,90 @@ class _ProfileItemState extends State<ProfileItem> {
); );
} }
List<Widget> _buildUserInfo(UserInfo userInfo) {
final use = userInfo.upload + userInfo.download;
final total = userInfo.total;
if(total == 0){
return [];
}
final useShow = TrafficValue(value: use).show;
final totalShow = TrafficValue(value: total).show;
final progress = total == 0 ? 0.0 : use / total;
final expireShow = userInfo.expire == 0
? appLocalizations.infiniteTime
: DateTime.fromMillisecondsSinceEpoch(userInfo.expire * 1000).show;
return [
LinearProgressIndicator(
minHeight: 6,
value: progress,
),
const SizedBox(
height: 8,
),
Text(
"$useShow / $totalShow · $expireShow",
style: context.textTheme.labelMedium?.toLight,
),
const SizedBox(
height: 4,
),
];
}
List<Widget> _buildUrlProfileInfo(Profile profile) {
final userInfo = profile.userInfo;
return [
const SizedBox(
height: 8,
),
if (userInfo != null) ..._buildUserInfo(userInfo),
Text(
profile.lastUpdateDate?.lastUpdateTimeDesc ?? "",
style: context.textTheme.labelMedium?.toLight,
),
];
}
List<Widget> _buildFileProfileInfo(Profile profile) {
return [
const SizedBox(
height: 8,
),
Text(
profile.lastUpdateDate?.lastUpdateTimeDesc ?? "",
style: context.textTheme.labelMedium?.toLight,
),
];
}
_buildTitle(Profile profile) { _buildTitle(Profile profile) {
final textTheme = context.textTheme;
return Container( return Container(
padding: const EdgeInsets.symmetric(vertical: 4), padding: const EdgeInsets.symmetric(vertical: 4),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Row( Text(
mainAxisSize: MainAxisSize.max, profile.label ?? profile.id,
mainAxisAlignment: MainAxisAlignment.spaceBetween, style: context.textTheme.titleMedium,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Flexible( ...switch (profile.type) {
child: Text( ProfileType.file => _buildFileProfileInfo(
profile.label ?? profile.id, profile,
style: textTheme.titleMedium, ),
maxLines: 1, ProfileType.url => _buildUrlProfileInfo(
overflow: TextOverflow.ellipsis, profile,
), ),
), },
Text(
profile.lastUpdateDate?.lastUpdateTimeDesc ?? '',
style: textTheme.labelMedium?.toLight,
),
], ],
), ),
Builder(builder: (context) {
final userInfo = profile.userInfo ?? const UserInfo();
final use = userInfo.upload + userInfo.download;
final total = userInfo.total;
final useShow = TrafficValue(value: use).show;
final totalShow = TrafficValue(value: total).show;
final progress = total == 0 ? 0.0 : use / total;
final expireShow = userInfo.expire == 0
? appLocalizations.infiniteTime
: DateTime.fromMillisecondsSinceEpoch(userInfo.expire * 1000)
.show;
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.symmetric(
vertical: 8,
),
child: LinearProgressIndicator(
minHeight: 6,
value: progress,
),
),
Text(
"$useShow / $totalShow",
style: textTheme.labelMedium?.toLight,
),
const SizedBox(
height: 2,
),
Row(
children: [
Text(
expireShow,
style: textTheme.labelMedium?.toLight,
),
],
)
],
);
}),
], ],
), ),
); );

View File

@@ -26,9 +26,7 @@ class ThemeFragment extends StatelessWidget {
final previewCard = Padding( final previewCard = Padding(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: CommonCard( child: CommonCard(
onPressed: (){ onPressed: () {},
},
info: Info( info: Info(
label: appLocalizations.preview, label: appLocalizations.preview,
iconData: Icons.looks, iconData: Icons.looks,
@@ -87,7 +85,6 @@ class ThemeColorsBox extends StatefulWidget {
} }
class _ThemeColorsBoxState extends State<ThemeColorsBox> { class _ThemeColorsBoxState extends State<ThemeColorsBox> {
Widget _themeModeCheckBox({ Widget _themeModeCheckBox({
bool? isSelected, bool? isSelected,
required ThemeModeItem themeModeItem, required ThemeModeItem themeModeItem,
@@ -229,6 +226,27 @@ class _ThemeColorsBoxState extends State<ThemeColorsBox> {
), ),
), ),
), ),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Selector<Config, bool>(
selector: (_, config) => config.prueBlack,
builder: (_, value, ___) {
return ListItem.switchItem(
leading: Icon(
Icons.contrast,
color: context.colorScheme.primary,
),
title: Text(appLocalizations.prueBlackMode),
delegate: SwitchDelegate(
value: value,
onChanged: (value){
globalState.appController.config.prueBlack = value;
}
),
);
},
),
)
], ],
); );
} }

View File

@@ -219,5 +219,6 @@
"autoCloseConnectionsDesc": "Auto close connections after change node", "autoCloseConnectionsDesc": "Auto close connections after change node",
"onlyStatisticsProxy": "Only statistics proxy", "onlyStatisticsProxy": "Only statistics proxy",
"onlyStatisticsProxyDesc": "When turned on, only statistics proxy traffic", "onlyStatisticsProxyDesc": "When turned on, only statistics proxy traffic",
"deleteProfileTip": "Sure you want to delete the current profile?" "deleteProfileTip": "Sure you want to delete the current profile?",
"prueBlackMode": "Prue black mode"
} }

View File

@@ -219,5 +219,6 @@
"autoCloseConnectionsDesc": "切换节点后自动关闭连接", "autoCloseConnectionsDesc": "切换节点后自动关闭连接",
"onlyStatisticsProxy": "仅统计代理", "onlyStatisticsProxy": "仅统计代理",
"onlyStatisticsProxyDesc": "开启后,将只统计代理流量", "onlyStatisticsProxyDesc": "开启后,将只统计代理流量",
"deleteProfileTip": "确定要删除当前配置吗?" "deleteProfileTip": "确定要删除当前配置吗?",
"prueBlackMode": "纯黑模式"
} }

View File

@@ -257,6 +257,8 @@ class MessageLookup extends MessageLookupByLibrary {
"proxyPort": MessageLookupByLibrary.simpleMessage("ProxyPort"), "proxyPort": MessageLookupByLibrary.simpleMessage("ProxyPort"),
"proxyPortDesc": MessageLookupByLibrary.simpleMessage( "proxyPortDesc": MessageLookupByLibrary.simpleMessage(
"Set the Clash listening port"), "Set the Clash listening port"),
"prueBlackMode":
MessageLookupByLibrary.simpleMessage("Prue black mode"),
"qrcode": MessageLookupByLibrary.simpleMessage("QR code"), "qrcode": MessageLookupByLibrary.simpleMessage("QR code"),
"qrcodeDesc": MessageLookupByLibrary.simpleMessage( "qrcodeDesc": MessageLookupByLibrary.simpleMessage(
"Scan QR code to obtain profile"), "Scan QR code to obtain profile"),

View File

@@ -208,6 +208,7 @@ class MessageLookup extends MessageLookupByLibrary {
"proxyGroup": MessageLookupByLibrary.simpleMessage("代理组"), "proxyGroup": MessageLookupByLibrary.simpleMessage("代理组"),
"proxyPort": MessageLookupByLibrary.simpleMessage("代理端口"), "proxyPort": MessageLookupByLibrary.simpleMessage("代理端口"),
"proxyPortDesc": MessageLookupByLibrary.simpleMessage("设置Clash监听端口"), "proxyPortDesc": MessageLookupByLibrary.simpleMessage("设置Clash监听端口"),
"prueBlackMode": MessageLookupByLibrary.simpleMessage("纯黑模式"),
"qrcode": MessageLookupByLibrary.simpleMessage("二维码"), "qrcode": MessageLookupByLibrary.simpleMessage("二维码"),
"qrcodeDesc": MessageLookupByLibrary.simpleMessage("扫描二维码获取配置文件"), "qrcodeDesc": MessageLookupByLibrary.simpleMessage("扫描二维码获取配置文件"),
"recovery": MessageLookupByLibrary.simpleMessage("恢复"), "recovery": MessageLookupByLibrary.simpleMessage("恢复"),

View File

@@ -2259,6 +2259,16 @@ class AppLocalizations {
args: [], args: [],
); );
} }
/// `Prue black mode`
String get prueBlackMode {
return Intl.message(
'Prue black mode',
name: 'prueBlackMode',
desc: '',
args: [],
);
}
} }
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> { class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> {

View File

@@ -82,6 +82,7 @@ class Config extends ChangeNotifier {
String _testUrl; String _testUrl;
WindowProps _windowProps; WindowProps _windowProps;
bool _onlyProxy; bool _onlyProxy;
bool _prueBlack;
Config() Config()
: _profiles = [], : _profiles = [],
@@ -107,6 +108,7 @@ class Config extends ChangeNotifier {
_windowProps = defaultWindowProps, _windowProps = defaultWindowProps,
_proxiesType = ProxiesType.tab, _proxiesType = ProxiesType.tab,
_proxiesColumns = 2, _proxiesColumns = 2,
_prueBlack = false,
_onlyProxy = false; _onlyProxy = false;
deleteProfileById(String id) { deleteProfileById(String id) {
@@ -423,6 +425,17 @@ class Config extends ChangeNotifier {
} }
} }
@JsonKey(defaultValue: false)
bool get prueBlack {
return _prueBlack;
}
set prueBlack(bool value) {
if (_prueBlack != value) {
_prueBlack = value;
notifyListeners();
}
}
@JsonKey(defaultValue: false) @JsonKey(defaultValue: false)
bool get isCloseConnections { bool get isCloseConnections {
@@ -530,6 +543,7 @@ class Config extends ChangeNotifier {
_accessControl = config._accessControl; _accessControl = config._accessControl;
_isAnimateToPage = config._isAnimateToPage; _isAnimateToPage = config._isAnimateToPage;
_autoCheckUpdate = config._autoCheckUpdate; _autoCheckUpdate = config._autoCheckUpdate;
_prueBlack = config._prueBlack;
_testUrl = config._testUrl; _testUrl = config._testUrl;
_isExclude = config._isExclude; _isExclude = config._isExclude;
_windowProps = config._windowProps; _windowProps = config._windowProps;

View File

@@ -36,6 +36,7 @@ Config _$ConfigFromJson(Map<String, dynamic> json) => Config()
..allowBypass = json['allowBypass'] as bool? ?? true ..allowBypass = json['allowBypass'] as bool? ?? true
..systemProxy = json['systemProxy'] as bool? ?? false ..systemProxy = json['systemProxy'] as bool? ?? false
..onlyProxy = json['onlyProxy'] as bool? ?? false ..onlyProxy = json['onlyProxy'] as bool? ?? false
..prueBlack = json['prueBlack'] as bool? ?? false
..isCloseConnections = json['isCloseConnections'] as bool? ?? false ..isCloseConnections = json['isCloseConnections'] as bool? ?? false
..proxiesType = $enumDecodeNullable(_$ProxiesTypeEnumMap, json['proxiesType'], ..proxiesType = $enumDecodeNullable(_$ProxiesTypeEnumMap, json['proxiesType'],
unknownValue: ProxiesType.tab) ?? unknownValue: ProxiesType.tab) ??
@@ -71,6 +72,7 @@ Map<String, dynamic> _$ConfigToJson(Config instance) => <String, dynamic>{
'allowBypass': instance.allowBypass, 'allowBypass': instance.allowBypass,
'systemProxy': instance.systemProxy, 'systemProxy': instance.systemProxy,
'onlyProxy': instance.onlyProxy, 'onlyProxy': instance.onlyProxy,
'prueBlack': instance.prueBlack,
'isCloseConnections': instance.isCloseConnections, 'isCloseConnections': instance.isCloseConnections,
'proxiesType': _$ProxiesTypeEnumMap[instance.proxiesType]!, 'proxiesType': _$ProxiesTypeEnumMap[instance.proxiesType]!,
'proxyCardType': _$ProxyCardTypeEnumMap[instance.proxyCardType]!, 'proxyCardType': _$ProxyCardTypeEnumMap[instance.proxyCardType]!,

View File

@@ -633,6 +633,7 @@ mixin _$ApplicationSelectorState {
String? get locale => throw _privateConstructorUsedError; String? get locale => throw _privateConstructorUsedError;
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;
@JsonKey(ignore: true) @JsonKey(ignore: true)
$ApplicationSelectorStateCopyWith<ApplicationSelectorState> get copyWith => $ApplicationSelectorStateCopyWith<ApplicationSelectorState> get copyWith =>
@@ -645,7 +646,11 @@ abstract class $ApplicationSelectorStateCopyWith<$Res> {
$Res Function(ApplicationSelectorState) then) = $Res Function(ApplicationSelectorState) then) =
_$ApplicationSelectorStateCopyWithImpl<$Res, ApplicationSelectorState>; _$ApplicationSelectorStateCopyWithImpl<$Res, ApplicationSelectorState>;
@useResult @useResult
$Res call({String? locale, ThemeMode? themeMode, int? primaryColor}); $Res call(
{String? locale,
ThemeMode? themeMode,
int? primaryColor,
bool prueBlack});
} }
/// @nodoc /// @nodoc
@@ -665,6 +670,7 @@ class _$ApplicationSelectorStateCopyWithImpl<$Res,
Object? locale = freezed, Object? locale = freezed,
Object? themeMode = freezed, Object? themeMode = freezed,
Object? primaryColor = freezed, Object? primaryColor = freezed,
Object? prueBlack = null,
}) { }) {
return _then(_value.copyWith( return _then(_value.copyWith(
locale: freezed == locale locale: freezed == locale
@@ -679,6 +685,10 @@ class _$ApplicationSelectorStateCopyWithImpl<$Res,
? _value.primaryColor ? _value.primaryColor
: primaryColor // ignore: cast_nullable_to_non_nullable : primaryColor // ignore: cast_nullable_to_non_nullable
as int?, as int?,
prueBlack: null == prueBlack
? _value.prueBlack
: prueBlack // ignore: cast_nullable_to_non_nullable
as bool,
) as $Val); ) as $Val);
} }
} }
@@ -692,7 +702,11 @@ abstract class _$$ApplicationSelectorStateImplCopyWith<$Res>
__$$ApplicationSelectorStateImplCopyWithImpl<$Res>; __$$ApplicationSelectorStateImplCopyWithImpl<$Res>;
@override @override
@useResult @useResult
$Res call({String? locale, ThemeMode? themeMode, int? primaryColor}); $Res call(
{String? locale,
ThemeMode? themeMode,
int? primaryColor,
bool prueBlack});
} }
/// @nodoc /// @nodoc
@@ -711,6 +725,7 @@ class __$$ApplicationSelectorStateImplCopyWithImpl<$Res>
Object? locale = freezed, Object? locale = freezed,
Object? themeMode = freezed, Object? themeMode = freezed,
Object? primaryColor = freezed, Object? primaryColor = freezed,
Object? prueBlack = null,
}) { }) {
return _then(_$ApplicationSelectorStateImpl( return _then(_$ApplicationSelectorStateImpl(
locale: freezed == locale locale: freezed == locale
@@ -725,6 +740,10 @@ class __$$ApplicationSelectorStateImplCopyWithImpl<$Res>
? _value.primaryColor ? _value.primaryColor
: primaryColor // ignore: cast_nullable_to_non_nullable : primaryColor // ignore: cast_nullable_to_non_nullable
as int?, as int?,
prueBlack: null == prueBlack
? _value.prueBlack
: prueBlack // ignore: cast_nullable_to_non_nullable
as bool,
)); ));
} }
} }
@@ -733,7 +752,10 @@ class __$$ApplicationSelectorStateImplCopyWithImpl<$Res>
class _$ApplicationSelectorStateImpl implements _ApplicationSelectorState { class _$ApplicationSelectorStateImpl implements _ApplicationSelectorState {
const _$ApplicationSelectorStateImpl( const _$ApplicationSelectorStateImpl(
{this.locale, this.themeMode, this.primaryColor}); {required this.locale,
required this.themeMode,
required this.primaryColor,
required this.prueBlack});
@override @override
final String? locale; final String? locale;
@@ -741,10 +763,12 @@ class _$ApplicationSelectorStateImpl implements _ApplicationSelectorState {
final ThemeMode? themeMode; final ThemeMode? themeMode;
@override @override
final int? primaryColor; final int? primaryColor;
@override
final bool prueBlack;
@override @override
String toString() { String toString() {
return 'ApplicationSelectorState(locale: $locale, themeMode: $themeMode, primaryColor: $primaryColor)'; return 'ApplicationSelectorState(locale: $locale, themeMode: $themeMode, primaryColor: $primaryColor, prueBlack: $prueBlack)';
} }
@override @override
@@ -756,11 +780,14 @@ class _$ApplicationSelectorStateImpl implements _ApplicationSelectorState {
(identical(other.themeMode, themeMode) || (identical(other.themeMode, themeMode) ||
other.themeMode == themeMode) && other.themeMode == themeMode) &&
(identical(other.primaryColor, primaryColor) || (identical(other.primaryColor, primaryColor) ||
other.primaryColor == primaryColor)); other.primaryColor == primaryColor) &&
(identical(other.prueBlack, prueBlack) ||
other.prueBlack == prueBlack));
} }
@override @override
int get hashCode => Object.hash(runtimeType, locale, themeMode, primaryColor); int get hashCode =>
Object.hash(runtimeType, locale, themeMode, primaryColor, prueBlack);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@override @override
@@ -772,9 +799,10 @@ class _$ApplicationSelectorStateImpl implements _ApplicationSelectorState {
abstract class _ApplicationSelectorState implements ApplicationSelectorState { abstract class _ApplicationSelectorState implements ApplicationSelectorState {
const factory _ApplicationSelectorState( const factory _ApplicationSelectorState(
{final String? locale, {required final String? locale,
final ThemeMode? themeMode, required final ThemeMode? themeMode,
final int? primaryColor}) = _$ApplicationSelectorStateImpl; required final int? primaryColor,
required final bool prueBlack}) = _$ApplicationSelectorStateImpl;
@override @override
String? get locale; String? get locale;
@@ -783,6 +811,8 @@ abstract class _ApplicationSelectorState implements ApplicationSelectorState {
@override @override
int? get primaryColor; int? get primaryColor;
@override @override
bool get prueBlack;
@override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$ApplicationSelectorStateImplCopyWith<_$ApplicationSelectorStateImpl> _$$ApplicationSelectorStateImplCopyWith<_$ApplicationSelectorStateImpl>
get copyWith => throw _privateConstructorUsedError; get copyWith => throw _privateConstructorUsedError;

View File

@@ -41,9 +41,10 @@ class ProfilesSelectorState with _$ProfilesSelectorState {
@freezed @freezed
class ApplicationSelectorState with _$ApplicationSelectorState { class ApplicationSelectorState with _$ApplicationSelectorState {
const factory ApplicationSelectorState({ const factory ApplicationSelectorState({
String? locale, required String? locale,
ThemeMode? themeMode, required ThemeMode? themeMode,
int? primaryColor, required int? primaryColor,
required bool prueBlack,
}) = _ApplicationSelectorState; }) = _ApplicationSelectorState;
} }

View File

@@ -12,15 +12,15 @@ class SystemColorSchemes {
}); });
getSystemColorSchemeForBrightness(Brightness? brightness) { getSystemColorSchemeForBrightness(Brightness? brightness) {
if (brightness != null && brightness == Brightness.dark) { if (brightness == Brightness.dark) {
return darkColorScheme != null return darkColorScheme != null
? ColorScheme.fromSeed( ? ColorScheme.fromSeed(
seedColor: darkColorScheme!.primary, seedColor: darkColorScheme!.primary,
brightness: brightness, brightness: Brightness.dark,
) )
: ColorScheme.fromSeed( : ColorScheme.fromSeed(
seedColor: defaultPrimaryColor, seedColor: defaultPrimaryColor,
brightness: brightness, brightness: Brightness.dark,
); );
} }
return lightColorScheme != null return lightColorScheme != null

View File

@@ -111,6 +111,15 @@ class GlobalState {
config: config, config: config,
clashConfig: clashConfig, clashConfig: clashConfig,
); );
clashCore.setState(
CoreState(
accessControl: config.isAccessControl ? config.accessControl : null,
allowBypass: config.allowBypass,
systemProxy: config.systemProxy,
mixedPort: clashConfig.mixedPort,
onlyProxy: config.onlyProxy,
),
);
} }
updateCoreVersionInfo(appState); updateCoreVersionInfo(appState);
} }

View File

@@ -1,14 +1,11 @@
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/enum/enum.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/scaffold.dart'; import 'package:fl_clash/widgets/scaffold.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'side_sheet.dart'; import 'side_sheet.dart';
showExtendPage( showExtendPage(BuildContext context, {
BuildContext context, {
required Widget body, required Widget body,
required String title, required String title,
double? extendPageWidth, double? extendPageWidth,
@@ -20,35 +17,31 @@ showExtendPage(
key: globalKey, key: globalKey,
child: body, child: body,
); );
final isMobile = globalState.appController.appState.viewMode ==
ViewMode.mobile;
navigator.push( navigator.push(
ModalSideSheetRoute( ModalSideSheetRoute(
modalBarrierColor: Colors.black38, modalBarrierColor: Colors.black38,
builder: (context) => Selector<AppState, double>( builder: (context) {
selector: (_, appState) => appState.viewWidth, final commonScaffold = CommonScaffold(
builder: (_, viewWidth, __) { automaticallyImplyLeading: isMobile ? true : false,
final isMobile = actions: isMobile
globalState.appController.appState.viewMode == ViewMode.mobile; ? null
final commonScaffold = CommonScaffold( : [
automaticallyImplyLeading: isMobile ? true : false, const SizedBox(
actions: isMobile height: kToolbarHeight,
? null width: kToolbarHeight,
: [ child: CloseButton(),
const SizedBox( ),
height: kToolbarHeight, ],
width: kToolbarHeight, title: title,
child: CloseButton(), body: uniqueBody,
), );
], return SizedBox(
title: title, width: isMobile ? context.width : extendPageWidth ?? 300,
body: uniqueBody, child: commonScaffold,
); );
return AnimatedContainer( },
duration: kThemeAnimationDuration,
width: isMobile ? viewWidth : extendPageWidth ?? 300,
child: commonScaffold,
);
},
),
constraints: const BoxConstraints(), constraints: const BoxConstraints(),
filter: filter, filter: filter,
), ),

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.49+202407311 version: 0.8.50+202408011
environment: environment:
sdk: '>=3.1.0 <4.0.0' sdk: '>=3.1.0 <4.0.0'
@@ -38,8 +38,6 @@ dependencies:
webdav_client: ^1.2.2 webdav_client: ^1.2.2
dio: ^5.4.3+1 dio: ^5.4.3+1
country_flags: ^2.2.0 country_flags: ^2.2.0
re_editor: ^0.3.0
re_highlight: ^0.0.3
win32: ^5.5.1 win32: ^5.5.1
ffi: ^2.1.2 ffi: ^2.1.2
material_color_utilities: ^0.8.0 material_color_utilities: ^0.8.0