diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2021-11-12 16:23:15 +0100 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-03-14 13:58:44 +0100 |
| commit | a4a064bdbadaa3c77a63b2deac06d2948246e808 (patch) | |
| tree | 3c164926885b74f2318d4d0daf3f135741c56d68 /gui | |
| parent | 61cacab42463bd0913905c31e5da4a69a4c359c7 (diff) | |
| download | mullvadvpn-a4a064bdbadaa3c77a63b2deac06d2948246e808.tar.xz mullvadvpn-a4a064bdbadaa3c77a63b2deac06d2948246e808.zip | |
Switch to using device removal daemon event for device list updates
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/src/main/daemon-rpc.ts | 10 | ||||
| -rw-r--r-- | gui/src/main/index.ts | 7 | ||||
| -rw-r--r-- | gui/src/renderer/app.tsx | 12 | ||||
| -rw-r--r-- | gui/src/renderer/components/TooManyDevices.tsx | 13 | ||||
| -rw-r--r-- | gui/src/renderer/redux/account/actions.ts | 18 | ||||
| -rw-r--r-- | gui/src/renderer/redux/account/reducers.ts | 10 | ||||
| -rw-r--r-- | gui/src/shared/daemon-rpc-types.ts | 3 | ||||
| -rw-r--r-- | gui/src/shared/ipc-schema.ts | 1 |
8 files changed, 58 insertions, 16 deletions
diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts index cae04be5ad..8eace70f8b 100644 --- a/gui/src/main/daemon-rpc.ts +++ b/gui/src/main/daemon-rpc.ts @@ -1155,11 +1155,17 @@ function convertFromDaemonEvent(data: grpcTypes.DaemonEvent): DaemonEvent { return { deviceConfig: convertFromDeviceEvent(deviceConfig) }; } + const deviceRemoval = data.getRemoveDevice(); + if (deviceRemoval !== undefined) { + return { deviceRemoval: convertFromDeviceRemoval(deviceRemoval) }; + } + const versionInfo = data.getVersionInfo(); if (versionInfo !== undefined) { return { appVersionInfo: versionInfo.toObject() }; } + // Handle unknown daemon events const keys = Object.entries(data.toObject()) .filter(([, value]) => value !== undefined) .map(([key]) => key); @@ -1374,6 +1380,10 @@ function convertFromDeviceConfig(deviceConfig?: grpcTypes.DeviceConfig): DeviceC ); } +function convertFromDeviceRemoval(deviceRemoval: grpcTypes.RemoveDeviceEvent): Array<IDevice> { + return deviceRemoval.getNewDeviceListList().map((device) => device.toObject()); +} + function ensureExists<T>(value: T | undefined, errorMessage: string): T { if (value) { return value; diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts index c41a8fd804..d2264242cc 100644 --- a/gui/src/main/index.ts +++ b/gui/src/main/index.ts @@ -781,6 +781,13 @@ class ApplicationMain { this.setLatestVersion(daemonEvent.appVersionInfo); } else if ('deviceConfig' in daemonEvent) { this.setDeviceConfig(daemonEvent.deviceConfig); + } else if ('deviceRemoval' in daemonEvent) { + if (this.windowController) { + IpcMainEventChannel.account.notifyDevices( + this.windowController.webContents, + daemonEvent.deviceRemoval, + ); + } } }, (error: Error) => { diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx index eb6ccb1a11..586e120868 100644 --- a/gui/src/renderer/app.tsx +++ b/gui/src/renderer/app.tsx @@ -129,6 +129,10 @@ export default class AppRenderer { this.handleAccountChange(deviceConfig, oldDeviceConfig?.accountToken); }); + IpcRendererEventChannel.account.listenDevices((devices) => { + this.reduxActions.account.updateDevices(devices); + }); + IpcRendererEventChannel.accountHistory.listen((newAccountHistory?: AccountToken) => { this.setAccountHistory(newAccountHistory); }); @@ -325,9 +329,11 @@ export default class AppRenderer { IpcRendererEventChannel.account.updateData(); } - public listDevices(accountToken: AccountToken): Promise<Array<IDevice>> { - return IpcRendererEventChannel.account.listDevices(accountToken); - } + public fetchDevices = async (accountToken: AccountToken): Promise<Array<IDevice>> => { + const devices = await IpcRendererEventChannel.account.listDevices(accountToken); + this.reduxActions.account.updateDevices(devices); + return devices; + }; public removeDevice(deviceRemoval: IDeviceRemoval): Promise<void> { return IpcRendererEventChannel.account.removeDevice(deviceRemoval); diff --git a/gui/src/renderer/components/TooManyDevices.tsx b/gui/src/renderer/components/TooManyDevices.tsx index 7b434468c7..56ecbd99c1 100644 --- a/gui/src/renderer/components/TooManyDevices.tsx +++ b/gui/src/renderer/components/TooManyDevices.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect } from 'react'; import { sprintf } from 'sprintf-js'; import styled from 'styled-components'; import { colors } from '../../config.json'; @@ -91,18 +91,13 @@ const StyledRemoveDeviceButton = styled.button({ export default function TooManyDevices() { const history = useHistory(); - const { listDevices, removeDevice, login, cancelLogin } = useAppContext(); + const { fetchDevices, removeDevice, login, cancelLogin } = useAppContext(); const accountToken = useSelector((state) => state.account.accountToken)!; - const [devices, setDevices] = useState<Array<IDevice>>(); - - const fetchDevices = useCallback(async () => { - setDevices(await listDevices(accountToken)); - }, [listDevices, accountToken]); + const devices = useSelector((state) => state.account.devices); const onRemoveDevice = useCallback( async (deviceId: string) => { await removeDevice({ accountToken, deviceId }); - await fetchDevices(); }, [removeDevice, accountToken], ); @@ -113,7 +108,7 @@ export default function TooManyDevices() { history.reset(RoutePath.login, transitions.pop); }, [history.reset, cancelLogin]); - useEffect(() => void fetchDevices(), []); + useEffect(() => void fetchDevices(accountToken), []); const iconSource = getIconSource(devices); const title = getTitle(devices); diff --git a/gui/src/renderer/redux/account/actions.ts b/gui/src/renderer/redux/account/actions.ts index 5affa1bb26..e53cb11545 100644 --- a/gui/src/renderer/redux/account/actions.ts +++ b/gui/src/renderer/redux/account/actions.ts @@ -1,4 +1,4 @@ -import { AccountToken, DeviceConfig } from '../../../shared/daemon-rpc-types'; +import { AccountToken, DeviceConfig, IDevice } from '../../../shared/daemon-rpc-types'; interface IStartLoginAction { type: 'START_LOGIN'; @@ -64,6 +64,11 @@ interface IUpdateAccountExpiryAction { expiry?: string; } +interface IUpdateDevicesAction { + type: 'UPDATE_DEVICES'; + devices: Array<IDevice>; +} + export type AccountAction = | IStartLoginAction | ILoggedInAction @@ -77,7 +82,8 @@ export type AccountAction = | IAccountSetupFinished | IUpdateAccountTokenAction | IUpdateAccountHistoryAction - | IUpdateAccountExpiryAction; + | IUpdateAccountExpiryAction + | IUpdateDevicesAction; function startLogin(accountToken: AccountToken): IStartLoginAction { return { @@ -167,6 +173,13 @@ function updateAccountExpiry(expiry?: string): IUpdateAccountExpiryAction { }; } +function updateDevices(devices: Array<IDevice>): IUpdateDevicesAction { + return { + type: 'UPDATE_DEVICES', + devices: devices.sort((a, b) => a.name.localeCompare(b.name)), + }; +} + export default { startLogin, loggedIn, @@ -181,4 +194,5 @@ export default { updateAccountToken, updateAccountHistory, updateAccountExpiry, + updateDevices, }; diff --git a/gui/src/renderer/redux/account/reducers.ts b/gui/src/renderer/redux/account/reducers.ts index 6c5fa1d76b..b336ea665a 100644 --- a/gui/src/renderer/redux/account/reducers.ts +++ b/gui/src/renderer/redux/account/reducers.ts @@ -1,4 +1,4 @@ -import { AccountToken } from '../../../shared/daemon-rpc-types'; +import { AccountToken, IDevice } from '../../../shared/daemon-rpc-types'; import { ReduxAction } from '../store'; type LoginMethod = 'existing_account' | 'new_account'; @@ -9,6 +9,7 @@ export type LoginState = export interface IAccountReduxState { accountToken?: AccountToken; deviceName?: string; + devices: Array<IDevice>; accountHistory?: AccountToken; expiry?: string; // ISO8601 status: LoginState; @@ -17,6 +18,7 @@ export interface IAccountReduxState { const initialState: IAccountReduxState = { accountToken: undefined, deviceName: undefined, + devices: [], accountHistory: undefined, expiry: undefined, status: { type: 'none' }, @@ -83,6 +85,7 @@ export default function ( }; case 'ACCOUNT_SETUP_FINISHED': return { + ...state, status: { type: 'ok', method: 'existing_account' }, }; case 'UPDATE_ACCOUNT_TOKEN': @@ -100,6 +103,11 @@ export default function ( ...state, expiry: action.expiry, }; + case 'UPDATE_DEVICES': + return { + ...state, + devices: action.devices, + }; } return state; diff --git a/gui/src/shared/daemon-rpc-types.ts b/gui/src/shared/daemon-rpc-types.ts index 61a068c08e..6fe598c7a0 100644 --- a/gui/src/shared/daemon-rpc-types.ts +++ b/gui/src/shared/daemon-rpc-types.ts @@ -105,7 +105,8 @@ export type DaemonEvent = | { settings: ISettings } | { relayList: IRelayList } | { appVersionInfo: IAppVersionInfo } - | { deviceConfig: DeviceConfig }; + | { deviceConfig: DeviceConfig } + | { deviceRemoval: Array<IDevice> }; export interface ITunnelStateRelayInfo { endpoint: ITunnelEndpoint; diff --git a/gui/src/shared/ipc-schema.ts b/gui/src/shared/ipc-schema.ts index 6ea154bf89..93947bee62 100644 --- a/gui/src/shared/ipc-schema.ts +++ b/gui/src/shared/ipc-schema.ts @@ -168,6 +168,7 @@ export const ipcSchema = { account: { '': notifyRenderer<IAccountData | undefined>(), device: notifyRenderer<DeviceConfig>(), + devices: notifyRenderer<Array<IDevice>>(), create: invoke<void, string>(), login: invoke<AccountToken, void>(), logout: invoke<void, void>(), |
