Skip to content

Conversation

@AustinChangLinksys
Copy link
Collaborator

@AustinChangLinksys AustinChangLinksys commented Jan 8, 2026

User description

Summary

Resolves multiple UI issues identified in Phase 2 and Phase 3 testing, including topology clipping, device detail truncation, missing labels, and layout overflows. Also upgrades ui_kit_library to v2.10.3 to incorporate latest component fixes.

Changes

🚀 Enhancements & Fixes

  • Instant Verify:
    • Fixed RenderFlex overflow (2px) in Port Card by letting it size naturally.
    • Fixed Topology focus border overflow.
    • Fixed Ping/Traceroute stuck spinner state logic.
  • Node Detail View:
    • Fixed device list clipping on hover in mobile layout by adding padding.
  • Device Detail:
    • Fixed device name truncation with appropriate styling and tooltip.
  • Local Network:
    • Added missing field labels (Max users, Lease time).
    • Fixed input auto-selection bug during typing.
  • Internet Settings:
    • Fixed Bridge Mode text rendering (bold styling).
    • Fixed IPv6 Automatic dropdown disabled state visibility.
  • WiFi Settings:
    • Fixed Mac Filtering cell size inconsistency and text overflow.
    • Added missing Edit button in Filtered Devices list.
  • Advanced Settings:
    • Fixed Firewall Add button state persistence on save.
    • Fixed DMZ IP cursor skipping for read-only segments.

📦 Dependencies

  • Upgraded ui_kit_library and generative_ui to v2.10.3.
    • Includes fixes for Topology clipping, AppPageView titles, and input focus.

Verification

  • Verified on Mobile (<600px) and Desktop layouts.
  • Verified Local Network, Internet Settings, and Topology views functionality.
  • Localization snapshots generated and updated.

PR Type

Enhancement, Bug fix, Tests


Description

  • Major refactoring of Internet Settings view with component extraction and simplified state management using UiKitPageView.withSliver replacing StyledAppPageView

  • Instant Verify view refactored with topology integration, improved layout handling for mobile/desktop, and UI kit upgrade to v2.10.3

  • WiFi settings null-safety improvements in deserialization with sensible defaults for missing enum values

  • IPv6 WAN form factory created for dynamic form creation based on connection type

  • Comprehensive test modernization across multiple modules (Internet Settings, WiFi Settings, Apps & Gaming) using new TestHelper utility class for cleaner setup and golden file testing

  • Provider import paths updated from core/jnap/providers to core/data/providers for improved architecture

  • Cleanup of unused mock classes and imports in health check provider mocks

  • New placeholder file added for future node connected devices view implementation


Diagram Walkthrough

flowchart LR
  A["Internet Settings View"] -->|"Component Extraction"| B["Ipv4ConnectionView<br/>Ipv6ConnectionView<br/>ReleaseAndRenewView"]
  C["Instant Verify View"] -->|"Topology Integration"| D["_buildInstantTopology<br/>PortStatusWidget"]
  E["WiFiItem Deserialization"] -->|"Null-Safety"| F["fromMap with<br/>Default Values"]
  G["Test Infrastructure"] -->|"TestHelper Utility"| H["Cleaner Mock Setup<br/>Golden File Testing"]
  I["Provider Imports"] -->|"Path Update"| J["core/data/providers"]
  D -->|"UI Kit v2.10.3"| K["Updated Components<br/>& Styling"]
Loading

File Walkthrough

Relevant files
Tests
3 files
apps_and_gaming_view_test.dart
Refactor Apps & Gaming tests to use TestHelper utility     

test/page/advanced_settings/apps_and_gaming/views/localizations/apps_and_gaming_view_test.dart

  • Refactored test file to use new TestHelper utility class instead of
    manual mock setup and dependency injection
  • Replaced individual mock notifiers with centralized testHelper
    instance managing all mocks
  • Updated test cases to use testHelper.pumpView() for widget setup
    instead of testableSingleRoute()
  • Added helper function switchToTab() for tab navigation and improved
    test organization with Test IDs and golden file naming
  • Simplified test assertions and removed boilerplate code for provider
    overrides
