diff options
5 files changed, 60 insertions, 13 deletions
diff --git a/gui/packages/desktop/src/renderer/app.js b/gui/packages/desktop/src/renderer/app.js index d0048950d5..5c4847d76a 100644 --- a/gui/packages/desktop/src/renderer/app.js +++ b/gui/packages/desktop/src/renderer/app.js @@ -402,9 +402,9 @@ export default class AppRenderer { actions.settings.updateAutoConnect(autoConnect); } - async _fetchSecurityState() { - const securityState = await this._daemonRpc.getState(); - const connectionState = this._tunnelStateToConnectionState(securityState); + async _fetchTunnelState() { + const tunnelState = await this._daemonRpc.getState(); + const connectionState = this._tunnelStateToConnectionState(tunnelState); this._updateConnectionState(connectionState); } @@ -514,7 +514,7 @@ export default class AppRenderer { _fetchInitialState() { return Promise.all([ - this._fetchSecurityState(), + this._fetchTunnelState(), this.fetchRelaySettings(), this._fetchRelayLocations(), this._fetchAllowLan(), @@ -530,6 +530,7 @@ export default class AppRenderer { const iconTypes: { [ConnectionState]: TrayIconType } = { connected: 'secured', connecting: 'securing', + blocked: 'securing', }; const type = iconTypes[connectionState] || 'unsecured'; @@ -545,14 +546,20 @@ export default class AppRenderer { } _tunnelStateToConnectionState(tunnelState: TunnelState): ConnectionState { - if (tunnelState === 'disconnected' || tunnelState === 'disconnecting') { - return 'disconnected'; - } else if (tunnelState === 'blocked') { - return 'connecting'; - } else if (tunnelState === 'connected' || tunnelState === 'connecting') { - return tunnelState; + switch (tunnelState) { + case 'disconnected': + // Fall through + case 'disconnecting': + return 'disconnected'; + case 'connected': + return 'connected'; + case 'connecting': + return 'connecting'; + case 'blocked': + return 'blocked'; + default: + throw new Error('Unknown tunnel state: ' + (tunnelState: empty)); } - throw new Error('Unsupported state/target state combination: ' + JSON.stringify(tunnelState)); } _updateConnectionState(connectionState: ConnectionState) { @@ -567,6 +574,11 @@ export default class AppRenderer { case 'disconnected': actions.connection.disconnected(); break; + case 'blocked': + actions.connection.blocked(); + break; + default: + log.error(`Unexpected ConnectionState: ${(connectionState: empty)}`); } this._updateTrayIcon(connectionState); @@ -584,6 +596,9 @@ export default class AppRenderer { case 'disconnected': this._notificationController.show('Unsecured'); break; + case 'blocked': + this._notificationController.show('Blocked all connections'); + break; default: log.error(`Unexpected ConnectionState: ${(connectionState: empty)}`); return; diff --git a/gui/packages/desktop/src/renderer/components/Connect.js b/gui/packages/desktop/src/renderer/components/Connect.js index d9c3768df6..dd5c4afa14 100644 --- a/gui/packages/desktop/src/renderer/components/Connect.js +++ b/gui/packages/desktop/src/renderer/components/Connect.js @@ -10,7 +10,7 @@ import * as AppButton from './AppButton'; import Img from './Img'; import Map from './Map'; import styles from './ConnectStyles'; -import { NoCreditError, NoInternetError } from '../errors'; +import { BlockedError, NoCreditError, NoInternetError } from '../errors'; import WindowStateObserver from '../lib/window-state-observer'; import type { HeaderBarStyle } from './HeaderBar'; @@ -103,6 +103,11 @@ export default class Connect extends Component<Props, State> { message = 'Your internet connection will be secured when you get back online'; } + if (error instanceof BlockedError) { + title = 'Blocked'; + message = error.message; + } + return ( <View style={styles.connect}> <View style={styles.status_icon}> @@ -345,6 +350,7 @@ export default class Connect extends Component<Props, State> { return 'error'; case 'connecting': case 'connected': + case 'blocked': return 'success'; default: throw new Error(`Invalid ConnectionState: ${(status: empty)}`); @@ -392,6 +398,11 @@ export default class Connect extends Component<Props, State> { return new NoCreditError(); } + // Tunnel is blocked due to an error? + if (this.props.connection.status === 'blocked') { + return new BlockedError(); + } + return null; } } diff --git a/gui/packages/desktop/src/renderer/errors.js b/gui/packages/desktop/src/renderer/errors.js index 7464851a1f..185b5920c7 100644 --- a/gui/packages/desktop/src/renderer/errors.js +++ b/gui/packages/desktop/src/renderer/errors.js @@ -1,5 +1,11 @@ // @flow +export class BlockedError extends Error { + constructor() { + super('Network connections blocked due to an internal error'); + } +} + export class NoCreditError extends Error { constructor() { super("Account doesn't have enough credit available for connection"); diff --git a/gui/packages/desktop/src/renderer/redux/connection/actions.js b/gui/packages/desktop/src/renderer/redux/connection/actions.js index a4c5c68890..37a44e99fc 100644 --- a/gui/packages/desktop/src/renderer/redux/connection/actions.js +++ b/gui/packages/desktop/src/renderer/redux/connection/actions.js @@ -14,6 +14,10 @@ type DisconnectedAction = { type: 'DISCONNECTED', }; +type BlockedAction = { + type: 'BLOCKED', +}; + type NewLocationAction = { type: 'NEW_LOCATION', newLocation: { @@ -39,6 +43,7 @@ export type ConnectionAction = | ConnectingAction | ConnectedAction | DisconnectedAction + | BlockedAction | OnlineAction | OfflineAction; @@ -60,6 +65,12 @@ function disconnected(): DisconnectedAction { }; } +function blocked(): BlockedAction { + return { + type: 'BLOCKED', + }; +} + function newLocation(newLoc: $PropertyType<NewLocationAction, 'newLocation'>): NewLocationAction { return { type: 'NEW_LOCATION', @@ -84,6 +95,7 @@ export default { connecting, connected, disconnected, + blocked, online, offline, }; diff --git a/gui/packages/desktop/src/renderer/redux/connection/reducers.js b/gui/packages/desktop/src/renderer/redux/connection/reducers.js index c75d0f2a8f..1bdc48806d 100644 --- a/gui/packages/desktop/src/renderer/redux/connection/reducers.js +++ b/gui/packages/desktop/src/renderer/redux/connection/reducers.js @@ -3,7 +3,7 @@ import type { ReduxAction } from '../store'; import type { Ip } from '../../lib/daemon-rpc'; -export type ConnectionState = 'disconnected' | 'connecting' | 'connected'; +export type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'blocked'; export type ConnectionReduxState = { status: ConnectionState, isOnline: boolean, @@ -41,6 +41,9 @@ export default function( case 'DISCONNECTED': return { ...state, ...{ status: 'disconnected' } }; + case 'BLOCKED': + return { ...state, ...{ status: 'blocked' } }; + case 'ONLINE': return { ...state, ...{ isOnline: true } }; |
