Advertisement
amonnoris

home_page.dart

Oct 5th, 2024
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 11.49 KB | Source Code | 0 0
  1. // lib/pages/home_page.dart
  2.  
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_v2ray/flutter_v2ray.dart';
  5. import 'package:provider/provider.dart';
  6.  
  7. import '../providers/app_state.dart';
  8.  
  9. class HomePage extends StatefulWidget {
  10.   final Function(int) onNavigate; // Callback to navigate to a specific tab
  11.  
  12.   const HomePage({super.key, required this.onNavigate});
  13.  
  14.   @override
  15.   State<HomePage> createState() => _HomePageState();
  16. }
  17.  
  18. class _HomePageState extends State<HomePage> {
  19.   final bypassSubnetController = TextEditingController();
  20.  
  21.   @override
  22.   void initState() {
  23.     super.initState();
  24.     // Fetch IP and location at startup
  25.     WidgetsBinding.instance.addPostFrameCallback((_) {
  26.       Provider.of<AppState>(context, listen: false).fetchIpAndLocation();
  27.     });
  28.   }
  29.  
  30.   @override
  31.   void dispose() {
  32.     bypassSubnetController.dispose();
  33.     super.dispose();
  34.   }
  35.  
  36.   @override
  37.   Widget build(BuildContext context) {
  38.     final appState = Provider.of<AppState>(context);
  39.  
  40.     return SingleChildScrollView(
  41.       padding: const EdgeInsets.all(20.0),
  42.       child: Column(
  43.         crossAxisAlignment: CrossAxisAlignment.stretch,
  44.         children: [
  45.           const SizedBox(height: 10),
  46.           const SizedBox(height: 5),
  47.           // Location and IP Address Display
  48.           Row(
  49.             mainAxisAlignment: MainAxisAlignment.spaceBetween,
  50.             children: [
  51.               Expanded(
  52.                 child: Text.rich(
  53.                   TextSpan(
  54.                     children: [
  55.                       TextSpan(
  56.                         text: appState.country,
  57.                         style: const TextStyle(
  58.                           fontWeight: FontWeight.bold,
  59.                           fontSize: 18,
  60.                         ),
  61.                       ),
  62.                       const TextSpan(
  63.                         text: '\nYour location',
  64.                         style: TextStyle(
  65.                           fontWeight: FontWeight.normal,
  66.                           fontSize: 14,
  67.                           color: Colors.grey,
  68.                         ),
  69.                       ),
  70.                     ],
  71.                   ),
  72.                   overflow: TextOverflow.ellipsis,
  73.                 ),
  74.               ),
  75.               const SizedBox(width: 10),
  76.               Expanded(
  77.                 child: Text.rich(
  78.                   TextSpan(
  79.                     children: [
  80.                       TextSpan(
  81.                         text: appState.currentIp,
  82.                         style: const TextStyle(
  83.                           fontWeight: FontWeight.bold,
  84.                           fontSize: 18,
  85.                         ),
  86.                       ),
  87.                       const TextSpan(
  88.                         text: '\nIP Address',
  89.                         style: TextStyle(
  90.                           fontWeight: FontWeight.normal,
  91.                           fontSize: 14,
  92.                           color: Colors.grey,
  93.                         ),
  94.                       ),
  95.                     ],
  96.                   ),
  97.                   overflow: TextOverflow.ellipsis,
  98.                   textAlign: TextAlign.end,
  99.                 ),
  100.               ),
  101.             ],
  102.           ),
  103.           const SizedBox(height: 20),
  104.           // Protocol and Network Display
  105.           Row(
  106.             mainAxisAlignment: MainAxisAlignment.spaceBetween,
  107.             children: [
  108.               const Expanded(
  109.                 child: Text.rich(
  110.                   TextSpan(
  111.                     children: [
  112.                       TextSpan(
  113.                         text: 'V2Ray',
  114.                         style: TextStyle(
  115.                           fontWeight: FontWeight.bold,
  116.                           fontSize: 18,
  117.                         ),
  118.                       ),
  119.                       TextSpan(
  120.                         text: '\nProtocol in use',
  121.                         style: TextStyle(
  122.                           fontWeight: FontWeight.normal,
  123.                           fontSize: 14,
  124.                           color: Colors.grey,
  125.                         ),
  126.                       ),
  127.                     ],
  128.                   ),
  129.                 ),
  130.               ),
  131.               const SizedBox(width: 10),
  132.               Expanded(
  133.                 child: Text(
  134.                   appState.network,
  135.                   style: const TextStyle(fontSize: 16),
  136.                   overflow: TextOverflow.ellipsis,
  137.                   textAlign: TextAlign.end,
  138.                 ),
  139.               ),
  140.             ],
  141.           ),
  142.           const SizedBox(height: 30),
  143.           // Selected Configuration Display
  144.           ListTile(
  145.             title: Text(
  146.               appState.selectedConfig != null
  147.                   ? appState.selectedConfig!.name
  148.                   : 'No configuration selected',
  149.             ),
  150.             subtitle: Text(
  151.               appState.selectedConfig?.remark ??
  152.                   'Please select a configuration.',
  153.             ),
  154.             trailing: IconButton(
  155.               icon: const Icon(Icons.manage_accounts),
  156.               onPressed: () {
  157.                 // Navigate to Servers (Configurations) tab using the callback
  158.                 widget.onNavigate(1); // Index 1 corresponds to Servers
  159.               },
  160.             ),
  161.           ),
  162.           const SizedBox(height: 10),
  163.           // Connect/Disconnect Buttons
  164.           Row(
  165.             mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  166.             children: [
  167.               ElevatedButton(
  168.                 onPressed:
  169.                     appState.isConnected ? null : () => appState.connect(),
  170.                 style: ElevatedButton.styleFrom(
  171.                   backgroundColor: Colors.green,
  172.                   padding:
  173.                       const EdgeInsets.symmetric(horizontal: 30, vertical: 15),
  174.                 ),
  175.                 child: const Text('Connect'),
  176.               ),
  177.               ElevatedButton(
  178.                 onPressed:
  179.                     appState.isConnected ? () => appState.disconnect() : null,
  180.                 style: ElevatedButton.styleFrom(
  181.                   backgroundColor: Colors.red,
  182.                   padding:
  183.                       const EdgeInsets.symmetric(horizontal: 30, vertical: 15),
  184.                 ),
  185.                 child: const Text('Disconnect'),
  186.               ),
  187.             ],
  188.           ),
  189.           const SizedBox(height: 10),
  190.           // Server Delay Button
  191.           ElevatedButton(
  192.             onPressed: () => appState.delay(),
  193.             child: const Text('Server Delay'),
  194.           ),
  195.           const SizedBox(height: 20),
  196.           // Real-Time Statistics
  197.           ValueListenableBuilder<V2RayStatus>(
  198.             valueListenable: appState.v2rayStatus,
  199.             builder: (context, value, child) {
  200.               return Column(
  201.                 children: [
  202.                   const SizedBox(height: 10),
  203.                   // Show the remaining time if connected
  204.                   if (appState.isConnected)
  205.                     Text(
  206.                       'Time remaining: ${_formatTime(appState.remainingTime)}',
  207.                       style: const TextStyle(fontSize: 24),
  208.                     ),
  209.                   const SizedBox(height: 10),
  210.                   // Display connection state
  211.                   Text(
  212.                     'State: ${appState.v2rayStatus.value.state}',
  213.                     style: const TextStyle(fontSize: 18),
  214.                   ),
  215.                   const SizedBox(height: 10),
  216.                   // Display connection duration
  217.                   Text(
  218.                     'Duration: ${appState.v2rayStatus.value.duration}',
  219.                     style: const TextStyle(fontSize: 16),
  220.                   ),
  221.                   const SizedBox(height: 10),
  222.                   // Display upload and download speeds
  223.                   Row(
  224.                     mainAxisAlignment: MainAxisAlignment.center,
  225.                     children: [
  226.                       const Text('Speed:', style: TextStyle(fontSize: 16)),
  227.                       const SizedBox(width: 10),
  228.                       Text(
  229.                         '${_formatSpeed(appState.v2rayStatus.value.uploadSpeed)} ↑',
  230.                         style: const TextStyle(fontSize: 16, color: Colors.red),
  231.                       ),
  232.                       const SizedBox(width: 10),
  233.                       Text(
  234.                         '${_formatSpeed(appState.v2rayStatus.value.downloadSpeed)} ↓',
  235.                         style:
  236.                             const TextStyle(fontSize: 16, color: Colors.green),
  237.                       ),
  238.                     ],
  239.                   ),
  240.                   const SizedBox(height: 10),
  241.                   // Display total data uploaded and downloaded
  242.                   Row(
  243.                     mainAxisAlignment: MainAxisAlignment.center,
  244.                     children: [
  245.                       const Text('Data Used:', style: TextStyle(fontSize: 16)),
  246.                       const SizedBox(width: 10),
  247.                       Text(
  248.                         '${_formatBytes(appState.v2rayStatus.value.upload)} ↑',
  249.                         style: const TextStyle(fontSize: 16, color: Colors.red),
  250.                       ),
  251.                       const SizedBox(width: 10),
  252.                       Text(
  253.                         '${_formatBytes(appState.v2rayStatus.value.download)} ↓',
  254.                         style:
  255.                             const TextStyle(fontSize: 16, color: Colors.green),
  256.                       ),
  257.                     ],
  258.                   ),
  259.                   const SizedBox(height: 10),
  260.                   // Display latency
  261.                   Text(
  262.                     'Latency: ${appState.latency > 0 ? '${appState.latency} ms' : 'N/A'}',
  263.                     style: const TextStyle(fontSize: 16),
  264.                   ),
  265.                   const SizedBox(height: 10),
  266.                   // Display core version
  267.                   Text(
  268.                     'Core Version: ${appState.coreVersion ?? 'N/A'}',
  269.                     style: const TextStyle(fontSize: 16),
  270.                   ),
  271.                 ],
  272.               );
  273.             },
  274.           ),
  275.           const SizedBox(height: 20),
  276.         ],
  277.       ),
  278.     );
  279.   }
  280.  
  281.   // Helper method to format Duration
  282.   String _formatDuration(Duration duration) {
  283.     String twoDigits(int n) => n.toString().padLeft(2, '0');
  284.     String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
  285.     String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
  286.     return '${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds';
  287.   }
  288.  
  289.   // Helper method to format remaining time
  290.   String _formatTime(int seconds) {
  291.     int minutes = seconds ~/ 60;
  292.     int remainingSeconds = seconds % 60;
  293.     return '${minutes.toString().padLeft(2, '0')}:${remainingSeconds.toString().padLeft(2, '0')}';
  294.   }
  295.  
  296.   // Helper method to format speed
  297.   String _formatSpeed(int speed) {
  298.     // Convert bytes per second to kbps or Mbps
  299.     double kbps = speed / 1000;
  300.     if (kbps >= 1000) {
  301.       double mbps = kbps / 1000;
  302.       return '${mbps.toStringAsFixed(2)} Mbps';
  303.     }
  304.     return '${kbps.toStringAsFixed(2)} kbps';
  305.   }
  306.  
  307.   // Helper method to format bytes
  308.   String _formatBytes(int bytes) {
  309.     if (bytes < 1024) return '$bytes B';
  310.     double kb = bytes / 1024;
  311.     if (kb < 1024) return '${kb.toStringAsFixed(2)} KB';
  312.     double mb = kb / 1024;
  313.     if (mb < 1024) return '${mb.toStringAsFixed(2)} MB';
  314.     double gb = mb / 1024;
  315.     return '${gb.toStringAsFixed(2)} GB';
  316.   }
  317. }
  318.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement