Fix notification duplicate creation issue

Fix AccessControl click issue
This commit is contained in:
chen08209
2024-06-03 11:24:41 +08:00
parent bd5470b863
commit 3074b1299e
8 changed files with 558 additions and 315 deletions

View File

@@ -13,6 +13,7 @@ import android.os.Binder
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE
import androidx.core.graphics.drawable.IconCompat
import com.follow.clash.GlobalState
import com.follow.clash.MainActivity
@@ -20,6 +21,7 @@ import com.follow.clash.models.AccessControl
import com.follow.clash.models.AccessControlMode
@SuppressLint("WrongConstant")
class FlClashVpnService : VpnService() {
@@ -97,6 +99,43 @@ class FlClashVpnService : VpnService() {
stopForeground()
}
private val notificationBuilder by lazy {
val intent = Intent(this, MainActivity::class.java)
val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
} else {
PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
}
val icon = IconCompat.createWithResource(this, this.applicationInfo.icon)
with(NotificationCompat.Builder(this, CHANNEL)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setSmallIcon(icon)
}
setContentTitle("FlClash")
foregroundServiceBehavior = FOREGROUND_SERVICE_IMMEDIATE
setContentIntent(pendingIntent)
setCategory(NotificationCompat.CATEGORY_SERVICE)
priority = NotificationCompat.PRIORITY_LOW
setOngoing(true)
setShowWhen(false)
setOnlyAlertOnce(true)
}
}
@SuppressLint("ForegroundServiceType", "WrongConstant")
fun startForeground(title: String, content: String) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -104,42 +143,13 @@ class FlClashVpnService : VpnService() {
NotificationChannel(CHANNEL, "FlClash", NotificationManager.IMPORTANCE_LOW)
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(channel)
val intent = Intent(this, MainActivity::class.java)
val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
} else {
PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
}
val icon = IconCompat.createWithResource(this, this.applicationInfo.icon)
val notification = with(NotificationCompat.Builder(this, CHANNEL)) {
setSmallIcon(icon)
setContentTitle(title)
setContentText(content)
foregroundServiceBehavior = NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE
setContentIntent(pendingIntent)
setOngoing(true)
setShowWhen(false)
build()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
startForeground(notificationId, notification, FOREGROUND_SERVICE_TYPE_SPECIAL_USE)
} else {
startForeground(notificationId, notification)
}
}
val notification =
notificationBuilder.setContentTitle(title).setContentText(content).build()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
startForeground(notificationId, notification, FOREGROUND_SERVICE_TYPE_SPECIAL_USE)
} else {
startForeground(notificationId, notification)
}
}

View File

