Windows: suppress settings-triggered VPN notifications#8582
Windows: suppress settings-triggered VPN notifications#8582
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds an “origin” signal to Windows VPN status updates so the app can suppress user-facing connected/disconnected notifications when the VPN is restarted due to settings changes (e.g., Block Ads and routing mode), reducing noisy OS/app notifications during toggles.
Changes:
- Introduces
VPNStatusOriginonLanternStatusand propagates it through the Windows IPC status stream (with a TTL-based fallback when origin isn’t present in events). - Marks Windows status origin as
settingsMutationfor settings-driven FFI calls, anduserActionfor connect/disconnect actions. - Suppresses connected/disconnected notifications in
VpnNotifierwhen the status origin indicates a settings mutation; adds in-flight guards for routing mode and block-ads setting updates.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/lantern/lantern_windows_service.dart | Adds pending/TTL-based origin attribution for Windows status events and includes origin in LanternStatus parsing input. |
| lib/lantern/lantern_ffi_service.dart | Marks Windows status origin for settings mutations and user actions; moves block-ads FFI call into runInBackground. |
| lib/features/vpn/provider/vpn_notifier.dart | Suppresses connect/disconnect notifications when status origin is settingsMutation. |
| lib/features/home/provider/app_setting_notifier.dart | Adds in-flight guards and awaits persistence/service calls for routing mode and block-ads updates. |
| lib/core/models/lantern_status.dart | Adds VPNStatusOrigin enum, parsing logic, and stores origin on LanternStatus. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (_isRoutingModeUpdateInFlight) { | ||
| appLogger.info( | ||
| 'Routing mode update already in progress. Ignoring duplicate request.', | ||
| ); | ||
| return right(unit); | ||
| } |
There was a problem hiding this comment.
The in-flight guard currently ignores any routing mode change request that arrives while a previous update is in progress. If the user quickly switches modes (A→B then B→A), the second request will be dropped and the final persisted/service state may not match the user’s last selection. Consider queuing the latest requested mode (or cancelling/restarting the in-flight request) so the last user intent is always applied, rather than returning success while doing nothing.
| if (_isBlockAdsUpdateInFlight) { | ||
| appLogger.info( | ||
| 'Block ads update already in progress. Ignoring duplicate request.', | ||
| ); | ||
| return; | ||
| } |
There was a problem hiding this comment.
Similar to routing mode, this in-flight guard drops subsequent block-ads toggle requests while an earlier update is running. If the user toggles quickly (on→off→on), the later intent can be ignored, leaving UI/storage and the core service out of sync with what the user last chose. Consider storing the latest desired value and applying it after the current request completes (or using a debounce/serial queue) instead of returning early.
| static String _originToWireValue(VPNStatusOrigin origin) { | ||
| switch (origin) { | ||
| case VPNStatusOrigin.userAction: | ||
| return 'user_action'; | ||
| case VPNStatusOrigin.settingsMutation: | ||
| return 'settings_mutation'; | ||
| case VPNStatusOrigin.system: | ||
| return 'system'; | ||
| case VPNStatusOrigin.unknown: | ||
| return 'unknown'; | ||
| } |
There was a problem hiding this comment.
The wire-value mapping for VPNStatusOrigin is duplicated here and in LanternStatus._originFromJson. This creates a real risk of the two drifting out of sync (e.g., adding a new origin or renaming a wire value). Consider centralizing the conversion in a single place (e.g., extension methods on VPNStatusOrigin for toWire()/fromWire()) and reusing it in both the Windows service and LanternStatus parsing.
Resolves