diff options
| author | Oliver <oliver@mohlin.dev> | 2025-03-13 09:03:16 +0100 |
|---|---|---|
| committer | Markus Pettersson <markus.pettersson@mullvad.net> | 2025-03-19 15:06:37 +0100 |
| commit | cbafe25da4a7e13199351363eb0e81208dccb9f3 (patch) | |
| tree | 8d06014f3b1bd8d3e38752cdbc83b4f169fb7831 | |
| parent | 0f122446c65e59af0bec90630aff2089df5afb49 (diff) | |
| download | mullvadvpn-cbafe25da4a7e13199351363eb0e81208dccb9f3.tar.xz mullvadvpn-cbafe25da4a7e13199351363eb0e81208dccb9f3.zip | |
Add no vpn server available notification
| -rw-r--r-- | desktop/packages/mullvad-vpn/src/renderer/lib/notifications/index.ts | 1 | ||||
| -rw-r--r-- | desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts | 122 |
2 files changed, 123 insertions, 0 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/index.ts index 513b97fefb..d949ff0428 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/index.ts +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/index.ts @@ -1,3 +1,4 @@ export * from './new-device'; export * from './new-version'; export * from './open-vpn-support-ending'; +export * from './no-open-vpn-server-available'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts new file mode 100644 index 0000000000..dc8819835a --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts @@ -0,0 +1,122 @@ +import { sprintf } from 'sprintf-js'; + +import { strings } from '../../../shared/constants'; +import { + ErrorStateCause, + TunnelParameterError, + TunnelProtocol, + TunnelState, +} from '../../../shared/daemon-rpc-types'; +import { messages } from '../../../shared/gettext'; +import { + InAppNotification, + InAppNotificationProvider, + InAppNotificationSubtitle, +} from '../../../shared/notifications'; +import { IRelayLocationCountryRedux } from '../../redux/settings/reducers'; +import { RoutePath } from '../routes'; + +interface NoOpenVpnServerAvailableNotificationContext { + tunnelProtocol: TunnelProtocol; + tunnelState: TunnelState; + relayLocations: IRelayLocationCountryRedux[]; +} + +export class NoOpenVpnServerAvailableNotificationProvider implements InAppNotificationProvider { + public constructor(private context: NoOpenVpnServerAvailableNotificationContext) {} + + public mayDisplay = () => { + const { tunnelState } = this.context; + return ( + tunnelState.state === 'error' && + tunnelState.details.cause === ErrorStateCause.tunnelParameterError && + tunnelState.details.parameterError === TunnelParameterError.noMatchingRelay + ); + }; + + public getInAppNotification(): InAppNotification { + let title: string = ''; + const subtitle: InAppNotificationSubtitle[] = []; + const capitalizedOpenVpn = strings.openvpn.toUpperCase(); + if (this.anyOpenVpnLocationsEnabled()) { + title = sprintf( + // TRANSLATORS: Notification title when there are no openVPN servers + // TRANSLATORS: matching current settings. + // TRANSLATORS: Available placeholders: + // TRANSLATORS: %(openVpn)s - Will be replaced with OPENVPN + messages.pgettext('in-app-notifications', 'NO %(openVpn)s SERVER AVAILABLE'), + { openVpn: capitalizedOpenVpn }, + ); + subtitle.push({ + content: sprintf( + // TRANSLATORS: First part of notification subtitle when there are no openVPN servers + // TRANSLATORS: matching current settings. Will be followed by a link to VPN settings. + // TRANSLATORS: Available placeholders: + // TRANSLATORS: %(openVpn)s - Will be replaced with OpenVPN + messages.pgettext( + 'in-app-notifications', + '%(openVpn)s support is ending. Switch location or', + ), + { openVpn: strings.openvpn }, + ), + }); + } else { + title = sprintf( + // TRANSLATORS: Notification title when there are no openVPN servers available. + // TRANSLATORS: Available placeholders: + // TRANSLATORS: %(openVpn)s - Will be replaced with OPENVPN + messages.pgettext('in-app-notifications', 'NO %(openVpn)s SERVERS AVAILABLE'), + { openVpn: capitalizedOpenVpn }, + ); + subtitle.push({ + content: sprintf( + // TRANSLATORS: First part of notification subtitle when there are no openVPN servers available. + // TRANSLATORS: Will be followed by a link to VPN settings. + // TRANSLATORS: Available placeholders: + // TRANSLATORS: %(openVpn)s - Will be replaced with OpenVPN + messages.pgettext( + 'in-app-notifications', + '%(openVpn)s support has ended. Please update the app or', + ), + { openVpn: strings.openvpn }, + ), + }); + } + subtitle.push({ + content: sprintf( + // TRANSLATORS: Link following the first part of the notification subtitle. + // TRANSLATORS: Will navigate the user to the VPN settings. + // TRANSLATORS: Available placeholders: + // TRANSLATORS: %(wireGuard)s - Will be replaced with WireGuard + messages.pgettext('in-app-notifications', 'change tunnel protocol to %(wireGuard)s'), + { wireGuard: strings.wireguard }, + ), + action: { + type: 'navigate-internal', + link: { + to: RoutePath.vpnSettings, + 'aria-label': + // TRANSLATORS: Accessibility label for link to VPN settings where + // TRANSLATORS: the user can change tunnel protocol. + messages.pgettext('accessibility', 'Go to VPN settings to change tunnel protocol'), + }, + }, + }); + + return { + indicator: 'error', + title, + subtitle, + }; + } + + private anyOpenVpnLocationsEnabled() { + return this.context.relayLocations.some((location) => { + return location.cities.some((city) => { + return city.relays.some((relay) => { + return relay.endpointType === 'openvpn' && relay.active; + }); + }); + }); + } +} |
