Optimize provider page

Optimize delay test

Support local backup and recovery
This commit is contained in:
chen08209
2024-08-04 08:21:14 +08:00
parent 6cfcaa4edc
commit bee2f8aa4f
53 changed files with 1993 additions and 1128 deletions

View File

@@ -1,4 +1,6 @@
import 'package:fl_clash/models/models.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ScrollOverBuilder extends StatefulWidget {
final Widget Function(bool isOver) builder;
@@ -15,7 +17,6 @@ class ScrollOverBuilder extends StatefulWidget {
class _ScrollOverBuilderState extends State<ScrollOverBuilder> {
final isOverNotifier = ValueNotifier<bool>(false);
@override
void dispose() {
super.dispose();
@@ -38,3 +39,29 @@ class _ScrollOverBuilderState extends State<ScrollOverBuilder> {
);
}
}
class ProxiesActionsBuilder extends StatelessWidget {
final Widget? child;
final Widget Function(
ProxiesActionsState state,
Widget? child,
) builder;
const ProxiesActionsBuilder({
super.key,
required this.child,
required this.builder,
});
@override
Widget build(BuildContext context) {
return Selector<AppState, ProxiesActionsState>(
selector: (_, appState) => ProxiesActionsState(
isCurrent: appState.currentLabel == "proxies",
hasProvider: appState.providers.isNotEmpty,
),
builder: (_, state, child) => builder(state, child),
child: child,
);
}
}

View File

@@ -32,40 +32,39 @@ class InfoHeader extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
if (info.iconData != null) ...[
Icon(
info.iconData,
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(
width: 8,
),
],
Flexible(
child: TooltipText(
text: Text(
info.label,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.titleMedium,
),
),
),
],
),
Expanded(
flex: 1,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
...actions,
if (info.iconData != null) ...[
Icon(
info.iconData,
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(
width: 8,
),
],
Flexible(
child: TooltipText(
text: Text(
info.label,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.titleMedium,
),
),
),
],
),
),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
...actions,
],
),
],
),
);
@@ -146,13 +145,11 @@ class CommonCard extends StatelessWidget {
childWidget = Column(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
flex: 0,
child: InfoHeader(
info: info!,
),
InfoHeader(
info: info!,
),
Flexible(
flex: 1,
child: child,
),
],

View File

@@ -27,6 +27,8 @@ class _ClashContainerState extends State<ClashContainer>
systemProxy: config.systemProxy,
mixedPort: clashConfig.mixedPort,
onlyProxy: config.onlyProxy,
currentProfileName:
config.currentProfile?.label ?? config.currentProfileId ?? "",
),
builder: (__, state, child) {
clashCore.setState(state);
@@ -36,9 +38,32 @@ class _ClashContainerState extends State<ClashContainer>
);
}
_changeProfileHandle() {
WidgetsBinding.instance.addPostFrameCallback((_) async {
final appController = globalState.appController;
appController.appState.delayMap = {};
await appController.applyProfile();
});
}
Widget _changeProfileContainer(Widget child) {
return Selector<Config, String?>(
selector: (_, config) => config.currentProfileId,
builder: (__, state, child) {
_changeProfileHandle();
return child!;
},
child: child,
);
}
@override
Widget build(BuildContext context) {
return _updateCoreState(widget.child);
return _changeProfileContainer(
_updateCoreState(
widget.child,
),
);
}
@override
@@ -73,16 +98,15 @@ class _ClashContainerState extends State<ClashContainer>
}
@override
void onLoaded(String groupName) {
void onLoaded(String providerName) {
final appController = globalState.appController;
final currentSelectedMap = appController.config.currentSelectedMap;
final proxyName = currentSelectedMap[groupName];
if (proxyName == null) return;
appController.changeProxy(
groupName: groupName,
proxyName: proxyName,
appController.appState.setProvider(
clashCore.getExternalProvider(
providerName,
),
);
super.onLoaded(proxyName);
appController.addCheckIpNumDebounce();
super.onLoaded(providerName);
}
@override

View File

@@ -5,10 +5,12 @@ import 'package:fl_clash/widgets/scaffold.dart';
import 'package:flutter/material.dart';
import 'side_sheet.dart';
showExtendPage(BuildContext context, {
showExtendPage(
BuildContext context, {
required Widget body,
required String title,
double? extendPageWidth,
bool forceNotSide = false,
Widget? action,
}) {
final NavigatorState navigator = Navigator.of(context);
@@ -17,23 +19,24 @@ showExtendPage(BuildContext context, {
key: globalKey,
child: body,
);
final isMobile = globalState.appController.appState.viewMode ==
ViewMode.mobile;
final isMobile =
globalState.appController.appState.viewMode == ViewMode.mobile;
final isNotSide = isMobile || forceNotSide;
navigator.push(
ModalSideSheetRoute(
modalBarrierColor: Colors.black38,
builder: (context) {
final commonScaffold = CommonScaffold(
automaticallyImplyLeading: isMobile ? true : false,
actions: isMobile
automaticallyImplyLeading: isNotSide,
actions: isNotSide
? null
: [
const SizedBox(
height: kToolbarHeight,
width: kToolbarHeight,
child: CloseButton(),
),
],
const SizedBox(
height: kToolbarHeight,
width: kToolbarHeight,
child: CloseButton(),
),
],
title: title,
body: uniqueBody,
);

View File

@@ -220,16 +220,14 @@ class _WindowHeaderState extends State<WindowHeader> {
),
),
),
if (!Platform.isMacOS) ...[
const Positioned(
left: 0,
child: AppIcon(),
),
Positioned(
right: 0,
child: _buildActions(),
),
]
const Positioned(
left: 0,
child: AppIcon(),
),
Positioned(
right: 0,
child: _buildActions(),
),
],
),
);