+728/-1301
wifi_main_view_test.dart
Restructure WiFi Settings Tests with Helper Utilities       

test/page/wifi_settings/views/localizations/wifi_main_view_test.dart

  • Completely restructured test file from 862 lines to 426 lines using
    new TestHelper utility class for cleaner test setup
  • Replaced individual mock notifier setup with centralized testHelper
    instance managing all mocks and dependencies
  • Reorganized tests into logical groups with clear test IDs
    (WIFIS-ADV_VIEW, WIFIS-MLO_WARN, WIFIS-MAC_VIEW, etc.) and descriptive
    names
  • Added golden file references for screenshot testing with consistent
    naming convention
  • Introduced getWifiBundleTestState() helper function to create test
    states with dirty state simulation
  • Simplified test assertions and removed redundant mock setup code
    through helper abstractions
+319/-755
internet_settings_view_test.dart
Modernize internet settings tests with TestHelper and golden files

test/page/advanced_settings/internet_settings/views/localizations/internet_settings_view_test.dart

  • Migrated test infrastructure from custom testableSingleRoute() to new
    TestHelper class for simplified setup and mocking
  • Added comprehensive test documentation with view ID (ISET) and
    detailed test scenario descriptions for all 25 test cases
  • Updated test assertions to use new widget keys (ipv4EditButton,
    ipv6EditButton, etc.) instead of icon-based finders
  • Replaced LinksysIcons with AppFontIcons and updated widget type
    expectations to use ui_kit_library components
  • Added golden filename parameters for screenshot testing and improved
    test descriptions with verification details
  • Simplified mock setup by using testHelper.mockInternetSettingsNotifier
    instead of manual mock creation
+534/-380
Bug fix
1 files
wifi_item.dart
Add null-safety to WiFiItem deserialization                           

lib/page/wifi_settings/providers/wifi_item.dart

  • Removed fromRadio() factory constructor that depended on RouterRadio
    model
  • Added null-safety checks in fromMap() factory to handle missing or
    null map values
  • Provided sensible default values for enum fields when map values are
    absent
  • Changed import from radio_info.dart to wifi_enums.dart and added
    re-export
+36/-226
Enhancement
3 files
ipv6_wan_form_factory.dart
Add IPv6 WAN form factory for dynamic form creation           

lib/page/advanced_settings/internet_settings/widgets/wan_forms/ipv6/ipv6_wan_form_factory.dart

  • Created new factory class IPv6WanFormFactory to handle IPv6 WAN form
    creation based on connection type
  • Implemented create() method that returns appropriate form widget for
    WanIPv6Type
  • Added _UnsupportedIPv6Form fallback widget for unsupported IPv6
    connection types
  • Provides user-friendly error messages for unsupported configurations
+86/-0   
internet_settings_view.dart
Refactor Internet Settings View with Component Extraction

lib/page/advanced_settings/internet_settings/views/internet_settings_view.dart

  • Refactored the view to use new UiKitPageView.withSliver component
    replacing StyledAppPageView for improved UI consistency
  • Extracted complex IPv4, IPv6, and Release/Renew logic into separate
    dedicated view components (Ipv4ConnectionView, Ipv6ConnectionView,
    ReleaseAndRenewView)
  • Simplified state management by removing numerous TextEditingController
    instances and replacing with form provider-based validation
  • Streamlined editing flow with single isEditing boolean and
    _toggleEditing() method instead of separate IPv4/IPv6 editing states
  • Updated error handling to use ServiceSideEffectError and improved
    async operation safety with mounted checks
+129/-1825
instant_verify_view.dart
Refactor Instant Verify view with topology integration and UI kit
upgrade

