From 05b56f6a66db63e6a28c981d0fb7af13910e2c30 Mon Sep 17 00:00:00 2001 From: lukki15 <50550773+lukki15@users.noreply.github.com> Date: Sat, 4 Jan 2025 06:57:34 +0000 Subject: [PATCH] refactor: :recycle: separate network info logic from page UI and restructure network stats to use the futures directly --- lib/pages/main_scaffold.dart | 2 +- lib/pages/network_info.dart | 17 +++ lib/pages/network_info/network_stats.dart | 133 ------------------ lib/pages/network_scan/device_info.dart | 2 +- lib/pages/network_scan/network_scan.dart | 2 +- .../network_scan => widget}/future_text.dart | 12 +- .../connectivity_info_tiles.dart} | 24 ++-- .../network_info/connectivity_stats.dart | 122 ++++++++++++++++ lib/widget/network_info/future_ftile.dart | 33 +++++ 9 files changed, 194 insertions(+), 153 deletions(-) create mode 100644 lib/pages/network_info.dart delete mode 100644 lib/pages/network_info/network_stats.dart rename lib/{pages/network_scan => widget}/future_text.dart (58%) rename lib/{pages/network_info/network_info.dart => widget/network_info/connectivity_info_tiles.dart} (72%) create mode 100644 lib/widget/network_info/connectivity_stats.dart create mode 100644 lib/widget/network_info/future_ftile.dart diff --git a/lib/pages/main_scaffold.dart b/lib/pages/main_scaffold.dart index 4ce31ef..3dc596a 100644 --- a/lib/pages/main_scaffold.dart +++ b/lib/pages/main_scaffold.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:forui/forui.dart'; import 'package:provider/provider.dart'; -import 'package:network_info_app/pages/network_info/network_info.dart'; +import 'package:network_info_app/pages/network_info.dart'; import 'package:network_info_app/pages/network_scan/network_scan.dart'; import 'package:network_info_app/provider/connectivity_notifier.dart'; diff --git a/lib/pages/network_info.dart b/lib/pages/network_info.dart new file mode 100644 index 0000000..fdc1c4b --- /dev/null +++ b/lib/pages/network_info.dart @@ -0,0 +1,17 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:network_info_app/provider/connectivity_notifier.dart'; +import 'package:network_info_app/widget/network_info/connectivity_info_tiles.dart'; + +class NetworkInfo extends StatelessWidget { + const NetworkInfo({super.key}); + + @override + Widget build(BuildContext context) { + return Consumer( + builder: (context, myNotifier, child) => + ConnectivityInfoTiles(conductivities: myNotifier.connectionStatus), + ); + } +} diff --git a/lib/pages/network_info/network_stats.dart b/lib/pages/network_info/network_stats.dart deleted file mode 100644 index b492486..0000000 --- a/lib/pages/network_info/network_stats.dart +++ /dev/null @@ -1,133 +0,0 @@ -import 'dart:async'; -import 'dart:developer' as developer; -import 'dart:io'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:network_info_plus/network_info_plus.dart'; -import 'package:permission_handler/permission_handler.dart'; -import 'package:forui/forui.dart'; - -class NetworkStats extends StatefulWidget { - const NetworkStats({super.key}); - - @override - State createState() => _NetworkStatsState(); -} - -class _NetworkStatsState extends State { - List> _connectionStatus = []; - final NetworkInfo _networkInfo = NetworkInfo(); - - @override - void initState() { - super.initState(); - _initNetworkInfo(); - } - - @override - Widget build(BuildContext context) { - return FTileGroup( - children: List.generate( - _connectionStatus.length, - (index) => FTile( - title: Text(_connectionStatus[index][0]), - details: Text(_connectionStatus[index][1]), - onLongPress: () => Clipboard.setData( - ClipboardData(text: _connectionStatus[index][1])), - )), - ); - } - - Future _initNetworkInfo() async { - String? wifiName, - wifiBSSID, - wifiIPv4, - wifiIPv6, - wifiGatewayIP, - wifiBroadcast, - wifiSubmask; - - try { - if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) { - // Request permissions as recommended by the plugin documentation: - // https://github.com/fluttercommunity/plus_plugins/tree/main/packages/network_info_plus/network_info_plus - if (await Permission.locationWhenInUse.request().isGranted) { - wifiName = await _networkInfo.getWifiName(); - } else { - wifiName = 'Unauthorized to get Wifi Name'; - } - } else { - wifiName = await _networkInfo.getWifiName(); - } - } on PlatformException catch (e) { - developer.log('Failed to get Wifi Name', error: e); - wifiName = 'Failed to get Wifi Name'; - } - - try { - if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) { - // Request permissions as recommended by the plugin documentation: - // https://github.com/fluttercommunity/plus_plugins/tree/main/packages/network_info_plus/network_info_plus - if (await Permission.locationWhenInUse.request().isGranted) { - wifiBSSID = await _networkInfo.getWifiBSSID(); - } else { - wifiBSSID = 'Unauthorized to get Wifi BSSID'; - } - } else { - wifiName = await _networkInfo.getWifiName(); - } - } on PlatformException catch (e) { - developer.log('Failed to get Wifi BSSID', error: e); - wifiBSSID = 'Failed to get Wifi BSSID'; - } - - try { - wifiIPv4 = await _networkInfo.getWifiIP(); - } on PlatformException catch (e) { - developer.log('Failed to get Wifi IPv4', error: e); - wifiIPv4 = 'Failed to get Wifi IPv4'; - } - - try { - wifiIPv6 = await _networkInfo.getWifiIPv6(); - } on PlatformException catch (e) { - developer.log('Failed to get Wifi IPv6', error: e); - wifiIPv6 = 'Failed to get Wifi IPv6'; - } - - try { - wifiSubmask = await _networkInfo.getWifiSubmask(); - } on PlatformException catch (e) { - developer.log('Failed to get Wifi submask address', error: e); - wifiSubmask = 'Failed to get Wifi submask address'; - } - - try { - wifiBroadcast = await _networkInfo.getWifiBroadcast(); - } on PlatformException catch (e) { - developer.log('Failed to get Wifi broadcast', error: e); - wifiBroadcast = 'Failed to get Wifi broadcast'; - } - - try { - wifiGatewayIP = await _networkInfo.getWifiGatewayIP(); - } on PlatformException catch (e) { - developer.log('Failed to get Wifi gateway address', error: e); - wifiGatewayIP = 'Failed to get Wifi gateway address'; - } - - setState(() { - _connectionStatus = [ - ['Wifi Name', wifiName ?? "N/A"], - ['Wifi BSSID', wifiBSSID ?? "N/A"], - ['Wifi IPv4', wifiIPv4 ?? "N/A"], - ['Wifi IPv6', wifiIPv6 ?? "N/A"], - ['Wifi Broadcast', wifiBroadcast ?? "N/A"], - ['Wifi Gateway', wifiGatewayIP ?? "N/A"], - ['Wifi Submask', wifiSubmask ?? "N/A"], - ]; - }); - } -} diff --git a/lib/pages/network_scan/device_info.dart b/lib/pages/network_scan/device_info.dart index 4f4d7ac..6b502af 100644 --- a/lib/pages/network_scan/device_info.dart +++ b/lib/pages/network_scan/device_info.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:forui/forui.dart'; -import 'package:network_info_app/pages/network_scan/future_text.dart'; import 'package:network_tools/network_tools.dart'; import 'package:network_info_app/pages/network_scan/port_map.dart'; +import 'package:network_info_app/widget/future_text.dart'; class DeviceInfo extends StatelessWidget { const DeviceInfo({ diff --git a/lib/pages/network_scan/network_scan.dart b/lib/pages/network_scan/network_scan.dart index 2c147a0..13bd344 100644 --- a/lib/pages/network_scan/network_scan.dart +++ b/lib/pages/network_scan/network_scan.dart @@ -11,7 +11,7 @@ import 'package:network_tools/network_tools.dart'; import 'package:provider/provider.dart'; import 'package:network_info_app/pages/network_scan/device_info.dart'; -import 'package:network_info_app/pages/network_scan/future_text.dart'; +import 'package:network_info_app/widget/future_text.dart'; class NetworkScan extends StatelessWidget { const NetworkScan({super.key}); diff --git a/lib/pages/network_scan/future_text.dart b/lib/widget/future_text.dart similarity index 58% rename from lib/pages/network_scan/future_text.dart rename to lib/widget/future_text.dart index 933f4b2..44aaf65 100644 --- a/lib/pages/network_scan/future_text.dart +++ b/lib/widget/future_text.dart @@ -5,10 +5,12 @@ class FutureText extends StatelessWidget { super.key, required this.future, required this.convertToString, + this.errorMessage = "Error", }); final Future future; final String Function(T) convertToString; + final String errorMessage; @override Widget build(BuildContext context) { @@ -16,10 +18,12 @@ class FutureText extends StatelessWidget { future: future, builder: (BuildContext context, AsyncSnapshot snapshot) { return Text( - snapshot.hasData && snapshot.data != null - ? convertToString(snapshot - .data!) // ignore: null_check_on_nullable_type_parameter - : "N/A", + snapshot.hasError + ? errorMessage + : snapshot.hasData && snapshot.data != null + ? convertToString(snapshot + .data!) // ignore: null_check_on_nullable_type_parameter + : "N/A", ); }); } diff --git a/lib/pages/network_info/network_info.dart b/lib/widget/network_info/connectivity_info_tiles.dart similarity index 72% rename from lib/pages/network_info/network_info.dart rename to lib/widget/network_info/connectivity_info_tiles.dart index 2d25ad8..4e1d074 100644 --- a/lib/pages/network_info/network_info.dart +++ b/lib/widget/network_info/connectivity_info_tiles.dart @@ -1,17 +1,17 @@ import 'dart:io'; +import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/material.dart'; import 'package:forui/forui.dart'; -import 'package:connectivity_plus/connectivity_plus.dart'; -import 'package:provider/provider.dart'; -import 'package:network_info_app/pages/network_info/network_stats.dart'; -import 'package:network_info_app/provider/connectivity_notifier.dart'; +import 'package:network_info_app/widget/network_info/connectivity_stats.dart'; + +class ConnectivityInfoTiles extends StatelessWidget { + const ConnectivityInfoTiles({super.key, required this.conductivities}); -class NetworkInfo extends StatelessWidget { - const NetworkInfo({super.key}); + final List conductivities; - List _getTiles(List conductivities) { + List _generateTiles() { List tiles = [ FTile( prefixIcon: FIcon( @@ -27,7 +27,7 @@ class NetworkInfo extends StatelessWidget { ]; if (conductivities.contains(ConnectivityResult.wifi)) { - tiles.add(NetworkStats()); + tiles.add(ConnectivityStats()); } if (Platform.isAndroid && @@ -62,11 +62,9 @@ class NetworkInfo extends StatelessWidget { @override Widget build(BuildContext context) { - return Consumer( - builder: (context, myNotifier, child) => Column( - spacing: 10, - children: _getTiles(myNotifier.connectionStatus), - ), + return Column( + spacing: 10, + children: _generateTiles(), ); } } diff --git a/lib/widget/network_info/connectivity_stats.dart b/lib/widget/network_info/connectivity_stats.dart new file mode 100644 index 0000000..2c06fd6 --- /dev/null +++ b/lib/widget/network_info/connectivity_stats.dart @@ -0,0 +1,122 @@ +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:forui/forui.dart'; +import 'package:network_info_plus/network_info_plus.dart'; +import 'package:permission_handler/permission_handler.dart'; + +import 'package:network_info_app/widget/network_info/future_ftile.dart'; + +class ConnectivityStats extends StatefulWidget { + const ConnectivityStats({super.key}); + + @override + State createState() => _ConnectivityStatsState(); +} + +class _ConnectivityStatsState extends State { + final NetworkInfo _networkInfo = NetworkInfo(); + + Future _wifiName = Future.value(null); + Future _wifiBSSID = Future.value(null); + Future _wifiIPv4 = Future.value(null); + Future _wifiIPv6 = Future.value(null); + Future _wifiGatewayIP = Future.value(null); + Future _wifiBroadcast = Future.value(null); + Future _wifiSubMask = Future.value(null); + + Future _initWifiName() async { + if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) { + // Request permissions as recommended by the plugin documentation: + // https://github.com/fluttercommunity/plus_plugins/tree/main/packages/network_info_plus/network_info_plus + if (await Permission.locationWhenInUse.isGranted) { + return _networkInfo.getWifiName(); + } else { + return 'Unauthorized to get Wifi Name'; + } + } else { + return _networkInfo.getWifiName(); + } + } + + Future _initWifiBSSID() async { + if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) { + // Request permissions as recommended by the plugin documentation: + // https://github.com/fluttercommunity/plus_plugins/tree/main/packages/network_info_plus/network_info_plus + if (await Permission.locationWhenInUse.isGranted) { + return _networkInfo.getWifiBSSID(); + } else { + return 'Unauthorized to get Wifi BSSID'; + } + } else { + return _networkInfo.getWifiBSSID(); + } + } + + void _init() async { + if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) { + await Permission.locationWhenInUse.request(); + } + + setState(() { + _wifiName = _initWifiName(); + _wifiBSSID = _initWifiBSSID(); + _wifiIPv4 = _networkInfo.getWifiIP(); + _wifiIPv6 = _networkInfo.getWifiIPv6(); + _wifiGatewayIP = _networkInfo.getWifiGatewayIP(); + _wifiBroadcast = _networkInfo.getWifiBroadcast(); + _wifiSubMask = _networkInfo.getWifiSubmask(); + }); + } + + @override + void initState() { + super.initState(); + + _init(); + } + + @override + Widget build(BuildContext context) { + return FTileGroup( + children: [ + FutureFTile( + title: 'Wifi Name', + future: _wifiName, + errorMessage: 'Failed to get Wifi Name', + ), + FutureFTile( + title: 'Wifi BSSID', + future: _wifiBSSID, + errorMessage: 'Failed to get Wifi BSSID', + ), + FutureFTile( + title: 'Wifi IPv4', + future: _wifiIPv4, + errorMessage: 'Failed to get Wifi IPv4', + ), + FutureFTile( + title: 'Wifi IPv6', + future: _wifiIPv6, + errorMessage: 'Failed to get Wifi IPv6', + ), + FutureFTile( + title: 'Wifi Gateway', + future: _wifiGatewayIP, + errorMessage: 'Failed to get Wifi gateway address', + ), + FutureFTile( + title: 'Wifi Broadcast', + future: _wifiBroadcast, + errorMessage: 'Failed to get Wifi broadcast', + ), + FutureFTile( + title: 'Wifi Submask', + future: _wifiSubMask, + errorMessage: 'Failed to get Wifi submask address', + ), + ], + ); + } +} diff --git a/lib/widget/network_info/future_ftile.dart b/lib/widget/network_info/future_ftile.dart new file mode 100644 index 0000000..5054c63 --- /dev/null +++ b/lib/widget/network_info/future_ftile.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:forui/forui.dart'; + +import 'package:network_info_app/widget/future_text.dart'; + +class FutureFTile extends FTile { + FutureFTile({ + super.key, + required String title, + required Future future, + required String errorMessage, + }) : super( + title: Text(title), + details: FutureText( + future: future, + convertToString: (String? s) => s ?? "N/A", + errorMessage: errorMessage, + ), + onLongPress: () => _setClipboardData(future), + ); + + static void _setClipboardData(Future future) async { + try { + String? text = await future; + if (text != null) { + Clipboard.setData(ClipboardData(text: text)); + } + } catch (e) { + // nothing to copy + } + } +}