diff --git a/lib/storage/favorites.dart b/lib/storage/favorites.dart index 72c163a..ebb3223 100644 --- a/lib/storage/favorites.dart +++ b/lib/storage/favorites.dart @@ -8,6 +8,8 @@ import 'package:network_proxy/storage/path.dart'; class FavoriteStorage { static Queue? list; + static Function()? addNotifier; + /// 获取收藏列表 static Future> get favorites async { if (list == null) { @@ -40,6 +42,8 @@ class FavoriteStorage { favorites.addFirst(Favorite(request)); flushConfig(); + //通知 + addNotifier?.call(); } static Future removeFavorite(Favorite favorite) async { diff --git a/lib/ui/component/widgets.dart b/lib/ui/component/widgets.dart index e57b1da..e372ac6 100644 --- a/lib/ui/component/widgets.dart +++ b/lib/ui/component/widgets.dart @@ -131,3 +131,48 @@ class IconText extends StatelessWidget { ])); } } + +class LazyIndexedStack extends StatefulWidget { + final List children; + final int index; + + const LazyIndexedStack({ + super.key, + required this.children, + required this.index, + }); + + @override + State createState() => _LazyIndexedStackState(); +} + +class _LazyIndexedStackState extends State { + final List _childrenCache = []; + + @override + void initState() { + super.initState(); + _childrenCache.length = widget.children.length; + } + + @override + void didUpdateWidget(LazyIndexedStack oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.children.length != widget.children.length) { + _childrenCache.length = widget.children.length; + } + } + + @override + Widget build(BuildContext context) { + _childrenCache[widget.index] ??= widget.children[widget.index]; + + return IndexedStack( + index: widget.index, + children: List.generate( + widget.children.length, + (i) => _childrenCache[i] ?? Container(), + ), + ); + } +} diff --git a/lib/ui/desktop/desktop.dart b/lib/ui/desktop/desktop.dart index 4e6009f..3a5c6a0 100644 --- a/lib/ui/desktop/desktop.dart +++ b/lib/ui/desktop/desktop.dart @@ -6,8 +6,8 @@ import 'package:network_proxy/network/channel.dart'; import 'package:network_proxy/network/handler.dart'; import 'package:network_proxy/network/http/http.dart'; import 'package:network_proxy/network/http/websocket.dart'; -import 'package:network_proxy/ui/component/state_component.dart'; import 'package:network_proxy/ui/component/toolbox.dart'; +import 'package:network_proxy/ui/component/widgets.dart'; import 'package:network_proxy/ui/configuration.dart'; import 'package:network_proxy/ui/content/panel.dart'; import 'package:network_proxy/ui/desktop/left_menus/favorite.dart'; @@ -74,6 +74,13 @@ class _DesktopHomePagePageState extends State implements EventL @override Widget build(BuildContext context) { + var navigationView = [ + DomainList(key: domainStateKey, proxyServer: proxyServer, panel: panel, list: container), + Favorites(panel: panel), + HistoryPageWidget(proxyServer: proxyServer, container: container, panel: panel), + const Toolbox() + ]; + return Scaffold( appBar: Tab(child: Toolbar(proxyServer, domainStateKey, sideNotifier: _selectIndex)), body: Row( @@ -91,13 +98,7 @@ class _DesktopHomePagePageState extends State implements EventL }, left: ValueListenableBuilder( valueListenable: _selectIndex, - builder: (_, index, __) => IndexedStack(index: index, children: [ - DomainList(key: domainStateKey, proxyServer: proxyServer, panel: panel, list: container), - Favorites(panel: panel), - KeepAliveWrapper( - child: HistoryPageWidget(proxyServer: proxyServer, container: container, panel: panel)), - const Toolbox() - ])), + builder: (_, index, __) => LazyIndexedStack(index: index, children: navigationView)), right: panel), ) ], diff --git a/lib/ui/desktop/left_menus/favorite.dart b/lib/ui/desktop/left_menus/favorite.dart index 6a63156..b4b7ec2 100644 --- a/lib/ui/desktop/left_menus/favorite.dart +++ b/lib/ui/desktop/left_menus/favorite.dart @@ -18,6 +18,7 @@ import 'package:network_proxy/ui/component/widgets.dart'; import 'package:network_proxy/ui/content/panel.dart'; import 'package:network_proxy/ui/desktop/request/repeat.dart'; import 'package:network_proxy/utils/curl.dart'; +import 'package:network_proxy/utils/lang.dart'; import 'package:network_proxy/utils/python.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:window_manager/window_manager.dart'; @@ -38,6 +39,14 @@ class Favorites extends StatefulWidget { class _FavoritesState extends State { AppLocalizations get localizations => AppLocalizations.of(context)!; + @override + void initState() { + super.initState(); + FavoriteStorage.addNotifier = () { + setState(() {}); + }; + } + @override Widget build(BuildContext context) { return FutureBuilder( @@ -90,23 +99,19 @@ class _FavoriteItemState extends State<_FavoriteItem> { static _FavoriteItemState? selectedState; bool selected = false; - late HttpRequest request; AppLocalizations get localizations => AppLocalizations.of(context)!; - @override - void initState() { - super.initState(); - request = widget.favorite.request; - } - @override Widget build(BuildContext context) { + var request = widget.favorite.request; + var response = widget.favorite.response; - var title = '${request.method.name} ${request.requestUrl}'; + var title = '${request.method.name} ${request.requestUrl}'.fixAutoLines(); var time = formatDate(request.requestTime, [mm, '-', d, ' ', HH, ':', nn, ':', ss]); + return GestureDetector( - onSecondaryLongPressDown: menu, + onSecondaryLongPressDown: (details) => menu(details, request), child: ListTile( minLeadingWidth: 25, leading: getIcon(response), @@ -122,11 +127,11 @@ class _FavoriteItemState extends State<_FavoriteItem> { ])), selected: selected, dense: true, - onTap: onClick)); + onTap: () => onClick(request))); } ///右键菜单 - menu(LongPressDownDetails details) { + menu(LongPressDownDetails details, HttpRequest request) { showContextMenu( context, details.globalPosition, @@ -154,7 +159,7 @@ class _FavoriteItemState extends State<_FavoriteItem> { popupItem(localizations.customRepeat, onTap: () => showCustomRepeat(request)), popupItem(localizations.editRequest, onTap: () { WidgetsBinding.instance.addPostFrameCallback((_) { - requestEdit(); + requestEdit(request); }); }), const PopupMenuDivider(height: 0.3), @@ -222,7 +227,7 @@ class _FavoriteItemState extends State<_FavoriteItem> { } ///请求编辑 - requestEdit() async { + requestEdit(HttpRequest request) async { var size = MediaQuery.of(context).size; var ratio = 1.0; if (Platform.isWindows) { @@ -240,7 +245,7 @@ class _FavoriteItemState extends State<_FavoriteItem> { } //点击事件 - void onClick() { + void onClick(HttpRequest request) { if (selected) { return; } diff --git a/lib/ui/desktop/request/request.dart b/lib/ui/desktop/request/request.dart index c2e4832..0254286 100644 --- a/lib/ui/desktop/request/request.dart +++ b/lib/ui/desktop/request/request.dart @@ -155,7 +155,7 @@ class _RequestWidgetState extends State { label: localizations.favorite, onClick: (_) { FavoriteStorage.addFavorite(widget.request); - FlutterToastr.show(localizations.operationSuccess, context); + FlutterToastr.show(localizations.operationSuccess, context, rootNavigator: true); }), MenuItem( label: localizations.highlight,