Optimize back navigation
This commit is contained in:
@@ -11,6 +11,7 @@ import 'package:fl_clash/plugins/app.dart';
|
||||
import 'package:fl_clash/providers/providers.dart';
|
||||
import 'package:fl_clash/state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
@@ -46,6 +47,7 @@ class ApplicationState extends ConsumerState<Application> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
SystemNavigator.setFrameworkHandlesBack(true);
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
||||
if (globalState.navigatorKey.currentContext != null) {
|
||||
await globalState.attach();
|
||||
@@ -141,6 +143,7 @@ class ApplicationState extends ConsumerState<Application> {
|
||||
return MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
navigatorKey: globalState.navigatorKey,
|
||||
onNavigationNotification: (_) => true,
|
||||
localizationsDelegates: const [
|
||||
AppLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
|
||||
@@ -78,6 +78,8 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
|
||||
shortcuts: {
|
||||
utils.controlSingleActivator(LogicalKeyboardKey.keyW):
|
||||
const CloseWindowIntent(),
|
||||
const SingleActivator(LogicalKeyboardKey.escape):
|
||||
const EscapeBackIntent(),
|
||||
},
|
||||
child: Actions(
|
||||
actions: {
|
||||
@@ -86,6 +88,9 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
|
||||
.read(systemActionProvider.notifier)
|
||||
.handleClose(false),
|
||||
),
|
||||
EscapeBackIntent: CallbackAction<EscapeBackIntent>(
|
||||
onInvoke: (_) => globalState.navigatorKey.currentState?.maybePop(),
|
||||
),
|
||||
DoNothingIntent: CallbackAction<DoNothingIntent>(
|
||||
onInvoke: (_) => null,
|
||||
),
|
||||
|
||||
@@ -14,7 +14,6 @@ typedef DelayMap = Map<String, Map<String, int?>>;
|
||||
abstract class AppState with _$AppState {
|
||||
const factory AppState({
|
||||
@Default(false) bool isInit,
|
||||
@Default(false) bool backBlock,
|
||||
@Default(PageLabel.dashboard) PageLabel pageLabel,
|
||||
@Default([]) List<Package> packages,
|
||||
@Default(0) int sortNum,
|
||||
|
||||
@@ -581,6 +581,10 @@ class CloseWindowIntent extends Intent {
|
||||
const CloseWindowIntent();
|
||||
}
|
||||
|
||||
class EscapeBackIntent extends Intent {
|
||||
const EscapeBackIntent();
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class Result<T> with _$Result<T> {
|
||||
const factory Result({
|
||||
|
||||
@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$AppState {
|
||||
|
||||
bool get isInit; bool get backBlock; PageLabel get pageLabel; List<Package> get packages; int get sortNum; Size get viewSize; double get sideWidth; DelayMap get delayMap; List<Group> get groups; int get checkIpNum; Brightness get brightness; int? get runTime; List<ExternalProvider> get providers; String? get localIp; FixedList<TrackerInfo> get requests; int get version; FixedList<Log> get logs; FixedList<Traffic> get traffics; Traffic get totalTraffic; TunAuthorizationState get authorizedTunEnable; bool get loading; SystemUiOverlayStyle get systemUiOverlayStyle; CoreStatus get coreStatus;
|
||||
bool get isInit; PageLabel get pageLabel; List<Package> get packages; int get sortNum; Size get viewSize; double get sideWidth; DelayMap get delayMap; List<Group> get groups; int get checkIpNum; Brightness get brightness; int? get runTime; List<ExternalProvider> get providers; String? get localIp; FixedList<TrackerInfo> get requests; int get version; FixedList<Log> get logs; FixedList<Traffic> get traffics; Traffic get totalTraffic; TunAuthorizationState get authorizedTunEnable; bool get loading; SystemUiOverlayStyle get systemUiOverlayStyle; CoreStatus get coreStatus;
|
||||
/// Create a copy of AppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -25,12 +25,12 @@ $AppStateCopyWith<AppState> get copyWith => _$AppStateCopyWithImpl<AppState>(thi
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppState&&(identical(other.isInit, isInit) || other.isInit == isInit)&&(identical(other.backBlock, backBlock) || other.backBlock == backBlock)&&(identical(other.pageLabel, pageLabel) || other.pageLabel == pageLabel)&&const DeepCollectionEquality().equals(other.packages, packages)&&(identical(other.sortNum, sortNum) || other.sortNum == sortNum)&&(identical(other.viewSize, viewSize) || other.viewSize == viewSize)&&(identical(other.sideWidth, sideWidth) || other.sideWidth == sideWidth)&&const DeepCollectionEquality().equals(other.delayMap, delayMap)&&const DeepCollectionEquality().equals(other.groups, groups)&&(identical(other.checkIpNum, checkIpNum) || other.checkIpNum == checkIpNum)&&(identical(other.brightness, brightness) || other.brightness == brightness)&&(identical(other.runTime, runTime) || other.runTime == runTime)&&const DeepCollectionEquality().equals(other.providers, providers)&&(identical(other.localIp, localIp) || other.localIp == localIp)&&(identical(other.requests, requests) || other.requests == requests)&&(identical(other.version, version) || other.version == version)&&(identical(other.logs, logs) || other.logs == logs)&&(identical(other.traffics, traffics) || other.traffics == traffics)&&(identical(other.totalTraffic, totalTraffic) || other.totalTraffic == totalTraffic)&&(identical(other.authorizedTunEnable, authorizedTunEnable) || other.authorizedTunEnable == authorizedTunEnable)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.systemUiOverlayStyle, systemUiOverlayStyle) || other.systemUiOverlayStyle == systemUiOverlayStyle)&&(identical(other.coreStatus, coreStatus) || other.coreStatus == coreStatus));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppState&&(identical(other.isInit, isInit) || other.isInit == isInit)&&(identical(other.pageLabel, pageLabel) || other.pageLabel == pageLabel)&&const DeepCollectionEquality().equals(other.packages, packages)&&(identical(other.sortNum, sortNum) || other.sortNum == sortNum)&&(identical(other.viewSize, viewSize) || other.viewSize == viewSize)&&(identical(other.sideWidth, sideWidth) || other.sideWidth == sideWidth)&&const DeepCollectionEquality().equals(other.delayMap, delayMap)&&const DeepCollectionEquality().equals(other.groups, groups)&&(identical(other.checkIpNum, checkIpNum) || other.checkIpNum == checkIpNum)&&(identical(other.brightness, brightness) || other.brightness == brightness)&&(identical(other.runTime, runTime) || other.runTime == runTime)&&const DeepCollectionEquality().equals(other.providers, providers)&&(identical(other.localIp, localIp) || other.localIp == localIp)&&(identical(other.requests, requests) || other.requests == requests)&&(identical(other.version, version) || other.version == version)&&(identical(other.logs, logs) || other.logs == logs)&&(identical(other.traffics, traffics) || other.traffics == traffics)&&(identical(other.totalTraffic, totalTraffic) || other.totalTraffic == totalTraffic)&&(identical(other.authorizedTunEnable, authorizedTunEnable) || other.authorizedTunEnable == authorizedTunEnable)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.systemUiOverlayStyle, systemUiOverlayStyle) || other.systemUiOverlayStyle == systemUiOverlayStyle)&&(identical(other.coreStatus, coreStatus) || other.coreStatus == coreStatus));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hashAll([runtimeType,isInit,backBlock,pageLabel,const DeepCollectionEquality().hash(packages),sortNum,viewSize,sideWidth,const DeepCollectionEquality().hash(delayMap),const DeepCollectionEquality().hash(groups),checkIpNum,brightness,runTime,const DeepCollectionEquality().hash(providers),localIp,requests,version,logs,traffics,totalTraffic,authorizedTunEnable,loading,systemUiOverlayStyle,coreStatus]);
|
||||
int get hashCode => Object.hashAll([runtimeType,isInit,pageLabel,const DeepCollectionEquality().hash(packages),sortNum,viewSize,sideWidth,const DeepCollectionEquality().hash(delayMap),const DeepCollectionEquality().hash(groups),checkIpNum,brightness,runTime,const DeepCollectionEquality().hash(providers),localIp,requests,version,logs,traffics,totalTraffic,authorizedTunEnable,loading,systemUiOverlayStyle,coreStatus]);
|
||||
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ abstract mixin class $AppStateCopyWith<$Res> {
|
||||
factory $AppStateCopyWith(AppState value, $Res Function(AppState) _then) = _$AppStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, TunAuthorizationState authorizedTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus
|
||||
bool isInit, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, TunAuthorizationState authorizedTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus
|
||||
});
|
||||
|
||||
|
||||
@@ -58,10 +58,9 @@ class _$AppStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of AppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? isInit = null,Object? backBlock = null,Object? pageLabel = null,Object? packages = null,Object? sortNum = null,Object? viewSize = null,Object? sideWidth = null,Object? delayMap = null,Object? groups = null,Object? checkIpNum = null,Object? brightness = null,Object? runTime = freezed,Object? providers = null,Object? localIp = freezed,Object? requests = null,Object? version = null,Object? logs = null,Object? traffics = null,Object? totalTraffic = null,Object? authorizedTunEnable = null,Object? loading = null,Object? systemUiOverlayStyle = null,Object? coreStatus = null,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? isInit = null,Object? pageLabel = null,Object? packages = null,Object? sortNum = null,Object? viewSize = null,Object? sideWidth = null,Object? delayMap = null,Object? groups = null,Object? checkIpNum = null,Object? brightness = null,Object? runTime = freezed,Object? providers = null,Object? localIp = freezed,Object? requests = null,Object? version = null,Object? logs = null,Object? traffics = null,Object? totalTraffic = null,Object? authorizedTunEnable = null,Object? loading = null,Object? systemUiOverlayStyle = null,Object? coreStatus = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
isInit: null == isInit ? _self.isInit : isInit // ignore: cast_nullable_to_non_nullable
|
||||
as bool,backBlock: null == backBlock ? _self.backBlock : backBlock // ignore: cast_nullable_to_non_nullable
|
||||
as bool,pageLabel: null == pageLabel ? _self.pageLabel : pageLabel // ignore: cast_nullable_to_non_nullable
|
||||
as PageLabel,packages: null == packages ? _self.packages : packages // ignore: cast_nullable_to_non_nullable
|
||||
as List<Package>,sortNum: null == sortNum ? _self.sortNum : sortNum // ignore: cast_nullable_to_non_nullable
|
||||
@@ -177,10 +176,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, TunAuthorizationState authorizedTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isInit, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, TunAuthorizationState authorizedTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppState() when $default != null:
|
||||
return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.authorizedTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.coreStatus);case _:
|
||||
return $default(_that.isInit,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.authorizedTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.coreStatus);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -198,10 +197,10 @@ return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_tha
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, TunAuthorizationState authorizedTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isInit, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, TunAuthorizationState authorizedTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppState():
|
||||
return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.authorizedTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.coreStatus);case _:
|
||||
return $default(_that.isInit,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.authorizedTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.coreStatus);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -218,10 +217,10 @@ return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_tha
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, TunAuthorizationState authorizedTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isInit, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, TunAuthorizationState authorizedTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppState() when $default != null:
|
||||
return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.authorizedTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.coreStatus);case _:
|
||||
return $default(_that.isInit,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.authorizedTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.coreStatus);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -233,11 +232,10 @@ return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_tha
|
||||
|
||||
|
||||
class _AppState implements AppState {
|
||||
const _AppState({this.isInit = false, this.backBlock = false, this.pageLabel = PageLabel.dashboard, final List<Package> packages = const [], this.sortNum = 0, required this.viewSize, this.sideWidth = 0, final DelayMap delayMap = const {}, final List<Group> groups = const [], this.checkIpNum = 0, required this.brightness, this.runTime, final List<ExternalProvider> providers = const [], this.localIp, required this.requests, required this.version, required this.logs, required this.traffics, required this.totalTraffic, this.authorizedTunEnable = TunAuthorizationState.none, this.loading = false, required this.systemUiOverlayStyle, this.coreStatus = CoreStatus.connecting}): _packages = packages,_delayMap = delayMap,_groups = groups,_providers = providers;
|
||||
const _AppState({this.isInit = false, this.pageLabel = PageLabel.dashboard, final List<Package> packages = const [], this.sortNum = 0, required this.viewSize, this.sideWidth = 0, final DelayMap delayMap = const {}, final List<Group> groups = const [], this.checkIpNum = 0, required this.brightness, this.runTime, final List<ExternalProvider> providers = const [], this.localIp, required this.requests, required this.version, required this.logs, required this.traffics, required this.totalTraffic, this.authorizedTunEnable = TunAuthorizationState.none, this.loading = false, required this.systemUiOverlayStyle, this.coreStatus = CoreStatus.connecting}): _packages = packages,_delayMap = delayMap,_groups = groups,_providers = providers;
|
||||
|
||||
|
||||
@override@JsonKey() final bool isInit;
|
||||
@override@JsonKey() final bool backBlock;
|
||||
@override@JsonKey() final PageLabel pageLabel;
|
||||
final List<Package> _packages;
|
||||
@override@JsonKey() List<Package> get packages {
|
||||
@@ -294,12 +292,12 @@ _$AppStateCopyWith<_AppState> get copyWith => __$AppStateCopyWithImpl<_AppState>
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppState&&(identical(other.isInit, isInit) || other.isInit == isInit)&&(identical(other.backBlock, backBlock) || other.backBlock == backBlock)&&(identical(other.pageLabel, pageLabel) || other.pageLabel == pageLabel)&&const DeepCollectionEquality().equals(other._packages, _packages)&&(identical(other.sortNum, sortNum) || other.sortNum == sortNum)&&(identical(other.viewSize, viewSize) || other.viewSize == viewSize)&&(identical(other.sideWidth, sideWidth) || other.sideWidth == sideWidth)&&const DeepCollectionEquality().equals(other._delayMap, _delayMap)&&const DeepCollectionEquality().equals(other._groups, _groups)&&(identical(other.checkIpNum, checkIpNum) || other.checkIpNum == checkIpNum)&&(identical(other.brightness, brightness) || other.brightness == brightness)&&(identical(other.runTime, runTime) || other.runTime == runTime)&&const DeepCollectionEquality().equals(other._providers, _providers)&&(identical(other.localIp, localIp) || other.localIp == localIp)&&(identical(other.requests, requests) || other.requests == requests)&&(identical(other.version, version) || other.version == version)&&(identical(other.logs, logs) || other.logs == logs)&&(identical(other.traffics, traffics) || other.traffics == traffics)&&(identical(other.totalTraffic, totalTraffic) || other.totalTraffic == totalTraffic)&&(identical(other.authorizedTunEnable, authorizedTunEnable) || other.authorizedTunEnable == authorizedTunEnable)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.systemUiOverlayStyle, systemUiOverlayStyle) || other.systemUiOverlayStyle == systemUiOverlayStyle)&&(identical(other.coreStatus, coreStatus) || other.coreStatus == coreStatus));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppState&&(identical(other.isInit, isInit) || other.isInit == isInit)&&(identical(other.pageLabel, pageLabel) || other.pageLabel == pageLabel)&&const DeepCollectionEquality().equals(other._packages, _packages)&&(identical(other.sortNum, sortNum) || other.sortNum == sortNum)&&(identical(other.viewSize, viewSize) || other.viewSize == viewSize)&&(identical(other.sideWidth, sideWidth) || other.sideWidth == sideWidth)&&const DeepCollectionEquality().equals(other._delayMap, _delayMap)&&const DeepCollectionEquality().equals(other._groups, _groups)&&(identical(other.checkIpNum, checkIpNum) || other.checkIpNum == checkIpNum)&&(identical(other.brightness, brightness) || other.brightness == brightness)&&(identical(other.runTime, runTime) || other.runTime == runTime)&&const DeepCollectionEquality().equals(other._providers, _providers)&&(identical(other.localIp, localIp) || other.localIp == localIp)&&(identical(other.requests, requests) || other.requests == requests)&&(identical(other.version, version) || other.version == version)&&(identical(other.logs, logs) || other.logs == logs)&&(identical(other.traffics, traffics) || other.traffics == traffics)&&(identical(other.totalTraffic, totalTraffic) || other.totalTraffic == totalTraffic)&&(identical(other.authorizedTunEnable, authorizedTunEnable) || other.authorizedTunEnable == authorizedTunEnable)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.systemUiOverlayStyle, systemUiOverlayStyle) || other.systemUiOverlayStyle == systemUiOverlayStyle)&&(identical(other.coreStatus, coreStatus) || other.coreStatus == coreStatus));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hashAll([runtimeType,isInit,backBlock,pageLabel,const DeepCollectionEquality().hash(_packages),sortNum,viewSize,sideWidth,const DeepCollectionEquality().hash(_delayMap),const DeepCollectionEquality().hash(_groups),checkIpNum,brightness,runTime,const DeepCollectionEquality().hash(_providers),localIp,requests,version,logs,traffics,totalTraffic,authorizedTunEnable,loading,systemUiOverlayStyle,coreStatus]);
|
||||
int get hashCode => Object.hashAll([runtimeType,isInit,pageLabel,const DeepCollectionEquality().hash(_packages),sortNum,viewSize,sideWidth,const DeepCollectionEquality().hash(_delayMap),const DeepCollectionEquality().hash(_groups),checkIpNum,brightness,runTime,const DeepCollectionEquality().hash(_providers),localIp,requests,version,logs,traffics,totalTraffic,authorizedTunEnable,loading,systemUiOverlayStyle,coreStatus]);
|
||||
|
||||
|
||||
|
||||
@@ -310,7 +308,7 @@ abstract mixin class _$AppStateCopyWith<$Res> implements $AppStateCopyWith<$Res>
|
||||
factory _$AppStateCopyWith(_AppState value, $Res Function(_AppState) _then) = __$AppStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, TunAuthorizationState authorizedTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus
|
||||
bool isInit, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, TunAuthorizationState authorizedTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus
|
||||
});
|
||||
|
||||
|
||||
@@ -327,10 +325,9 @@ class __$AppStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of AppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? isInit = null,Object? backBlock = null,Object? pageLabel = null,Object? packages = null,Object? sortNum = null,Object? viewSize = null,Object? sideWidth = null,Object? delayMap = null,Object? groups = null,Object? checkIpNum = null,Object? brightness = null,Object? runTime = freezed,Object? providers = null,Object? localIp = freezed,Object? requests = null,Object? version = null,Object? logs = null,Object? traffics = null,Object? totalTraffic = null,Object? authorizedTunEnable = null,Object? loading = null,Object? systemUiOverlayStyle = null,Object? coreStatus = null,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? isInit = null,Object? pageLabel = null,Object? packages = null,Object? sortNum = null,Object? viewSize = null,Object? sideWidth = null,Object? delayMap = null,Object? groups = null,Object? checkIpNum = null,Object? brightness = null,Object? runTime = freezed,Object? providers = null,Object? localIp = freezed,Object? requests = null,Object? version = null,Object? logs = null,Object? traffics = null,Object? totalTraffic = null,Object? authorizedTunEnable = null,Object? loading = null,Object? systemUiOverlayStyle = null,Object? coreStatus = null,}) {
|
||||
return _then(_AppState(
|
||||
isInit: null == isInit ? _self.isInit : isInit // ignore: cast_nullable_to_non_nullable
|
||||
as bool,backBlock: null == backBlock ? _self.backBlock : backBlock // ignore: cast_nullable_to_non_nullable
|
||||
as bool,pageLabel: null == pageLabel ? _self.pageLabel : pageLabel // ignore: cast_nullable_to_non_nullable
|
||||
as PageLabel,packages: null == packages ? _self._packages : packages // ignore: cast_nullable_to_non_nullable
|
||||
as List<Package>,sortNum: null == sortNum ? _self.sortNum : sortNum // ignore: cast_nullable_to_non_nullable
|
||||
|
||||
+19
-12
@@ -110,7 +110,24 @@ class HomePage extends ConsumerWidget {
|
||||
onDidRemovePage: (_) {},
|
||||
),
|
||||
);
|
||||
return view;
|
||||
return Consumer(
|
||||
key: ValueKey(navigationItem.label),
|
||||
builder: (_, ref, child) {
|
||||
final isActive = ref.watch(
|
||||
currentPageLabelProvider.select(
|
||||
(label) => label == navigationItem.label,
|
||||
),
|
||||
);
|
||||
return PageActivityScope(
|
||||
isActive: isActive,
|
||||
child: ExcludeFocus(
|
||||
excluding: !isActive,
|
||||
child: child!,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: view,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
@@ -204,12 +221,6 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
|
||||
final itemCount = ref.watch(
|
||||
currentNavigationItemsStateProvider.select((state) => state.value.length),
|
||||
);
|
||||
final currentIndex = ref.watch(
|
||||
currentPageLabelProvider.select(
|
||||
(label) =>
|
||||
widget.navigationItems.indexWhere((item) => item.label == label),
|
||||
),
|
||||
);
|
||||
return PageView.builder(
|
||||
controller: _pageController,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
@@ -224,11 +235,7 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
|
||||
return index == -1 ? null : index;
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
return ExcludeFocus(
|
||||
key: ValueKey(widget.navigationItems[index].label),
|
||||
excluding: index != currentIndex,
|
||||
child: widget.pageBuilder(context, index),
|
||||
);
|
||||
return widget.pageBuilder(context, index);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -594,9 +594,6 @@ class SystemAction extends _$SystemAction {
|
||||
}
|
||||
|
||||
Future<void> handleClose([bool exit = true]) async {
|
||||
if (!system.isDesktop) {
|
||||
if (ref.read(backBlockProvider)) return;
|
||||
}
|
||||
if (ref.read(appSettingProvider).minimizeOnExit || !exit) {
|
||||
if (system.isDesktop) {
|
||||
await preferences.saveConfig(ref.read(configProvider));
|
||||
|
||||
@@ -217,22 +217,6 @@ class CheckIpNum extends _$CheckIpNum with AutoDisposeNotifierMixin {
|
||||
int add() => state++;
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class BackBlock extends _$BackBlock with AutoDisposeNotifierMixin {
|
||||
@override
|
||||
bool build() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void backBlock() {
|
||||
value = true;
|
||||
}
|
||||
|
||||
void unBackBlock() {
|
||||
value = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class Version extends _$Version with AutoDisposeNotifierMixin {
|
||||
@override
|
||||
@@ -464,7 +448,6 @@ class LocationPermissions extends _$LocationPermissions
|
||||
List<Override> buildAppStateOverrides(AppState appState) {
|
||||
return [
|
||||
initProvider.overrideWithBuild((_, _) => appState.isInit),
|
||||
backBlockProvider.overrideWithBuild((_, _) => appState.backBlock),
|
||||
currentPageLabelProvider.overrideWithBuild((_, _) => appState.pageLabel),
|
||||
packagesProvider.overrideWithBuild((_, _) => appState.packages),
|
||||
sortNumProvider.overrideWithBuild((_, _) => appState.sortNum),
|
||||
|
||||
@@ -244,7 +244,7 @@ final class SystemActionProvider extends $NotifierProvider<SystemAction, void> {
|
||||
}
|
||||
}
|
||||
|
||||
String _$systemActionHash() => r'04f09af2702925aff276423a9c224fd8d3aca061';
|
||||
String _$systemActionHash() => r'fe481ef6812b1aad42ed3f1a8a2459c9bbd289d9';
|
||||
|
||||
abstract class _$SystemAction extends $Notifier<void> {
|
||||
void build();
|
||||
|
||||
@@ -999,57 +999,6 @@ abstract class _$CheckIpNum extends $Notifier<int> {
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(BackBlock)
|
||||
final backBlockProvider = BackBlockProvider._();
|
||||
|
||||
final class BackBlockProvider extends $NotifierProvider<BackBlock, bool> {
|
||||
BackBlockProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'backBlockProvider',
|
||||
isAutoDispose: false,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$backBlockHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
BackBlock create() => BackBlock();
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(bool value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<bool>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$backBlockHash() => r'c867df920425f9b063807ca758dff8d849ca069e';
|
||||
|
||||
abstract class _$BackBlock extends $Notifier<bool> {
|
||||
bool build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
WhenComplete runBuild() {
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<bool, bool>,
|
||||
bool,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
return element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(Version)
|
||||
final versionProvider = VersionProvider._();
|
||||
|
||||
|
||||
@@ -69,12 +69,12 @@ class _DashboardViewState extends ConsumerState<DashboardView> {
|
||||
? IconButton(
|
||||
key: const ValueKey(true),
|
||||
icon: const Icon(Icons.save, key: ValueKey('save-icon')),
|
||||
onPressed: _handleUpdateIsEdit,
|
||||
onPressed: _handleSaveAndExit,
|
||||
)
|
||||
: IconButton(
|
||||
key: const ValueKey(false),
|
||||
icon: const Icon(Icons.edit, key: ValueKey('edit-icon')),
|
||||
onPressed: _handleUpdateIsEdit,
|
||||
onPressed: _handleEnterEdit,
|
||||
),
|
||||
),
|
||||
];
|
||||
@@ -102,11 +102,32 @@ class _DashboardViewState extends ConsumerState<DashboardView> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _handleUpdateIsEdit() async {
|
||||
if (_isEditNotifier.value == true) {
|
||||
await _handleSave();
|
||||
void _handleEnterEdit() {
|
||||
if (_isEditNotifier.value) {
|
||||
return;
|
||||
}
|
||||
_isEditNotifier.value = true;
|
||||
}
|
||||
|
||||
void _handleExitEdit() {
|
||||
if (!_isEditNotifier.value) {
|
||||
return;
|
||||
}
|
||||
final dashboardWidgets = _getDashboardWidgets(key.currentState);
|
||||
if (dashboardWidgets != null) {
|
||||
_saveDashboardWidgets(dashboardWidgets);
|
||||
}
|
||||
_isEditNotifier.value = false;
|
||||
}
|
||||
|
||||
Future<void> _handleSaveAndExit() async {
|
||||
if (!_isEditNotifier.value) {
|
||||
return;
|
||||
}
|
||||
await _handleSave();
|
||||
if (mounted) {
|
||||
_isEditNotifier.value = false;
|
||||
}
|
||||
_isEditNotifier.value = !_isEditNotifier.value;
|
||||
}
|
||||
|
||||
Future<void> _handleSave() async {
|
||||
@@ -114,7 +135,7 @@ class _DashboardViewState extends ConsumerState<DashboardView> {
|
||||
if (currentState == null) {
|
||||
return;
|
||||
}
|
||||
if (!mounted || currentState.children.isEmpty) {
|
||||
if (!mounted || currentState.snapshotChildren.isEmpty) {
|
||||
return;
|
||||
}
|
||||
final transformCompleted = await currentState.isTransformCompleter;
|
||||
@@ -124,9 +145,25 @@ class _DashboardViewState extends ConsumerState<DashboardView> {
|
||||
!identical(key.currentState, currentState)) {
|
||||
return;
|
||||
}
|
||||
final dashboardWidgets = currentState.children
|
||||
.map((item) => DashboardWidget.getDashboardWidget(item))
|
||||
.toList();
|
||||
final dashboardWidgets = _getDashboardWidgets(currentState);
|
||||
if (dashboardWidgets == null) {
|
||||
return;
|
||||
}
|
||||
_saveDashboardWidgets(dashboardWidgets);
|
||||
}
|
||||
|
||||
List<DashboardWidget>? _getDashboardWidgets(SuperGridState? currentState) {
|
||||
if (currentState == null) {
|
||||
return null;
|
||||
}
|
||||
final children = currentState.snapshotChildren;
|
||||
if (children.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
return children.map(DashboardWidget.getDashboardWidget).toList();
|
||||
}
|
||||
|
||||
void _saveDashboardWidgets(List<DashboardWidget> dashboardWidgets) {
|
||||
ref
|
||||
.read(appSettingProvider.notifier)
|
||||
.update((state) => state.copyWith(dashboardWidgets: dashboardWidgets));
|
||||
@@ -173,21 +210,16 @@ class _DashboardViewState extends ConsumerState<DashboardView> {
|
||||
_maxCrossAxisCount,
|
||||
);
|
||||
return isEdit
|
||||
? SystemBackBlock(
|
||||
child: CommonPopScope(
|
||||
child: SuperGrid(
|
||||
key: key,
|
||||
crossAxisCount: columns,
|
||||
crossAxisSpacing: spacing,
|
||||
mainAxisSpacing: spacing,
|
||||
children: children,
|
||||
onUpdate: () {
|
||||
_handleSave();
|
||||
},
|
||||
),
|
||||
onPop: (context) {
|
||||
_handleUpdateIsEdit();
|
||||
return false;
|
||||
? BackLayerScope(
|
||||
onBack: _handleExitEdit,
|
||||
child: SuperGrid(
|
||||
key: key,
|
||||
crossAxisCount: columns,
|
||||
crossAxisSpacing: spacing,
|
||||
mainAxisSpacing: spacing,
|
||||
children: children,
|
||||
onUpdate: () {
|
||||
_handleSave();
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
@@ -20,7 +20,6 @@ class ProxiesView extends ConsumerStatefulWidget {
|
||||
}
|
||||
|
||||
class _ProxiesViewState extends ConsumerState<ProxiesView> {
|
||||
final GlobalKey<CommonScaffoldState> _scaffoldKey = GlobalKey();
|
||||
final GlobalKey<ProxiesTabViewState> _proxiesTabKey = GlobalKey();
|
||||
bool _hasProviders = false;
|
||||
bool _isTab = false;
|
||||
@@ -122,14 +121,6 @@ class _ProxiesViewState extends ConsumerState<ProxiesView> {
|
||||
},
|
||||
fireImmediately: true,
|
||||
);
|
||||
ref.listenManual(
|
||||
currentPageLabelProvider.select((state) => state == PageLabel.proxies),
|
||||
(prev, next) {
|
||||
if (prev != next && next == false) {
|
||||
_scaffoldKey.currentState?.handleExitSearching();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -139,7 +130,6 @@ class _ProxiesViewState extends ConsumerState<ProxiesView> {
|
||||
);
|
||||
final isLoading = ref.watch(loadingProvider(LoadingTag.proxies));
|
||||
return CommonScaffold(
|
||||
key: _scaffoldKey,
|
||||
isLoading: isLoading,
|
||||
resizeToAvoidBottomInset: false,
|
||||
floatingActionButton: _buildFAB(),
|
||||
|
||||
@@ -2,6 +2,28 @@ import 'package:fl_clash/enum/enum.dart';
|
||||
import 'package:fl_clash/widgets/sheet.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PageActivityScope extends InheritedWidget {
|
||||
final bool isActive;
|
||||
|
||||
const PageActivityScope({
|
||||
super.key,
|
||||
required this.isActive,
|
||||
required super.child,
|
||||
});
|
||||
|
||||
static bool isActiveOf(BuildContext context) {
|
||||
return context
|
||||
.dependOnInheritedWidgetOfExactType<PageActivityScope>()
|
||||
?.isActive ??
|
||||
true;
|
||||
}
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(PageActivityScope oldWidget) {
|
||||
return isActive != oldWidget.isActive;
|
||||
}
|
||||
}
|
||||
|
||||
class CommonScaffoldBackActionProvider extends InheritedWidget {
|
||||
final VoidCallback? backAction;
|
||||
|
||||
|
||||
+76
-15
@@ -1,9 +1,8 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:fl_clash/providers/app.dart';
|
||||
import 'package:fl_clash/state.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'inherited.dart';
|
||||
|
||||
class CommonPopScope extends StatelessWidget {
|
||||
final Widget child;
|
||||
@@ -19,8 +18,10 @@ class CommonPopScope extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final route = ModalRoute.of(context);
|
||||
final hasBackLayer = route?.willHandlePopInternally == true;
|
||||
return PopScope(
|
||||
canPop: onPop == null ? true : false,
|
||||
canPop: onPop == null || hasBackLayer,
|
||||
onPopInvokedWithResult: onPop == null
|
||||
? null
|
||||
: (didPop, _) async {
|
||||
@@ -44,30 +45,90 @@ class CommonPopScope extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class SystemBackBlock extends ConsumerStatefulWidget {
|
||||
class BackLayerScope extends StatefulWidget {
|
||||
final Widget child;
|
||||
final VoidCallback onBack;
|
||||
@visibleForTesting
|
||||
final void Function(void Function(Duration) callback)?
|
||||
schedulePostFrameCallback;
|
||||
|
||||
const SystemBackBlock({super.key, required this.child});
|
||||
const BackLayerScope({
|
||||
super.key,
|
||||
required this.onBack,
|
||||
required this.child,
|
||||
@visibleForTesting this.schedulePostFrameCallback,
|
||||
});
|
||||
|
||||
@override
|
||||
ConsumerState<SystemBackBlock> createState() => _SystemBackBlockState();
|
||||
State<BackLayerScope> createState() => _BackLayerScopeState();
|
||||
}
|
||||
|
||||
class _SystemBackBlockState extends ConsumerState<SystemBackBlock> {
|
||||
class _BackLayerScopeState extends State<BackLayerScope> {
|
||||
ModalRoute<dynamic>? _route;
|
||||
LocalHistoryEntry? _entry;
|
||||
bool _isDetaching = false;
|
||||
bool _isPageActive = true;
|
||||
int _syncRevision = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
globalState.container.read(backBlockProvider.notifier).backBlock();
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
final route = ModalRoute.of(context);
|
||||
final isPageActive = PageActivityScope.isActiveOf(context);
|
||||
if (identical(_route, route) && _isPageActive == isPageActive) {
|
||||
return;
|
||||
}
|
||||
_detach();
|
||||
_route = route;
|
||||
_isPageActive = isPageActive;
|
||||
final revision = ++_syncRevision;
|
||||
final schedulePostFrameCallback =
|
||||
widget.schedulePostFrameCallback ??
|
||||
WidgetsBinding.instance.addPostFrameCallback;
|
||||
schedulePostFrameCallback((_) {
|
||||
if (!mounted || revision != _syncRevision) {
|
||||
return;
|
||||
}
|
||||
if (!_isPageActive) {
|
||||
widget.onBack();
|
||||
return;
|
||||
}
|
||||
if (route == null) {
|
||||
return;
|
||||
}
|
||||
final entry = LocalHistoryEntry(
|
||||
impliesAppBarDismissal: false,
|
||||
onRemove: _handleRemove,
|
||||
);
|
||||
_entry = entry;
|
||||
route.addLocalHistoryEntry(entry);
|
||||
});
|
||||
}
|
||||
|
||||
void _handleRemove() {
|
||||
_entry = null;
|
||||
if (!_isDetaching && mounted) {
|
||||
widget.onBack();
|
||||
}
|
||||
}
|
||||
|
||||
void _detach() {
|
||||
final entry = _entry;
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
_entry = null;
|
||||
_isDetaching = true;
|
||||
entry.remove();
|
||||
_isDetaching = false;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_syncRevision++;
|
||||
_detach();
|
||||
_route = null;
|
||||
super.dispose();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
globalState.container.read(backBlockProvider.notifier).unBackBlock();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
+18
-16
@@ -139,7 +139,7 @@ class CommonScaffoldState extends State<CommonScaffold> {
|
||||
_handleClearInput();
|
||||
return;
|
||||
}
|
||||
_updateSearchState((state) => state?.copyWith(query: null));
|
||||
_popAppBarLayer();
|
||||
}
|
||||
|
||||
void handleExitSearching() {
|
||||
@@ -150,6 +150,20 @@ class CommonScaffoldState extends State<CommonScaffold> {
|
||||
_updateSearchState((state) => state?.copyWith(query: null));
|
||||
}
|
||||
|
||||
void _handleExitAppBarLayer() {
|
||||
handleExitSearching();
|
||||
if (_isEdit) {
|
||||
_appBarState.value.editState?.onExit();
|
||||
}
|
||||
}
|
||||
|
||||
void _popAppBarLayer() {
|
||||
if (!_isEdit && !_isSearch) {
|
||||
return;
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_appBarState.dispose();
|
||||
@@ -177,13 +191,13 @@ class CommonScaffoldState extends State<CommonScaffold> {
|
||||
Widget? _buildLeading(VoidCallback? backAction) {
|
||||
if (_isEdit) {
|
||||
return IconButton(
|
||||
onPressed: _appBarState.value.editState?.onExit,
|
||||
onPressed: _popAppBarLayer,
|
||||
icon: const Icon(Icons.close),
|
||||
);
|
||||
}
|
||||
if (_isSearch) {
|
||||
return IconButton(
|
||||
onPressed: handleExitSearching,
|
||||
onPressed: _popAppBarLayer,
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
);
|
||||
}
|
||||
@@ -244,19 +258,7 @@ class CommonScaffoldState extends State<CommonScaffold> {
|
||||
Widget _buildAppBarWrap(Widget child) {
|
||||
final appBar = _isSearch ? _buildSearchingAppBarTheme(child) : child;
|
||||
if (_isEdit || _isSearch) {
|
||||
return SystemBackBlock(
|
||||
child: CommonPopScope(
|
||||
onPop: (context) {
|
||||
if (_isEdit || _isSearch) {
|
||||
handleExitSearching();
|
||||
_appBarState.value.editState?.onExit();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
child: appBar,
|
||||
),
|
||||
);
|
||||
return BackLayerScope(onBack: _handleExitAppBarLayer, child: appBar);
|
||||
}
|
||||
return appBar;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,10 @@ class SuperGridState extends State<SuperGrid> with TickerProviderStateMixin {
|
||||
|
||||
late final ValueNotifier<List<GridItem>> _childrenNotifier;
|
||||
List<GridItem> children = [];
|
||||
List<GridItem>? _pendingChildren;
|
||||
|
||||
List<GridItem> get snapshotChildren =>
|
||||
List<GridItem>.unmodifiable(_pendingChildren ?? children);
|
||||
|
||||
int get length => _childrenNotifier.value.length;
|
||||
List<int> _tempIndexList = [];
|
||||
@@ -355,13 +359,16 @@ class SuperGridState extends State<SuperGrid> with TickerProviderStateMixin {
|
||||
_preTransformState();
|
||||
final indexWhere = _tempIndexList.indexWhere((i) => i == index);
|
||||
_tempIndexList.removeAt(indexWhere);
|
||||
final nextChildren = List<GridItem>.from(_childrenNotifier.value)
|
||||
..removeAt(index);
|
||||
_pendingChildren = nextChildren;
|
||||
final completed = await _transform();
|
||||
if (!completed || !mounted) {
|
||||
_pendingChildren = null;
|
||||
return;
|
||||
}
|
||||
final children = List<GridItem>.from(_childrenNotifier.value);
|
||||
children.removeAt(index);
|
||||
_childrenNotifier.value = children;
|
||||
_childrenNotifier.value = nextChildren;
|
||||
_pendingChildren = null;
|
||||
_initState();
|
||||
}
|
||||
|
||||
@@ -606,6 +613,7 @@ class SuperGridState extends State<SuperGrid> with TickerProviderStateMixin {
|
||||
_childrenNotifier.removeListener(_handleChildrenChanged);
|
||||
_childrenNotifier.value = const [];
|
||||
children = const [];
|
||||
_pendingChildren = null;
|
||||
_itemContexts = [];
|
||||
_sizes = [];
|
||||
_offsets = [];
|
||||
|
||||
Reference in New Issue
Block a user