ios版本

This commit is contained in:
wanghongen
2023-07-05 02:15:20 +08:00
parent 5b9107fe1c
commit cc8b84f7e8
55 changed files with 665 additions and 404 deletions

View File

@@ -26,6 +26,7 @@ class MobileHomePage extends StatefulWidget {
class MobileHomeState extends State<MobileHomePage> implements EventListener {
static const MethodChannel proxyVpnChannel = MethodChannel('com.proxy/proxyVpn');
final ValueNotifier<bool> sllEnableListenable = ValueNotifier<bool>(true);
late ProxyServer proxyServer;
final requestStateKey = GlobalKey<RequestWidgetState>();
@@ -43,9 +44,16 @@ class MobileHomeState extends State<MobileHomePage> implements EventListener {
@override
void initState() {
proxyServer = ProxyServer(listener: this);
proxyServer.initialize().then((value) => sllEnableListenable.value = proxyServer.enableSsl);
super.initState();
}
@override
void dispose() {
sllEnableListenable.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -54,16 +62,19 @@ class MobileHomeState extends State<MobileHomePage> implements EventListener {
tooltip: "清理",
icon: const Icon(Icons.cleaning_services_outlined),
onPressed: () => requestStateKey.currentState?.clean()),
IconButton(
tooltip: "Https代理",
icon: const Icon(Icons.https),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context) {
return MobileSslWidget(proxyServer: proxyServer);
}),
);
})
ValueListenableBuilder(
valueListenable: sllEnableListenable,
builder: (_, bool enabled, __) => IconButton(
tooltip: "Https代理",
icon: Icon(Icons.https, color: enabled ? null : Colors.red),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context) {
return MobileSslWidget(
proxyServer: proxyServer, onEnableChange: (val) => sllEnableListenable.value = val);
}),
);
}))
]),
drawer: drawer(),
floatingActionButton: FloatingActionButton(
@@ -101,9 +112,13 @@ class MobileHomeState extends State<MobileHomePage> implements EventListener {
trailing: const Icon(Icons.arrow_right),
onTap: () => _filter(HostFilter.blacklist)),
ListTile(title: const Text("请求重写"), trailing: const Icon(Icons.arrow_right), onTap: () => _reqeustRewrite()),
ListTile(title: const Text("Github"), trailing: const Icon(Icons.arrow_right), onTap: () {
launchUrl(Uri.parse("https://github.com/wanghongenpin/network-proxy-flutter"), mode: LaunchMode.externalApplication);
})
ListTile(
title: const Text("Github"),
trailing: const Icon(Icons.arrow_right),
onTap: () {
launchUrl(Uri.parse("https://github.com/wanghongenpin/network_proxy_flutter"),
mode: LaunchMode.externalApplication);
})
],
));
}

View File

@@ -213,6 +213,7 @@ class DomainListState extends State<DomainList> {
Map<HostAndPort, List<HttpRequest>> containerMap = {};
LinkedHashSet<HostAndPort> container = LinkedHashSet<HostAndPort>();
List<HostAndPort> list = [];
HostAndPort? showHostAndPort;
@override
@@ -228,10 +229,13 @@ class DomainListState extends State<DomainList> {
}
list.add(request);
}
list = container.toList();
}
add(HttpRequest request) {
var hostAndPort = request.hostAndPort!;
container.remove(hostAndPort);
container.add(hostAndPort);
var list = containerMap[hostAndPort];
if (list == null) {
@@ -243,6 +247,7 @@ class DomainListState extends State<DomainList> {
requestSequenceKey.currentState?.add(request);
}
this.list = [...container].reversed.toList();
setState(() {});
}
@@ -261,22 +266,23 @@ class DomainListState extends State<DomainList> {
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: container.length,
return ListView.separated(
separatorBuilder: (context, index) => Divider(height: 0.5, color: Theme.of(context).focusColor),
itemCount: list.length,
itemBuilder: (context, index) {
var time = formatDate(
containerMap[container.elementAt(index)]!.last.requestTime, [m, '/', d, ' ', HH, ':', nn, ':', ss]);
containerMap[list.elementAt(index)]!.last.requestTime, [m, '/', d, ' ', HH, ':', nn, ':', ss]);
return ListTile(
title: Text(container.elementAt(index).url, maxLines: 1, overflow: TextOverflow.ellipsis),
title: Text(list.elementAt(index).url, maxLines: 1, overflow: TextOverflow.ellipsis),
trailing: const Icon(Icons.chevron_right),
subtitle: Text("最后请求时间: $time, 次数: ${containerMap[container.elementAt(index)]!.length}",
subtitle: Text("最后请求时间: $time, 次数: ${containerMap[list.elementAt(index)]!.length}",
maxLines: 1, overflow: TextOverflow.ellipsis),
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
showHostAndPort = container.elementAt(index);
showHostAndPort = list.elementAt(index);
return Scaffold(
appBar: AppBar(title: const Text("请求列表")),
body: RequestSequence(key: requestSequenceKey, list: containerMap[container.elementAt(index)]!));
body: RequestSequence(key: requestSequenceKey, list: containerMap[list.elementAt(index)]!));
}));
});
});

View File

@@ -4,14 +4,25 @@ import 'package:url_launcher/url_launcher.dart';
class MobileSslWidget extends StatefulWidget {
final ProxyServer proxyServer;
final Function(bool val) onEnableChange;
const MobileSslWidget({super.key, required this.proxyServer});
const MobileSslWidget({super.key, required this.proxyServer, required this.onEnableChange});
@override
State<MobileSslWidget> createState() => _MobileSslState();
}
class _MobileSslState extends State<MobileSslWidget> {
bool changed = false;
@override
void dispose() {
super.dispose();
if (changed) {
widget.proxyServer.flushConfig();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -20,7 +31,16 @@ class _MobileSslState extends State<MobileSslWidget> {
centerTitle: true,
),
body: Column(children: [
_Switch(proxyServer: widget.proxyServer),
SwitchListTile(
hoverColor: Colors.transparent,
title: const Text("启用Https代理", style: TextStyle(fontSize: 16)),
value: widget.proxyServer.enableSsl,
onChanged: (val) {
widget.proxyServer.enableSsl = val;
widget.onEnableChange(val);
changed = true;
setState(() {});
}),
ExpansionTile(
title: const Text("安装根证书"),
initiallyExpanded: true,
@@ -39,37 +59,3 @@ class _MobileSslState extends State<MobileSslWidget> {
launchUrl(Uri.parse("http://127.0.0.1:${widget.proxyServer.port}/ssl"), mode: LaunchMode.externalApplication);
}
}
class _Switch extends StatefulWidget {
final ProxyServer proxyServer;
const _Switch({Key? key, required this.proxyServer}) : super(key: key);
@override
State<_Switch> createState() => _SwitchState();
}
class _SwitchState extends State<_Switch> {
bool changed = false;
@override
Widget build(BuildContext context) {
return SwitchListTile(
hoverColor: Colors.transparent,
title: const Text("启用Https代理", style: TextStyle(fontSize: 16)),
value: widget.proxyServer.enableSsl,
onChanged: (val) {
widget.proxyServer.enableSsl = val;
changed = true;
setState(() {});
});
}
@override
void dispose() {
super.dispose();
if (changed) {
widget.proxyServer.flushConfig();
}
}
}