Skip to content

Commit

Permalink
Optimize proxies expansion panel 2
Browse files Browse the repository at this point in the history
Fix android scan qrcode error
  • Loading branch information
chen08209 committed Jun 27, 2024
1 parent 5e3b0e4 commit 713e83d
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 104 deletions.
1 change: 0 additions & 1 deletion lib/application.dart
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ class ApplicationState extends State<Application> {
builder: (lightDynamic, darkDynamic) {
_updateSystemColorSchemes(lightDynamic, darkDynamic);
return MaterialApp(
debugShowCheckedModeBanner: false,
navigatorKey: globalState.navigatorKey,
localizationsDelegates: const [
AppLocalizations.delegate,
Expand Down
1 change: 0 additions & 1 deletion lib/common/android.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ class Android {
init() async {
app?.onExit = () {
clashCore.shutdown();
print("adsadda==>");
exit(0);
};
}
Expand Down
15 changes: 8 additions & 7 deletions lib/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -421,18 +423,17 @@ class AppController {
});
}


List<Proxy> _sortOfName(List<Proxy> proxies) {
return List.of(proxies)
..sort(
(a, b) => other.sortByChar(a.name, b.name),
(a, b) => other.sortByChar(a.name, b.name),
);
}

List<Proxy> _sortOfDelay(List<Proxy> 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) {
Expand All @@ -449,11 +450,11 @@ class AppController {
);
}

List<Proxy> getSortProxies(List<Proxy> proxies){
return switch(config.proxiesSortType){
List<Proxy> getSortProxies(List<Proxy> proxies) {
return switch (config.proxiesSortType) {
ProxiesSortType.none => proxies,
ProxiesSortType.delay => _sortOfDelay(proxies),
ProxiesSortType.name =>_sortOfName(proxies),
ProxiesSortType.name => _sortOfName(proxies),
};
}
}
4 changes: 3 additions & 1 deletion lib/fragments/profiles/add_profile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ class AddProfile extends StatelessWidget {
final url = await Navigator.of(context)
.push<String>(MaterialPageRoute(builder: (_) => const ScanPage()));
if (url != null) {
_handleAddProfileFormURL(url);
WidgetsBinding.instance.addPostFrameCallback((_){
_handleAddProfileFormURL(url);
});
}
}

Expand Down
10 changes: 5 additions & 5 deletions lib/fragments/profiles/profiles.dart
Original file line number Diff line number Diff line change
Expand Up @@ -437,16 +437,16 @@ class _ProfileItemState extends State<ProfileItem> {
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) {
Expand Down
193 changes: 105 additions & 88 deletions lib/fragments/proxies.dart
Original file line number Diff line number Diff line change
Expand Up @@ -230,17 +230,6 @@ class ProxiesExpansionPanelFragment extends StatefulWidget {

class _ProxiesExpansionPanelFragmentState
extends State<ProxiesExpansionPanelFragment> {

@override
void initState() {
super.initState();
}

@override
void dispose() {
super.dispose();
}

@override
Widget build(BuildContext context) {
return Selector2<AppState, Config, ProxiesSelectorState>(
Expand All @@ -259,6 +248,7 @@ class _ProxiesExpansionPanelFragmentState
itemBuilder: (_, index) {
final groupName = state.groupNames[index];
return ProxyGroupView(
key: PageStorageKey(groupName),
groupName: groupName,
type: ProxiesType.expansion,
);
Expand Down Expand Up @@ -291,6 +281,7 @@ class ProxyGroupView extends StatefulWidget {
class _ProxyGroupViewState extends State<ProxyGroupView> {
var isLock = false;
final isBoundaryNotifier = ValueNotifier<bool>(false);
final scrollController = ScrollController();
var isEnd = false;

String get groupName => widget.groupName;
Expand Down Expand Up @@ -384,28 +375,49 @@ class _ProxyGroupViewState extends State<ProxyGroupView> {
}

Widget _androidExpansionHandle(Widget child) {
return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
if (notification is ScrollEndNotification) {
if (notification.metrics.atEdge) {
isEnd = notification.metrics.pixels ==
notification.metrics.maxScrollExtent;
isBoundaryNotifier.value = true;
}
// return NotificationListener<ScrollNotification>(
// 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,
);
}

Expand All @@ -422,14 +434,16 @@ class _ProxyGroupViewState extends State<ProxyGroupView> {
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<Config, Set<String>>(
selector: (_, config) => config.currentUnfoldSet,
builder: (_, currentUnfoldSet, __) {
return CommonCard(
child: ExpansionTile(
childrenPadding: const EdgeInsets.all(8),
initiallyExpanded: currentUnfoldSet.contains(groupName),
iconColor: context.colorScheme.onSurfaceVariant,
onExpansionChanged: (value) {
Expand Down Expand Up @@ -527,12 +541,6 @@ class _ProxyGroupViewState extends State<ProxyGroupView> {
collapsedShape: const RoundedRectangleBorder(
side: BorderSide.none,
),
childrenPadding: const EdgeInsets.only(
top: 8,
bottom: 8,
left: 8,
right: 8,
),
children: [
SizedBox(
height: height,
Expand All @@ -541,62 +549,70 @@ class _ProxyGroupViewState extends State<ProxyGroupView> {
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,
);
});
},
),
),
],
),
Expand All @@ -609,6 +625,7 @@ class _ProxyGroupViewState extends State<ProxyGroupView> {
void dispose() {
super.dispose();
isBoundaryNotifier.dispose();
scrollController.dispose();
}

@override
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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'

Expand Down

0 comments on commit 713e83d

Please sign in to comment.