summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/main/daemon-rpc.ts10
-rw-r--r--gui/src/main/index.ts7
-rw-r--r--gui/src/renderer/app.tsx12
-rw-r--r--gui/src/renderer/components/TooManyDevices.tsx13
-rw-r--r--gui/src/renderer/redux/account/actions.ts18
-rw-r--r--gui/src/renderer/redux/account/reducers.ts10
-rw-r--r--gui/src/shared/daemon-rpc-types.ts3
-rw-r--r--gui/src/shared/ipc-schema.ts1
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>(),