mirror of
https://github.com/wanghongenpin/proxypin.git
synced 2026-05-14 15:48:03 +08:00
mobile:add scroll bar to request list
This commit is contained in:
@@ -131,16 +131,18 @@ class _DesktopHomePagePageState extends State<DesktopHomePage> 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)));
|
||||
});
|
||||
|
||||
@@ -170,7 +170,7 @@ class MobileHomeState extends State<MobileHomePage> 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<MobileHomePage> 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;
|
||||
|
||||
@@ -318,38 +318,42 @@ class _HistoryRecordState extends State<HistoryRecord> {
|
||||
@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)),
|
||||
|
||||
@@ -145,6 +145,9 @@ class RequestSequence extends StatefulWidget {
|
||||
}
|
||||
|
||||
class RequestSequenceState extends State<RequestSequence> with AutomaticKeepAliveClientMixin {
|
||||
// Define a ScrollController
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
///请求和对应的row的映射
|
||||
Map<HttpRequest, GlobalKey<RequestRowState>> indexes = HashMap();
|
||||
|
||||
@@ -174,6 +177,7 @@ class RequestSequenceState extends State<RequestSequence> with AutomaticKeepAliv
|
||||
@override
|
||||
dispose() {
|
||||
KeywordHighlight.keywordsController.removeListener(highlightListener);
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -253,26 +257,30 @@ class RequestSequenceState extends State<RequestSequence> 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<RequestRowState> 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<RequestRowState> 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<DomainList> with AutomaticKeepAliveClientMixin {
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
GlobalKey<RequestSequenceState> requestSequenceKey = GlobalKey<RequestSequenceState>();
|
||||
late Configuration configuration;
|
||||
|
||||
@@ -403,15 +413,24 @@ class DomainListState extends State<DomainList> 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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user