Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
196a50aaf7 |
@@ -142,6 +142,7 @@ class ApplicationState extends State<Application> {
|
||||
locale: config.locale,
|
||||
themeMode: config.themeMode,
|
||||
primaryColor: config.primaryColor,
|
||||
prueBlack: config.prueBlack,
|
||||
),
|
||||
builder: (_, state, child) {
|
||||
return DynamicColorBuilder(
|
||||
@@ -180,7 +181,7 @@ class ApplicationState extends State<Application> {
|
||||
brightness: Brightness.dark,
|
||||
systemColorSchemes: systemColorSchemes,
|
||||
primaryColor: state.primaryColor,
|
||||
),
|
||||
).toPrueBlack(state.prueBlack),
|
||||
),
|
||||
home: child,
|
||||
);
|
||||
|
||||
@@ -16,4 +16,13 @@ extension ColorExtension on Color {
|
||||
toLittle() {
|
||||
return withOpacity(0.03);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ColorSchemeExtension on ColorScheme {
|
||||
ColorScheme toPrueBlack(bool isPrueBlack) => isPrueBlack
|
||||
? copyWith(
|
||||
surface: Colors.black,
|
||||
background: Colors.black,
|
||||
)
|
||||
: this;
|
||||
}
|
||||
|
||||
@@ -89,8 +89,11 @@ class _EditProfileState extends State<EditProfile> {
|
||||
});
|
||||
}
|
||||
|
||||
Future<FileInfo> _getFileInfo(path) async {
|
||||
Future<FileInfo?> _getFileInfo(path) async {
|
||||
final file = File(path);
|
||||
if (!await file.exists()) {
|
||||
return null;
|
||||
}
|
||||
final lastModified = await file.lastModified();
|
||||
final size = await file.length();
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
final items = [
|
||||
@@ -250,9 +200,49 @@ class _EditProfileState extends State<EditProfile> {
|
||||
),
|
||||
),
|
||||
],
|
||||
ListItem(
|
||||
title: Text(appLocalizations.profile),
|
||||
subtitle: _buildSubtitle(),
|
||||
ValueListenableBuilder<FileInfo?>(
|
||||
valueListenable: fileInfoNotifier,
|
||||
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(
|
||||
|
||||
@@ -189,7 +189,7 @@ class _ProfileItemState extends State<ProfileItem> {
|
||||
),
|
||||
onTab: () async {
|
||||
await globalState.appController.deleteProfile(widget.profile.id);
|
||||
if(mounted){
|
||||
if (mounted) {
|
||||
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) {
|
||||
final textTheme = context.textTheme;
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
Text(
|
||||
profile.label ?? profile.id,
|
||||
style: context.textTheme.titleMedium,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
profile.label ?? profile.id,
|
||||
style: textTheme.titleMedium,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
profile.lastUpdateDate?.lastUpdateTimeDesc ?? '',
|
||||
style: textTheme.labelMedium?.toLight,
|
||||
),
|
||||
...switch (profile.type) {
|
||||
ProfileType.file => _buildFileProfileInfo(
|
||||
profile,
|
||||
),
|
||||
ProfileType.url => _buildUrlProfileInfo(
|
||||
profile,
|
||||
),
|
||||
},
|
||||
],
|
||||
),
|
||||
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,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -26,9 +26,7 @@ class ThemeFragment extends StatelessWidget {
|
||||
final previewCard = Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: CommonCard(
|
||||
onPressed: (){
|
||||
|
||||
},
|
||||
onPressed: () {},
|
||||
info: Info(
|
||||
label: appLocalizations.preview,
|
||||
iconData: Icons.looks,
|
||||
@@ -87,7 +85,6 @@ class ThemeColorsBox extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ThemeColorsBoxState extends State<ThemeColorsBox> {
|
||||
|
||||
Widget _themeModeCheckBox({
|
||||
bool? isSelected,
|
||||
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;
|
||||
}
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -219,5 +219,6 @@
|
||||
"autoCloseConnectionsDesc": "Auto close connections after change node",
|
||||
"onlyStatisticsProxy": "Only statistics proxy",
|
||||
"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"
|
||||
}
|
||||
@@ -219,5 +219,6 @@
|
||||
"autoCloseConnectionsDesc": "切换节点后自动关闭连接",
|
||||
"onlyStatisticsProxy": "仅统计代理",
|
||||
"onlyStatisticsProxyDesc": "开启后,将只统计代理流量",
|
||||
"deleteProfileTip": "确定要删除当前配置吗?"
|
||||
"deleteProfileTip": "确定要删除当前配置吗?",
|
||||
"prueBlackMode": "纯黑模式"
|
||||
}
|
||||
@@ -257,6 +257,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"proxyPort": MessageLookupByLibrary.simpleMessage("ProxyPort"),
|
||||
"proxyPortDesc": MessageLookupByLibrary.simpleMessage(
|
||||
"Set the Clash listening port"),
|
||||
"prueBlackMode":
|
||||
MessageLookupByLibrary.simpleMessage("Prue black mode"),
|
||||
"qrcode": MessageLookupByLibrary.simpleMessage("QR code"),
|
||||
"qrcodeDesc": MessageLookupByLibrary.simpleMessage(
|
||||
"Scan QR code to obtain profile"),
|
||||
|
||||
@@ -208,6 +208,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"proxyGroup": MessageLookupByLibrary.simpleMessage("代理组"),
|
||||
"proxyPort": MessageLookupByLibrary.simpleMessage("代理端口"),
|
||||
"proxyPortDesc": MessageLookupByLibrary.simpleMessage("设置Clash监听端口"),
|
||||
"prueBlackMode": MessageLookupByLibrary.simpleMessage("纯黑模式"),
|
||||
"qrcode": MessageLookupByLibrary.simpleMessage("二维码"),
|
||||
"qrcodeDesc": MessageLookupByLibrary.simpleMessage("扫描二维码获取配置文件"),
|
||||
"recovery": MessageLookupByLibrary.simpleMessage("恢复"),
|
||||
|
||||
@@ -2259,6 +2259,16 @@ class AppLocalizations {
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Prue black mode`
|
||||
String get prueBlackMode {
|
||||
return Intl.message(
|
||||
'Prue black mode',
|
||||
name: 'prueBlackMode',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> {
|
||||
|
||||
@@ -82,6 +82,7 @@ class Config extends ChangeNotifier {
|
||||
String _testUrl;
|
||||
WindowProps _windowProps;
|
||||
bool _onlyProxy;
|
||||
bool _prueBlack;
|
||||
|
||||
Config()
|
||||
: _profiles = [],
|
||||
@@ -107,6 +108,7 @@ class Config extends ChangeNotifier {
|
||||
_windowProps = defaultWindowProps,
|
||||
_proxiesType = ProxiesType.tab,
|
||||
_proxiesColumns = 2,
|
||||
_prueBlack = false,
|
||||
_onlyProxy = false;
|
||||
|
||||
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)
|
||||
bool get isCloseConnections {
|
||||
@@ -530,6 +543,7 @@ class Config extends ChangeNotifier {
|
||||
_accessControl = config._accessControl;
|
||||
_isAnimateToPage = config._isAnimateToPage;
|
||||
_autoCheckUpdate = config._autoCheckUpdate;
|
||||
_prueBlack = config._prueBlack;
|
||||
_testUrl = config._testUrl;
|
||||
_isExclude = config._isExclude;
|
||||
_windowProps = config._windowProps;
|
||||
|
||||
@@ -36,6 +36,7 @@ Config _$ConfigFromJson(Map<String, dynamic> json) => Config()
|
||||
..allowBypass = json['allowBypass'] as bool? ?? true
|
||||
..systemProxy = json['systemProxy'] as bool? ?? false
|
||||
..onlyProxy = json['onlyProxy'] as bool? ?? false
|
||||
..prueBlack = json['prueBlack'] as bool? ?? false
|
||||
..isCloseConnections = json['isCloseConnections'] as bool? ?? false
|
||||
..proxiesType = $enumDecodeNullable(_$ProxiesTypeEnumMap, json['proxiesType'],
|
||||
unknownValue: ProxiesType.tab) ??
|
||||
@@ -71,6 +72,7 @@ Map<String, dynamic> _$ConfigToJson(Config instance) => <String, dynamic>{
|
||||
'allowBypass': instance.allowBypass,
|
||||
'systemProxy': instance.systemProxy,
|
||||
'onlyProxy': instance.onlyProxy,
|
||||
'prueBlack': instance.prueBlack,
|
||||
'isCloseConnections': instance.isCloseConnections,
|
||||
'proxiesType': _$ProxiesTypeEnumMap[instance.proxiesType]!,
|
||||
'proxyCardType': _$ProxyCardTypeEnumMap[instance.proxyCardType]!,
|
||||
|
||||
@@ -633,6 +633,7 @@ mixin _$ApplicationSelectorState {
|
||||
String? get locale => throw _privateConstructorUsedError;
|
||||
ThemeMode? get themeMode => throw _privateConstructorUsedError;
|
||||
int? get primaryColor => throw _privateConstructorUsedError;
|
||||
bool get prueBlack => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
$ApplicationSelectorStateCopyWith<ApplicationSelectorState> get copyWith =>
|
||||
@@ -645,7 +646,11 @@ abstract class $ApplicationSelectorStateCopyWith<$Res> {
|
||||
$Res Function(ApplicationSelectorState) then) =
|
||||
_$ApplicationSelectorStateCopyWithImpl<$Res, ApplicationSelectorState>;
|
||||
@useResult
|
||||
$Res call({String? locale, ThemeMode? themeMode, int? primaryColor});
|
||||
$Res call(
|
||||
{String? locale,
|
||||
ThemeMode? themeMode,
|
||||
int? primaryColor,
|
||||
bool prueBlack});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -665,6 +670,7 @@ class _$ApplicationSelectorStateCopyWithImpl<$Res,
|
||||
Object? locale = freezed,
|
||||
Object? themeMode = freezed,
|
||||
Object? primaryColor = freezed,
|
||||
Object? prueBlack = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
locale: freezed == locale
|
||||
@@ -679,6 +685,10 @@ class _$ApplicationSelectorStateCopyWithImpl<$Res,
|
||||
? _value.primaryColor
|
||||
: primaryColor // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
prueBlack: null == prueBlack
|
||||
? _value.prueBlack
|
||||
: prueBlack // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
@@ -692,7 +702,11 @@ abstract class _$$ApplicationSelectorStateImplCopyWith<$Res>
|
||||
__$$ApplicationSelectorStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({String? locale, ThemeMode? themeMode, int? primaryColor});
|
||||
$Res call(
|
||||
{String? locale,
|
||||
ThemeMode? themeMode,
|
||||
int? primaryColor,
|
||||
bool prueBlack});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -711,6 +725,7 @@ class __$$ApplicationSelectorStateImplCopyWithImpl<$Res>
|
||||
Object? locale = freezed,
|
||||
Object? themeMode = freezed,
|
||||
Object? primaryColor = freezed,
|
||||
Object? prueBlack = null,
|
||||
}) {
|
||||
return _then(_$ApplicationSelectorStateImpl(
|
||||
locale: freezed == locale
|
||||
@@ -725,6 +740,10 @@ class __$$ApplicationSelectorStateImplCopyWithImpl<$Res>
|
||||
? _value.primaryColor
|
||||
: primaryColor // ignore: cast_nullable_to_non_nullable
|
||||
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 {
|
||||
const _$ApplicationSelectorStateImpl(
|
||||
{this.locale, this.themeMode, this.primaryColor});
|
||||
{required this.locale,
|
||||
required this.themeMode,
|
||||
required this.primaryColor,
|
||||
required this.prueBlack});
|
||||
|
||||
@override
|
||||
final String? locale;
|
||||
@@ -741,10 +763,12 @@ class _$ApplicationSelectorStateImpl implements _ApplicationSelectorState {
|
||||
final ThemeMode? themeMode;
|
||||
@override
|
||||
final int? primaryColor;
|
||||
@override
|
||||
final bool prueBlack;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ApplicationSelectorState(locale: $locale, themeMode: $themeMode, primaryColor: $primaryColor)';
|
||||
return 'ApplicationSelectorState(locale: $locale, themeMode: $themeMode, primaryColor: $primaryColor, prueBlack: $prueBlack)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -756,11 +780,14 @@ class _$ApplicationSelectorStateImpl implements _ApplicationSelectorState {
|
||||
(identical(other.themeMode, themeMode) ||
|
||||
other.themeMode == themeMode) &&
|
||||
(identical(other.primaryColor, primaryColor) ||
|
||||
other.primaryColor == primaryColor));
|
||||
other.primaryColor == primaryColor) &&
|
||||
(identical(other.prueBlack, prueBlack) ||
|
||||
other.prueBlack == prueBlack));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, locale, themeMode, primaryColor);
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, locale, themeMode, primaryColor, prueBlack);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@@ -772,9 +799,10 @@ class _$ApplicationSelectorStateImpl implements _ApplicationSelectorState {
|
||||
|
||||
abstract class _ApplicationSelectorState implements ApplicationSelectorState {
|
||||
const factory _ApplicationSelectorState(
|
||||
{final String? locale,
|
||||
final ThemeMode? themeMode,
|
||||
final int? primaryColor}) = _$ApplicationSelectorStateImpl;
|
||||
{required final String? locale,
|
||||
required final ThemeMode? themeMode,
|
||||
required final int? primaryColor,
|
||||
required final bool prueBlack}) = _$ApplicationSelectorStateImpl;
|
||||
|
||||
@override
|
||||
String? get locale;
|
||||
@@ -783,6 +811,8 @@ abstract class _ApplicationSelectorState implements ApplicationSelectorState {
|
||||
@override
|
||||
int? get primaryColor;
|
||||
@override
|
||||
bool get prueBlack;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$ApplicationSelectorStateImplCopyWith<_$ApplicationSelectorStateImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
|
||||
@@ -41,9 +41,10 @@ class ProfilesSelectorState with _$ProfilesSelectorState {
|
||||
@freezed
|
||||
class ApplicationSelectorState with _$ApplicationSelectorState {
|
||||
const factory ApplicationSelectorState({
|
||||
String? locale,
|
||||
ThemeMode? themeMode,
|
||||
int? primaryColor,
|
||||
required String? locale,
|
||||
required ThemeMode? themeMode,
|
||||
required int? primaryColor,
|
||||
required bool prueBlack,
|
||||
}) = _ApplicationSelectorState;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,15 +12,15 @@ class SystemColorSchemes {
|
||||
});
|
||||
|
||||
getSystemColorSchemeForBrightness(Brightness? brightness) {
|
||||
if (brightness != null && brightness == Brightness.dark) {
|
||||
if (brightness == Brightness.dark) {
|
||||
return darkColorScheme != null
|
||||
? ColorScheme.fromSeed(
|
||||
seedColor: darkColorScheme!.primary,
|
||||
brightness: brightness,
|
||||
brightness: Brightness.dark,
|
||||
)
|
||||
: ColorScheme.fromSeed(
|
||||
seedColor: defaultPrimaryColor,
|
||||
brightness: brightness,
|
||||
brightness: Brightness.dark,
|
||||
);
|
||||
}
|
||||
return lightColorScheme != null
|
||||
|
||||
@@ -111,6 +111,15 @@ class GlobalState {
|
||||
config: config,
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
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/state.dart';
|
||||
import 'package:fl_clash/widgets/scaffold.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'side_sheet.dart';
|
||||
|
||||
showExtendPage(
|
||||
BuildContext context, {
|
||||
showExtendPage(BuildContext context, {
|
||||
required Widget body,
|
||||
required String title,
|
||||
double? extendPageWidth,
|
||||
@@ -20,35 +17,31 @@ showExtendPage(
|
||||
key: globalKey,
|
||||
child: body,
|
||||
);
|
||||
final isMobile = globalState.appController.appState.viewMode ==
|
||||
ViewMode.mobile;
|
||||
navigator.push(
|
||||
ModalSideSheetRoute(
|
||||
modalBarrierColor: Colors.black38,
|
||||
builder: (context) => Selector<AppState, double>(
|
||||
selector: (_, appState) => appState.viewWidth,
|
||||
builder: (_, viewWidth, __) {
|
||||
final isMobile =
|
||||
globalState.appController.appState.viewMode == ViewMode.mobile;
|
||||
final commonScaffold = CommonScaffold(
|
||||
automaticallyImplyLeading: isMobile ? true : false,
|
||||
actions: isMobile
|
||||
? null
|
||||
: [
|
||||
const SizedBox(
|
||||
height: kToolbarHeight,
|
||||
width: kToolbarHeight,
|
||||
child: CloseButton(),
|
||||
),
|
||||
],
|
||||
title: title,
|
||||
body: uniqueBody,
|
||||
);
|
||||
return AnimatedContainer(
|
||||
duration: kThemeAnimationDuration,
|
||||
width: isMobile ? viewWidth : extendPageWidth ?? 300,
|
||||
child: commonScaffold,
|
||||
);
|
||||
},
|
||||
),
|
||||
builder: (context) {
|
||||
final commonScaffold = CommonScaffold(
|
||||
automaticallyImplyLeading: isMobile ? true : false,
|
||||
actions: isMobile
|
||||
? null
|
||||
: [
|
||||
const SizedBox(
|
||||
height: kToolbarHeight,
|
||||
width: kToolbarHeight,
|
||||
child: CloseButton(),
|
||||
),
|
||||
],
|
||||
title: title,
|
||||
body: uniqueBody,
|
||||
);
|
||||
return SizedBox(
|
||||
width: isMobile ? context.width : extendPageWidth ?? 300,
|
||||
child: commonScaffold,
|
||||
);
|
||||
},
|
||||
constraints: const BoxConstraints(),
|
||||
filter: filter,
|
||||
),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: fl_clash
|
||||
description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free.
|
||||
publish_to: 'none'
|
||||
version: 0.8.49+202407311
|
||||
version: 0.8.50+202408011
|
||||
environment:
|
||||
sdk: '>=3.1.0 <4.0.0'
|
||||
|
||||
@@ -38,8 +38,6 @@ dependencies:
|
||||
webdav_client: ^1.2.2
|
||||
dio: ^5.4.3+1
|
||||
country_flags: ^2.2.0
|
||||
re_editor: ^0.3.0
|
||||
re_highlight: ^0.0.3
|
||||
win32: ^5.5.1
|
||||
ffi: ^2.1.2
|
||||
material_color_utilities: ^0.8.0
|
||||
|
||||
Reference in New Issue
Block a user