lib/page/instant_verify/views/instant_verify_view.dart

  • Reorganized imports to use new provider paths (core/data/providers
    instead of core/jnap/providers) and updated UI kit references to
    ui_kit_library
  • Refactored _instantTopology() into comprehensive
    _buildInstantTopology() method with topology adapter, node rendering,
    and menu handling
  • Restructured instant info layout with new _mobileLayout() and
    _desktopLayout() helper methods using AppResponsiveLayout
  • Extracted connectivity widget into separate _linkStatusWidget(),
    _wanStatusWidget(), _wifiStatusWidget(), and _pingTracerouteWidget()
    methods with improved styling
  • Replaced custom port widget logic with PortStatusWidget component and
    simplified port card rendering
  • Moved PDF generation logic to InstantVerifyPdfService and updated icon
    usage to AppIcon.font() with AppFontIcons
  • Updated spacing constants from Spacing.* to AppSpacing.* throughout
    the file
+730/-905
Miscellaneous
2 files
node_connected_devices_view.dart
Add Empty Node Connected Devices View File                             

lib/page/nodes/views/node_connected_devices_view.dart

  • New empty file created as placeholder for future node connected
    devices view implementation
+1/-0     
health_check_provider_mocks.dart
Clean up unused mock classes and imports                                 

test/mocks/health_check_provider_mocks.dart

  • Removed unused _FakeJNAPResult_2 class and its associated import of
    JNAPResult
  • Reformatted MockHealthCheckProvider class declaration for better
    readability
+2/-52   
Configuration changes
1 files
add_nodes_state.dart
Update provider import path structure                                       

lib/page/nodes/providers/add_nodes_state.dart

  • Updated import path from core/jnap/providers/device_manager_state.dart
    to core/data/providers/device_manager_state.dart
+1/-1     
Additional files
101 files
review-screenshot-tests.md +142/-0 
speckit.analyze.md +184/-0 
speckit.checklist.md +294/-0 
speckit.clarify.md +181/-0 
speckit.constitution.md +82/-0   
speckit.implement.md +135/-0 
speckit.plan.md +89/-0   
speckit.specify.md +258/-0 
speckit.tasks.md +137/-0 
speckit.taskstoissues.md +30/-0   
settings.local.json +24/-0   
.fvmrc +3/-0     
ci.yml +156/-0 
deploy-demo.yml +84/-0   
.gitmodules +0/-3     
.metadata +30/-0   
constitution.md +1093/-0
check-prerequisites.sh +166/-0 
common.sh +156/-0 
create-new-feature.sh +297/-0 
setup-plan.sh +61/-0   
update-agent-context.sh +799/-0 
agent-file-template.md +28/-0   
checklist-template.md +40/-0   
plan-template.md +104/-0 
spec-template.md +115/-0 
tasks-template.md +251/-0 
launch.json +19/-85 
.windsurfrules +385/-0 
AGENTS.md +29/-0   
APPGAP_MAPPING.md +148/-0 
CLAUDE.md +169/-0 
README.md +116/-10
SCREENSHOT_TESTING.md +146/-0 
TEST_CASES.md +381/-0 
THEME.md +201/-0 
google-services.json +0/-46   
AndroidManifest.xml +0/-7     
AndroidManifest.xml +0/-73   
MainActivity.kt +0/-7     
launch_background.xml +0/-9     
launch_background.xml +0/-9     
launch_background.xml +0/-9     
launch_background.xml +0/-9     
ic_launcher.xml +0/-5     
ic_launcher_round.xml +0/-5     
styles.xml +0/-21   
styles.xml +0/-21   
styles.xml +0/-21   
styles.xml +0/-21   
network_security_config.xml +0/-7     
AndroidManifest.xml +0/-7     
gradle.properties +0/-3     
gradle-wrapper.properties +0/-6     
project.properties +0/-4     
env.template +5/-0     
demo_cache_data.json +2818/-0
build_android.sh +0/-61   
build_ios.sh +0/-53   
clear_goldens.sh +30/-0   
constitution.md +1093/-0
lcov.info +59460/-0
dart_test.yaml +2/-1     
devtools_options.yaml +3/-0     
FAQ_AGENT.md +279/-0 
router_ai_assistant.md +142/-0 
router_assistant_architecture.md +155/-0 
architecture_analysis_2026-01-05.md +727/-0 
MIGRATION_TEST_RESULTS.md +1103/-0
REMAINING_TESTS_SUMMARY.md +352/-0 
SCREENSHOT_TEST_COVERAGE.md +239/-0 
SCREEN_SIZE_VERIFICATION_STATUS.md +358/-0 
dirty_guard_framework_guide.md +226/-0 
dirty_guard_framework_requirements.md +266/-0 
pnp-flow.md +144/-0 
pnp.md +58/-0   
responsive_page_view.md +574/-0 
routing.md +51/-0   
SCREENSHOT_TEST_ANALYSIS_REPORT.md +205/-0 
SCREENSHOT_TEST_MASTER_REPORT.md +248/-0 
TICKER_MODE_SUMMARY.md +235/-0 
screenshot_testing_fix_workflow.md +697/-0 
screenshot_testing_guideline.md +89/-0   
screenshot_testing_knowledge_base.md +1295/-0
screenshot_testing_ticker_mode_enhancement.md +454/-0 
speedtest.md +93/-0   
mock_generation_guide.md +221/-0 
COMMON_ACTIONS.md +17/-0   
MOCKING.md +83/-0   
TEST_PROMPT.md +63/-0   
adm_tests.yaml +78/-0   
advrt_tests.yaml +80/-0   
apps_tests.yaml +175/-0 
dashboard_tests.yaml +59/-0   
dhcp_tests.yaml +60/-0   
dmz_tests.yaml +36/-0   
fw_tests.yaml +118/-0 
instant_adm_tests.yaml +53/-0   
instant_privacy_tests.yaml +16/-0   
instant_safety_tests.yaml +16/-0   
Additional files not shown

