From 9dd69b567fa11989b68020246df4d4007c23da96 Mon Sep 17 00:00:00 2001 From: wanghongenpin Date: Fri, 8 Nov 2024 21:00:52 +0800 Subject: [PATCH] toolbox timestamp convert --- .../components/manager/rewrite_rule.dart | 4 +- .../components/manager/script_manager.dart | 4 +- lib/network/components/request_rewrite.dart | 2 +- lib/network/http/http.dart | 7 + lib/ui/component/toolbox/timestamp.dart | 192 ++++++++++++------ lib/ui/component/toolbox/toolbox.dart | 2 +- .../setting/rewrite/rewrite_update.dart | 4 +- .../setting/rewrite/rewrite_update.dart | 4 +- pubspec.yaml | 4 +- 9 files changed, 154 insertions(+), 69 deletions(-) diff --git a/lib/network/components/manager/rewrite_rule.dart b/lib/network/components/manager/rewrite_rule.dart index cc04b34..d4e204e 100644 --- a/lib/network/components/manager/rewrite_rule.dart +++ b/lib/network/components/manager/rewrite_rule.dart @@ -113,7 +113,7 @@ class RewriteItem { List items = []; items.add(RewriteItem(RewriteType.replaceRequestLine, false)..path = request.requestUri?.path); items.add(RewriteItem(RewriteType.replaceRequestHeader, false)..headers = request.headers.toMap()); - items.add(RewriteItem(RewriteType.replaceRequestBody, true)..body = request.bodyAsString); + items.add(RewriteItem(RewriteType.replaceRequestBody, true)..body = request.getBodyString()); return items; } @@ -122,7 +122,7 @@ class RewriteItem { List items = []; items.add(RewriteItem(RewriteType.replaceResponseStatus, false)..statusCode = response.status.code); items.add(RewriteItem(RewriteType.replaceResponseHeader, false)..headers = response.headers.toMap()); - items.add(RewriteItem(RewriteType.replaceResponseBody, true)..body = response.bodyAsString); + items.add(RewriteItem(RewriteType.replaceResponseBody, true)..body = response.getBodyString()); return items; } diff --git a/lib/network/components/manager/script_manager.dart b/lib/network/components/manager/script_manager.dart index ebc89d2..dca56ad 100644 --- a/lib/network/components/manager/script_manager.dart +++ b/lib/network/components/manager/script_manager.dart @@ -325,14 +325,14 @@ async function onResponse(context, request, response) { 'queries': requestUri?.queryParameters, 'headers': request.headers.toMap(), 'method': request.method.name, - 'body': request.bodyAsString, + 'body': request.getBodyString(), 'rawBody': request.body }; } //转换js response Map convertJsResponse(HttpResponse response) { - dynamic body = response.bodyAsString; + dynamic body = response.getBodyString(); if (response.contentType.isBinary) { body = response.body; } diff --git a/lib/network/components/request_rewrite.dart b/lib/network/components/request_rewrite.dart index 9006bb9..d9c6c5f 100644 --- a/lib/network/components/request_rewrite.dart +++ b/lib/network/components/request_rewrite.dart @@ -177,7 +177,7 @@ class RequestRewriteInterceptor extends Interceptor { //修改消息 _updateMessage(HttpMessage message, RewriteItem item) { if (item.type == RewriteType.updateBody && message.body != null) { - String body = message.bodyAsString.replaceAllMapped(RegExp(item.key!), (match) { + String body = message.getBodyString().replaceAllMapped(RegExp(item.key!), (match) { if (match.groupCount > 0 && item.value?.contains("\$1") == true) { return item.value!.replaceAll("\$1", match.group(1)!); } diff --git a/lib/network/http/http.dart b/lib/network/http/http.dart index fa7dcc5..c7768c8 100644 --- a/lib/network/http/http.dart +++ b/lib/network/http/http.dart @@ -90,10 +90,17 @@ abstract class HttpMessage { return mediaType.charset ?? MediaType.defaultCharset(mediaType); } + ///获取消息 String get bodyAsString { + return getBodyString(charset: 'utf-8'); + } + + String getBodyString({String? charset}) { if (body == null || body?.isEmpty == true) { return ""; } + + charset ??= this.charset; try { List rawBody = body!; if (headers.contentEncoding == 'br') { diff --git a/lib/ui/component/toolbox/timestamp.dart b/lib/ui/component/toolbox/timestamp.dart index c016dd3..edf1c34 100644 --- a/lib/ui/component/toolbox/timestamp.dart +++ b/lib/ui/component/toolbox/timestamp.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_toastr/flutter_toastr.dart'; import 'package:proxypin/utils/lang.dart'; +import 'package:proxypin/utils/platform.dart'; import '../text_field.dart'; @@ -61,79 +62,156 @@ class _TimestampPageState extends State { super.dispose(); } + TextStyle? get textStyle => Theme.of(context).textTheme.titleMedium; + + bool get isCN => Localizations.localeOf(context) == const Locale.fromSubtags(languageCode: 'zh'); + @override Widget build(BuildContext context) { - var textStyle = Theme.of(context).textTheme.titleMedium; - return Scaffold( appBar: AppBar(title: Text(localizations.timestamp, style: TextStyle(fontSize: 16)), centerTitle: true), body: ListView( - padding: const EdgeInsets.symmetric(horizontal: 10), + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5), children: [ - Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Text('${localizations.nowTimestamp}:', style: textStyle), - const SizedBox(width: 6), - SizedBox( - width: 100, - child: TextField( - controller: nowTimestamp, readOnly: true, decoration: InputDecoration(border: InputBorder.none))), - IconButton( + Wrap(crossAxisAlignment: WrapCrossAlignment.center, children: [ + Text('${localizations.nowTimestamp}:', style: textStyle), + const SizedBox(width: 6), + SizedBox( + width: 100, + child: TextField( + controller: nowTimestamp, readOnly: true, decoration: InputDecoration(border: InputBorder.none))), + IconButton( icon: Icon(Icons.copy, size: 18), onPressed: () { Clipboard.setData(ClipboardData(text: nowTimestamp.text)); FlutterToastr.show(localizations.copied, context); - }, - ), - ], - ), - SizedBox(height: 15), - Wrap( - spacing: 10.0, runSpacing: 10.0, crossAxisAlignment: WrapCrossAlignment.center, - children: [ - SizedBox(width: 93, child: Text('${localizations.timestamp}:', style: textStyle)), - SizedBox( - width: 215, - child: TextFormField(controller: timestamp, decoration: decoration(context, hintText: 'timestamp'))), - FilledButton.icon( - icon: Icon(Icons.play_arrow_rounded), - style: buttonStyle, - label: Text(localizations.convert), - onPressed: () => timestampConvert(timestamp.text)), - SizedBox( - width: 200, - child: TextFormField( - controller: timestampOut, - readOnly: true, - decoration: InputDecoration(border: OutlineInputBorder())), - ), - ], - ), - SizedBox(height: 35), - Wrap(spacing: 10.0, runSpacing: 10.0, crossAxisAlignment: WrapCrossAlignment.center, children: [ - SizedBox(width: 93, child: Text('${localizations.time}:', style: textStyle)), - SizedBox( - width: 215, - child: TextFormField( - controller: dateTime, decoration: decoration(context, hintText: 'yyyy-MM-dd HH:mm:ss'))), - FilledButton.icon( - icon: Icon(Icons.play_arrow_rounded), - style: buttonStyle, - label: Text(localizations.convert), - onPressed: () => timeConvert(dateTime.text)), - SizedBox( - width: 200, - child: TextFormField( - controller: dateTimeOut, - readOnly: true, - decoration: InputDecoration(border: OutlineInputBorder()))), + }) ]), + SizedBox(height: 15), + if (Platforms.isDesktop()) + Wrap(spacing: 10.0, runSpacing: 10.0, crossAxisAlignment: WrapCrossAlignment.center, children: [ + timestampLabel(), + SizedBox(width: 210, child: timestampField()), + timestampButton(), + SizedBox(width: 200, child: timestampOutField()), + ]), + if (Platforms.isMobile()) + Row(children: [ + timestampLabel(), + SizedBox(width: 8), + Expanded( + child: Column(children: [ + timestampField(), + SizedBox(height: 5), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [timestampButton(), timestampOutCopyButton()]), + SizedBox(height: 5), + timestampOutField() + ])), + ]), + SizedBox(height: 35), + if (Platforms.isDesktop()) + Wrap(spacing: 10.0, runSpacing: 10.0, crossAxisAlignment: WrapCrossAlignment.center, children: [ + timeLabel(), + SizedBox(width: 210, child: timeField()), + timeButton(), + SizedBox(width: 200, child: timeOutField()) + ]), + if (Platforms.isMobile()) + Row(children: [ + timeLabel(), + SizedBox(width: 8), + Expanded( + child: Column(children: [ + timeField(), + SizedBox(height: 5), + Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [timeButton(), timeOutCopyButton()]), + SizedBox(height: 5), + timeOutField() + ])), + ]), ], ), ); } + Widget timestampLabel() { + return SizedBox(width: isCN ? 60 : 93, child: Text('${localizations.timestamp}:', style: textStyle)); + } + + Widget timestampButton() { + return SizedBox( + height: 40, + child: FilledButton.icon( + icon: Icon(Icons.play_arrow_rounded), + style: buttonStyle, + label: Text(localizations.convert), + onPressed: () => timestampConvert(timestamp.text))); + } + + Widget timestampField() { + return TextFormField( + controller: timestamp, + onTapOutside: (event) => FocusManager.instance.primaryFocus?.unfocus(), + decoration: decoration(context, + hintText: 'timestamp', + suffixIcon: IconButton(icon: Icon(Icons.clear, size: 20), onPressed: () => timestamp.clear()))); + } + + Widget timestampOutField() { + return TextFormField( + controller: timestampOut, readOnly: true, decoration: InputDecoration(border: OutlineInputBorder())); + } + + Widget timestampOutCopyButton() { + return IconButton( + icon: Icon(Icons.copy, size: 22), + onPressed: () { + if (timestampOut.text.isEmpty) return; + Clipboard.setData(ClipboardData(text: timestampOut.text)); + FlutterToastr.show(localizations.copied, context); + }); + } + + Widget timeLabel() { + return SizedBox(width: isCN ? 60 : 93, child: Text('${localizations.time}:', style: textStyle)); + } + + Widget timeField() { + return TextFormField( + controller: dateTime, + onTapOutside: (event) => FocusManager.instance.primaryFocus?.unfocus(), + decoration: decoration(context, + hintText: 'yyyy-MM-dd HH:mm:ss', + suffixIcon: IconButton(icon: Icon(Icons.clear, size: 20), onPressed: () => dateTime.clear()))); + } + + Widget timeButton() { + return SizedBox( + height: 40, + child: FilledButton.icon( + icon: Icon(Icons.play_arrow_rounded), + style: buttonStyle, + label: Text(localizations.convert), + onPressed: () => timeConvert(dateTime.text))); + } + + Widget timeOutField() { + return TextFormField( + controller: dateTimeOut, readOnly: true, decoration: InputDecoration(border: OutlineInputBorder())); + } + + Widget timeOutCopyButton() { + return IconButton( + icon: Icon(Icons.copy, size: 22), + onPressed: () { + if (dateTimeOut.text.isEmpty) return; + Clipboard.setData(ClipboardData(text: dateTimeOut.text)); + FlutterToastr.show(localizations.copied, context); + }); + } + timestampConvert(String timestamp) { if (timestamp.isEmpty) return; try { diff --git a/lib/ui/component/toolbox/toolbox.dart b/lib/ui/component/toolbox/toolbox.dart index 0bb65c9..c57327b 100644 --- a/lib/ui/component/toolbox/toolbox.dart +++ b/lib/ui/component/toolbox/toolbox.dart @@ -121,7 +121,7 @@ class _ToolboxState extends State { return; } - MultiWindow.openWindow(localizations.timestamp, 'TimestampPage', size: const Size(650, 330)); + MultiWindow.openWindow(localizations.timestamp, 'TimestampPage', size: const Size(700, 350)); }, icon: Icons.av_timer, text: localizations.timestamp), diff --git a/lib/ui/desktop/toolbar/setting/rewrite/rewrite_update.dart b/lib/ui/desktop/toolbar/setting/rewrite/rewrite_update.dart index 214320f..79b3fcf 100644 --- a/lib/ui/desktop/toolbar/setting/rewrite/rewrite_update.dart +++ b/lib/ui/desktop/toolbar/setting/rewrite/rewrite_update.dart @@ -248,8 +248,8 @@ class _RewriteUpdateAddState extends State { if (rewriteType == RewriteType.updateBody) { dataController.text = (widget.ruleType == RuleType.requestUpdate - ? widget.request?.bodyAsString - : widget.request?.response?.bodyAsString) ?? + ? widget.request?.getBodyString() + : widget.request?.response?.getBodyString()) ?? ''; return; } diff --git a/lib/ui/mobile/setting/rewrite/rewrite_update.dart b/lib/ui/mobile/setting/rewrite/rewrite_update.dart index 45042e4..0f81d77 100644 --- a/lib/ui/mobile/setting/rewrite/rewrite_update.dart +++ b/lib/ui/mobile/setting/rewrite/rewrite_update.dart @@ -239,8 +239,8 @@ class _RewriteUpdateAddState extends State { if (rewriteType == RewriteType.updateBody) { dataController.text = (widget.ruleType == RuleType.requestUpdate - ? widget.request?.bodyAsString - : widget.request?.response?.bodyAsString) ?? + ? widget.request?.getBodyString() + : widget.request?.response?.getBodyString()) ?? ''; return; } diff --git a/pubspec.yaml b/pubspec.yaml index d58924a..1dd97d7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,14 +27,14 @@ dependencies: proxy_manager: ^0.0.3 permission_handler: ^11.3.1 flutter_toastr: ^1.0.3 - share_plus: ^10.1.1 + share_plus: ^10.1.2 flutter_js: ^0.8.1 flutter_code_editor: git: url: https://github.com/wanghongenpin/flutter-code-editor.git ref: secure-keyboard flutter_desktop_context_menu: ^0.2.0 - device_info_plus: ^11.1.0 + device_info_plus: ^11.1.1 shared_preferences: ^2.3.2 image_pickers: ^2.0.5+2 url_launcher: ^6.3.1