Skip to content

Comments

Select server location from menu bar#8454

Merged
jigar-f merged 4 commits intomainfrom
myles/tray-server-location
Feb 9, 2026
Merged

Select server location from menu bar#8454
jigar-f merged 4 commits intomainfrom
myles/tray-server-location

Conversation

@myleshorton
Copy link
Contributor

This pull request enhances the system tray functionality by adding a dynamic server location selection menu for Pro users. It introduces logic to listen for changes in user status and available server locations, updating the tray menu accordingly. Additionally, it implements the ability for users to connect to a selected server location directly from the tray menu.

System tray enhancements:

  • Added a submenu to the tray menu allowing Pro users to select a VPN server location, dynamically listing available locations sorted by country and city. Selecting a location triggers a connection to that server.
  • Implemented logic to listen for changes in user Pro status and available server locations, ensuring the tray menu updates in real time as these values change.

Localization:

  • Added a new localization string for "Select Location" to support the new tray menu option.

Internal state management:

  • Introduced _isUserPro and _locations fields in SystemTrayNotifier to track user status and available locations.
  • Added a private _onLocationSelected method to handle connecting to a selected server and updating the current server location in the app state.

Dependency management:

  • Imported necessary models and providers to support the new tray menu functionality and state management.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a dynamic “Select Location” submenu to the desktop system tray menu so Pro users can pick a VPN server location directly from the tray, with menu contents updating when Pro status or available server locations change.

Changes:

  • Listen to Pro status and available server list changes to refresh the tray menu in real time.
  • Add a “Select Location” tray submenu for Pro users, listing locations sorted by country/city and connecting on selection.
  • Add the select_location localization string.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
lib/features/system_tray/provider/system_tray_notifier.dart Adds Pro/location state tracking, listeners to refresh the tray menu, and a location-selection submenu with connect behavior.
assets/locales/en.po Adds English translation for the new “Select Location” tray label.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 35 to 50
_isUserPro = ref.read(isUserProProvider);
ref.listen<bool>(
isUserProProvider,
(previous, next) async {
_isUserPro = next;
await updateTrayMenu();
},
);

ref.listen<AsyncValue<AvailableServers>>(
availableServersProvider,
(previous, next) async {
final data = next.value;
_locations = data?.lantern.locations.values.toList() ?? [];
await updateTrayMenu();
},
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

ref.listen callbacks are declared async and await updateTrayMenu(), but ref.listen expects a synchronous callback; the returned Future is ignored and any exceptions become unhandled. Consider making the listener callback synchronous and triggering the async work explicitly (e.g., fire-and-forget with centralized error handling/logging inside updateTrayMenu).

Copilot uses AI. Check for mistakes.
Comment on lines 79 to 93
result.fold(
(failure) => appLogger
.error('Failed to connect: ${failure.localizedErrorMessage}'),
(success) async {
final savedServerLocation =
sl<LocalStorageService>().getSavedServerLocations();
final serverLocation = savedServerLocation.lanternLocation(
server: location,
autoSelect: false,
);
await ref
.read(serverLocationProvider.notifier)
.updateServerLocation(serverLocation);
},
);
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

result.fold mixes a synchronous left handler with an async right handler; the Future returned from the success branch is not awaited, so updateServerLocation may run later (or fail) without being observed. Prefer making both branches async and awaiting the fold result (or rewrite to an explicit if (result.isLeft/Right) flow) so errors are handled deterministically.

Copilot uses AI. Check for mistakes.
Comment on lines 74 to 92
Future<void> _onLocationSelected(Location_ location) async {
final result = await ref.read(vpnProvider.notifier).connectToServer(
ServerLocationType.lanternLocation,
location.tag,
);
result.fold(
(failure) => appLogger
.error('Failed to connect: ${failure.localizedErrorMessage}'),
(success) async {
final savedServerLocation =
sl<LocalStorageService>().getSavedServerLocations();
final serverLocation = savedServerLocation.lanternLocation(
server: location,
autoSelect: false,
);
await ref
.read(serverLocationProvider.notifier)
.updateServerLocation(serverLocation);
},
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

The tray path updates the saved/selected server location immediately on connectToServer success. Elsewhere (e.g. server selection UI) the app waits until the VPN status actually becomes connected before persisting the chosen location, to avoid showing/saving a location if the connection ultimately fails. Consider aligning this flow by updating serverLocationProvider only after the VPN reports connected (or after verifying the switch completed).

Copilot uses AI. Check for mistakes.
return MenuItem(
key: 'location_${location.tag}',
label: displayName,
onClick: (_) => _onLocationSelected(location),
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

MenuItem.onClick is invoked from a synchronous tray event handler; returning a Future from (_) => _onLocationSelected(location) means errors can surface as unhandled async exceptions. Consider invoking the async method without returning its future and handling/logging errors within _onLocationSelected (or via an explicit fire-and-forget helper).

Suggested change
onClick: (_) => _onLocationSelected(location),
onClick: (_) {
_onLocationSelected(location).catchError((error, stackTrace) {
stderr.writeln('Error selecting location $displayName: $error');
stderr.writeln(stackTrace);
});
},

Copilot uses AI. Check for mistakes.
@jigar-f jigar-f merged commit ac53244 into main Feb 9, 2026
9 checks passed
@jigar-f jigar-f deleted the myles/tray-server-location branch February 9, 2026 11:45
atavism pushed a commit that referenced this pull request Feb 9, 2026
* Select server location from menu bar

* Improve readability and check extension status.

* Merge main

---------

Co-authored-by: Jigar-f <jigar@getlantern.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants