diff options
| author | Oskar <oskar@mullvad.net> | 2024-11-05 07:57:08 +0100 |
|---|---|---|
| committer | Oskar <oskar@mullvad.net> | 2024-11-14 16:43:18 +0100 |
| commit | 84f14d79c4f0dde73337820ec94ba8ff928a3797 (patch) | |
| tree | ce468658e5ba7b0a74950c7ad1b09b3a4d00520b /gui/src/shared/notifications | |
| parent | e3ce0eb5cd0610dbff6ec98cb8cb388415c74bf6 (diff) | |
| download | mullvadvpn-84f14d79c4f0dde73337820ec94ba8ff928a3797.tar.xz mullvadvpn-84f14d79c4f0dde73337820ec94ba8ff928a3797.zip | |
Move gui directory to desktop/packages/mullvad-vpn
Diffstat (limited to 'gui/src/shared/notifications')
| -rw-r--r-- | gui/src/shared/notifications/account-expired.ts | 42 | ||||
| -rw-r--r-- | gui/src/shared/notifications/block-when-disconnected.ts | 66 | ||||
| -rw-r--r-- | gui/src/shared/notifications/close-to-account-expiry.ts | 72 | ||||
| -rw-r--r-- | gui/src/shared/notifications/connected.ts | 42 | ||||
| -rw-r--r-- | gui/src/shared/notifications/connecting.ts | 60 | ||||
| -rw-r--r-- | gui/src/shared/notifications/daemon-disconnected.ts | 22 | ||||
| -rw-r--r-- | gui/src/shared/notifications/disconnected.ts | 28 | ||||
| -rw-r--r-- | gui/src/shared/notifications/error.ts | 338 | ||||
| -rw-r--r-- | gui/src/shared/notifications/inconsistent-version.ts | 39 | ||||
| -rw-r--r-- | gui/src/shared/notifications/new-device.ts | 32 | ||||
| -rw-r--r-- | gui/src/shared/notifications/notification.ts | 86 | ||||
| -rw-r--r-- | gui/src/shared/notifications/reconnecting.ts | 35 | ||||
| -rw-r--r-- | gui/src/shared/notifications/unsupported-version.ts | 62 | ||||
| -rw-r--r-- | gui/src/shared/notifications/update-available.ts | 96 |
14 files changed, 0 insertions, 1020 deletions
diff --git a/gui/src/shared/notifications/account-expired.ts b/gui/src/shared/notifications/account-expired.ts deleted file mode 100644 index a7af4f2c8b..0000000000 --- a/gui/src/shared/notifications/account-expired.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { links } from '../../config.json'; -import { hasExpired } from '../account-expiry'; -import { TunnelState } from '../daemon-rpc-types'; -import { messages } from '../gettext'; -import { - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -interface AccountExpiredNotificaitonContext { - accountExpiry: string; - tunnelState: TunnelState; -} - -export class AccountExpiredNotificationProvider implements SystemNotificationProvider { - public constructor(private context: AccountExpiredNotificaitonContext) {} - - public mayDisplay() { - // Only show when disconnected since the error state handles this if the connection is closed - // due to account expiry. - return ( - this.context.tunnelState.state === 'disconnected' && hasExpired(this.context.accountExpiry) - ); - } - - public getSystemNotification(): SystemNotification { - return { - message: messages.pgettext('notifications', 'Account is out of time'), - category: SystemNotificationCategory.expiry, - severity: SystemNotificationSeverityType.high, - presentOnce: { value: true, name: this.constructor.name }, - action: { - type: 'open-url', - url: links.purchase, - withAuth: true, - text: messages.pgettext('notifications', 'Buy more'), - }, - }; - } -} diff --git a/gui/src/shared/notifications/block-when-disconnected.ts b/gui/src/shared/notifications/block-when-disconnected.ts deleted file mode 100644 index 2f3df718b6..0000000000 --- a/gui/src/shared/notifications/block-when-disconnected.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { sprintf } from 'sprintf-js'; - -import { strings } from '../../config.json'; -import { messages } from '../../shared/gettext'; -import { TunnelState } from '../daemon-rpc-types'; -import { - InAppNotification, - InAppNotificationProvider, - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -interface BlockWhenDisconnectedNotificationContext { - tunnelState: TunnelState; - blockWhenDisconnected: boolean; - hasExcludedApps: boolean; -} - -export class BlockWhenDisconnectedNotificationProvider - implements InAppNotificationProvider, SystemNotificationProvider -{ - public constructor(private context: BlockWhenDisconnectedNotificationContext) {} - - public mayDisplay() { - return ( - (this.context.tunnelState.state === 'disconnecting' || - this.context.tunnelState.state === 'disconnected') && - this.context.blockWhenDisconnected - ); - } - - public getSystemNotification(): SystemNotification { - const message = messages.pgettext('notifications', 'Lockdown mode active, connection blocked'); - - return { - message, - severity: SystemNotificationSeverityType.info, - category: SystemNotificationCategory.tunnelState, - }; - } - - public getInAppNotification(): InAppNotification { - const lockdownModeSettingName = messages.pgettext('vpn-settings-view', 'Lockdown mode'); - let subtitle = sprintf( - messages.pgettext('in-app-notifications', '"%(lockdownModeSettingName)s" is enabled.'), - { lockdownModeSettingName }, - ); - if (this.context.hasExcludedApps) { - subtitle = `${subtitle} ${sprintf( - messages.pgettext( - 'notifications', - 'The apps excluded with %(splitTunneling)s might not work properly right now.', - ), - { splitTunneling: strings.splitTunneling.toLowerCase() }, - )}`; - } - - return { - indicator: 'warning', - title: messages.pgettext('in-app-notifications', 'BLOCKING INTERNET'), - subtitle, - }; - } -} diff --git a/gui/src/shared/notifications/close-to-account-expiry.ts b/gui/src/shared/notifications/close-to-account-expiry.ts deleted file mode 100644 index 4fde6ab395..0000000000 --- a/gui/src/shared/notifications/close-to-account-expiry.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { sprintf } from 'sprintf-js'; - -import { links } from '../../config.json'; -import { messages } from '../../shared/gettext'; -import { closeToExpiry, formatRemainingTime } from '../account-expiry'; -import { - InAppNotification, - InAppNotificationProvider, - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -interface CloseToAccountExpiryNotificationContext { - accountExpiry: string; - locale: string; -} - -export class CloseToAccountExpiryNotificationProvider - implements InAppNotificationProvider, SystemNotificationProvider -{ - public constructor(private context: CloseToAccountExpiryNotificationContext) {} - - public mayDisplay = () => closeToExpiry(this.context.accountExpiry); - - public getSystemNotification(): SystemNotification { - const message = sprintf( - // TRANSLATORS: The system notification displayed to the user when the account credit is close to expiry. - // TRANSLATORS: Available placeholder: - // TRANSLATORS: %(duration)s - remaining time, e.g. "2 days" - messages.pgettext( - 'notifications', - 'Account credit expires in %(duration)s. Buy more credit.', - ), - { - duration: formatRemainingTime(this.context.accountExpiry), - }, - ); - - return { - message, - category: SystemNotificationCategory.expiry, - severity: SystemNotificationSeverityType.medium, - action: { - type: 'open-url', - url: links.purchase, - withAuth: true, - text: messages.pgettext('notifications', 'Buy more'), - }, - }; - } - - public getInAppNotification(): InAppNotification { - const subtitle = sprintf( - messages.pgettext('in-app-notifications', '%(duration)s. Buy more credit.'), - { - duration: formatRemainingTime(this.context.accountExpiry, { - capitalize: true, - suffix: true, - }), - }, - ); - - return { - indicator: 'warning', - title: messages.pgettext('in-app-notifications', 'ACCOUNT CREDIT EXPIRES SOON'), - subtitle, - action: { type: 'open-url', url: links.purchase, withAuth: true }, - }; - } -} diff --git a/gui/src/shared/notifications/connected.ts b/gui/src/shared/notifications/connected.ts deleted file mode 100644 index c66339fe9e..0000000000 --- a/gui/src/shared/notifications/connected.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { sprintf } from 'sprintf-js'; - -import { messages } from '../../shared/gettext'; -import { TunnelState } from '../daemon-rpc-types'; -import { - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -export class ConnectedNotificationProvider implements SystemNotificationProvider { - public constructor(private context: TunnelState) {} - - public mayDisplay = () => this.context.state === 'connected'; - - public getSystemNotification(): SystemNotification | undefined { - if (this.context.state === 'connected') { - let message = messages.pgettext('notifications', 'Connected'); - const location = this.context.details.location?.hostname; - if (location) { - message = sprintf( - // TRANSLATORS: The message showed when a server has been connected to. - // TRANSLATORS: Available placeholder: - // TRANSLATORS: %(location) - name of the server location we're connected to (e.g. "se-got-003") - messages.pgettext('notifications', 'Connected to %(location)s'), - { - location, - }, - ); - } - - return { - message, - severity: SystemNotificationSeverityType.info, - category: SystemNotificationCategory.tunnelState, - }; - } else { - return undefined; - } - } -} diff --git a/gui/src/shared/notifications/connecting.ts b/gui/src/shared/notifications/connecting.ts deleted file mode 100644 index 444dd42beb..0000000000 --- a/gui/src/shared/notifications/connecting.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { sprintf } from 'sprintf-js'; - -import { messages } from '../../shared/gettext'; -import { TunnelState } from '../daemon-rpc-types'; -import { - InAppNotification, - InAppNotificationProvider, - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -interface ConnectingNotificationContext { - tunnelState: TunnelState; - reconnecting?: boolean; -} - -export class ConnectingNotificationProvider - implements SystemNotificationProvider, InAppNotificationProvider -{ - public constructor(private context: ConnectingNotificationContext) {} - - public mayDisplay() { - return this.context.tunnelState.state === 'connecting' && !this.context.reconnecting; - } - - public getSystemNotification(): SystemNotification | undefined { - if (this.context.tunnelState.state === 'connecting') { - let message = messages.pgettext('notifications', 'Connecting'); - const location = this.context.tunnelState.details?.location?.hostname; - if (location) { - message = sprintf( - // TRANSLATORS: The message showed when a server is being connected to. - // TRANSLATORS: Available placeholder: - // TRANSLATORS: %(location) - name of the server location we're connecting to (e.g. "se-got-003") - messages.pgettext('notifications', 'Connecting to %(location)s'), - { - location, - }, - ); - } - - return { - message, - severity: SystemNotificationSeverityType.info, - category: SystemNotificationCategory.tunnelState, - throttle: true, - }; - } else { - return undefined; - } - } - - public getInAppNotification(): InAppNotification { - return { - title: messages.pgettext('in-app-notifications', 'BLOCKING INTERNET'), - }; - } -} diff --git a/gui/src/shared/notifications/daemon-disconnected.ts b/gui/src/shared/notifications/daemon-disconnected.ts deleted file mode 100644 index 50a62266d0..0000000000 --- a/gui/src/shared/notifications/daemon-disconnected.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { messages } from '../../shared/gettext'; -import { - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -export class DaemonDisconnectedNotificationProvider implements SystemNotificationProvider { - public mayDisplay = () => true; - - public getSystemNotification(): SystemNotification { - return { - message: messages.pgettext( - 'notifications', - 'Connection might be unsecured. App lost contact with system service, please troubleshoot.', - ), - severity: SystemNotificationSeverityType.high, - category: SystemNotificationCategory.tunnelState, - }; - } -} diff --git a/gui/src/shared/notifications/disconnected.ts b/gui/src/shared/notifications/disconnected.ts deleted file mode 100644 index 874cb11b3e..0000000000 --- a/gui/src/shared/notifications/disconnected.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { messages } from '../../shared/gettext'; -import { TunnelState } from '../daemon-rpc-types'; -import { - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -interface DisconnectedNotificationContext { - tunnelState: TunnelState; - blockWhenDisconnected: boolean; -} - -export class DisconnectedNotificationProvider implements SystemNotificationProvider { - public constructor(private context: DisconnectedNotificationContext) {} - - public mayDisplay = () => - this.context.tunnelState.state === 'disconnected' && !this.context.blockWhenDisconnected; - - public getSystemNotification(): SystemNotification | undefined { - return { - message: messages.pgettext('notifications', 'Disconnected and unsecure'), - severity: SystemNotificationSeverityType.info, - category: SystemNotificationCategory.tunnelState, - }; - } -} diff --git a/gui/src/shared/notifications/error.ts b/gui/src/shared/notifications/error.ts deleted file mode 100644 index af82748d7b..0000000000 --- a/gui/src/shared/notifications/error.ts +++ /dev/null @@ -1,338 +0,0 @@ -import { sprintf } from 'sprintf-js'; - -import { strings } from '../../config.json'; -import { - AuthFailedError, - ErrorStateCause, - ErrorStateDetails, - TunnelParameterError, - TunnelState, -} from '../daemon-rpc-types'; -import { messages } from '../gettext'; -import { - InAppNotification, - InAppNotificationAction, - InAppNotificationProvider, - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -interface ErrorNotificationContext { - tunnelState: TunnelState; - hasExcludedApps: boolean; - showFullDiskAccessSettings?: () => void; -} - -export class ErrorNotificationProvider - implements SystemNotificationProvider, InAppNotificationProvider -{ - public constructor(private context: ErrorNotificationContext) {} - - public mayDisplay = () => this.context.tunnelState.state === 'error'; - - public getSystemNotification(): SystemNotification | undefined { - if (this.context.tunnelState.state === 'error') { - let message = this.getMessage(this.context.tunnelState.details); - if (!this.context.tunnelState.details.blockingError && this.context.hasExcludedApps) { - message = `${message} ${sprintf( - messages.pgettext( - 'notifications', - 'The apps excluded with %(splitTunneling)s might not work properly right now.', - ), - { splitTunneling: strings.splitTunneling.toLowerCase() }, - )}`; - } - - return { - message, - severity: - this.context.tunnelState.details.blockingError === undefined - ? SystemNotificationSeverityType.low - : SystemNotificationSeverityType.high, - category: SystemNotificationCategory.tunnelState, - }; - } else { - return undefined; - } - } - - public getInAppNotification(): InAppNotification | undefined { - if (this.context.tunnelState.state === 'error') { - let subtitle = this.getMessage(this.context.tunnelState.details); - if (!this.context.tunnelState.details.blockingError && this.context.hasExcludedApps) { - subtitle = `${subtitle} ${sprintf( - messages.pgettext( - 'notifications', - 'The apps excluded with %(splitTunneling)s might not work properly right now.', - ), - { splitTunneling: strings.splitTunneling.toLowerCase() }, - )}`; - } - - return { - indicator: - this.context.tunnelState.details.cause === ErrorStateCause.isOffline - ? 'warning' - : 'error', - title: this.context.tunnelState.details.blockingError - ? messages.pgettext('in-app-notifications', 'NETWORK TRAFFIC MIGHT BE LEAKING') - : messages.pgettext('in-app-notifications', 'BLOCKING INTERNET'), - subtitle, - action: this.getActions(this.context.tunnelState.details) ?? undefined, - }; - } else { - return undefined; - } - } - - private getMessage(errorState: ErrorStateDetails): string { - if (errorState.blockingError) { - if (errorState.cause === ErrorStateCause.setFirewallPolicyError) { - switch (process.platform ?? window.env.platform) { - case 'win32': - return messages.pgettext( - 'notifications', - 'Unable to block all network traffic. Try temporarily disabling any third-party antivirus or security software or send a problem report.', - ); - case 'linux': - return messages.pgettext( - 'notifications', - 'Unable to block all network traffic. Try updating your kernel or send a problem report.', - ); - } - } - - return messages.pgettext( - 'notifications', - 'Unable to block all network traffic. Please troubleshoot or send a problem report.', - ); - } else { - switch (errorState.cause) { - case ErrorStateCause.authFailed: - switch (errorState.authFailedError) { - case AuthFailedError.invalidAccount: - return messages.pgettext( - 'auth-failure', - 'You are logged in with an invalid account number. Please log out and try another one.', - ); - - case AuthFailedError.expiredAccount: - return messages.pgettext('auth-failure', 'Blocking internet: account is out of time'); - - case AuthFailedError.tooManyConnections: - return messages.pgettext( - 'auth-failure', - 'Too many simultaneous connections on this account. Disconnect another device or try connecting again shortly.', - ); - - case AuthFailedError.unknown: - default: - return messages.pgettext( - 'auth-failure', - 'Unable to authenticate account. Please send a problem report.', - ); - } - case ErrorStateCause.ipv6Unavailable: - return messages.pgettext( - 'notifications', - 'Could not configure IPv6. Disable it in the app or enable it on your device.', - ); - case ErrorStateCause.setFirewallPolicyError: - switch (process.platform ?? window.env.platform) { - case 'win32': - return messages.pgettext( - 'notifications', - 'Unable to apply firewall rules. Try temporarily disabling any third-party antivirus or security software.', - ); - case 'linux': - return messages.pgettext( - 'notifications', - 'Unable to apply firewall rules. Try updating your kernel.', - ); - default: - return messages.pgettext('notifications', 'Unable to apply firewall rules.'); - } - case ErrorStateCause.setDnsError: - return messages.pgettext( - 'notifications', - 'Unable to set system DNS server. Please send a problem report.', - ); - case ErrorStateCause.startTunnelError: - return messages.pgettext( - 'notifications', - 'Unable to start tunnel connection. Please send a problem report.', - ); - case ErrorStateCause.createTunnelDeviceError: - if (errorState.osError === 4319) { - return messages.pgettext( - 'notifications', - 'Unable to start tunnel connection. This could be because of conflicts with VMware, please troubleshoot.', - ); - } - - return messages.pgettext( - 'notifications', - 'Unable to start tunnel connection. Please send a problem report.', - ); - case ErrorStateCause.tunnelParameterError: - return this.getTunnelParameterMessage(errorState.parameterError); - case ErrorStateCause.isOffline: - return messages.pgettext( - 'notifications', - 'Your device is offline. The tunnel will automatically connect once your device is back online.', - ); - case ErrorStateCause.needFullDiskPermissions: - return messages.pgettext('notifications', 'Failed to enable split tunneling.'); - case ErrorStateCause.splitTunnelError: - switch (process.platform ?? window.env.platform) { - case 'darwin': - return messages.pgettext( - 'notifications', - 'Failed to enable split tunneling. Please try reconnecting or disable split tunneling.', - ); - default: - return messages.pgettext( - 'notifications', - 'Unable to communicate with Mullvad kernel driver. Try reconnecting or send a problem report.', - ); - } - } - } - } - - private getTunnelParameterMessage(error: TunnelParameterError): string { - switch (error) { - /// TODO: once bridge constraints can be set, add a more descriptive error message - case TunnelParameterError.noMatchingBridgeRelay: - case TunnelParameterError.noMatchingRelay: - return messages.pgettext( - 'notifications', - 'No servers match your settings, try changing server or other settings.', - ); - case TunnelParameterError.noWireguardKey: - return sprintf( - // TRANSLATORS: Available placeholders: - // TRANSLATORS: %(wireguard)s - will be replaced with "WireGuard" - messages.pgettext( - 'notifications', - 'Valid %(wireguard)s key is missing. Manage keys under Advanced settings.', - ), - { wireguard: strings.wireguard }, - ); - case TunnelParameterError.customTunnelHostResolutionError: - return messages.pgettext( - 'notifications', - 'Unable to resolve host of custom tunnel. Try changing your settings.', - ); - } - } - - private getActions(errorState: ErrorStateDetails): InAppNotificationAction | void { - const platform = process.platform ?? window.env.platform; - - if (errorState.cause === ErrorStateCause.setFirewallPolicyError && platform === 'linux') { - return { - type: 'troubleshoot-dialog', - troubleshoot: { - details: messages.pgettext('troubleshoot', 'This might be caused by an outdated kernel.'), - steps: [ - messages.pgettext('troubleshoot', 'Update your kernel.'), - messages.pgettext('troubleshoot', 'Make sure you have NF tables support.'), - ], - }, - }; - } else if (errorState.cause === ErrorStateCause.setDnsError) { - const troubleshootSteps = []; - if (platform === 'darwin') { - troubleshootSteps.push( - messages.pgettext( - 'troubleshoot', - 'Try to turn Wi-Fi Calling off in the FaceTime app settings and restart the Mac.', - ), - messages.pgettext( - 'troubleshoot', - 'Uninstall or disable other DNS, networking and ads/website blocking apps.', - ), - ); - } else if (platform === 'win32') { - troubleshootSteps.push( - messages.pgettext( - 'troubleshoot', - 'Uninstall or disable other DNS, networking and ads/website blocking apps.', - ), - ); - } - - return { - type: 'troubleshoot-dialog', - troubleshoot: { - details: messages.pgettext( - 'troubleshoot', - 'This error can happen when something other than Mullvad is actively updating the DNS.', - ), - steps: troubleshootSteps, - }, - }; - } else if (errorState.cause === ErrorStateCause.needFullDiskPermissions) { - let troubleshootButtons = undefined; - if (this.context.showFullDiskAccessSettings) { - troubleshootButtons = [ - { - label: messages.pgettext('troubleshoot', 'Open system settings'), - action: () => this.context.showFullDiskAccessSettings?.(), - }, - ]; - } - - return { - type: 'troubleshoot-dialog', - troubleshoot: { - details: messages.pgettext( - 'troubleshoot', - 'Failed to enable split tunneling. This is because the app is missing system permissions. What you can do:', - ), - steps: [ - messages.pgettext( - 'troubleshoot', - 'Enable “Full Disk Access” for “Mullvad VPN” in the macOS system settings.', - ), - ], - buttons: troubleshootButtons, - }, - }; - } else if (platform === 'win32' && errorState.cause === ErrorStateCause.splitTunnelError) { - return { - type: 'troubleshoot-dialog', - troubleshoot: { - details: messages.pgettext( - 'troubleshoot', - 'Unable to communicate with Mullvad kernel driver.', - ), - steps: [ - messages.pgettext('troubleshoot', 'Try reconnecting.'), - messages.pgettext('troubleshoot', 'Try restarting your device.'), - ], - }, - }; - } else if ( - errorState.cause === ErrorStateCause.createTunnelDeviceError && - errorState.osError === 4319 - ) { - return { - type: 'troubleshoot-dialog', - troubleshoot: { - details: messages.pgettext( - 'troubleshoot', - 'Unable to start tunnel connection because of a failure when creating the tunnel device. This is often caused by conflicts with the VMware Bridge Protocol.', - ), - steps: [ - messages.pgettext('troubleshoot', 'Try to reinstall VMware.'), - messages.pgettext('troubleshoot', 'Try to uninstall VMware.'), - ], - }, - }; - } - } -} diff --git a/gui/src/shared/notifications/inconsistent-version.ts b/gui/src/shared/notifications/inconsistent-version.ts deleted file mode 100644 index e4f7a8ddc1..0000000000 --- a/gui/src/shared/notifications/inconsistent-version.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { messages } from '../../shared/gettext'; -import { - InAppNotification, - InAppNotificationProvider, - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -interface InconsistentVersionNotificationContext { - consistent: boolean; -} - -export class InconsistentVersionNotificationProvider - implements SystemNotificationProvider, InAppNotificationProvider -{ - public constructor(private context: InconsistentVersionNotificationContext) {} - - public mayDisplay = () => !this.context.consistent; - - public getSystemNotification(): SystemNotification { - return { - message: messages.pgettext('notifications', 'App is out of sync. Please quit and restart.'), - category: SystemNotificationCategory.inconsistentVersion, - severity: SystemNotificationSeverityType.high, - presentOnce: { value: true, name: this.constructor.name }, - suppressInDevelopment: true, - }; - } - - public getInAppNotification(): InAppNotification { - return { - indicator: 'error', - title: messages.pgettext('in-app-notifications', 'APP IS OUT OF SYNC'), - subtitle: messages.pgettext('in-app-notifications', 'Please quit and restart the app.'), - }; - } -} diff --git a/gui/src/shared/notifications/new-device.ts b/gui/src/shared/notifications/new-device.ts deleted file mode 100644 index 7d0fe9f299..0000000000 --- a/gui/src/shared/notifications/new-device.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { sprintf } from 'sprintf-js'; - -import { messages } from '../../shared/gettext'; -import { capitalizeEveryWord } from '../string-helpers'; -import { InAppNotification, InAppNotificationProvider } from './notification'; - -interface NewDeviceNotificationContext { - shouldDisplay: boolean; - deviceName: string; - close: () => void; -} - -export class NewDeviceNotificationProvider implements InAppNotificationProvider { - public constructor(private context: NewDeviceNotificationContext) {} - - public mayDisplay = () => this.context.shouldDisplay; - - public getInAppNotification(): InAppNotification { - return { - indicator: 'success', - title: messages.pgettext('in-app-notifications', 'NEW DEVICE CREATED'), - subtitle: sprintf( - messages.pgettext( - 'in-app-notifications', - 'Welcome, this device is now called <b>%(deviceName)s</b>. For more details see the info button in Account.', - ), - { deviceName: capitalizeEveryWord(this.context.deviceName) }, - ), - action: { type: 'close', close: this.context.close }, - }; - } -} diff --git a/gui/src/shared/notifications/notification.ts b/gui/src/shared/notifications/notification.ts deleted file mode 100644 index 87166aab4d..0000000000 --- a/gui/src/shared/notifications/notification.ts +++ /dev/null @@ -1,86 +0,0 @@ -export type NotificationAction = { - type: 'open-url'; - url: string; - text?: string; - withAuth?: boolean; -}; - -export interface InAppNotificationTroubleshootInfo { - details: string; - steps: string[]; - buttons?: Array<InAppNotificationTroubleshootButton>; -} - -export interface InAppNotificationTroubleshootButton { - label: string; - action: () => void; -} - -export type InAppNotificationAction = - | NotificationAction - | { - type: 'troubleshoot-dialog'; - troubleshoot: InAppNotificationTroubleshootInfo; - } - | { - type: 'close'; - close: () => void; - }; - -export type InAppNotificationIndicatorType = 'success' | 'warning' | 'error'; - -export enum SystemNotificationSeverityType { - info = 0, - low, - medium, - high, -} - -export enum SystemNotificationCategory { - tunnelState, - expiry, - newVersion, - inconsistentVersion, -} - -interface NotificationProvider { - mayDisplay(): boolean; -} - -export interface SystemNotification { - message: string; - severity: SystemNotificationSeverityType; - category: SystemNotificationCategory; - throttle?: boolean; - presentOnce?: { value: boolean; name: string }; - suppressInDevelopment?: boolean; - action?: NotificationAction; -} - -export interface InAppNotification { - indicator?: InAppNotificationIndicatorType; - title: string; - subtitle?: string; - action?: InAppNotificationAction; -} - -export interface SystemNotificationProvider extends NotificationProvider { - getSystemNotification(): SystemNotification | undefined; -} - -export interface InAppNotificationProvider extends NotificationProvider { - getInAppNotification(): InAppNotification | undefined; -} - -export * from './account-expired'; -export * from './close-to-account-expiry'; -export * from './block-when-disconnected'; -export * from './connected'; -export * from './connecting'; -export * from './disconnected'; -export * from './daemon-disconnected'; -export * from './error'; -export * from './inconsistent-version'; -export * from './reconnecting'; -export * from './unsupported-version'; -export * from './update-available'; diff --git a/gui/src/shared/notifications/reconnecting.ts b/gui/src/shared/notifications/reconnecting.ts deleted file mode 100644 index 4362c0edb6..0000000000 --- a/gui/src/shared/notifications/reconnecting.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { messages } from '../../shared/gettext'; -import { TunnelState } from '../daemon-rpc-types'; -import { - InAppNotification, - InAppNotificationProvider, - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -export class ReconnectingNotificationProvider - implements SystemNotificationProvider, InAppNotificationProvider -{ - public constructor(private context: TunnelState) {} - - public mayDisplay() { - return this.context.state === 'disconnecting' && this.context.details === 'reconnect'; - } - - public getSystemNotification(): SystemNotification | undefined { - return { - message: messages.pgettext('notifications', 'Reconnecting'), - severity: SystemNotificationSeverityType.info, - category: SystemNotificationCategory.tunnelState, - throttle: true, - }; - } - - public getInAppNotification(): InAppNotification { - return { - title: messages.pgettext('in-app-notifications', 'BLOCKING INTERNET'), - }; - } -} diff --git a/gui/src/shared/notifications/unsupported-version.ts b/gui/src/shared/notifications/unsupported-version.ts deleted file mode 100644 index 15c622703c..0000000000 --- a/gui/src/shared/notifications/unsupported-version.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { messages } from '../../shared/gettext'; -import { getDownloadUrl } from '../version'; -import { - InAppNotification, - InAppNotificationProvider, - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -interface UnsupportedVersionNotificationContext { - supported: boolean; - consistent: boolean; - suggestedUpgrade?: string; - suggestedIsBeta?: boolean; -} - -export class UnsupportedVersionNotificationProvider - implements SystemNotificationProvider, InAppNotificationProvider -{ - public constructor(private context: UnsupportedVersionNotificationContext) {} - - public mayDisplay() { - return this.context.consistent && !this.context.supported; - } - - public getSystemNotification(): SystemNotification { - return { - message: this.getMessage(), - category: SystemNotificationCategory.newVersion, - severity: SystemNotificationSeverityType.high, - action: { - type: 'open-url', - url: getDownloadUrl(this.context.suggestedIsBeta ?? false), - text: messages.pgettext('notifications', 'Upgrade'), - }, - presentOnce: { value: true, name: this.constructor.name }, - suppressInDevelopment: true, - }; - } - - public getInAppNotification(): InAppNotification { - return { - indicator: 'error', - title: messages.pgettext('in-app-notifications', 'UNSUPPORTED VERSION'), - subtitle: this.getMessage(), - action: { - type: 'open-url', - url: getDownloadUrl(this.context.suggestedIsBeta ?? false), - }, - }; - } - - private getMessage(): string { - // TRANSLATORS: The in-app banner and system notification which are displayed to the user when the running app becomes unsupported. - return messages.pgettext( - 'notifications', - 'Your privacy might be at risk with this unsupported app version. Please update now.', - ); - } -} diff --git a/gui/src/shared/notifications/update-available.ts b/gui/src/shared/notifications/update-available.ts deleted file mode 100644 index 732e7bb9a8..0000000000 --- a/gui/src/shared/notifications/update-available.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { sprintf } from 'sprintf-js'; - -import { messages } from '../../shared/gettext'; -import { getDownloadUrl } from '../version'; -import { - InAppNotification, - InAppNotificationProvider, - SystemNotification, - SystemNotificationCategory, - SystemNotificationProvider, - SystemNotificationSeverityType, -} from './notification'; - -interface UpdateAvailableNotificationContext { - suggestedUpgrade?: string; - suggestedIsBeta?: boolean; -} - -export class UpdateAvailableNotificationProvider - implements InAppNotificationProvider, SystemNotificationProvider -{ - public constructor(private context: UpdateAvailableNotificationContext) {} - - public mayDisplay() { - return this.context.suggestedUpgrade ? true : false; - } - - public getInAppNotification(): InAppNotification { - return { - indicator: 'warning', - title: this.context.suggestedIsBeta - ? messages.pgettext('in-app-notifications', 'BETA UPDATE AVAILABLE') - : messages.pgettext('in-app-notifications', 'UPDATE AVAILABLE'), - subtitle: this.inAppMessage(), - action: { - type: 'open-url', - url: getDownloadUrl(this.context.suggestedIsBeta ?? false), - }, - }; - } - - public getSystemNotification(): SystemNotification { - return { - message: this.systemMessage(), - category: SystemNotificationCategory.newVersion, - severity: SystemNotificationSeverityType.medium, - action: { - type: 'open-url', - url: getDownloadUrl(this.context.suggestedIsBeta ?? false), - text: messages.pgettext('notifications', 'Upgrade'), - }, - presentOnce: { value: true, name: this.constructor.name }, - suppressInDevelopment: true, - }; - } - - private inAppMessage(): string { - if (this.context.suggestedIsBeta) { - return sprintf( - // TRANSLATORS: The in-app banner displayed to the user when the app beta update is - // TRANSLATORS: available. - // TRANSLATORS: Available placeholders: - // TRANSLATORS: %(version)s - The version number of the new beta version. - messages.pgettext('in-app-notifications', 'Try out the newest beta version (%(version)s).'), - { version: this.context.suggestedUpgrade }, - ); - } else { - // TRANSLATORS: The in-app banner displayed to the user when the app update is available. - return messages.pgettext( - 'in-app-notifications', - 'Install the latest app version to stay up to date.', - ); - } - } - - private systemMessage(): string { - if (this.context.suggestedIsBeta) { - return sprintf( - // TRANSLATORS: The system notification that notifies the user when a beta update is - // TRANSLATORS: available. - // TRANSLATORS: Available placeholders: - // TRANSLATORS: %(version)s - The version number of the new beta version. - messages.pgettext( - 'notifications', - 'Beta update available. Try out the newest beta version (%(version)s).', - ), - { version: this.context.suggestedUpgrade }, - ); - } else { - return messages.pgettext( - 'notifications', - 'Update available. Install the latest app version to stay up to date', - ); - } - } -} |
