Skip to content

Commit 56eeccd

Browse files
refactor(dashboard-manager): Extract focused providers from DashboardManagerProvider (#588)
* refactor(dashboard-manager): Extract focused providers from DashboardManagerProvider - Extract device info data into dedicated `deviceInfoProvider` - Extract ethernet ports data into `ethernetPortsProvider` - Extract router time data into `routerTimeProvider` - Extract system stats data into `systemStatsProvider` - Extract WiFi radios data into `wifiRadiosProvider` - Add `polling_helpers.dart` for shared polling data extraction utilities - Rename `DashboardManagerProvider` to `SessionProvider` for session operations - Rename `DashboardManagerService` to `SessionService` for clarity - Update all consumers to use new focused providers - Add comprehensive unit tests for all new providers - Remove obsolete `DashboardManagerState` and related files * feat(tools): Add --collect flag to run_screenshot_tests.dart - Add new `--collect` / `-p` flag to collect golden files after tests - Implement `_copyGoldensToSnapshots()` function to copy all golden files from test directories to snapshots folder - Fix issue where golden files were never collected when using the Dart tool (since it always passes `-f` to shell script) * fix(providers): Replace undefined dashboardManagerProvider with ethernetPortsProvider - Fix instant_verify_view.dart using undefined dashboardManagerProvider - Fix wifi_bundle_provider.dart using undefined dashboardManagerProvider * fix(test): Use correct SharedPreferences key constants in session_provider_test - Add import for pref_key.dart constants - Replace hardcoded 'currentSN' with pCurrentSN constant - Replace hardcoded 'selectedNetworkId' with pSelectedNetworkId constant - Replace hardcoded 'pnpConfiguredSN' with pPnpConfiguredSN constant * test(wifi-bundle): Refactor wifi_bundle_provider_test.dart for better test design - Add ethernetPortsProvider mock override to match provider dependencies - Extract createRadiosTestData() helper function for test data creation - Refactor seedWithRadios() to properly set state before container creation - Add documentation comments explaining the test setup sequence
1 parent f8539b6 commit 56eeccd

54 files changed

Lines changed: 2840 additions & 1959 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

lib/app.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ class _LinksysAppState extends ConsumerState<LinksysApp>
175175
// .then((prefs) {
176176
// final currentSN = prefs.getString(pCurrentSN);
177177
// if (currentSN != null &&
178-
// ref.read(dashboardManagerProvider).deviceInfo?.serialNumber !=
178+
// ref.read(sessionProvider).deviceInfo?.serialNumber !=
179179
// currentSN) {
180180
// // if (mounted) {
181181
// // showRouterNotFoundAlert(context, ref);

lib/core/data/providers/dashboard_manager_provider.dart

Lines changed: 0 additions & 55 deletions
This file was deleted.

lib/core/data/providers/dashboard_manager_state.dart

Lines changed: 0 additions & 131 deletions
This file was deleted.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:flutter_riverpod/flutter_riverpod.dart';
3+
import 'package:privacy_gui/core/jnap/actions/better_action.dart';
4+
import 'package:privacy_gui/core/jnap/models/device_info.dart';
5+
import 'package:privacy_gui/core/jnap/models/soft_sku_settings.dart';
6+
import 'package:privacy_gui/core/data/providers/polling_provider.dart';
7+
import 'package:privacy_gui/core/data/providers/polling_helpers.dart';
8+
9+
final deviceInfoProvider = Provider<DeviceInfoState>((ref) {
10+
final pollingData = ref.watch(pollingProvider).value;
11+
12+
NodeDeviceInfo? deviceInfo;
13+
String? skuModelNumber;
14+
15+
final deviceInfoOutput =
16+
getPollingOutput(pollingData, JNAPAction.getDeviceInfo);
17+
if (deviceInfoOutput != null) {
18+
deviceInfo = NodeDeviceInfo.fromJson(deviceInfoOutput);
19+
}
20+
21+
final skuOutput =
22+
getPollingOutput(pollingData, JNAPAction.getSoftSKUSettings);
23+
if (skuOutput != null) {
24+
final settings = SoftSKUSettings.fromMap(skuOutput);
25+
skuModelNumber = settings.modelNumber;
26+
}
27+
28+
return DeviceInfoState(
29+
deviceInfo: deviceInfo,
30+
skuModelNumber: skuModelNumber,
31+
);
32+
});
33+
34+
class DeviceInfoState extends Equatable {
35+
final NodeDeviceInfo? deviceInfo;
36+
final String? skuModelNumber;
37+
38+
const DeviceInfoState({
39+
this.deviceInfo,
40+
this.skuModelNumber,
41+
});
42+
43+
@override
44+
List<Object?> get props => [deviceInfo, skuModelNumber];
45+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:flutter_riverpod/flutter_riverpod.dart';
3+
import 'package:privacy_gui/core/jnap/actions/better_action.dart';
4+
import 'package:privacy_gui/core/data/providers/polling_provider.dart';
5+
import 'package:privacy_gui/core/data/providers/polling_helpers.dart';
6+
7+
final ethernetPortsProvider = Provider<EthernetPortsState>((ref) {
8+
final pollingData = ref.watch(pollingProvider).value;
9+
10+
String? wanConnection;
11+
List<String> lanConnections = [];
12+
13+
final portsOutput =
14+
getPollingOutput(pollingData, JNAPAction.getEthernetPortConnections);
15+
if (portsOutput != null) {
16+
wanConnection = portsOutput['wanPortConnection'] as String?;
17+
lanConnections = List<String>.from(portsOutput['lanPortConnections'] ?? []);
18+
}
19+
20+
return EthernetPortsState(
21+
wanConnection: wanConnection,
22+
lanConnections: lanConnections,
23+
);
24+
});
25+
26+
class EthernetPortsState extends Equatable {
27+
final String? wanConnection;
28+
final List<String> lanConnections;
29+
30+
const EthernetPortsState({
31+
this.wanConnection,
32+
this.lanConnections = const [],
33+
});
34+
35+
@override
36+
List<Object?> get props => [wanConnection, lanConnections];
37+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import 'package:privacy_gui/core/jnap/actions/better_action.dart';
2+
import 'package:privacy_gui/core/jnap/result/jnap_result.dart';
3+
import 'package:privacy_gui/core/data/providers/polling_provider.dart';
4+
5+
/// Extracts the output Map from polling data for a specific action.
6+
Map<String, dynamic>? getPollingOutput(
7+
CoreTransactionData? data,
8+
JNAPAction action,
9+
) {
10+
return _getPollingSuccess(data, action)?.output;
11+
}
12+
13+
/// Safely extracts a successful result for a specific action from polling data.
14+
///
15+
/// Returns null if the data is null, the action is not found, or the result
16+
/// is not a JNAPSuccess (e.g., it's a JNAPError).
17+
JNAPSuccess? _getPollingSuccess(
18+
CoreTransactionData? data,
19+
JNAPAction action,
20+
) {
21+
if (data == null) return null;
22+
final result = data.data[action];
23+
return result is JNAPSuccess ? result : null;
24+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import 'package:flutter_riverpod/flutter_riverpod.dart';
2+
import 'package:intl/intl.dart';
3+
import 'package:privacy_gui/core/jnap/actions/better_action.dart';
4+
import 'package:privacy_gui/core/data/providers/polling_provider.dart';
5+
import 'package:privacy_gui/core/data/providers/polling_helpers.dart';
6+
7+
/// Provides the router's local time as milliseconds since epoch.
8+
///
9+
/// Extracts the current time from polling data for getLocalTime action.
10+
/// Falls back to the current system time if unable to retrieve router time.
11+
final routerTimeProvider = Provider<int>((ref) {
12+
final pollingData = ref.watch(pollingProvider).value;
13+
14+
final timeOutput = getPollingOutput(pollingData, JNAPAction.getLocalTime);
15+
if (timeOutput != null) {
16+
final timeString = timeOutput['currentTime'] as String?;
17+
if (timeString != null) {
18+
final parsedTime =
19+
DateFormat("yyyy-MM-ddThh:mm:ssZ").tryParse(timeString);
20+
if (parsedTime != null) {
21+
return parsedTime.millisecondsSinceEpoch;
22+
}
23+
}
24+
}
25+
26+
return DateTime.now().millisecondsSinceEpoch;
27+
});

0 commit comments

Comments
 (0)