From 713e83d9d8e198a98085c3bde0073760dc019bec Mon Sep 17 00:00:00 2001 From: chen08209 Date: Thu, 27 Jun 2024 17:23:59 +0800 Subject: [PATCH] Optimize proxies expansion panel 2 Fix android scan qrcode error --- lib/application.dart | 1 - lib/common/android.dart | 1 - lib/controller.dart | 15 +- lib/fragments/profiles/add_profile.dart | 4 +- lib/fragments/profiles/profiles.dart | 10 +- lib/fragments/proxies.dart | 193 +++++++++++++----------- pubspec.yaml | 2 +- 7 files changed, 122 insertions(+), 104 deletions(-) diff --git a/lib/application.dart b/lib/application.dart index 82c9db7..dcccc5a 100644 --- a/lib/application.dart +++ b/lib/application.dart @@ -150,7 +150,6 @@ class ApplicationState extends State { builder: (lightDynamic, darkDynamic) { _updateSystemColorSchemes(lightDynamic, darkDynamic); return MaterialApp( - debugShowCheckedModeBanner: false, navigatorKey: globalState.navigatorKey, localizationsDelegates: const [ AppLocalizations.delegate, diff --git a/lib/common/android.dart b/lib/common/android.dart index 8fbb472..143403b 100644 --- a/lib/common/android.dart +++ b/lib/common/android.dart @@ -7,7 +7,6 @@ class Android { init() async { app?.onExit = () { clashCore.shutdown(); - print("adsadda==>"); exit(0); }; } diff --git a/lib/controller.dart b/lib/controller.dart index 05e055a..286eea7 100644 --- a/lib/controller.dart +++ b/lib/controller.dart @@ -359,7 +359,9 @@ class AppController { } addProfileFormURL(String url) async { - globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst); + if (globalState.navigatorKey.currentState?.canPop() ?? false) { + globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst); + } toProfiles(); final commonScaffoldState = globalState.homeScaffoldKey.currentState; if (commonScaffoldState?.mounted != true) return; @@ -421,18 +423,17 @@ class AppController { }); } - List _sortOfName(List proxies) { return List.of(proxies) ..sort( - (a, b) => other.sortByChar(a.name, b.name), + (a, b) => other.sortByChar(a.name, b.name), ); } List _sortOfDelay(List proxies) { return proxies = List.of(proxies) ..sort( - (a, b) { + (a, b) { final aDelay = appState.getDelay(a.name); final bDelay = appState.getDelay(b.name); if (aDelay == null && bDelay == null) { @@ -449,11 +450,11 @@ class AppController { ); } - List getSortProxies(List proxies){ - return switch(config.proxiesSortType){ + List getSortProxies(List proxies) { + return switch (config.proxiesSortType) { ProxiesSortType.none => proxies, ProxiesSortType.delay => _sortOfDelay(proxies), - ProxiesSortType.name =>_sortOfName(proxies), + ProxiesSortType.name => _sortOfName(proxies), }; } } diff --git a/lib/fragments/profiles/add_profile.dart b/lib/fragments/profiles/add_profile.dart index 6920b26..378612f 100644 --- a/lib/fragments/profiles/add_profile.dart +++ b/lib/fragments/profiles/add_profile.dart @@ -25,7 +25,9 @@ class AddProfile extends StatelessWidget { final url = await Navigator.of(context) .push(MaterialPageRoute(builder: (_) => const ScanPage())); if (url != null) { - _handleAddProfileFormURL(url); + WidgetsBinding.instance.addPostFrameCallback((_){ + _handleAddProfileFormURL(url); + }); } } diff --git a/lib/fragments/profiles/profiles.dart b/lib/fragments/profiles/profiles.dart index 70a1cc6..245daed 100644 --- a/lib/fragments/profiles/profiles.dart +++ b/lib/fragments/profiles/profiles.dart @@ -437,16 +437,16 @@ class _ProfileItemState extends State { label: appLocalizations.update, iconData: Icons.sync, ), - CommonPopupMenuItem( - action: ProfileActions.delete, - label: appLocalizations.delete, - iconData: Icons.delete, - ), CommonPopupMenuItem( action: ProfileActions.view, label: appLocalizations.view, iconData: Icons.visibility, ), + CommonPopupMenuItem( + action: ProfileActions.delete, + label: appLocalizations.delete, + iconData: Icons.delete, + ), ], onSelected: (ProfileActions? action) async { switch (action) { diff --git a/lib/fragments/proxies.dart b/lib/fragments/proxies.dart index af48513..4843b2d 100644 --- a/lib/fragments/proxies.dart +++ b/lib/fragments/proxies.dart @@ -230,17 +230,6 @@ class ProxiesExpansionPanelFragment extends StatefulWidget { class _ProxiesExpansionPanelFragmentState extends State { - - @override - void initState() { - super.initState(); - } - - @override - void dispose() { - super.dispose(); - } - @override Widget build(BuildContext context) { return Selector2( @@ -259,6 +248,7 @@ class _ProxiesExpansionPanelFragmentState itemBuilder: (_, index) { final groupName = state.groupNames[index]; return ProxyGroupView( + key: PageStorageKey(groupName), groupName: groupName, type: ProxiesType.expansion, ); @@ -291,6 +281,7 @@ class ProxyGroupView extends StatefulWidget { class _ProxyGroupViewState extends State { var isLock = false; final isBoundaryNotifier = ValueNotifier(false); + final scrollController = ScrollController(); var isEnd = false; String get groupName => widget.groupName; @@ -384,28 +375,49 @@ class _ProxyGroupViewState extends State { } Widget _androidExpansionHandle(Widget child) { - return NotificationListener( - onNotification: (ScrollNotification notification) { - if (notification is ScrollEndNotification) { - if (notification.metrics.atEdge) { - isEnd = notification.metrics.pixels == - notification.metrics.maxScrollExtent; - isBoundaryNotifier.value = true; - } + // return NotificationListener( + // onNotification: (ScrollNotification notification) { + // if (notification is ScrollEndNotification) { + // if (notification.metrics.atEdge) { + // isEnd = notification.metrics.pixels == + // notification.metrics.maxScrollExtent; + // isBoundaryNotifier.value = true; + // } + // } + // return false; + // }, + // child: Listener( + // onPointerMove: (details) { + // double yOffset = details.delta.dy; + // final isEnd = scrollController.position.maxScrollExtent == scrollController.position.pixels; + // final isTop = scrollController.position.minScrollExtent == scrollController.position.pixels; + // if(isEnd || isTop){ + // isBoundaryNotifier.value = true; + // } else if (yOffset > 0 && scrollController.position.maxScrollExtent == scrollController.position.pixels) { + // isBoundaryNotifier.value = false; + // } else if (yOffset < 0 && !isEnd) { + // isBoundaryNotifier.value = false; + // } + // }, + // child: child, + // ), + // ); + return Listener( + onPointerMove: (details) { + double yOffset = details.delta.dy; + final isEnd = scrollController.position.maxScrollExtent == + scrollController.position.pixels; + final isTop = scrollController.position.minScrollExtent == + scrollController.position.pixels; + if (isEnd && yOffset < 0) { + isBoundaryNotifier.value = true; + } else if (isTop && yOffset > 0) { + isBoundaryNotifier.value = true; + } else { + isBoundaryNotifier.value = false; } - return false; }, - child: Listener( - onPointerMove: (details) { - double yOffset = details.delta.dy; - if (yOffset > 0 && isEnd) { - isBoundaryNotifier.value = false; - } else if (yOffset < 0 && !isEnd) { - isBoundaryNotifier.value = false; - } - }, - child: child, - ), + child: child, ); } @@ -422,7 +434,8 @@ class _ProxyGroupViewState extends State { final itemHeight = _getItemHeight(proxyCardType); final innerHeight = context.appSize.height - 200; final lines = (sortedProxies.length / columns).ceil(); - final minLines = innerHeight >= 200 ? (innerHeight / itemHeight).floor() : 3; + final minLines = + innerHeight >= 200 ? (innerHeight / itemHeight).floor() : 3; final hasScrollable = lines > minLines; final height = (itemHeight + 8) * min(lines, minLines) - 8; return Selector>( @@ -430,6 +443,7 @@ class _ProxyGroupViewState extends State { builder: (_, currentUnfoldSet, __) { return CommonCard( child: ExpansionTile( + childrenPadding: const EdgeInsets.all(8), initiallyExpanded: currentUnfoldSet.contains(groupName), iconColor: context.colorScheme.onSurfaceVariant, onExpansionChanged: (value) { @@ -527,12 +541,6 @@ class _ProxyGroupViewState extends State { collapsedShape: const RoundedRectangleBorder( side: BorderSide.none, ), - childrenPadding: const EdgeInsets.only( - top: 8, - bottom: 8, - left: 8, - right: 8, - ), children: [ SizedBox( height: height, @@ -541,62 +549,70 @@ class _ProxyGroupViewState extends State { ValueListenableBuilder( valueListenable: isBoundaryNotifier, builder: (_, isBoundary, child) { - return GridView.builder( - physics: isBoundary || !hasScrollable - ? const NeverScrollableScrollPhysics() - : const AlwaysScrollableScrollPhysics(), - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: columns, - mainAxisSpacing: 8, - crossAxisSpacing: 8, - mainAxisExtent: _getItemHeight(proxyCardType), + return Scrollbar( + thickness: 6, + interactive: true, + radius: const Radius.circular(6), + child: GridView.builder( + key: widget.key, + controller: scrollController, + physics: isBoundary || !hasScrollable + ? const NeverScrollableScrollPhysics() + : const AlwaysScrollableScrollPhysics(), + gridDelegate: + SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: columns, + mainAxisSpacing: 8, + crossAxisSpacing: 8, + mainAxisExtent: _getItemHeight(proxyCardType), + ), + itemCount: sortedProxies.length, + itemBuilder: (_, index) { + final proxy = sortedProxies[index]; + return _currentProxyNameBuilder( + builder: (value) { + return ProxyCard( + style: CommonCardType.filled, + type: proxyCardType, + isSelected: value == proxy.name, + key: ValueKey('$groupName.${proxy.name}'), + proxy: proxy, + groupName: groupName, + ); + }); + }, ), - itemCount: sortedProxies.length, - itemBuilder: (_, index) { - final proxy = sortedProxies[index]; - return _currentProxyNameBuilder( - builder: (value) { - return ProxyCard( - style: CommonCardType.filled, - type: proxyCardType, - isSelected: value == proxy.name, - key: ValueKey('$groupName.${proxy.name}'), - proxy: proxy, - groupName: groupName, - ); - }); - }, ); }, ), ) : GridView.builder( - physics: !hasScrollable - ? const NeverScrollableScrollPhysics() - : const AlwaysScrollableScrollPhysics(), - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: columns, - mainAxisSpacing: 8, - crossAxisSpacing: 8, - mainAxisExtent: _getItemHeight(proxyCardType), - ), - itemCount: sortedProxies.length, - itemBuilder: (_, index) { - final proxy = sortedProxies[index]; - return _currentProxyNameBuilder(builder: (value) { - return ProxyCard( - style: CommonCardType.filled, - type: proxyCardType, - isSelected: value == proxy.name, - key: ValueKey('$groupName.${proxy.name}'), - proxy: proxy, - groupName: groupName, - ); - }); - }, - ), + key: widget.key, + controller: scrollController, + physics: !hasScrollable + ? const NeverScrollableScrollPhysics() + : const AlwaysScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: columns, + mainAxisSpacing: 8, + crossAxisSpacing: 8, + mainAxisExtent: _getItemHeight(proxyCardType), + ), + itemCount: sortedProxies.length, + itemBuilder: (_, index) { + final proxy = sortedProxies[index]; + return _currentProxyNameBuilder(builder: (value) { + return ProxyCard( + style: CommonCardType.filled, + type: proxyCardType, + isSelected: value == proxy.name, + key: ValueKey('$groupName.${proxy.name}'), + proxy: proxy, + groupName: groupName, + ); + }); + }, + ), ), ], ), @@ -609,6 +625,7 @@ class _ProxyGroupViewState extends State { void dispose() { super.dispose(); isBoundaryNotifier.dispose(); + scrollController.dispose(); } @override diff --git a/pubspec.yaml b/pubspec.yaml index c63fbd8..4305fbb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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.29 +version: 0.8.30 environment: sdk: '>=3.1.0 <4.0.0'