- Move env.template to assets/agents/env.template
- Update dotenv loading paths in main.dart and main_demo.dart
- Fix type definition in IdleChecker
- Fix lints in tests
- Update Notifier mock signatures in test/mocks/ to correctly extend AsyncNotifier/Notifier and mixin Mock
- Fix node_detail_view_test.dart by stubbing missing node light status
- Update CI workflow env setup
…gnment

- AppDialog: unified scroll behavior with scrollable parameter
- AppText: add maxLines/minLines to all factories
- AppTextField: fix disabled background color
- WiFi Card: add intrinsicHeight alignment for equal card heights
- WiFi Mode: add minLines:2 for consistent height
- Remove redundant SingleChildScrollView from dialogs
- Fix crossAxisSpacing in advanced settings grid
- Refactor : remove unused code, extract
- Refactor : unify layout logic, extract
- Refactor : merge layout methods
- Refactor : extract  component
- Introduce  for consistent layout handling
- Replace inner  with shared  in
- Eliminate code duplication for port status rendering
- Extract  and  to separate files
- Reduce  complexity (840 -> 246 lines)
- Improve separation of concerns in dashboard components
- Use  instead of fixed  in
- Ensure visual consistency between grid items and parent layout
…row layouts

- Fix horizontal overflow in WiFiCard header and footer using Expanded/Flexible
- Fix horizontal overflow in PortStatusWidget
- Optimise vertical spacing in ExternalSpeedTestLinks
- Increase fixed container height for InternetConnectionWidget in desktop layout
- Protect Networks info tiles from overflow
- Fix 'Cannot hit test a render box with no size' error by replacing Spacer() with AppGap in ExternalSpeedTestLinks
- Optimize vertical padding/gaps in ExternalSpeedTestLinks to fit constrained desktop layouts
- Enhance stability of DashboardLayoutVariant mobile handling
…ExternalSpeedTestLinks

