summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2022-08-05 11:06:54 +0200
committerOskar Nyberg <oskar@mullvad.net>2022-08-22 08:34:37 +0200
commit5890d65e59919356fd257e2a8d21630ec5cc7260 (patch)
tree891be8fc28c3456c515e4d69894d930559117ea7 /gui/src
parentb9100181bee6e6cd02e5f41d0ff06aad20c3e083 (diff)
downloadmullvadvpn-5890d65e59919356fd257e2a8d21630ec5cc7260.tar.xz
mullvadvpn-5890d65e59919356fd257e2a8d21630ec5cc7260.zip
Curry IpcMainEventChannel functions with WebContents where applicable
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/main/ipc-event-channel.ts48
-rw-r--r--gui/src/shared/ipc-helpers.ts6
2 files changed, 48 insertions, 6 deletions
diff --git a/gui/src/main/ipc-event-channel.ts b/gui/src/main/ipc-event-channel.ts
index d883f52152..d189634950 100644
--- a/gui/src/main/ipc-event-channel.ts
+++ b/gui/src/main/ipc-event-channel.ts
@@ -1,6 +1,48 @@
-import { ipcMain } from 'electron';
+import { ipcMain, WebContents } from 'electron';
-import { createIpcMain } from '../shared/ipc-helpers';
+import { createIpcMain, IpcMain, Schema } from '../shared/ipc-helpers';
import { ipcSchema } from '../shared/ipc-schema';
-export const IpcMainEventChannel = createIpcMain(ipcSchema, ipcMain);
+// Type where the notify functions have been replaced with either `undefined` if no `WebContents` is
+// available, or with the function curried with the `WebContents`.
+type IpcMainBootstrappedWithWebContents<S extends Schema> = {
+ [GK in keyof IpcMain<S>]: {
+ [CK in keyof IpcMain<S>[GK]]: CK extends `notify${string}`
+ ? undefined | ((arg: Parameters<IpcMain<S>[GK][CK]>[1]) => ReturnType<IpcMain<S>[GK][CK]>)
+ : IpcMain<S>[GK][CK];
+ };
+};
+
+const ipcMainFromSchema = createIpcMain(ipcSchema, ipcMain);
+// eslint-disable-next-line @typescript-eslint/naming-convention
+export let IpcMainEventChannel = bootstrapIpcMainWithWebContents();
+
+// Curries all notify functions with `WebContents` if it's not `undefined`. If it is `undefined`
+// then the whole function will be replaced with `undefined`.
+function bootstrapIpcMainWithWebContents(
+ webContents?: WebContents,
+): IpcMainBootstrappedWithWebContents<typeof ipcSchema> {
+ return Object.fromEntries(
+ Object.entries(ipcMainFromSchema).map(([groupKey, group]) => {
+ const newGroup = Object.fromEntries(
+ Object.entries(group).map(([callKey, call]) => {
+ if (callKey.startsWith('notify')) {
+ const newCall = webContents
+ ? (arg: Parameters<typeof call>[1]) => call(webContents, arg)
+ : undefined;
+ return [callKey, newCall];
+ } else {
+ return [callKey, call];
+ }
+ }),
+ );
+
+ return [groupKey, newGroup];
+ }),
+ ) as IpcMainBootstrappedWithWebContents<typeof ipcSchema>;
+}
+
+// Change the `IpcMainEventChannel` for a new one with a new `WebContents`.
+export function changeIpcWebContents(webContents?: WebContents) {
+ IpcMainEventChannel = bootstrapIpcMainWithWebContents(webContents);
+}
diff --git a/gui/src/shared/ipc-helpers.ts b/gui/src/shared/ipc-helpers.ts
index cde27bb32b..1680b45d11 100644
--- a/gui/src/shared/ipc-helpers.ts
+++ b/gui/src/shared/ipc-helpers.ts
@@ -23,7 +23,7 @@ interface RendererToMain<T, R> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type AnyIpcCall = MainToRenderer<any> | RendererToMain<any, any>;
-type Schema = Record<string, Record<string, AnyIpcCall>>;
+export type Schema = Record<string, Record<string, AnyIpcCall>>;
// Renames all IPC calls, e.g. `callName` to either `notifyCallName` or `handleCallName` depending
// on direction.
@@ -48,14 +48,14 @@ type IpcRendererFn<I extends AnyIpcCall> = I['direction'] extends 'main-to-rende
: ReturnType<I['send']>;
// Transforms the provided schema to the correct type for the main event channel.
-type IpcMain<S extends Schema> = {
+export type IpcMain<S extends Schema> = {
[G in keyof S]: {
[K in keyof S[G] as IpcMainKey<string & K, S[G][K]>]: IpcMainFn<S[G][K]>;
};
};
// Transforms the provided schema to the correct type for the renderer event channel.
-type IpcRenderer<S extends Schema> = {
+export type IpcRenderer<S extends Schema> = {
[G in keyof S]: {
[K in keyof S[G] as IpcRendererKey<string & K, S[G][K]>]: IpcRendererFn<S[G][K]>;
};