From 462e92aa7dcfd57b625b44593e142e24d752e6f5 Mon Sep 17 00:00:00 2001 From: wanghongenpin Date: Fri, 23 Aug 2024 13:30:05 +0800 Subject: [PATCH] =?UTF-8?q?mobile=EF=BC=9Aadd=20scroll=20bar=20to=20reques?= =?UTF-8?q?t=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/ui/desktop/desktop.dart | 12 ++--- lib/ui/mobile/mobile.dart | 16 ++++--- lib/ui/mobile/request/history.dart | 68 ++++++++++++++-------------- lib/ui/mobile/request/list.dart | 71 +++++++++++++++++++----------- pubspec.yaml | 6 +-- 5 files changed, 101 insertions(+), 72 deletions(-) diff --git a/lib/ui/desktop/desktop.dart b/lib/ui/desktop/desktop.dart index b96f443..4e6009f 100644 --- a/lib/ui/desktop/desktop.dart +++ b/lib/ui/desktop/desktop.dart @@ -131,16 +131,18 @@ class _DesktopHomePagePageState extends State implements EventL '1. iOS 通知栏显示VPN状态;\n' '2. iOS修复停止长时间切换后台再开启抓包无网络问题;\n' '3. 桌面端保存调整左右面板比例;\n' - '4. 修复请求重发和脚本导致URL错误;\n' - '5. 修复脚本二进制body转换问题;\n' - '6. 修复请求编辑中文路径编码问题;\n' + '4. 手机端请求列表增加滚动条;\n' + '5. 修复请求重发和脚本导致URL错误;\n' + '6. 修复脚本二进制body转换问题;\n' + '7. 修复请求编辑中文路径编码问题;\n' : 'Tips:By default, HTTPS packet capture will not be enabled. Please install the certificate before enabling HTTPS packet capture。\n' 'Click HTTPS Capture packets(Lock icon),Choose to install the root certificate and follow the prompts to proceed。\n\n' '1. iOS notification bar displays VPN status;\n' '2. iOS fix: Stop switching to the background for a long time and then start packet capture without network problem;\n' '3. Desktop: save the left and right panel ratio;\n' - '4. fix request repeat & script change url wrong;\n' - '5. fix script binary body convert;\n' + '4. Mobile:Add a scrollbar to the request list;\n' + '5. fix request repeat & script change url wrong;\n' + '6. fix script binary body convert;\n' '', style: const TextStyle(fontSize: 14))); }); diff --git a/lib/ui/mobile/mobile.dart b/lib/ui/mobile/mobile.dart index 4aec815..15761e0 100644 --- a/lib/ui/mobile/mobile.dart +++ b/lib/ui/mobile/mobile.dart @@ -170,7 +170,7 @@ class MobileHomeState extends State implements EventListener, Li child: Scaffold( floatingActionButton: PictureInPictureIcon(proxyServer), body: Scaffold( - appBar: appBar(), + appBar: PreferredSize(preferredSize: const Size.fromHeight(42), child: appBar()), drawer: DrawerWidget(proxyServer: proxyServer, container: container), floatingActionButton: _launchActionButton(), body: ValueListenableBuilder( @@ -226,15 +226,19 @@ class MobileHomeState extends State implements EventListener, Li ? '提示:默认不会开启HTTPS抓包,请安装证书后再开启HTTPS抓包。\n\n' '1. iOS 通知栏显示VPN状态;\n' '2. iOS修复停止长时间切换后台再开启抓包无网络问题;\n' - '3. 修复请求重发和脚本导致URL错误;\n' - '4. 修复脚本二进制body转换问题;\n' - '5. 修复请求编辑中文路径编码问题;\n' + '3. 桌面端保存调整左右面板比例;\n' + '4. 手机端请求列表增加滚动条;\n' + '5. 修复请求重发和脚本导致URL错误;\n' + '6. 修复脚本二进制body转换问题;\n' + '7. 修复请求编辑中文路径编码问题;\n' : 'Tips:By default, HTTPS packet capture will not be enabled. Please install the certificate before enabling HTTPS packet capture。\n\n' 'Click HTTPS Capture packets(Lock icon),Choose to install the root certificate and follow the prompts to proceed。\n\n' '1. iOS notification bar displays VPN status;\n' '2. iOS fix: Stop switching to the background for a long time and then start packet capture without network problem;\n' - '3. fix request repeat & script change url wrong;\n' - '4. fix script binary body convert;\n' + '3. Desktop: save the left and right panel ratio;\n' + '4. Mobile:Add a scrollbar to the request list;\n' + '5. fix request repeat & script change url wrong;\n' + '6. fix script binary body convert;\n' ''; showAlertDialog(isCN ? '更新内容V1.1.2' : "Update content V1.1.2", content, () { widget.appConfiguration.upgradeNoticeV12 = false; diff --git a/lib/ui/mobile/request/history.dart b/lib/ui/mobile/request/history.dart index dfd9f9f..8464802 100644 --- a/lib/ui/mobile/request/history.dart +++ b/lib/ui/mobile/request/history.dart @@ -318,38 +318,42 @@ class _HistoryRecordState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: ValueListenableBuilder( - valueListenable: searchEnabled, - builder: (BuildContext context, bool value, Widget? child) { - return value - ? MobileSearch(onSearch: (val) => requestStateKey.currentState?.search(val), showSearch: true) - : Text(localizations.historyRecordTitle(widget.history.requestLength, widget.history.name), - style: const TextStyle(fontSize: 16)); - }), - actions: [ - PopupMenuButton( - offset: const Offset(0, 30), - icon: const Icon(Icons.more_vert_outlined), - itemBuilder: (BuildContext context) { - return [ - PopupMenuItem( - onTap: () => searchEnabled.value = true, - child: IconText(icon: const Icon(Icons.search), text: localizations.search)), - PopupMenuItem( - onTap: export, child: IconText(icon: const Icon(Icons.share), text: localizations.viewExport)), - PopupMenuItem( - onTap: () async { - HistoryStorage storage = await HistoryStorage.instance; - var requests = (await storage.getRequests(widget.history)).reversed; - //重发所有请求 - _repeatAllRequests(requests.toList(), widget.proxyServer, context: mounted ? context : null); - }, - child: IconText(icon: const Icon(Icons.repeat), text: localizations.repeatAllRequests)), - ]; - }), - ], - ), + appBar: PreferredSize( + preferredSize: const Size.fromHeight(38), + child: AppBar( + title: ValueListenableBuilder( + valueListenable: searchEnabled, + builder: (BuildContext context, bool value, Widget? child) { + return value + ? MobileSearch(onSearch: (val) => requestStateKey.currentState?.search(val), showSearch: true) + : Text(localizations.historyRecordTitle(widget.history.requestLength, widget.history.name), + style: const TextStyle(fontSize: 16)); + }), + actions: [ + PopupMenuButton( + offset: const Offset(0, 30), + icon: const Icon(Icons.more_vert_outlined), + itemBuilder: (BuildContext context) { + return [ + PopupMenuItem( + onTap: () => searchEnabled.value = true, + child: IconText(icon: const Icon(Icons.search), text: localizations.search)), + PopupMenuItem( + onTap: export, + child: IconText(icon: const Icon(Icons.share), text: localizations.viewExport)), + PopupMenuItem( + onTap: () async { + HistoryStorage storage = await HistoryStorage.instance; + var requests = (await storage.getRequests(widget.history)).reversed; + //重发所有请求 + _repeatAllRequests(requests.toList(), widget.proxyServer, + context: mounted ? context : null); + }, + child: IconText(icon: const Icon(Icons.repeat), text: localizations.repeatAllRequests)), + ]; + }), + ], + )), body: futureWidget( loading: true, HistoryStorage.instance.then((storage) => storage.getRequests(widget.history)), diff --git a/lib/ui/mobile/request/list.dart b/lib/ui/mobile/request/list.dart index 5e00990..15fc4e3 100644 --- a/lib/ui/mobile/request/list.dart +++ b/lib/ui/mobile/request/list.dart @@ -145,6 +145,9 @@ class RequestSequence extends StatefulWidget { } class RequestSequenceState extends State with AutomaticKeepAliveClientMixin { + // Define a ScrollController + final ScrollController _scrollController = ScrollController(); + ///请求和对应的row的映射 Map> indexes = HashMap(); @@ -174,6 +177,7 @@ class RequestSequenceState extends State with AutomaticKeepAliv @override dispose() { KeywordHighlight.keywordsController.removeListener(highlightListener); + _scrollController.dispose(); super.dispose(); } @@ -253,26 +257,30 @@ class RequestSequenceState extends State with AutomaticKeepAliv Widget build(BuildContext context) { super.build(context); - return ListView.separated( - cacheExtent: 1000, - separatorBuilder: (context, index) => Divider(thickness: 0.2, height: 0, color: Theme.of(context).dividerColor), - itemCount: view.length, - itemBuilder: (context, index) { - GlobalKey key = GlobalKey(); - indexes[view.elementAt(index)] = key; - return RequestRow( - index: view.length - index, - key: key, - request: view.elementAt(index), - proxyServer: widget.proxyServer, - displayDomain: widget.displayDomain, - onRemove: (request) { - setState(() { - view.remove(request); - }); - widget.onRemove?.call([request]); - }); - }); + return Scrollbar( + controller: _scrollController, + child: ListView.separated( + controller: _scrollController, + cacheExtent: 1000, + separatorBuilder: (context, index) => + Divider(thickness: 0.2, height: 0, color: Theme.of(context).dividerColor), + itemCount: view.length, + itemBuilder: (context, index) { + GlobalKey key = GlobalKey(); + indexes[view.elementAt(index)] = key; + return RequestRow( + index: view.length - index, + key: key, + request: view.elementAt(index), + proxyServer: widget.proxyServer, + displayDomain: widget.displayDomain, + onRemove: (request) { + setState(() { + view.remove(request); + }); + widget.onRemove?.call([request]); + }); + })); } } @@ -291,6 +299,8 @@ class DomainList extends StatefulWidget { } class DomainListState extends State with AutomaticKeepAliveClientMixin { + final ScrollController _scrollController = ScrollController(); + GlobalKey requestSequenceKey = GlobalKey(); late Configuration configuration; @@ -403,15 +413,24 @@ class DomainListState extends State with AutomaticKeepAliveClientMix @override bool get wantKeepAlive => true; + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { super.build(context); - return ListView.separated( - padding: EdgeInsets.zero, - separatorBuilder: (context, index) => - Divider(thickness: 0.2, height: 0.5, color: Theme.of(context).dividerColor), - itemCount: view.length, - itemBuilder: (ctx, index) => title(index)); + return Scrollbar( + controller: _scrollController, + child: ListView.separated( + controller: _scrollController, + padding: EdgeInsets.zero, + separatorBuilder: (context, index) => + Divider(thickness: 0.2, height: 0.5, color: Theme.of(context).dividerColor), + itemCount: view.length, + itemBuilder: (ctx, index) => title(index))); } Widget title(int index) { diff --git a/pubspec.yaml b/pubspec.yaml index fc9f538..6f1f15a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,9 +16,9 @@ dependencies: crypto: ^3.0.3 cupertino_icons: ^1.0.2 basic_utils: ^5.7.0 - logger: ^2.0.1 - date_format: ^2.0.7 - window_manager: ^0.4.0 + logger: ^2.4.0 + date_format: ^2.0.9 + window_manager: ^0.4.2 desktop_multi_window: git: url: https://gitee.com/wanghongenpin/flutter-plugins.git