- Remove Flexible wrapper around buttons row to prevent layout exception in unconstrained height context (Mobile)
- Ensure compatibility with both fixed-height Desktop and infinite-height Mobile layouts
- Add dedicated Tablet layout (2-column flexible grid) to DashboardHomeView
- Fix DashboardLayoutVariant to support 'tablet' mode
- Update DashboardHomePortAndSpeed to support flexible height in tablet mode
- Fix desktop layout overflow by relaxing fixed height constraint to minHeight
- Replace ConstrainedBox(minHeight) with IntrinsicHeight in _desktopNoLanPortsLayout
- Ensures layout stability by resolving content size before constraints
- Fixes 'Unexpected null value' and 'LayoutBuilder assertion failed' caused by recursive layout failures
- Force single-column layout for WiFiGrid in Tablet mode (requested by user)
- Fix floating point height calculation in WiFiGrid using .ceil() to prevent bottom overflow
- Closes user request about squeezed card content in Tablet view
- Update topologyItemHeight constant to 72.0 to match actual UI Kit tile height
- Update treeViewBaseHeight to 72.0
- Ensures DashboardNetworks card height is limited to exactly 3 routers on Desktop/Tablet, enabling scroll for overflow
- Closes user request for scrollable network list
- Add  static factory to centralize complex layout determination logic
- Refactor  to use new helper, removing verbose ternary operators
- Refactor  to use , implicitly improving Tablet layout handling for vertical/horizontal decision
- Add missing export to  to fix library visibility
- Confirmed  and  extension methods on  are unused
- Removed to keep codebase clean and avoid ambiguity with
- Create DashboardLayoutStrategy interface and 7 concrete strategies:
  - MobileLayoutStrategy
  - DesktopHorizontalLayoutStrategy
  - DesktopVerticalLayoutStrategy
  - DesktopNoLanPortsLayoutStrategy
  - TabletLayoutStrategy
  - TabletHorizontalLayoutStrategy
  - TabletVerticalLayoutStrategy
- Create DashboardLayoutContext (IoC container) for widget injection
- Create DashboardLayoutFactory for O(1) strategy lookup
- Refactor DashboardHomeView to delegate layout to strategies
- Create DashboardLoadingWrapper for shared loading state handling
- Refactor all dashboard components to use DashboardLoadingWrapper:
  - port_and_speed.dart
  - home_title.dart
  - networks.dart (also simplified to StatelessWidget)
  - wifi_grid.dart
  - internet_status.dart
  - quick_panel.dart
- Reduce dashboard_home_view.dart from 367 to ~118 lines (-68%)

This eliminates scattered if-else layout logic and centralizes
layout decisions in Strategy classes following IoC principles.
…ard layouts

Phase 1 - Core models:
- DisplayMode: compact/normal/expanded enum
- HeightStrategy: intrinsic/columnBased/aspectRatio sealed class
- WidgetGridConstraints: column-based layout constraints
- WidgetSpec: widget specification with mode-based constraints
- DashboardWidgetSpecs: predefined specs for all dashboard widgets

Phase 2 - Layout resolver:
- GridLayoutResolver: calculates widget sizes using UI Kit's colWidth API
- Extended DashboardLayoutContext with constraint helpers

Phase 4 - User preferences:
- DashboardLayoutPreferences: persisted user layout preferences
- dashboardPreferencesProvider: Riverpod notifier for preferences

This implements the foundation for the dashboard layout customization system.
Phase 3 (component DisplayMode support) and Phase 5 (settings UI) remain for future work.
…gs UI

Phase 3 - Component DisplayMode support:
- InternetConnectionWidget: Added displayMode parameter with loading height variants
- DashboardNetworks: Added displayMode parameter with loading height variants
- DashboardWiFiGrid: Added displayMode parameter
- DashboardQuickPanel: Added displayMode parameter with loading height variants
- DashboardHomePortAndSpeed: Added displayMode parameter with loading height variants

