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}) : super(key: key); VpnConfig config; @override State createState() => _ConfigInfoViewState(); } class _ConfigInfoViewState extends State { final V2rayBox _v2rayBox = V2rayBox(); String ping = ""; DateTime lastPingUpdate = DateTime.utc(1700); bool _isChecking = false; Future _checkSpeed() async { if (_isChecking) { 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) { return Scaffold( appBar: AppBar(title: Text(widget.config.name)), body: ListView( children: [ 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, ), ); } }