Optimize dashboard performance
Fix some issues
This commit is contained in:
@@ -235,12 +235,12 @@ class ClashCore {
|
||||
return int.parse(value);
|
||||
}
|
||||
|
||||
Future<ClashConfig?> getProfile(String id) async {
|
||||
Future<ClashConfigSnippet?> getProfile(String id) async {
|
||||
final res = await clashInterface.getProfile(id);
|
||||
if (res.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
return ClashConfig.fromJson(json.decode(res));
|
||||
return ClashConfigSnippet.fromJson(json.decode(res));
|
||||
}
|
||||
|
||||
resetTraffic() {
|
||||
|
||||
@@ -14,6 +14,7 @@ class Navigation {
|
||||
const NavigationItem(
|
||||
icon: Icon(Icons.space_dashboard),
|
||||
label: PageLabel.dashboard,
|
||||
keep: false,
|
||||
fragment: DashboardFragment(
|
||||
key: GlobalObjectKey(PageLabel.dashboard),
|
||||
),
|
||||
|
||||
@@ -25,7 +25,7 @@ class Render {
|
||||
debouncer.call(
|
||||
DebounceTag.renderPause,
|
||||
_pause,
|
||||
duration: Duration(seconds: 15),
|
||||
duration: Duration(seconds: 5),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,12 +62,12 @@ class _MemoryInfoState extends State<MemoryInfo> {
|
||||
onPressed: () {
|
||||
clashCore.requestGc();
|
||||
},
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: _memoryInfoStateNotifier,
|
||||
builder: (_, trafficValue, __) {
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
child: Column(
|
||||
children: [
|
||||
ValueListenableBuilder(
|
||||
valueListenable: _memoryInfoStateNotifier,
|
||||
builder: (_, trafficValue, __) {
|
||||
return Padding(
|
||||
padding: baseInfoEdgeInsets.copyWith(
|
||||
bottom: 0,
|
||||
top: 12,
|
||||
@@ -87,30 +87,30 @@ class _MemoryInfoState extends State<MemoryInfo> {
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: WaveView(
|
||||
waveAmplitude: 12.0,
|
||||
waveFrequency: 0.35,
|
||||
waveColor: darkenLighter,
|
||||
),
|
||||
),
|
||||
Positioned.fill(
|
||||
child: WaveView(
|
||||
waveAmplitude: 12.0,
|
||||
waveFrequency: 0.9,
|
||||
waveColor: darken,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
Flexible(
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: WaveView(
|
||||
waveAmplitude: 12.0,
|
||||
waveFrequency: 0.35,
|
||||
waveColor: darkenLighter,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
Positioned.fill(
|
||||
child: WaveView(
|
||||
waveAmplitude: 12.0,
|
||||
waveFrequency: 0.9,
|
||||
waveColor: darken,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
class TrafficUsage extends StatelessWidget {
|
||||
const TrafficUsage({super.key});
|
||||
|
||||
Widget getTrafficDataItem(
|
||||
Widget _buildTrafficDataItem(
|
||||
BuildContext context,
|
||||
Icon icon,
|
||||
TrafficValue trafficValue,
|
||||
@@ -189,7 +189,7 @@ class TrafficUsage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
getTrafficDataItem(
|
||||
_buildTrafficDataItem(
|
||||
context,
|
||||
Icon(
|
||||
Icons.arrow_upward,
|
||||
@@ -201,7 +201,7 @@ class TrafficUsage extends StatelessWidget {
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
getTrafficDataItem(
|
||||
_buildTrafficDataItem(
|
||||
context,
|
||||
Icon(
|
||||
Icons.arrow_downward,
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import 'package:fl_clash/models/models.dart';
|
||||
import 'package:fl_clash/widgets/scaffold.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomProfile extends StatefulWidget {
|
||||
final String profileId;
|
||||
|
||||
const CustomProfile({
|
||||
super.key,
|
||||
required this.profileId,
|
||||
});
|
||||
|
||||
@override
|
||||
State<CustomProfile> createState() => _CustomProfileState();
|
||||
}
|
||||
|
||||
class _CustomProfileState extends State<CustomProfile> {
|
||||
final _currentClashConfigNotifier = ValueNotifier<ClashConfig?>(null);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initCurrentClashConfig();
|
||||
}
|
||||
|
||||
_initCurrentClashConfig() async {
|
||||
// final currentProfileId = globalState.config.currentProfileId;
|
||||
// if (currentProfileId == null) {
|
||||
// return;
|
||||
// }
|
||||
// _currentClashConfigNotifier.value =
|
||||
// await clashCore.getProfile(currentProfileId);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CommonScaffold(
|
||||
body: ValueListenableBuilder(
|
||||
valueListenable: _currentClashConfigNotifier,
|
||||
builder: (_, clashConfig, ___) {
|
||||
if (clashConfig == null) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
return Column(
|
||||
children: [],
|
||||
);
|
||||
},
|
||||
),
|
||||
title: "自定义",
|
||||
);
|
||||
}
|
||||
}
|
||||
87
lib/fragments/profiles/gen_profile.dart
Normal file
87
lib/fragments/profiles/gen_profile.dart
Normal file
@@ -0,0 +1,87 @@
|
||||
import 'package:fl_clash/clash/core.dart';
|
||||
import 'package:fl_clash/models/models.dart';
|
||||
import 'package:fl_clash/state.dart';
|
||||
import 'package:fl_clash/widgets/card.dart';
|
||||
import 'package:fl_clash/widgets/scaffold.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class GenProfile extends StatefulWidget {
|
||||
final String profileId;
|
||||
|
||||
const GenProfile({
|
||||
super.key,
|
||||
required this.profileId,
|
||||
});
|
||||
|
||||
@override
|
||||
State<GenProfile> createState() => _GenProfileState();
|
||||
}
|
||||
|
||||
class _GenProfileState extends State<GenProfile> {
|
||||
final _currentClashConfigNotifier = ValueNotifier<ClashConfigSnippet?>(null);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initCurrentClashConfig();
|
||||
}
|
||||
|
||||
_initCurrentClashConfig() async {
|
||||
final currentProfileId = globalState.config.currentProfileId;
|
||||
if (currentProfileId == null) {
|
||||
return;
|
||||
}
|
||||
_currentClashConfigNotifier.value =
|
||||
await clashCore.getProfile(currentProfileId);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CommonScaffold(
|
||||
body: ValueListenableBuilder(
|
||||
valueListenable: _currentClashConfigNotifier,
|
||||
builder: (_, clashConfig, ___) {
|
||||
if (clashConfig == null) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
return Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
SliverGrid.builder(
|
||||
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
||||
maxCrossAxisExtent: 100,
|
||||
mainAxisExtent: 50,
|
||||
mainAxisSpacing: 8,
|
||||
crossAxisSpacing: 8,
|
||||
),
|
||||
itemCount: clashConfig.proxyGroups.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return CommonCard(
|
||||
onPressed: () {},
|
||||
child: Text(
|
||||
clashConfig.proxyGroups[index].name,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
SliverList.builder(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final rule = clashConfig.rule[index];
|
||||
return Text(
|
||||
rule,
|
||||
);
|
||||
},
|
||||
itemCount: clashConfig.rule.length,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
title: "自定义",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'add_profile.dart';
|
||||
import 'gen_profile.dart';
|
||||
|
||||
class ProfilesFragment extends StatefulWidget {
|
||||
const ProfilesFragment({super.key});
|
||||
@@ -273,14 +274,14 @@ class ProfileItem extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
// _handlePushCustomPage(BuildContext context, String id) {
|
||||
// BaseNavigator.push(
|
||||
// context,
|
||||
// CustomProfile(
|
||||
// profileId: id,
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
_handlePushGenProfilePage(BuildContext context, String id) {
|
||||
BaseNavigator.push(
|
||||
context,
|
||||
GenProfile(
|
||||
profileId: id,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -334,7 +335,7 @@ class ProfileItem extends StatelessWidget {
|
||||
// icon: Icons.extension_outlined,
|
||||
// label: "自定义",
|
||||
// onPressed: () {
|
||||
// _handlePushCustomPage(context, profile.id);
|
||||
// _handlePushGenProfilePage(context, profile.id);
|
||||
// },
|
||||
// ),
|
||||
ActionItemData(
|
||||
|
||||
@@ -273,6 +273,17 @@ class GeoXUrl with _$GeoXUrl {
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ClashConfigSnippet with _$ClashConfigSnippet {
|
||||
const factory ClashConfigSnippet({
|
||||
@Default([]) @JsonKey(name: "proxy-groups") List<ProxyGroup> proxyGroups,
|
||||
@Default([]) List<String> rule,
|
||||
}) = _ClashConfigSnippet;
|
||||
|
||||
factory ClashConfigSnippet.fromJson(Map<String, Object?> json) =>
|
||||
_$ClashConfigSnippetFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ClashConfig with _$ClashConfig {
|
||||
const factory ClashConfig({
|
||||
@@ -301,7 +312,7 @@ class ClashConfig with _$ClashConfig {
|
||||
@JsonKey(name: "geodata-loader")
|
||||
GeodataLoader geodataLoader,
|
||||
@Default([]) @JsonKey(name: "proxy-groups") List<ProxyGroup> proxyGroups,
|
||||
@Default([]) List<String> rules,
|
||||
@Default([]) List<String> rule,
|
||||
@JsonKey(name: "global-ua") String? globalUa,
|
||||
@Default(ExternalControllerStatus.close)
|
||||
@JsonKey(name: "external-controller")
|
||||
|
||||
@@ -1834,6 +1834,202 @@ abstract class _GeoXUrl implements GeoXUrl {
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
ClashConfigSnippet _$ClashConfigSnippetFromJson(Map<String, dynamic> json) {
|
||||
return _ClashConfigSnippet.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ClashConfigSnippet {
|
||||
@JsonKey(name: "proxy-groups")
|
||||
List<ProxyGroup> get proxyGroups => throw _privateConstructorUsedError;
|
||||
List<String> get rule => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this ClashConfigSnippet to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of ClashConfigSnippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$ClashConfigSnippetCopyWith<ClashConfigSnippet> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ClashConfigSnippetCopyWith<$Res> {
|
||||
factory $ClashConfigSnippetCopyWith(
|
||||
ClashConfigSnippet value, $Res Function(ClashConfigSnippet) then) =
|
||||
_$ClashConfigSnippetCopyWithImpl<$Res, ClashConfigSnippet>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{@JsonKey(name: "proxy-groups") List<ProxyGroup> proxyGroups,
|
||||
List<String> rule});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ClashConfigSnippetCopyWithImpl<$Res, $Val extends ClashConfigSnippet>
|
||||
implements $ClashConfigSnippetCopyWith<$Res> {
|
||||
_$ClashConfigSnippetCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of ClashConfigSnippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? proxyGroups = null,
|
||||
Object? rule = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
proxyGroups: null == proxyGroups
|
||||
? _value.proxyGroups
|
||||
: proxyGroups // ignore: cast_nullable_to_non_nullable
|
||||
as List<ProxyGroup>,
|
||||
rule: null == rule
|
||||
? _value.rule
|
||||
: rule // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ClashConfigSnippetImplCopyWith<$Res>
|
||||
implements $ClashConfigSnippetCopyWith<$Res> {
|
||||
factory _$$ClashConfigSnippetImplCopyWith(_$ClashConfigSnippetImpl value,
|
||||
$Res Function(_$ClashConfigSnippetImpl) then) =
|
||||
__$$ClashConfigSnippetImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{@JsonKey(name: "proxy-groups") List<ProxyGroup> proxyGroups,
|
||||
List<String> rule});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ClashConfigSnippetImplCopyWithImpl<$Res>
|
||||
extends _$ClashConfigSnippetCopyWithImpl<$Res, _$ClashConfigSnippetImpl>
|
||||
implements _$$ClashConfigSnippetImplCopyWith<$Res> {
|
||||
__$$ClashConfigSnippetImplCopyWithImpl(_$ClashConfigSnippetImpl _value,
|
||||
$Res Function(_$ClashConfigSnippetImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of ClashConfigSnippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? proxyGroups = null,
|
||||
Object? rule = null,
|
||||
}) {
|
||||
return _then(_$ClashConfigSnippetImpl(
|
||||
proxyGroups: null == proxyGroups
|
||||
? _value._proxyGroups
|
||||
: proxyGroups // ignore: cast_nullable_to_non_nullable
|
||||
as List<ProxyGroup>,
|
||||
rule: null == rule
|
||||
? _value._rule
|
||||
: rule // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$ClashConfigSnippetImpl implements _ClashConfigSnippet {
|
||||
const _$ClashConfigSnippetImpl(
|
||||
{@JsonKey(name: "proxy-groups")
|
||||
final List<ProxyGroup> proxyGroups = const [],
|
||||
final List<String> rule = const []})
|
||||
: _proxyGroups = proxyGroups,
|
||||
_rule = rule;
|
||||
|
||||
factory _$ClashConfigSnippetImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$ClashConfigSnippetImplFromJson(json);
|
||||
|
||||
final List<ProxyGroup> _proxyGroups;
|
||||
@override
|
||||
@JsonKey(name: "proxy-groups")
|
||||
List<ProxyGroup> get proxyGroups {
|
||||
if (_proxyGroups is EqualUnmodifiableListView) return _proxyGroups;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_proxyGroups);
|
||||
}
|
||||
|
||||
final List<String> _rule;
|
||||
@override
|
||||
@JsonKey()
|
||||
List<String> get rule {
|
||||
if (_rule is EqualUnmodifiableListView) return _rule;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_rule);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ClashConfigSnippet(proxyGroups: $proxyGroups, rule: $rule)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ClashConfigSnippetImpl &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._proxyGroups, _proxyGroups) &&
|
||||
const DeepCollectionEquality().equals(other._rule, _rule));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
const DeepCollectionEquality().hash(_proxyGroups),
|
||||
const DeepCollectionEquality().hash(_rule));
|
||||
|
||||
/// Create a copy of ClashConfigSnippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ClashConfigSnippetImplCopyWith<_$ClashConfigSnippetImpl> get copyWith =>
|
||||
__$$ClashConfigSnippetImplCopyWithImpl<_$ClashConfigSnippetImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$ClashConfigSnippetImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _ClashConfigSnippet implements ClashConfigSnippet {
|
||||
const factory _ClashConfigSnippet(
|
||||
{@JsonKey(name: "proxy-groups") final List<ProxyGroup> proxyGroups,
|
||||
final List<String> rule}) = _$ClashConfigSnippetImpl;
|
||||
|
||||
factory _ClashConfigSnippet.fromJson(Map<String, dynamic> json) =
|
||||
_$ClashConfigSnippetImpl.fromJson;
|
||||
|
||||
@override
|
||||
@JsonKey(name: "proxy-groups")
|
||||
List<ProxyGroup> get proxyGroups;
|
||||
@override
|
||||
List<String> get rule;
|
||||
|
||||
/// Create a copy of ClashConfigSnippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$ClashConfigSnippetImplCopyWith<_$ClashConfigSnippetImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
ClashConfig _$ClashConfigFromJson(Map<String, dynamic> json) {
|
||||
return _ClashConfig.fromJson(json);
|
||||
}
|
||||
@@ -1866,7 +2062,7 @@ mixin _$ClashConfig {
|
||||
GeodataLoader get geodataLoader => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "proxy-groups")
|
||||
List<ProxyGroup> get proxyGroups => throw _privateConstructorUsedError;
|
||||
List<String> get rules => throw _privateConstructorUsedError;
|
||||
List<String> get rule => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "global-ua")
|
||||
String? get globalUa => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "external-controller")
|
||||
@@ -1907,7 +2103,7 @@ abstract class $ClashConfigCopyWith<$Res> {
|
||||
GeoXUrl geoXUrl,
|
||||
@JsonKey(name: "geodata-loader") GeodataLoader geodataLoader,
|
||||
@JsonKey(name: "proxy-groups") List<ProxyGroup> proxyGroups,
|
||||
List<String> rules,
|
||||
List<String> rule,
|
||||
@JsonKey(name: "global-ua") String? globalUa,
|
||||
@JsonKey(name: "external-controller")
|
||||
ExternalControllerStatus externalController,
|
||||
@@ -1947,7 +2143,7 @@ class _$ClashConfigCopyWithImpl<$Res, $Val extends ClashConfig>
|
||||
Object? geoXUrl = null,
|
||||
Object? geodataLoader = null,
|
||||
Object? proxyGroups = null,
|
||||
Object? rules = null,
|
||||
Object? rule = null,
|
||||
Object? globalUa = freezed,
|
||||
Object? externalController = null,
|
||||
Object? hosts = null,
|
||||
@@ -2009,9 +2205,9 @@ class _$ClashConfigCopyWithImpl<$Res, $Val extends ClashConfig>
|
||||
? _value.proxyGroups
|
||||
: proxyGroups // ignore: cast_nullable_to_non_nullable
|
||||
as List<ProxyGroup>,
|
||||
rules: null == rules
|
||||
? _value.rules
|
||||
: rules // ignore: cast_nullable_to_non_nullable
|
||||
rule: null == rule
|
||||
? _value.rule
|
||||
: rule // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
globalUa: freezed == globalUa
|
||||
? _value.globalUa
|
||||
@@ -2084,7 +2280,7 @@ abstract class _$$ClashConfigImplCopyWith<$Res>
|
||||
GeoXUrl geoXUrl,
|
||||
@JsonKey(name: "geodata-loader") GeodataLoader geodataLoader,
|
||||
@JsonKey(name: "proxy-groups") List<ProxyGroup> proxyGroups,
|
||||
List<String> rules,
|
||||
List<String> rule,
|
||||
@JsonKey(name: "global-ua") String? globalUa,
|
||||
@JsonKey(name: "external-controller")
|
||||
ExternalControllerStatus externalController,
|
||||
@@ -2125,7 +2321,7 @@ class __$$ClashConfigImplCopyWithImpl<$Res>
|
||||
Object? geoXUrl = null,
|
||||
Object? geodataLoader = null,
|
||||
Object? proxyGroups = null,
|
||||
Object? rules = null,
|
||||
Object? rule = null,
|
||||
Object? globalUa = freezed,
|
||||
Object? externalController = null,
|
||||
Object? hosts = null,
|
||||
@@ -2187,9 +2383,9 @@ class __$$ClashConfigImplCopyWithImpl<$Res>
|
||||
? _value._proxyGroups
|
||||
: proxyGroups // ignore: cast_nullable_to_non_nullable
|
||||
as List<ProxyGroup>,
|
||||
rules: null == rules
|
||||
? _value._rules
|
||||
: rules // ignore: cast_nullable_to_non_nullable
|
||||
rule: null == rule
|
||||
? _value._rule
|
||||
: rule // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
globalUa: freezed == globalUa
|
||||
? _value.globalUa
|
||||
@@ -2230,13 +2426,13 @@ class _$ClashConfigImpl implements _ClashConfig {
|
||||
this.geodataLoader = GeodataLoader.memconservative,
|
||||
@JsonKey(name: "proxy-groups")
|
||||
final List<ProxyGroup> proxyGroups = const [],
|
||||
final List<String> rules = const [],
|
||||
final List<String> rule = const [],
|
||||
@JsonKey(name: "global-ua") this.globalUa,
|
||||
@JsonKey(name: "external-controller")
|
||||
this.externalController = ExternalControllerStatus.close,
|
||||
final Map<String, String> hosts = const {}})
|
||||
: _proxyGroups = proxyGroups,
|
||||
_rules = rules,
|
||||
_rule = rule,
|
||||
_hosts = hosts;
|
||||
|
||||
factory _$ClashConfigImpl.fromJson(Map<String, dynamic> json) =>
|
||||
@@ -2290,13 +2486,13 @@ class _$ClashConfigImpl implements _ClashConfig {
|
||||
return EqualUnmodifiableListView(_proxyGroups);
|
||||
}
|
||||
|
||||
final List<String> _rules;
|
||||
final List<String> _rule;
|
||||
@override
|
||||
@JsonKey()
|
||||
List<String> get rules {
|
||||
if (_rules is EqualUnmodifiableListView) return _rules;
|
||||
List<String> get rule {
|
||||
if (_rule is EqualUnmodifiableListView) return _rule;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_rules);
|
||||
return EqualUnmodifiableListView(_rule);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2316,7 +2512,7 @@ class _$ClashConfigImpl implements _ClashConfig {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ClashConfig(mixedPort: $mixedPort, mode: $mode, allowLan: $allowLan, logLevel: $logLevel, ipv6: $ipv6, findProcessMode: $findProcessMode, keepAliveInterval: $keepAliveInterval, unifiedDelay: $unifiedDelay, tcpConcurrent: $tcpConcurrent, tun: $tun, dns: $dns, geoXUrl: $geoXUrl, geodataLoader: $geodataLoader, proxyGroups: $proxyGroups, rules: $rules, globalUa: $globalUa, externalController: $externalController, hosts: $hosts)';
|
||||
return 'ClashConfig(mixedPort: $mixedPort, mode: $mode, allowLan: $allowLan, logLevel: $logLevel, ipv6: $ipv6, findProcessMode: $findProcessMode, keepAliveInterval: $keepAliveInterval, unifiedDelay: $unifiedDelay, tcpConcurrent: $tcpConcurrent, tun: $tun, dns: $dns, geoXUrl: $geoXUrl, geodataLoader: $geodataLoader, proxyGroups: $proxyGroups, rule: $rule, globalUa: $globalUa, externalController: $externalController, hosts: $hosts)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2347,7 +2543,7 @@ class _$ClashConfigImpl implements _ClashConfig {
|
||||
other.geodataLoader == geodataLoader) &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._proxyGroups, _proxyGroups) &&
|
||||
const DeepCollectionEquality().equals(other._rules, _rules) &&
|
||||
const DeepCollectionEquality().equals(other._rule, _rule) &&
|
||||
(identical(other.globalUa, globalUa) ||
|
||||
other.globalUa == globalUa) &&
|
||||
(identical(other.externalController, externalController) ||
|
||||
@@ -2373,7 +2569,7 @@ class _$ClashConfigImpl implements _ClashConfig {
|
||||
geoXUrl,
|
||||
geodataLoader,
|
||||
const DeepCollectionEquality().hash(_proxyGroups),
|
||||
const DeepCollectionEquality().hash(_rules),
|
||||
const DeepCollectionEquality().hash(_rule),
|
||||
globalUa,
|
||||
externalController,
|
||||
const DeepCollectionEquality().hash(_hosts));
|
||||
@@ -2412,7 +2608,7 @@ abstract class _ClashConfig implements ClashConfig {
|
||||
final GeoXUrl geoXUrl,
|
||||
@JsonKey(name: "geodata-loader") final GeodataLoader geodataLoader,
|
||||
@JsonKey(name: "proxy-groups") final List<ProxyGroup> proxyGroups,
|
||||
final List<String> rules,
|
||||
final List<String> rule,
|
||||
@JsonKey(name: "global-ua") final String? globalUa,
|
||||
@JsonKey(name: "external-controller")
|
||||
final ExternalControllerStatus externalController,
|
||||
@@ -2462,7 +2658,7 @@ abstract class _ClashConfig implements ClashConfig {
|
||||
@JsonKey(name: "proxy-groups")
|
||||
List<ProxyGroup> get proxyGroups;
|
||||
@override
|
||||
List<String> get rules;
|
||||
List<String> get rule;
|
||||
@override
|
||||
@JsonKey(name: "global-ua")
|
||||
String? get globalUa;
|
||||
|
||||
@@ -206,6 +206,25 @@ Map<String, dynamic> _$$GeoXUrlImplToJson(_$GeoXUrlImpl instance) =>
|
||||
'geosite': instance.geosite,
|
||||
};
|
||||
|
||||
_$ClashConfigSnippetImpl _$$ClashConfigSnippetImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$ClashConfigSnippetImpl(
|
||||
proxyGroups: (json['proxy-groups'] as List<dynamic>?)
|
||||
?.map((e) => ProxyGroup.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
const [],
|
||||
rule:
|
||||
(json['rule'] as List<dynamic>?)?.map((e) => e as String).toList() ??
|
||||
const [],
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ClashConfigSnippetImplToJson(
|
||||
_$ClashConfigSnippetImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'proxy-groups': instance.proxyGroups,
|
||||
'rule': instance.rule,
|
||||
};
|
||||
|
||||
_$ClashConfigImpl _$$ClashConfigImplFromJson(Map<String, dynamic> json) =>
|
||||
_$ClashConfigImpl(
|
||||
mixedPort: (json['mixed-port'] as num?)?.toInt() ?? defaultMixedPort,
|
||||
@@ -238,8 +257,8 @@ _$ClashConfigImpl _$$ClashConfigImplFromJson(Map<String, dynamic> json) =>
|
||||
?.map((e) => ProxyGroup.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
const [],
|
||||
rules:
|
||||
(json['rules'] as List<dynamic>?)?.map((e) => e as String).toList() ??
|
||||
rule:
|
||||
(json['rule'] as List<dynamic>?)?.map((e) => e as String).toList() ??
|
||||
const [],
|
||||
globalUa: json['global-ua'] as String?,
|
||||
externalController: $enumDecodeNullable(
|
||||
@@ -267,7 +286,7 @@ Map<String, dynamic> _$$ClashConfigImplToJson(_$ClashConfigImpl instance) =>
|
||||
'geox-url': instance.geoXUrl,
|
||||
'geodata-loader': _$GeodataLoaderEnumMap[instance.geodataLoader]!,
|
||||
'proxy-groups': instance.proxyGroups,
|
||||
'rules': instance.rules,
|
||||
'rule': instance.rule,
|
||||
'global-ua': instance.globalUa,
|
||||
'external-controller':
|
||||
_$ExternalControllerStatusEnumMap[instance.externalController]!,
|
||||
|
||||
@@ -14,6 +14,153 @@ T _$identity<T>(T value) => value;
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
/// @nodoc
|
||||
mixin _$VM2<A, B> {
|
||||
A get a => throw _privateConstructorUsedError;
|
||||
B get b => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of VM2
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$VM2CopyWith<A, B, VM2<A, B>> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $VM2CopyWith<A, B, $Res> {
|
||||
factory $VM2CopyWith(VM2<A, B> value, $Res Function(VM2<A, B>) then) =
|
||||
_$VM2CopyWithImpl<A, B, $Res, VM2<A, B>>;
|
||||
@useResult
|
||||
$Res call({A a, B b});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$VM2CopyWithImpl<A, B, $Res, $Val extends VM2<A, B>>
|
||||
implements $VM2CopyWith<A, B, $Res> {
|
||||
_$VM2CopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of VM2
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? a = freezed,
|
||||
Object? b = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
a: freezed == a
|
||||
? _value.a
|
||||
: a // ignore: cast_nullable_to_non_nullable
|
||||
as A,
|
||||
b: freezed == b
|
||||
? _value.b
|
||||
: b // ignore: cast_nullable_to_non_nullable
|
||||
as B,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$VM2ImplCopyWith<A, B, $Res>
|
||||
implements $VM2CopyWith<A, B, $Res> {
|
||||
factory _$$VM2ImplCopyWith(
|
||||
_$VM2Impl<A, B> value, $Res Function(_$VM2Impl<A, B>) then) =
|
||||
__$$VM2ImplCopyWithImpl<A, B, $Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({A a, B b});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$VM2ImplCopyWithImpl<A, B, $Res>
|
||||
extends _$VM2CopyWithImpl<A, B, $Res, _$VM2Impl<A, B>>
|
||||
implements _$$VM2ImplCopyWith<A, B, $Res> {
|
||||
__$$VM2ImplCopyWithImpl(
|
||||
_$VM2Impl<A, B> _value, $Res Function(_$VM2Impl<A, B>) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of VM2
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? a = freezed,
|
||||
Object? b = freezed,
|
||||
}) {
|
||||
return _then(_$VM2Impl<A, B>(
|
||||
a: freezed == a
|
||||
? _value.a
|
||||
: a // ignore: cast_nullable_to_non_nullable
|
||||
as A,
|
||||
b: freezed == b
|
||||
? _value.b
|
||||
: b // ignore: cast_nullable_to_non_nullable
|
||||
as B,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$VM2Impl<A, B> implements _VM2<A, B> {
|
||||
const _$VM2Impl({required this.a, required this.b});
|
||||
|
||||
@override
|
||||
final A a;
|
||||
@override
|
||||
final B b;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'VM2<$A, $B>(a: $a, b: $b)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$VM2Impl<A, B> &&
|
||||
const DeepCollectionEquality().equals(other.a, a) &&
|
||||
const DeepCollectionEquality().equals(other.b, b));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
const DeepCollectionEquality().hash(a),
|
||||
const DeepCollectionEquality().hash(b));
|
||||
|
||||
/// Create a copy of VM2
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$VM2ImplCopyWith<A, B, _$VM2Impl<A, B>> get copyWith =>
|
||||
__$$VM2ImplCopyWithImpl<A, B, _$VM2Impl<A, B>>(this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _VM2<A, B> implements VM2<A, B> {
|
||||
const factory _VM2({required final A a, required final B b}) =
|
||||
_$VM2Impl<A, B>;
|
||||
|
||||
@override
|
||||
A get a;
|
||||
@override
|
||||
B get b;
|
||||
|
||||
/// Create a copy of VM2
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$VM2ImplCopyWith<A, B, _$VM2Impl<A, B>> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$StartButtonSelectorState {
|
||||
bool get isInit => throw _privateConstructorUsedError;
|
||||
|
||||
@@ -7,6 +7,15 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'generated/selector.freezed.dart';
|
||||
|
||||
@freezed
|
||||
class VM2<A, B> with _$VM2<A, B> {
|
||||
const factory VM2({
|
||||
required A a,
|
||||
required B b,
|
||||
}) = _VM2;
|
||||
}
|
||||
|
||||
|
||||
@freezed
|
||||
class StartButtonSelectorState with _$StartButtonSelectorState {
|
||||
const factory StartButtonSelectorState({
|
||||
@@ -134,18 +143,19 @@ extension PackageListSelectorStateExt on PackageListSelectorState {
|
||||
return packages
|
||||
.where((item) => isFilterSystemApp ? item.isSystem == false : true)
|
||||
.sorted(
|
||||
(a, b) {
|
||||
(a, b) {
|
||||
return switch (sort) {
|
||||
AccessSortType.none => 0,
|
||||
AccessSortType.name => other.sortByChar(
|
||||
other.getPinyin(a.label),
|
||||
other.getPinyin(b.label),
|
||||
),
|
||||
AccessSortType.name =>
|
||||
other.sortByChar(
|
||||
other.getPinyin(a.label),
|
||||
other.getPinyin(b.label),
|
||||
),
|
||||
AccessSortType.time => b.lastUpdateTime.compareTo(a.lastUpdateTime),
|
||||
};
|
||||
},
|
||||
).sorted(
|
||||
(a, b) {
|
||||
(a, b) {
|
||||
final isSelectA = selectedList.contains(a.packageName);
|
||||
final isSelectB = selectedList.contains(b.packageName);
|
||||
if (isSelectA && isSelectB) return 0;
|
||||
|
||||
@@ -95,7 +95,7 @@ final clashConfigStateProvider = AutoDisposeProvider<ClashConfigState>.internal(
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
typedef ClashConfigStateRef = AutoDisposeProviderRef<ClashConfigState>;
|
||||
String _$proxyStateHash() => r'61ec20fcf35118aca445719c83e77e7d237f5570';
|
||||
String _$proxyStateHash() => r'22478fb593aaca11dfe2cf64472013190475a5bc';
|
||||
|
||||
/// See also [proxyState].
|
||||
@ProviderFor(proxyState)
|
||||
|
||||
@@ -81,14 +81,19 @@ ClashConfigState clashConfigState(Ref ref) {
|
||||
@riverpod
|
||||
ProxyState proxyState(Ref ref) {
|
||||
final isStart = ref.watch(runTimeProvider.select((state) => state != null));
|
||||
final networkProps = ref.watch(networkSettingProvider);
|
||||
final vm2 = ref.watch(networkSettingProvider.select(
|
||||
(state) => VM2(
|
||||
a: state.systemProxy,
|
||||
b: state.bypassDomain,
|
||||
),
|
||||
));
|
||||
final mixedPort = ref.watch(
|
||||
patchClashConfigProvider.select((state) => state.mixedPort),
|
||||
);
|
||||
return ProxyState(
|
||||
isStart: isStart,
|
||||
systemProxy: networkProps.systemProxy,
|
||||
bassDomain: networkProps.bypassDomain,
|
||||
systemProxy: vm2.a,
|
||||
bassDomain: vm2.b,
|
||||
port: mixedPort,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:fl_clash/common/common.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@@ -18,6 +19,17 @@ class DonutChartData {
|
||||
String toString() {
|
||||
return 'DonutChartData{_value: $_value}';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is DonutChartData &&
|
||||
runtimeType == other.runtimeType &&
|
||||
_value == other._value &&
|
||||
color == other.color;
|
||||
|
||||
@override
|
||||
int get hashCode => _value.hashCode ^ color.hashCode;
|
||||
}
|
||||
|
||||
class DonutChart extends StatefulWidget {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class WaveView extends StatefulWidget {
|
||||
@@ -40,23 +41,25 @@ class _WaveViewState extends State<WaveView>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(builder: (_, container) {
|
||||
return AnimatedBuilder(
|
||||
animation: _controller,
|
||||
builder: (context, child) {
|
||||
return CustomPaint(
|
||||
painter: WavePainter(
|
||||
animationValue: _controller.value,
|
||||
waveAmplitude: widget.waveAmplitude,
|
||||
waveFrequency: widget.waveFrequency,
|
||||
waveColor: widget.waveColor,
|
||||
),
|
||||
size: Size(
|
||||
container.maxHeight,
|
||||
container.maxHeight,
|
||||
),
|
||||
);
|
||||
},
|
||||
return LayoutBuilder(builder: (_, constraints) {
|
||||
return RepaintBoundary(
|
||||
child: AnimatedBuilder(
|
||||
animation: _controller,
|
||||
builder: (context, child) {
|
||||
return CustomPaint(
|
||||
painter: WavePainter(
|
||||
animationValue: _controller.value,
|
||||
waveAmplitude: widget.waveAmplitude,
|
||||
waveFrequency: widget.waveFrequency,
|
||||
waveColor: widget.waveColor,
|
||||
),
|
||||
size: Size(
|
||||
constraints.maxWidth,
|
||||
constraints.maxHeight,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -68,41 +71,60 @@ class WavePainter extends CustomPainter {
|
||||
final double waveFrequency;
|
||||
final Color waveColor;
|
||||
|
||||
late Paint _paint;
|
||||
final Path _path = Path();
|
||||
Color _lastColor;
|
||||
|
||||
WavePainter({
|
||||
required this.animationValue,
|
||||
required this.waveAmplitude,
|
||||
required this.waveFrequency,
|
||||
required this.waveColor,
|
||||
});
|
||||
}) : _lastColor = waveColor {
|
||||
_paint = Paint()
|
||||
..color = waveColor
|
||||
..style = PaintingStyle.fill;
|
||||
}
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint = Paint()
|
||||
..color = waveColor
|
||||
..style = PaintingStyle.fill;
|
||||
|
||||
final path = Path();
|
||||
|
||||
final baseHeight = size.height / 3;
|
||||
|
||||
path.moveTo(0, baseHeight);
|
||||
|
||||
for (double x = 0; x <= size.width; x++) {
|
||||
final y = waveAmplitude *
|
||||
sin((x / size.width * 2 * pi * waveFrequency) +
|
||||
(animationValue * 2 * pi));
|
||||
path.lineTo(x, baseHeight + y);
|
||||
if (waveColor != _lastColor) {
|
||||
_paint = Paint()
|
||||
..color = waveColor
|
||||
..style = PaintingStyle.fill;
|
||||
_lastColor = waveColor;
|
||||
}
|
||||
|
||||
path.lineTo(size.width, size.height);
|
||||
path.lineTo(0, size.height);
|
||||
path.close();
|
||||
_path.reset();
|
||||
|
||||
canvas.drawPath(path, paint);
|
||||
final baseHeight = size.height / 3;
|
||||
final phase = animationValue * 2 * pi;
|
||||
final widthFactor = 2 * pi * waveFrequency / size.width;
|
||||
|
||||
_path.moveTo(0, baseHeight);
|
||||
|
||||
for (double x = 0; x <= size.width; x += size.width / 20) {
|
||||
final y = waveAmplitude * sin(x * widthFactor + phase);
|
||||
_path.lineTo(x, baseHeight + y);
|
||||
}
|
||||
|
||||
_path.lineTo(
|
||||
size.width,
|
||||
baseHeight + waveAmplitude * sin(size.width * widthFactor + phase),
|
||||
);
|
||||
|
||||
_path.lineTo(size.width, size.height);
|
||||
_path.lineTo(0, size.height);
|
||||
_path.close();
|
||||
|
||||
canvas.drawPath(_path, _paint);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
||||
return true;
|
||||
bool shouldRepaint(covariant WavePainter oldDelegate) {
|
||||
return oldDelegate.animationValue != animationValue ||
|
||||
oldDelegate.waveAmplitude != waveAmplitude ||
|
||||
oldDelegate.waveFrequency != waveFrequency ||
|
||||
oldDelegate.waveColor != waveColor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,5 @@
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>FLTEnableImpeller</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -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.79+202503071
|
||||
version: 0.8.80+202503101
|
||||
environment:
|
||||
sdk: '>=3.1.0 <4.0.0'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user