Phase 5 - Settings UI:
- Created DashboardLayoutSettingsPanel for customizing widget display modes
- Uses SegmentedButton for compact/normal/expanded selection
- Integrates with dashboardPreferencesProvider for persistence
- Added to barrel exports

All components now support DisplayMode.compact/normal/expanded rendering modes.
The settings panel allows users to customize each widget's display mode.
- Watch dashboardPreferencesProvider in DashboardHomeView
- Pass displayModes map to DashboardLayoutContext
- Pass individual displayMode to each widget component
- Widgets now respond to user preference settings

The dashboard now respects user layout preferences stored in SharedPreferences.
- Added 'Dashboard Layout' menu option in DashboardMenuView
- Shows DashboardLayoutSettingsPanel in a dialog on tap
- Uses widgets icon for the menu item
- Added components barrel export to menu view imports

Users can now access layout customization from the menu.
@AustinChangLinksys AustinChangLinksys changed the base branch from main to dev-2.0.0 January 8, 2026 16:36
@qodo-code-review
Copy link

qodo-code-review bot commented Jan 8, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status:
Error details exposed: A user-facing snackbar message includes interpolated internal error content
(<${pnpState.error}>), which can leak implementation details to end users.

Referred Code
ref.listen(pnpProvider.select((s) => s.status), (previous, next) {
  if (next == PnpFlowStatus.wizardConfiguring &&
      previous == PnpFlowStatus.wizardSaving) {
    // This handles the case for unconfigured routers where saving moves to the next step.
    _stepController?.stepContinue();
  }
  if (next == PnpFlowStatus.wizardSaveFailed) {
    showSimpleSnackBar(context, 'Unexcepted error! <${pnpState.error}>');
  }
});

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

qodo-code-review bot commented Jan 8, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Simplify tab switching helper

Refactor the switchToTab helper to directly tap the Tab widget at the given
index and then call pumpAndSettle(), which is a simpler and more robust approach
than manipulating the TabController.

test/page/advanced_settings/apps_and_gaming/views/localizations/apps_and_gaming_view_test.dart [23-35]

 Future<void> switchToTab(WidgetTester tester, int index) async {
-  final tabBarFinder = find.byType(TabBar);
-  expect(tabBarFinder, findsOneWidget);
+  final tabFinder = find.byType(Tab).at(index);
+  expect(tabFinder, findsOneWidget);
 
-  final tabBar = tester.widget<TabBar>(tabBarFinder);
-  final controller = tabBar.controller;
-  if (controller != null) {
-    controller.animateTo(index);
-    await tester.pump();
-    await tester.pump(const Duration(milliseconds: 300));
-    await tester.pumpAndSettle();
-  }
+  await tester.tap(tabFinder);
+  await tester.pumpAndSettle();
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: This suggestion significantly improves the new switchToTab helper by replacing a brittle, programmatic controller manipulation with a more robust user-centric tap action, which is a testing best practice.

Medium
Possible issue
Use non-generic widget finder

Remove the generic type parameter from find.byType(AppDropdown), changing it to
find.byType(AppDropdown), as the generic is ignored at runtime.

test/page/advanced_settings/apps_and_gaming/views/localizations/apps_and_gaming_view_test.dart [227]

-final systemTypeFinder = find.byType(AppDropdown<DynDDNSSystem>);
+final systemTypeFinder = find.byType(AppDropdown);
  • Apply / Chat
Suggestion importance[1-10]: 4

__

Why: The suggestion correctly identifies that generic type arguments are ignored by find.byType at runtime, and proposing the non-generic version improves code correctness and clarity.

Low
  • Update

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
Copy link
Collaborator

@PeterJhongLinksys PeterJhongLinksys left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@PeterJhongLinksys PeterJhongLinksys merged commit f3f1f24 into dev-2.0.0 Jan 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants