Files
vpn/lib/views/config_info_view.dart
2026-04-20 01:34:03 +03:00

133 lines
3.3 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:v2ray_box/v2ray_box.dart';
// ignore: must_be_immutable
class ConfigInfoView extends StatefulWidget {
ConfigInfoView({Key? key, required this.config, this.hideDetails = false})
: super(key: key);
VpnConfig config;
bool hideDetails;
@override
State<ConfigInfoView> createState() => _ConfigInfoViewState();
}
class _ConfigInfoViewState extends State<ConfigInfoView> {
final V2rayBox _v2rayBox = V2rayBox();
String ping = "";
DateTime lastPingUpdate = DateTime.utc(1700);
bool _isChecking = false;
Future<void> _checkSpeed() async {
if (_isChecking) {
return;
}
if (Platform.isLinux) {
setState(() {
ping = 'Unavailable on Linux backend';
lastPingUpdate = DateTime.now();
});
return;
}
setState(() {
_isChecking = true;
});
try {
await _v2rayBox.initialize(notificationStopButtonText: 'Stop');
final int latency = await _v2rayBox.ping(
widget.config.link,
timeout: 7000,
);
if (!mounted) {
return;
}
setState(() {
ping = latency < 0 ? 'Timeout' : '${latency} ms';
lastPingUpdate = DateTime.now();
});
} catch (_) {
if (!mounted) {
return;
}
setState(() {
ping = 'Error';
lastPingUpdate = DateTime.now();
});
} finally {
if (!mounted) {
return;
}
setState(() {
_isChecking = false;
});
}
}
@override
Widget build(BuildContext context) {
final bool hideDetails = widget.hideDetails;
return Scaffold(
appBar: AppBar(
title: Text(hideDetails ? 'Remote config' : widget.config.name),
),
body: ListView(
children: [
if (!hideDetails) ...[
ListTile(title: Text(widget.config.id), subtitle: Text("ID")),
SizedBox(height: 10),
ListTile(
title: Text(widget.config.protocol),
subtitle: Text("Protocol"),
),
SizedBox(height: 10),
ListTile(
title: Text(widget.config.server ?? "Unknown server"),
subtitle: Text("Server"),
),
SizedBox(height: 10),
ListTile(
title: Text(widget.config.port?.toString() ?? "0000"),
subtitle: Text("Port"),
),
SizedBox(height: 10),
],
ListTile(
title: Text(ping.isEmpty ? "Unknown" : ping),
subtitle: Text(
"Ping ${lastPingUpdate.year == 1700 ? "" : lastPingUpdate}",
),
),
SizedBox(height: 10),
],
),
floatingActionButton: FloatingActionButton(
foregroundColor: Theme.of(context).colorScheme.onPrimary,
backgroundColor: Theme.of(context).colorScheme.primary,
child: _isChecking
? SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Theme.of(context).colorScheme.onPrimary,
),
)
: Icon(Icons.shutter_speed),
onPressed: _isChecking ? null : _checkSpeed,
),
);
}
}