mirror of
https://github.com/wanghongenpin/proxypin.git
synced 2026-04-14 20:53:34 +08:00
298 lines
10 KiB
Dart
298 lines
10 KiB
Dart
/*
|
|
* Copyright 2023 Hongen Wang All rights reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* https://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
import 'package:flutter/material.dart';
|
|
import 'package:proxypin/l10n/app_localizations.dart';
|
|
import 'package:proxypin/network/bin/configuration.dart';
|
|
import 'package:proxypin/network/bin/server.dart';
|
|
import 'package:proxypin/network/components/manager/hosts_manager.dart';
|
|
import 'package:proxypin/network/components/manager/request_block_manager.dart';
|
|
import 'package:proxypin/network/util/system_proxy.dart';
|
|
import 'package:proxypin/ui/component/multi_window.dart';
|
|
import 'package:proxypin/ui/component/proxy_port_setting.dart';
|
|
import 'package:proxypin/ui/component/widgets.dart';
|
|
import 'package:proxypin/ui/desktop/setting/about.dart';
|
|
import 'package:proxypin/ui/desktop/setting/external_proxy.dart';
|
|
import 'package:proxypin/ui/desktop/setting/hosts.dart';
|
|
import 'package:proxypin/ui/desktop/setting/request_block.dart';
|
|
|
|
import 'filter.dart';
|
|
|
|
///设置菜单
|
|
/// @author wanghongen
|
|
/// 2023/10/8
|
|
class Setting extends StatefulWidget {
|
|
final ProxyServer proxyServer;
|
|
|
|
const Setting({super.key, required this.proxyServer});
|
|
|
|
@override
|
|
State<Setting> createState() => _SettingState();
|
|
}
|
|
|
|
class _SettingState extends State<Setting> {
|
|
late Configuration configuration;
|
|
|
|
AppLocalizations get localizations => AppLocalizations.of(context)!;
|
|
|
|
@override
|
|
void initState() {
|
|
configuration = widget.proxyServer.configuration;
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MenuAnchor(
|
|
builder: (context, controller, child) {
|
|
return IconButton(
|
|
icon: const Icon(Icons.settings, size: 21),
|
|
tooltip: localizations.setting,
|
|
onPressed: () {
|
|
if (controller.isOpen) {
|
|
controller.close();
|
|
} else {
|
|
controller.open();
|
|
}
|
|
});
|
|
},
|
|
menuChildren: [
|
|
_ProxyMenu(proxyServer: widget.proxyServer),
|
|
item(localizations.domainFilter, onPressed: hostFilter),
|
|
item(localizations.hosts, onPressed: hosts),
|
|
item(localizations.requestBlock, onPressed: showRequestBlock),
|
|
item(localizations.requestRewrite, onPressed: requestRewrite),
|
|
item(localizations.requestMap, onPressed: requestMap),
|
|
item(localizations.requestCrypto, onPressed: showRequestCrypto),
|
|
item(localizations.script,
|
|
onPressed: () => MultiWindow.openWindow(localizations.script, 'ScriptWidget', size: const Size(800, 780))),
|
|
item(localizations.breakpoint, onPressed: requestBreakpoint),
|
|
item(localizations.externalProxy, onPressed: setExternalProxy),
|
|
item(localizations.about, onPressed: showAbout),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget item(String text, {VoidCallback? onPressed}) {
|
|
return MenuItemButton(
|
|
trailingIcon: const Icon(Icons.arrow_right),
|
|
onPressed: onPressed,
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(left: 10, right: 5),
|
|
child: Text(text, style: const TextStyle(fontSize: 14))));
|
|
}
|
|
|
|
void showAbout() {
|
|
showDialog(context: context, builder: (context) => DesktopAbout());
|
|
}
|
|
|
|
///设置外部代理地址
|
|
void setExternalProxy() {
|
|
showDialog(
|
|
barrierDismissible: false,
|
|
context: context,
|
|
builder: (context) {
|
|
return ExternalProxyDialog(configuration: widget.proxyServer.configuration);
|
|
});
|
|
}
|
|
|
|
///请求重写Dialog
|
|
void requestRewrite() async {
|
|
MultiWindow.openWindow(localizations.requestRewrite, 'RequestRewriteWidget', size: const Size(800, 750));
|
|
}
|
|
|
|
void requestBreakpoint() async {
|
|
MultiWindow.openWindow(localizations.breakpoint, 'RequestBreakpointPage', size: const Size(800, 750));
|
|
}
|
|
|
|
///请求本地映射
|
|
void requestMap() async {
|
|
if (!mounted) return;
|
|
MultiWindow.openWindow(localizations.requestMap, 'RequestMapPage', size: const Size(800, 720));
|
|
}
|
|
|
|
///show域名过滤Dialog
|
|
void hostFilter() {
|
|
showDialog(
|
|
barrierDismissible: false, context: context, builder: (context) => FilterDialog(configuration: configuration));
|
|
}
|
|
|
|
///show域名过滤Dialog
|
|
void hosts() async {
|
|
var hosts = await HostsManager.instance;
|
|
if (!mounted) return;
|
|
showDialog(barrierDismissible: false, context: context, builder: (context) => HostsDialog(hostsManager: hosts));
|
|
}
|
|
|
|
//请求屏蔽
|
|
void showRequestBlock() async {
|
|
var requestBlockManager = await RequestBlockManager.instance;
|
|
if (!mounted) return;
|
|
showDialog(
|
|
barrierDismissible: false,
|
|
context: context,
|
|
builder: (context) => RequestBlock(requestBlockManager: requestBlockManager));
|
|
}
|
|
|
|
void showRequestCrypto() {
|
|
MultiWindow.openWindow(localizations.requestCrypto, 'RequestCryptoPage', size: const Size(820, 750));
|
|
}
|
|
}
|
|
|
|
///代理菜单
|
|
class _ProxyMenu extends StatefulWidget {
|
|
final ProxyServer proxyServer;
|
|
|
|
const _ProxyMenu({required this.proxyServer});
|
|
|
|
@override
|
|
State<StatefulWidget> createState() => _ProxyMenuState();
|
|
}
|
|
|
|
class _ProxyMenuState extends State<_ProxyMenu> {
|
|
var textEditingController = TextEditingController();
|
|
|
|
late Configuration configuration;
|
|
bool changed = false;
|
|
|
|
AppLocalizations get localizations => AppLocalizations.of(context)!;
|
|
|
|
@override
|
|
void initState() {
|
|
configuration = widget.proxyServer.configuration;
|
|
textEditingController.text = configuration.proxyPassDomains;
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
if (configuration.proxyPassDomains != textEditingController.text) {
|
|
changed = true;
|
|
configuration.proxyPassDomains = textEditingController.text;
|
|
SystemProxy.setProxyPassDomains(configuration.proxyPassDomains);
|
|
}
|
|
|
|
if (changed) {
|
|
configuration.flushConfig();
|
|
}
|
|
textEditingController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
bool isEn = localizations.localeName.startsWith("en");
|
|
return SubmenuButton(
|
|
menuChildren: [
|
|
PortWidget(proxyServer: widget.proxyServer, textStyle: const TextStyle(fontSize: 13)),
|
|
const Divider(thickness: 0.3, height: 8),
|
|
setSystemProxy(),
|
|
const Divider(thickness: 0.3, height: 8),
|
|
Row(children: [
|
|
Expanded(
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(left: 15),
|
|
child: Text("SOCKS5", style: const TextStyle(fontSize: 14)))),
|
|
SwitchWidget(
|
|
value: configuration.enableSocks5,
|
|
scale: 0.75,
|
|
onChanged: (val) {
|
|
configuration.enableSocks5 = val;
|
|
changed = true;
|
|
}),
|
|
SizedBox(width: 10)
|
|
]),
|
|
const Divider(thickness: 0.3, height: 8),
|
|
Row(children: [
|
|
Expanded(
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(left: 15),
|
|
child: Text(localizations.enabledHTTP2, style: const TextStyle(fontSize: 14)))),
|
|
SwitchWidget(
|
|
value: configuration.enabledHttp2,
|
|
scale: 0.75,
|
|
onChanged: (val) {
|
|
configuration.enabledHttp2 = val;
|
|
changed = true;
|
|
}),
|
|
SizedBox(width: 10)
|
|
]),
|
|
const Divider(thickness: 0.3, height: 8),
|
|
const SizedBox(height: 3),
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 15),
|
|
child: Row(children: [
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(localizations.proxyIgnoreDomain, style: const TextStyle(fontSize: 14)),
|
|
const SizedBox(height: 3),
|
|
Text(isEn ? "Use ';' to separate multiple entries": "多个使用;分割", style: TextStyle(fontSize: 11, color: Colors.grey.shade600)),
|
|
],
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 35),
|
|
child: TextButton(
|
|
child: Text(localizations.reset),
|
|
onPressed: () {
|
|
textEditingController.text = SystemProxy.proxyPassDomains;
|
|
},
|
|
))
|
|
])),
|
|
const SizedBox(height: 5),
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 15, right: 5),
|
|
child: TextField(
|
|
textInputAction: TextInputAction.done,
|
|
style: const TextStyle(fontSize: 13),
|
|
controller: textEditingController,
|
|
decoration: const InputDecoration(
|
|
contentPadding: EdgeInsets.all(10),
|
|
border: OutlineInputBorder(),
|
|
constraints: BoxConstraints(minWidth: 190, maxWidth: 190)),
|
|
maxLines: 5,
|
|
minLines: 1)),
|
|
const SizedBox(height: 10),
|
|
],
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(left: 10),
|
|
child: Text(localizations.proxy, style: const TextStyle(fontSize: 14))),
|
|
);
|
|
}
|
|
|
|
///设置系统代理
|
|
Widget setSystemProxy() {
|
|
return Row(children: [
|
|
Expanded(
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(left: 15, right: 20),
|
|
child: Text(localizations.setAs + localizations.systemProxy, style: const TextStyle(fontSize: 14)))),
|
|
Transform.scale(
|
|
scale: 0.75,
|
|
child: Switch(
|
|
hoverColor: Colors.transparent,
|
|
value: configuration.enableSystemProxy,
|
|
onChanged: (val) {
|
|
widget.proxyServer.setSystemProxyEnable(val);
|
|
configuration.enableSystemProxy = val;
|
|
setState(() {
|
|
changed = true;
|
|
});
|
|
})),
|
|
SizedBox(width: 10)
|
|
]);
|
|
}
|
|
}
|