diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-08-05 11:06:54 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-08-22 08:34:37 +0200 |
| commit | 5890d65e59919356fd257e2a8d21630ec5cc7260 (patch) | |
| tree | 891be8fc28c3456c515e4d69894d930559117ea7 /gui | |
| parent | b9100181bee6e6cd02e5f41d0ff06aad20c3e083 (diff) | |
| download | mullvadvpn-5890d65e59919356fd257e2a8d21630ec5cc7260.tar.xz mullvadvpn-5890d65e59919356fd257e2a8d21630ec5cc7260.zip | |
Curry IpcMainEventChannel functions with WebContents where applicable
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/src/main/ipc-event-channel.ts | 48 | ||||
| -rw-r--r-- | gui/src/shared/ipc-helpers.ts | 6 |
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]>; }; |
