refactor: make network_info_provider redux

This commit is contained in:
Tien Do Nam
2023-10-09 20:49:28 +02:00
parent 1c7a018aeb
commit 412d9b04fe
10 changed files with 71 additions and 60 deletions
+3 -3
View File
@@ -8,7 +8,7 @@ import 'package:localsend_app/pages/home_page.dart';
import 'package:localsend_app/provider/animation_provider.dart';
import 'package:localsend_app/provider/app_arguments_provider.dart';
import 'package:localsend_app/provider/device_info_provider.dart';
import 'package:localsend_app/provider/network_info_provider.dart';
import 'package:localsend_app/provider/local_ip_provider.dart';
import 'package:localsend_app/provider/persistence_provider.dart';
import 'package:localsend_app/provider/settings_provider.dart';
import 'package:localsend_app/provider/tv_provider.dart';
@@ -57,9 +57,9 @@ class LocalSendApp extends StatelessWidget {
return TrayWatcher(
child: WindowWatcher(
child: LifeCycleWatcher(
onChangedState: (AppLifecycleState state) async {
onChangedState: (AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
await ref.notifier(networkStateProvider).fetchLocalIp();
ref.redux(localIpProvider).dispatch(InitLocalIpAction());
}
},
child: ShortcutWatcher(
+2 -2
View File
@@ -3,8 +3,8 @@ import 'package:localsend_app/gen/strings.g.dart';
import 'package:localsend_app/pages/home_page.dart';
import 'package:localsend_app/pages/receive_history_page.dart';
import 'package:localsend_app/provider/animation_provider.dart';
import 'package:localsend_app/provider/local_ip_provider.dart';
import 'package:localsend_app/provider/network/server/server_provider.dart';
import 'package:localsend_app/provider/network_info_provider.dart';
import 'package:localsend_app/provider/settings_provider.dart';
import 'package:localsend_app/provider/ui/home_tab_provider.dart';
import 'package:localsend_app/util/ip_helper.dart';
@@ -37,7 +37,7 @@ class _ReceiveTagState extends State<ReceiveTab> with AutomaticKeepAliveClientMi
super.build(context);
final settings = ref.watch(settingsProvider);
final networkInfo = ref.watch(networkStateProvider);
final networkInfo = ref.watch(localIpProvider);
final serverState = ref.watch(serverProvider);
return Stack(
+2 -2
View File
@@ -10,10 +10,10 @@ import 'package:localsend_app/pages/send_page.dart';
import 'package:localsend_app/pages/troubleshoot_page.dart';
import 'package:localsend_app/pages/web_send_page.dart';
import 'package:localsend_app/provider/animation_provider.dart';
import 'package:localsend_app/provider/local_ip_provider.dart';
import 'package:localsend_app/provider/network/nearby_devices_provider.dart';
import 'package:localsend_app/provider/network/scan_provider.dart';
import 'package:localsend_app/provider/network/send_provider.dart';
import 'package:localsend_app/provider/network_info_provider.dart';
import 'package:localsend_app/provider/progress_provider.dart';
import 'package:localsend_app/provider/selection/selected_sending_files_provider.dart';
import 'package:localsend_app/provider/settings_provider.dart';
@@ -76,7 +76,7 @@ class _SendTabState extends State<SendTab> with Refena {
Widget build(BuildContext context) {
final sendMode = ref.watch(settingsProvider.select((s) => s.sendMode));
final selectedFiles = ref.watch(selectedSendingFilesProvider);
final networkInfo = ref.watch(networkStateProvider);
final networkInfo = ref.watch(localIpProvider);
final nearbyDevicesState = ref.watch(nearbyDevicesProvider);
return ResponsiveListView(
+2 -2
View File
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:localsend_app/gen/strings.g.dart';
import 'package:localsend_app/model/cross_file.dart';
import 'package:localsend_app/provider/local_ip_provider.dart';
import 'package:localsend_app/provider/network/server/server_provider.dart';
import 'package:localsend_app/provider/network_info_provider.dart';
import 'package:localsend_app/provider/settings_provider.dart';
import 'package:localsend_app/theme.dart';
import 'package:localsend_app/util/native/platform_check.dart';
@@ -120,7 +120,7 @@ class _WebSendPageState extends State<WebSendPage> with Refena {
final serverState = ref.watch(serverProvider)!;
final webSendState = serverState.webSendState!;
final networkState = ref.watch(networkStateProvider);
final networkState = ref.watch(localIpProvider);
return ResponsiveListView(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 20),
+2 -2
View File
@@ -1,8 +1,8 @@
import 'package:collection/collection.dart';
import 'package:localsend_app/constants.dart';
import 'package:localsend_app/model/device.dart';
import 'package:localsend_app/provider/local_ip_provider.dart';
import 'package:localsend_app/provider/network/server/server_provider.dart';
import 'package:localsend_app/provider/network_info_provider.dart';
import 'package:localsend_app/provider/security_provider.dart';
import 'package:localsend_app/provider/settings_provider.dart';
import 'package:localsend_app/util/native/device_info_helper.dart';
@@ -24,7 +24,7 @@ final deviceInfoProvider = ViewProvider<DeviceInfoResult>((ref) {
});
final deviceFullInfoProvider = ViewProvider((ref) {
final networkInfo = ref.watch(networkStateProvider);
final networkInfo = ref.watch(localIpProvider);
final serverState = ref.watch(serverProvider);
final rawInfo = ref.watch(deviceInfoProvider);
final securityContext = ref.read(securityProvider);
@@ -12,79 +12,90 @@ import 'package:refena_flutter/refena_flutter.dart';
final _logger = Logger('NetworkInfo');
final networkStateProvider = NotifierProvider<NetworkStateNotifier, NetworkState>((ref) {
return NetworkStateNotifier();
final localIpProvider = ReduxProvider<LocalIpService, NetworkState>((ref) {
return LocalIpService();
});
StreamSubscription? _subscription;
class NetworkStateNotifier extends Notifier<NetworkState> {
NetworkStateNotifier();
class LocalIpService extends ReduxNotifier<NetworkState> {
LocalIpService();
@override
NetworkState init() {
// ignore: discarded_futures
fetchLocalIp();
return const NetworkState(
localIps: [],
initialized: false,
);
}
Future<void> fetchLocalIp() async {
@override
get initialAction => InitLocalIpAction();
}
/// Fetches the local IP address and registers a listener to update the IP address
class InitLocalIpAction extends ReduxAction<LocalIpService, NetworkState> {
@override
NetworkState reduce() {
if (!kIsWeb) {
// ignore: unawaited_futures
// ignore: discarded_futures
_subscription?.cancel();
if (checkPlatform([TargetPlatform.windows])) {
// https://github.com/localsend/localsend/issues/12
_subscription = Stream.periodic(const Duration(seconds: 5), (_) {}).listen((_) async {
state = NetworkState(
localIps: await _getIp(),
initialized: true,
);
await dispatchAsync(_FetchLocalIpAction());
});
} else {
_subscription = Connectivity().onConnectivityChanged.listen((_) async {
state = NetworkState(
localIps: await _getIp(),
initialized: true,
);
await dispatchAsync(_FetchLocalIpAction());
});
}
}
state = NetworkState(
return state;
}
@override
void after() {
// ignore: discarded_futures
dispatchAsync(_FetchLocalIpAction());
}
}
class _FetchLocalIpAction extends AsyncReduxAction<LocalIpService, NetworkState> {
@override
Future<NetworkState> reduce() async {
return NetworkState(
localIps: await _getIp(),
initialized: true,
);
}
}
Future<List<String>> _getIp() async {
final info = plugin.NetworkInfo();
String? ip;
try {
ip = await info.getWifiIP();
} catch (e) {
_logger.warning('Failed to get wifi IP', e);
}
List<String> nativeResult = [];
if (!kIsWeb) {
try {
// fallback with dart:io NetworkInterface
final result = (await NetworkInterface.list()).map((networkInterface) => networkInterface.addresses).expand((ip) => ip);
nativeResult = result.where((ip) => ip.type == InternetAddressType.IPv4).map((address) => address.address).toList();
} catch (e, st) {
_logger.info('Failed to get IP from dart:io', e, st);
}
}
final addresses = rankIpAddresses(nativeResult, ip);
_logger.info('Network state: $addresses');
return addresses;
Future<List<String>> _getIp() async {
final info = plugin.NetworkInfo();
String? ip;
try {
ip = await info.getWifiIP();
} catch (e) {
_logger.warning('Failed to get wifi IP', e);
}
List<String> nativeResult = [];
if (!kIsWeb) {
try {
// fallback with dart:io NetworkInterface
final result = (await NetworkInterface.list()).map((networkInterface) => networkInterface.addresses).expand((ip) => ip);
nativeResult = result.where((ip) => ip.type == InternetAddressType.IPv4).map((address) => address.address).toList();
} catch (e, st) {
_logger.info('Failed to get IP from dart:io', e, st);
}
}
final addresses = rankIpAddresses(nativeResult, ip);
_logger.info('Network state: $addresses');
return addresses;
}
List<String> rankIpAddresses(List<String> nativeResult, String? thirdPartyResult) {
+2 -2
View File
@@ -1,7 +1,7 @@
import 'dart:async';
import 'package:localsend_app/provider/local_ip_provider.dart';
import 'package:localsend_app/provider/network/nearby_devices_provider.dart';
import 'package:localsend_app/provider/network_info_provider.dart';
import 'package:localsend_app/provider/settings_provider.dart';
import 'package:localsend_app/util/sleep.dart';
import 'package:refena_flutter/refena_flutter.dart';
@@ -33,7 +33,7 @@ class ScanFacade {
// If no devices has been found, then switch to legacy discovery mode
// which is purely HTTP/TCP based.
if (forceLegacy || _ref.read(nearbyDevicesProvider).devices.isEmpty) {
final networkInterfaces = _ref.read(networkStateProvider).localIps.take(maxInterfaces).toList();
final networkInterfaces = _ref.read(localIpProvider).localIps.take(maxInterfaces).toList();
if (networkInterfaces.isNotEmpty) {
await startLegacySubnetScan(networkInterfaces);
}
+3 -3
View File
@@ -1,5 +1,5 @@
import 'package:localsend_app/provider/local_ip_provider.dart';
import 'package:localsend_app/provider/logging/discovery_logs_provider.dart';
import 'package:localsend_app/provider/network_info_provider.dart';
import 'package:localsend_app/provider/progress_provider.dart';
import 'package:logging/logging.dart';
import 'package:refena_flutter/refena_flutter.dart';
@@ -15,7 +15,7 @@ class CustomRefenaObserver extends RefenaMultiObserver {
exclude: (event) {
return event is ChangeEvent &&
(event.notifier.runtimeType == DiscoveryLogsNotifier ||
event.notifier.runtimeType == NetworkStateNotifier ||
event.notifier.runtimeType == LocalIpService ||
event.notifier.runtimeType == ProgressNotifier);
},
),
@@ -24,7 +24,7 @@ class CustomRefenaObserver extends RefenaMultiObserver {
exclude: (event) {
return event is ChangeEvent &&
(event.notifier.runtimeType == DiscoveryLogsNotifier ||
event.notifier.runtimeType == NetworkStateNotifier ||
event.notifier.runtimeType == LocalIpService ||
event.notifier.runtimeType == ProgressNotifier);
},
),
@@ -4,8 +4,8 @@ import 'package:flutter/material.dart';
import 'package:localsend_app/gen/strings.g.dart';
import 'package:localsend_app/model/device.dart';
import 'package:localsend_app/provider/last_devices.provider.dart';
import 'package:localsend_app/provider/local_ip_provider.dart';
import 'package:localsend_app/provider/network/targeted_discovery_provider.dart';
import 'package:localsend_app/provider/network_info_provider.dart';
import 'package:localsend_app/provider/settings_provider.dart';
import 'package:localsend_app/theme.dart';
import 'package:localsend_app/util/task_runner.dart';
@@ -85,7 +85,7 @@ class _AddressInputDialogState extends State<AddressInputDialog> with Refena {
@override
Widget build(BuildContext context) {
final localIps = (ref.watch(networkStateProvider.select((info) => info.localIps))).uniqueIpPrefix;
final localIps = (ref.watch(localIpProvider.select((info) => info.localIps))).uniqueIpPrefix;
final settings = ref.watch(settingsProvider);
final lastDevices = ref.watch(lastDevicesProvider);
@@ -1,4 +1,4 @@
import 'package:localsend_app/provider/network_info_provider.dart';
import 'package:localsend_app/provider/local_ip_provider.dart';
import 'package:test/test.dart';
void main() {