diff --git a/lib/network/util/script_manager.dart b/lib/network/util/script_manager.dart index 77addfe..4cd7b54 100644 --- a/lib/network/util/script_manager.dart +++ b/lib/network/util/script_manager.dart @@ -109,7 +109,6 @@ class ScriptManager { Future removeScript(int index) async { var item = list.removeAt(index); File(item.scriptPath!).delete(); - flushConfig(); } ///刷新配置 @@ -171,6 +170,7 @@ class ScriptManager { return response; } + /// static Future jsResultResolve(JsEvalResult jsResult) async { if (jsResult.isPromise) { jsResult = await flutterJs.handlePromise(jsResult); diff --git a/lib/ui/component/multi_window.dart b/lib/ui/component/multi_window.dart index 31e8926..6175196 100644 --- a/lib/ui/component/multi_window.dart +++ b/lib/ui/component/multi_window.dart @@ -12,6 +12,7 @@ import 'package:network_proxy/ui/desktop/left/request_editor.dart'; import 'package:network_proxy/ui/desktop/toolbar/setting/script.dart'; import 'package:network_proxy/utils/platform.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:url_launcher/url_launcher.dart'; import 'package:window_manager/window_manager.dart'; ///多窗口 @@ -75,22 +76,33 @@ void methodHandler() { DesktopMultiWindow.setMethodHandler((call, fromWindowId) async { print('${call.method} ${call.arguments} $fromWindowId'); - if (call.method == 'getApplicationSupportDirectory') { - return getApplicationSupportDirectory().then((it) => it.path); - } - if (call.method == 'getSaveLocation') { - return (await getSaveLocation(suggestedName: call.arguments))?.path; - } - if (call.method == 'openFile') { - XTypeGroup typeGroup = XTypeGroup(extensions: [call.arguments]); - final XFile? file = await openFile(acceptedTypeGroups: [typeGroup]); - return file?.path; - } if (call.method == 'refreshScript') { await ScriptManager.instance.then((value) { return value.reloadScript(); }); } + + if (call.method == 'getApplicationSupportDirectory') { + return getApplicationSupportDirectory().then((it) => it.path); + } + + if (call.method == 'getSaveLocation') { + String? path = (await getSaveLocation(suggestedName: call.arguments))?.path; + if (Platform.isWindows) windowManager.blur(); + return path; + } + + if (call.method == 'openFile') { + XTypeGroup typeGroup = XTypeGroup(extensions: [call.arguments]); + final XFile? file = await openFile(acceptedTypeGroups: [typeGroup]); + if (Platform.isWindows) windowManager.blur(); + return file?.path; + } + + if (call.method == 'launchUrl') { + return launchUrl(Uri.parse(call.arguments)); + } + return 'done'; }); } diff --git a/lib/ui/component/widgets.dart b/lib/ui/component/widgets.dart index 6a785ca..a6fbbb4 100644 --- a/lib/ui/component/widgets.dart +++ b/lib/ui/component/widgets.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:network_proxy/utils/lang.dart'; class CustomPopupMenuItem extends PopupMenuItem { final Color? color; @@ -32,32 +33,25 @@ class _CustomPopupMenuItemState extends PopupMenuItemState value; final ValueChanged onChanged; - const SwitchWidget({super.key, this.title, this.subtitle, required this.value, required this.onChanged}); + SwitchWidget({super.key, this.title, this.subtitle, required bool value, required this.onChanged}) + : value = ValueWrap.of(value); @override State createState() => _SwitchState(); } class _SwitchState extends State { - bool value = false; - - @override - void initState() { - super.initState(); - value = widget.value; - } - @override Widget build(BuildContext context) { if (widget.title == null) { return Switch( - value: value, + value: widget.value.get() == true, onChanged: (value) { setState(() { - this.value = value; + widget.value.set(value); }); widget.onChanged(value); }, @@ -66,11 +60,11 @@ class _SwitchState extends State { return SwitchListTile( title: widget.title == null ? null : Text(widget.title!), subtitle: widget.subtitle == null ? null : Text(widget.subtitle!), - value: value, + value: widget.value.get() == true, dense: true, onChanged: (value) { setState(() { - this.value = value; + widget.value.set(value); }); widget.onChanged(value); }, diff --git a/lib/ui/desktop/toolbar/setting/script.dart b/lib/ui/desktop/toolbar/setting/script.dart index fb83b50..1b133ec 100644 --- a/lib/ui/desktop/toolbar/setting/script.dart +++ b/lib/ui/desktop/toolbar/setting/script.dart @@ -19,6 +19,7 @@ import 'dart:io'; import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:file_selector/file_selector.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_code_editor/flutter_code_editor.dart'; @@ -153,11 +154,7 @@ class _ScriptWidgetState extends State { //导入js import() async { - String? file = Platform.isMacOS - ? await DesktopMultiWindow.invokeMethod(0, 'openFile', 'json') - : await openFile(acceptedTypeGroups: [ - const XTypeGroup(extensions: ['json']) - ]).then((it) => it?.path); + String? file = await DesktopMultiWindow.invokeMethod(0, 'openFile', 'json'); WindowController.fromWindowId(widget.windowId).show(); if (file == null) { return; @@ -212,9 +209,8 @@ async function onRequest(context, request) { // 更新或添加新标头 //request.headers["X-New-Headers"] = "My-Value"; - //var body = JSON.parse(response.body); - //body['key'] = "value"; - //response.body = JSON.stringify(body); + // Update Body 使用fetch API请求接口,具体文档可网上搜索fetch API + //response.body = await fetch('https://www.baidu.com/').then(response => response.text()); return request; } @@ -224,8 +220,9 @@ async function onResponse(context, request, response) { // response.headers["Name"] = "Value"; // response.statusCode = 200; - // Update Body - //response.body = await fetch('https://www.baidu.com/').then(response => response.text()); + //var body = JSON.parse(response.body); + //body['key'] = "value"; + //response.body = JSON.stringify(body); return response; } """; @@ -256,11 +253,16 @@ async function onResponse(context, request, response) { return AlertDialog( scrollable: true, titlePadding: const EdgeInsets.only(left: 15, top: 5, right: 15), - title: const Row(children: [ - Text("编辑脚本", style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)), - SizedBox(width: 10), - Tooltip(message: "使用 JavaScript 修改请求和响应", child: Icon(Icons.help_outline, size: 20)), - Expanded(child: Align(alignment: Alignment.topRight, child: CloseButton())) + title: Row(children: [ + const Text("编辑脚本", style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)), + const SizedBox(width: 10), + Text.rich(TextSpan( + text: '使用文档', + style: const TextStyle(color: Colors.blue, fontSize: 14), + recognizer: TapGestureRecognizer() + ..onTap = () => DesktopMultiWindow.invokeMethod( + 0, "launchUrl", 'https://gitee.com/wanghongenpin/network-proxy-flutter/wikis/%E8%84%9A%E6%9C%AC'))), + const Expanded(child: Align(alignment: Alignment.topRight, child: CloseButton())) ]), actionsPadding: const EdgeInsets.only(right: 10, bottom: 10), actions: [ @@ -400,7 +402,6 @@ class _ScriptListState extends State { child: list[index].enabled ? const Text("禁用") : const Text("启用"), onTap: () { list[index].enabled = !list[index].enabled; - _refreshScript(); setState(() {}); }), const PopupMenuDivider(), @@ -409,6 +410,7 @@ class _ScriptListState extends State { child: const Text("删除"), onTap: () async { (await ScriptManager.instance).removeScript(index); + _refreshScript(); setState(() {}); if (context.mounted) FlutterToastr.show('删除成功', context); }), @@ -446,9 +448,7 @@ class _ScriptListState extends State { export(ScriptItem item) async { //文件名称 String fileName = '${item.name}.json'; - String? saveLocation = Platform.isMacOS - ? await DesktopMultiWindow.invokeMethod(0, 'getSaveLocation', fileName) - : (await getSaveLocation(suggestedName: fileName))?.path; + String? saveLocation = await DesktopMultiWindow.invokeMethod(0, 'getSaveLocation', fileName); WindowController.fromWindowId(widget.windowId).show(); if (saveLocation == null) { return; diff --git a/lib/utils/lang.dart b/lib/utils/lang.dart index c8c41ac..e41e59b 100644 --- a/lib/utils/lang.dart +++ b/lib/utils/lang.dart @@ -1,5 +1,12 @@ class ValueWrap { V? _v; + ValueWrap(); + + factory ValueWrap.of(V v) { + var valueWrap = ValueWrap(); + valueWrap._v = v; + return valueWrap; + } void set(V? v) => this._v = v; diff --git a/pubspec.lock b/pubspec.lock index 62f023c..34f2678 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -405,10 +405,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.1" + version: "1.10.0" mime: dependency: transitive description: @@ -730,10 +730,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: "14f1f70c51119012600c5f1f60ca68efda5a9b6077748163c6af2893ec5df8fc" url: "https://pub.flutter-io.cn" source: hosted - version: "0.1.4-beta" + version: "0.2.1-beta" win32: dependency: transitive description: @@ -759,5 +759,5 @@ packages: source: hosted version: "1.0.3" sdks: - dart: ">=3.1.0 <4.0.0" + dart: ">=3.2.0-157.0.dev <4.0.0" flutter: ">=3.13.0"