@@ -1,7 +1,9 @@
import 'package:collection/collection.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@@ -19,8 +21,10 @@ class _AccessFragmentState extends State<AccessFragment> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
packagesListenable.value = await app?.getPackages() ?? [];
WidgetsBinding.instance.addPostFrameCallback((_) {
Future.delayed(const Duration(milliseconds: 300), () async {
packagesListenable.value = await app?.getPackages() ?? [];
});
});
}
@@ -91,13 +95,28 @@ class _AccessFragmentState extends State<AccessFragment> {
return IconButton(
tooltip: tooltip,
onPressed: () {
final config = context.read<Config>();
final config = globalState.appController.config;
final isAccept =
config.accessControl.mode == AccessControlMode.acceptSelected;
if (isSelectedAll) {
config.accessControl.currentList = [];
config.accessControl = config.accessControl.copyWith();
config.accessControl = switch (isAccept) {
true => config.accessControl.copyWith(
acceptList: [],
),
false => config.accessControl.copyWith(
rejectList: [],
),
};
} else {
config.accessControl.currentList = allValueList;
config.accessControl = config.accessControl.copyWith();
config.accessControl = switch (isAccept) {
true => config.accessControl.copyWith(
acceptList: allValueList,
),
false => config.accessControl.copyWith(
rejectList: allValueList,
),
};
}
},
icon: isSelectedAll
@@ -181,7 +200,8 @@ class _AccessFragmentState extends State<AccessFragment> {
children: [
Flexible(
child: _buildSelectedAllButton(
isSelectedAll: valueList.length == packageNameList.length,
isSelectedAll: const ListEquality<String>()
.equals(valueList, packageNameList),
allValueList: packageNameList,
),
),
@@ -195,13 +215,18 @@ class _AccessFragmentState extends State<AccessFragment> {
);
}
Widget _buildPackageList(bool isAccessControl) {
Widget _buildPackageList() {
return ValueListenableBuilder(
valueListenable: packagesListenable,
builder: (_, packages, ___) {
return Selector<Config, AccessControl>(
selector: (_, config) => config.accessControl,
builder: (context, accessControl, __) {
return Selector<Config, PackageListSelectorState>(
selector: (_, config) => PackageListSelectorState(
accessControl: config.accessControl,
isAccessControl: config.isAccessControl,
),
builder: (context, state, __) {
final accessControl = state.accessControl;
final isAccessControl = state.isAccessControl;
final isFilterSystemApp = accessControl.isFilterSystemApp;
final currentPackages = isFilterSystemApp
? packages
@@ -211,13 +236,15 @@ class _AccessFragmentState extends State<AccessFragment> {
final packageNameList =
currentPackages.map((e) => e.packageName).toList();
final accessControlMode = accessControl.mode;
final valueList =
accessControl.currentList.intersection(packageNameList);
final currentList =
accessControlMode == AccessControlMode.acceptSelected
? accessControl.acceptList
: accessControl.rejectList;
final valueList = currentList.intersection(packageNameList);
final describe =
accessControlMode == AccessControlMode.acceptSelected
? appLocalizations.accessControlAllowDesc
: appLocalizations.accessControlNotAllowDesc;
return DisabledMask(
status: !isAccessControl,
child: Column(
@@ -241,7 +268,7 @@ class _AccessFragmentState extends State<AccessFragment> {
itemBuilder: (_, index) {
final package = currentPackages[index];
return PackageListItem(
key: Key(package.label),
key: Key(package.packageName),
package: package,
value:
valueList.contains(package.packageName),
@@ -252,11 +279,20 @@ class _AccessFragmentState extends State<AccessFragment> {
} else {
valueList.remove(package.packageName);
}
final config = context.read<Config>();
config.accessControl.currentList =
valueList;
config.accessControl =
config.accessControl.copyWith();
final config =
globalState.appController.config;
if (accessControlMode ==
AccessControlMode.acceptSelected) {
config.accessControl =
config.accessControl.copyWith(
acceptList: valueList,
);
} else {
config.accessControl =
config.accessControl.copyWith(
rejectList: valueList,
);
}
},
);
},
@@ -276,7 +312,7 @@ class _AccessFragmentState extends State<AccessFragment> {
Widget build(BuildContext context) {
return Selector<Config, bool>(
selector: (_, config) => config.isAccessControl,
builder: (_, isAccessControl, __) {
builder: (_, isAccessControl, child) {
return Column(
mainAxisSize: MainAxisSize.max,
children: [
@@ -300,11 +336,12 @@ class _AccessFragmentState extends State<AccessFragment> {
),
),
Flexible(
child: _buildPackageList(isAccessControl),
child: child!,
),
],
);
},
child: _buildPackageList(),
);
}
}

View File

@@ -1,78 +1,26 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import '../enum/enum.dart';
import '../common/common.dart';
import 'models.dart';
part 'generated/config.g.dart';
part 'generated/config.freezed.dart';
@JsonSerializable()
class AccessControl {
AccessControlMode mode;
List<String> acceptList;
List<String> rejectList;
bool isFilterSystemApp;
@freezed
class AccessControl with _$AccessControl {
const factory AccessControl({
@Default(AccessControlMode.rejectSelected) AccessControlMode mode,
@Default([]) List<String> acceptList,
@Default([]) List<String> rejectList,
@Default(true) bool isFilterSystemApp,
}) = _AccessControl;
AccessControl({
this.isFilterSystemApp = true,
this.mode = AccessControlMode.rejectSelected,
this.acceptList = const [],
this.rejectList = const [],
});
@JsonKey(includeFromJson: false, includeToJson: false)
List<String> get currentList =>
mode == AccessControlMode.acceptSelected ? acceptList : rejectList;
set currentList(List<String> currentList) {
if (mode == AccessControlMode.acceptSelected) {
acceptList = currentList;
} else {
rejectList = currentList;
}
}
AccessControl copyWith({
AccessControlMode? mode,
List<String>? acceptList,
List<String>? rejectList,
bool? isFilterSystemApp,
}) {
return AccessControl(
mode: mode ?? this.mode,
acceptList: acceptList ?? this.acceptList,
rejectList: rejectList ?? this.rejectList,
isFilterSystemApp: isFilterSystemApp ?? this.isFilterSystemApp,
);
}
Map<String, dynamic> toJson() {
return _$AccessControlToJson(this);
}
factory AccessControl.fromJson(Map<String, dynamic> json) {
return _$AccessControlFromJson(json);
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is AccessControl &&
runtimeType == other.runtimeType &&
mode == other.mode &&
acceptList == other.acceptList &&
rejectList == other.rejectList &&
isFilterSystemApp == other.isFilterSystemApp;
@override
int get hashCode =>
mode.hashCode ^
acceptList.hashCode ^
rejectList.hashCode ^
isFilterSystemApp.hashCode;
factory AccessControl.fromJson(Map<String, Object?> json) =>
_$AccessControlFromJson(json);
}
@JsonSerializable()
@@ -108,7 +56,7 @@ class Config extends ChangeNotifier {
_isMinimizeOnExit = true,
_isAccessControl = false,
_autoCheckUpdate = true,
_accessControl = AccessControl(),
_accessControl = const AccessControl(),
_isAnimateToPage = true;
deleteProfileById(String id) {
@@ -142,7 +90,7 @@ class Config extends ChangeNotifier {
_setProfile(Profile profile) {
final List<Profile> profilesTemp = List.from(_profiles);
final index =
profilesTemp.indexWhere((element) => element.id == profile.id);
profilesTemp.indexWhere((element) => element.id == profile.id);
final updateProfile = profile.copyWith(
label: _getLabel(profile.label, profile.id),
);
@@ -357,17 +305,18 @@ class Config extends ChangeNotifier {
}
}
update([Config? config, RecoveryOption recoveryOptions = RecoveryOption.all]) {
update(
[Config? config, RecoveryOption recoveryOptions = RecoveryOption.all]) {
if (config != null) {
_profiles = config._profiles;
for (final profile in config._profiles) {
_setProfile(profile);
}
final onlyProfiles = recoveryOptions == RecoveryOption.onlyProfiles;
if(_currentProfileId == null && onlyProfiles && profiles.isNotEmpty){
if (_currentProfileId == null && onlyProfiles && profiles.isNotEmpty) {
_currentProfileId = _profiles.first.id;
}
if(onlyProfiles) return;
if (onlyProfiles) return;
_currentProfileId = config._currentProfileId;
_isCompatible = config._isCompatible;
_autoLaunch = config._autoLaunch;

View File

@@ -0,0 +1,241 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of '../config.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
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');
AccessControl _$AccessControlFromJson(Map<String, dynamic> json) {
return _AccessControl.fromJson(json);
}
/// @nodoc
mixin _$AccessControl {
AccessControlMode get mode => throw _privateConstructorUsedError;
List<String> get acceptList => throw _privateConstructorUsedError;
List<String> get rejectList => throw _privateConstructorUsedError;
bool get isFilterSystemApp => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$AccessControlCopyWith<AccessControl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $AccessControlCopyWith<$Res> {
factory $AccessControlCopyWith(
AccessControl value, $Res Function(AccessControl) then) =
_$AccessControlCopyWithImpl<$Res, AccessControl>;
@useResult
$Res call(
{AccessControlMode mode,
List<String> acceptList,
List<String> rejectList,
bool isFilterSystemApp});
}
/// @nodoc
class _$AccessControlCopyWithImpl<$Res, $Val extends AccessControl>
implements $AccessControlCopyWith<$Res> {
_$AccessControlCopyWithImpl(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? mode = null,
Object? acceptList = null,
Object? rejectList = null,
Object? isFilterSystemApp = null,
}) {
return _then(_value.copyWith(
mode: null == mode
? _value.mode
: mode // ignore: cast_nullable_to_non_nullable
as AccessControlMode,
acceptList: null == acceptList
? _value.acceptList
: acceptList // ignore: cast_nullable_to_non_nullable
as List<String>,
rejectList: null == rejectList
? _value.rejectList
: rejectList // ignore: cast_nullable_to_non_nullable
as List<String>,
isFilterSystemApp: null == isFilterSystemApp
? _value.isFilterSystemApp
: isFilterSystemApp // ignore: cast_nullable_to_non_nullable
as bool,
) as $Val);
}
}
/// @nodoc
abstract class _$$AccessControlImplCopyWith<$Res>
implements $AccessControlCopyWith<$Res> {
factory _$$AccessControlImplCopyWith(
_$AccessControlImpl value, $Res Function(_$AccessControlImpl) then) =
__$$AccessControlImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{AccessControlMode mode,
List<String> acceptList,
List<String> rejectList,
bool isFilterSystemApp});
}
/// @nodoc
class __$$AccessControlImplCopyWithImpl<$Res>
extends _$AccessControlCopyWithImpl<$Res, _$AccessControlImpl>
implements _$$AccessControlImplCopyWith<$Res> {
__$$AccessControlImplCopyWithImpl(
_$AccessControlImpl _value, $Res Function(_$AccessControlImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? mode = null,
Object? acceptList = null,
Object? rejectList = null,
Object? isFilterSystemApp = null,
}) {
return _then(_$AccessControlImpl(
mode: null == mode
? _value.mode
: mode // ignore: cast_nullable_to_non_nullable
as AccessControlMode,
acceptList: null == acceptList
? _value._acceptList
: acceptList // ignore: cast_nullable_to_non_nullable
as List<String>,
rejectList: null == rejectList
? _value._rejectList
: rejectList // ignore: cast_nullable_to_non_nullable
as List<String>,
isFilterSystemApp: null == isFilterSystemApp
? _value.isFilterSystemApp
: isFilterSystemApp // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
@JsonSerializable()
class _$AccessControlImpl implements _AccessControl {
const _$AccessControlImpl(
{this.mode = AccessControlMode.rejectSelected,
final List<String> acceptList = const [],
final List<String> rejectList = const [],
this.isFilterSystemApp = true})
: _acceptList = acceptList,
_rejectList = rejectList;
factory _$AccessControlImpl.fromJson(Map<String, dynamic> json) =>
_$$AccessControlImplFromJson(json);
@override
@JsonKey()
final AccessControlMode mode;
final List<String> _acceptList;
@override
@JsonKey()
List<String> get acceptList {
if (_acceptList is EqualUnmodifiableListView) return _acceptList;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_acceptList);
}
final List<String> _rejectList;
@override
@JsonKey()
List<String> get rejectList {
if (_rejectList is EqualUnmodifiableListView) return _rejectList;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_rejectList);
}
@override
@JsonKey()
final bool isFilterSystemApp;
@override
String toString() {
return 'AccessControl(mode: $mode, acceptList: $acceptList, rejectList: $rejectList, isFilterSystemApp: $isFilterSystemApp)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$AccessControlImpl &&
(identical(other.mode, mode) || other.mode == mode) &&
const DeepCollectionEquality()
.equals(other._acceptList, _acceptList) &&
const DeepCollectionEquality()
.equals(other._rejectList, _rejectList) &&
(identical(other.isFilterSystemApp, isFilterSystemApp) ||
other.isFilterSystemApp == isFilterSystemApp));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hash(
runtimeType,
mode,
const DeepCollectionEquality().hash(_acceptList),
const DeepCollectionEquality().hash(_rejectList),
isFilterSystemApp);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$AccessControlImplCopyWith<_$AccessControlImpl> get copyWith =>
__$$AccessControlImplCopyWithImpl<_$AccessControlImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$AccessControlImplToJson(
this,
);
}
}
abstract class _AccessControl implements AccessControl {
const factory _AccessControl(
{final AccessControlMode mode,
final List<String> acceptList,
final List<String> rejectList,
final bool isFilterSystemApp}) = _$AccessControlImpl;
factory _AccessControl.fromJson(Map<String, dynamic> json) =
_$AccessControlImpl.fromJson;
@override
AccessControlMode get mode;
@override
List<String> get acceptList;
@override
List<String> get rejectList;
@override
bool get isFilterSystemApp;
@override
@JsonKey(ignore: true)
_$$AccessControlImplCopyWith<_$AccessControlImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -6,34 +6,6 @@ part of '../config.dart';
// JsonSerializableGenerator
// **************************************************************************
AccessControl _$AccessControlFromJson(Map<String, dynamic> json) =>
AccessControl(
isFilterSystemApp: json['isFilterSystemApp'] as bool? ?? true,
mode: $enumDecodeNullable(_$AccessControlModeEnumMap, json['mode']) ??
AccessControlMode.rejectSelected,
acceptList: (json['acceptList'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [],
rejectList: (json['rejectList'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [],
);
Map<String, dynamic> _$AccessControlToJson(AccessControl instance) =>
<String, dynamic>{
'mode': _$AccessControlModeEnumMap[instance.mode]!,
'acceptList': instance.acceptList,
'rejectList': instance.rejectList,
'isFilterSystemApp': instance.isFilterSystemApp,
};
const _$AccessControlModeEnumMap = {
AccessControlMode.acceptSelected: 'acceptSelected',
AccessControlMode.rejectSelected: 'rejectSelected',
};
Config _$ConfigFromJson(Map<String, dynamic> json) => Config()
..profiles = (json['profiles'] as List<dynamic>?)
?.map((e) => Profile.fromJson(e as Map<String, dynamic>))
@@ -93,3 +65,31 @@ const _$ProxiesSortTypeEnumMap = {
ProxiesSortType.delay: 'delay',
ProxiesSortType.name: 'name',
};
_$AccessControlImpl _$$AccessControlImplFromJson(Map<String, dynamic> json) =>
_$AccessControlImpl(
mode: $enumDecodeNullable(_$AccessControlModeEnumMap, json['mode']) ??
AccessControlMode.rejectSelected,
acceptList: (json['acceptList'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [],
rejectList: (json['rejectList'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [],
isFilterSystemApp: json['isFilterSystemApp'] as bool? ?? true,
);
Map<String, dynamic> _$$AccessControlImplToJson(_$AccessControlImpl instance) =>
<String, dynamic>{
'mode': _$AccessControlModeEnumMap[instance.mode]!,
'acceptList': instance.acceptList,
'rejectList': instance.rejectList,
'isFilterSystemApp': instance.isFilterSystemApp,
};
const _$AccessControlModeEnumMap = {
AccessControlMode.acceptSelected: 'acceptSelected',
AccessControlMode.rejectSelected: 'rejectSelected',
};

View File

@@ -667,155 +667,6 @@ abstract class _ProfilesSelectorState implements ProfilesSelectorState {
get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$PackageListSelectorState {
AccessControl get accessControl => throw _privateConstructorUsedError;
List<Package> get packages => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$PackageListSelectorStateCopyWith<PackageListSelectorState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $PackageListSelectorStateCopyWith<$Res> {
factory $PackageListSelectorStateCopyWith(PackageListSelectorState value,
$Res Function(PackageListSelectorState) then) =
_$PackageListSelectorStateCopyWithImpl<$Res, PackageListSelectorState>;
@useResult
$Res call({AccessControl accessControl, List<Package> packages});
}
/// @nodoc
class _$PackageListSelectorStateCopyWithImpl<$Res,
$Val extends PackageListSelectorState>
implements $PackageListSelectorStateCopyWith<$Res> {
_$PackageListSelectorStateCopyWithImpl(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? accessControl = null,
Object? packages = null,
}) {
return _then(_value.copyWith(
accessControl: null == accessControl
? _value.accessControl
: accessControl // ignore: cast_nullable_to_non_nullable
as AccessControl,
packages: null == packages
? _value.packages
: packages // ignore: cast_nullable_to_non_nullable
as List<Package>,
) as $Val);
}
}
/// @nodoc
abstract class _$$PackageListSelectorStateImplCopyWith<$Res>
implements $PackageListSelectorStateCopyWith<$Res> {
factory _$$PackageListSelectorStateImplCopyWith(
_$PackageListSelectorStateImpl value,
$Res Function(_$PackageListSelectorStateImpl) then) =
__$$PackageListSelectorStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({AccessControl accessControl, List<Package> packages});
}
/// @nodoc
class __$$PackageListSelectorStateImplCopyWithImpl<$Res>
extends _$PackageListSelectorStateCopyWithImpl<$Res,
_$PackageListSelectorStateImpl>
implements _$$PackageListSelectorStateImplCopyWith<$Res> {
__$$PackageListSelectorStateImplCopyWithImpl(
_$PackageListSelectorStateImpl _value,
$Res Function(_$PackageListSelectorStateImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? accessControl = null,
Object? packages = null,
}) {
return _then(_$PackageListSelectorStateImpl(
accessControl: null == accessControl
? _value.accessControl
: accessControl // ignore: cast_nullable_to_non_nullable
as AccessControl,
packages: null == packages
? _value._packages
: packages // ignore: cast_nullable_to_non_nullable
as List<Package>,
));
}
}
/// @nodoc
class _$PackageListSelectorStateImpl implements _PackageListSelectorState {
const _$PackageListSelectorStateImpl(
{required this.accessControl, required final List<Package> packages})
: _packages = packages;
@override
final AccessControl accessControl;
final List<Package> _packages;
@override
List<Package> get packages {
if (_packages is EqualUnmodifiableListView) return _packages;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_packages);
}
@override
String toString() {
return 'PackageListSelectorState(accessControl: $accessControl, packages: $packages)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$PackageListSelectorStateImpl &&
(identical(other.accessControl, accessControl) ||
other.accessControl == accessControl) &&
const DeepCollectionEquality().equals(other._packages, _packages));
}
@override
int get hashCode => Object.hash(runtimeType, accessControl,
const DeepCollectionEquality().hash(_packages));
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$PackageListSelectorStateImplCopyWith<_$PackageListSelectorStateImpl>
get copyWith => __$$PackageListSelectorStateImplCopyWithImpl<
_$PackageListSelectorStateImpl>(this, _$identity);
}
abstract class _PackageListSelectorState implements PackageListSelectorState {
const factory _PackageListSelectorState(
{required final AccessControl accessControl,
required final List<Package> packages}) = _$PackageListSelectorStateImpl;
@override
AccessControl get accessControl;
@override
List<Package> get packages;
@override
@JsonKey(ignore: true)
_$$PackageListSelectorStateImplCopyWith<_$PackageListSelectorStateImpl>
get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$ApplicationSelectorState {
String? get locale => throw _privateConstructorUsedError;
@@ -2219,3 +2070,159 @@ abstract class _MoreToolsSelectorState implements MoreToolsSelectorState {
_$$MoreToolsSelectorStateImplCopyWith<_$MoreToolsSelectorStateImpl>
get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$PackageListSelectorState {
AccessControl get accessControl => throw _privateConstructorUsedError;
bool get isAccessControl => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$PackageListSelectorStateCopyWith<PackageListSelectorState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $PackageListSelectorStateCopyWith<$Res> {
factory $PackageListSelectorStateCopyWith(PackageListSelectorState value,
$Res Function(PackageListSelectorState) then) =
_$PackageListSelectorStateCopyWithImpl<$Res, PackageListSelectorState>;
@useResult
$Res call({AccessControl accessControl, bool isAccessControl});
$AccessControlCopyWith<$Res> get accessControl;
}
/// @nodoc
class _$PackageListSelectorStateCopyWithImpl<$Res,
$Val extends PackageListSelectorState>
implements $PackageListSelectorStateCopyWith<$Res> {
_$PackageListSelectorStateCopyWithImpl(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? accessControl = null,
Object? isAccessControl = null,
}) {
return _then(_value.copyWith(
accessControl: null == accessControl
? _value.accessControl
: accessControl // ignore: cast_nullable_to_non_nullable
as AccessControl,
isAccessControl: null == isAccessControl
? _value.isAccessControl
: isAccessControl // ignore: cast_nullable_to_non_nullable
as bool,
) as $Val);
}
@override
@pragma('vm:prefer-inline')
$AccessControlCopyWith<$Res> get accessControl {
return $AccessControlCopyWith<$Res>(_value.accessControl, (value) {
return _then(_value.copyWith(accessControl: value) as $Val);
});
}
}
/// @nodoc
abstract class _$$PackageListSelectorStateImplCopyWith<$Res>
implements $PackageListSelectorStateCopyWith<$Res> {
factory _$$PackageListSelectorStateImplCopyWith(
_$PackageListSelectorStateImpl value,
$Res Function(_$PackageListSelectorStateImpl) then) =
__$$PackageListSelectorStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({AccessControl accessControl, bool isAccessControl});
@override
$AccessControlCopyWith<$Res> get accessControl;
}
/// @nodoc
class __$$PackageListSelectorStateImplCopyWithImpl<$Res>
extends _$PackageListSelectorStateCopyWithImpl<$Res,
_$PackageListSelectorStateImpl>
implements _$$PackageListSelectorStateImplCopyWith<$Res> {
__$$PackageListSelectorStateImplCopyWithImpl(
_$PackageListSelectorStateImpl _value,
$Res Function(_$PackageListSelectorStateImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? accessControl = null,
Object? isAccessControl = null,
}) {
return _then(_$PackageListSelectorStateImpl(
accessControl: null == accessControl
? _value.accessControl
: accessControl // ignore: cast_nullable_to_non_nullable
as AccessControl,
isAccessControl: null == isAccessControl
? _value.isAccessControl
: isAccessControl // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
class _$PackageListSelectorStateImpl implements _PackageListSelectorState {
const _$PackageListSelectorStateImpl(
{required this.accessControl, required this.isAccessControl});
@override
final AccessControl accessControl;
@override
final bool isAccessControl;
@override
String toString() {
return 'PackageListSelectorState(accessControl: $accessControl, isAccessControl: $isAccessControl)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$PackageListSelectorStateImpl &&
(identical(other.accessControl, accessControl) ||
other.accessControl == accessControl) &&
(identical(other.isAccessControl, isAccessControl) ||
other.isAccessControl == isAccessControl));
}
@override
int get hashCode => Object.hash(runtimeType, accessControl, isAccessControl);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$PackageListSelectorStateImplCopyWith<_$PackageListSelectorStateImpl>
get copyWith => __$$PackageListSelectorStateImplCopyWithImpl<
_$PackageListSelectorStateImpl>(this, _$identity);
}
abstract class _PackageListSelectorState implements PackageListSelectorState {
const factory _PackageListSelectorState(
{required final AccessControl accessControl,
required final bool isAccessControl}) = _$PackageListSelectorStateImpl;
@override
AccessControl get accessControl;
@override
bool get isAccessControl;
@override
@JsonKey(ignore: true)
_$$PackageListSelectorStateImplCopyWith<_$PackageListSelectorStateImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'config.dart';
import 'navigation.dart';
import 'package.dart';
import 'profile.dart';
import 'proxy.dart';
@@ -44,14 +43,6 @@ class ProfilesSelectorState with _$ProfilesSelectorState {
}) = _ProfilesSelectorState;
}
@freezed
class PackageListSelectorState with _$PackageListSelectorState {
const factory PackageListSelectorState({
required AccessControl accessControl,
required List<Package> packages,
}) = _PackageListSelectorState;
}
@freezed
class ApplicationSelectorState with _$ApplicationSelectorState {
const factory ApplicationSelectorState({
@@ -126,4 +117,12 @@ class MoreToolsSelectorState with _$MoreToolsSelectorState {
const factory MoreToolsSelectorState({
required List<NavigationItem> navigationItems,
}) = _MoreToolsSelectorState;
}
@freezed
class PackageListSelectorState with _$PackageListSelectorState {
const factory PackageListSelectorState({
required AccessControl accessControl,
required bool isAccessControl,
}) = _PackageListSelectorState;
}

View File

@@ -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.7
version: 0.8.8
environment:
sdk: '>=3.1.0 <4.0.0'