diff options
| author | Hank <hank@mullvad.net> | 2022-10-07 14:58:03 +0200 |
|---|---|---|
| committer | Hank <hank@mullvad.net> | 2022-10-07 14:58:03 +0200 |
| commit | d5d97969cfc391a491c6aeb5c5826a95dcfa197a (patch) | |
| tree | 5fec81c49b93e722ddaada635a28e967e62bf344 /gui/src | |
| parent | e8ea2448b50d52026f3ccae7e84535911ea7b06b (diff) | |
| parent | 48cf534d6610161e5db730dc91d187da79494aa7 (diff) | |
| download | mullvadvpn-d5d97969cfc391a491c6aeb5c5826a95dcfa197a.tar.xz mullvadvpn-d5d97969cfc391a491c6aeb5c5826a95dcfa197a.zip | |
Merge branch 'update-packages'
Diffstat (limited to 'gui/src')
| -rw-r--r-- | gui/src/main/ipc-event-channel.ts | 6 | ||||
| -rw-r--r-- | gui/src/renderer/.eslintignore | 1 | ||||
| -rw-r--r-- | gui/src/renderer/.eslintrc.js | 5 | ||||
| -rw-r--r-- | gui/src/renderer/components/AppButton.tsx | 5 | ||||
| -rw-r--r-- | gui/src/renderer/components/ErrorBoundary.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/LocationList.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/Login.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/ProblemReport.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/ScopeBar.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/SvgMap.tsx | 10 | ||||
| -rw-r--r-- | gui/src/renderer/components/TransitionContainer.tsx | 1 | ||||
| -rw-r--r-- | gui/src/renderer/context.tsx | 25 | ||||
| -rw-r--r-- | gui/src/renderer/index.ts | 5 | ||||
| -rw-r--r-- | gui/src/shared/ipc-helpers.ts | 4 |
14 files changed, 33 insertions, 39 deletions
diff --git a/gui/src/main/ipc-event-channel.ts b/gui/src/main/ipc-event-channel.ts index d189634950..bae499910d 100644 --- a/gui/src/main/ipc-event-channel.ts +++ b/gui/src/main/ipc-event-channel.ts @@ -1,14 +1,14 @@ import { ipcMain, WebContents } from 'electron'; -import { createIpcMain, IpcMain, Schema } from '../shared/ipc-helpers'; +import { createIpcMain, IpcMain, Notifier, Schema } from '../shared/ipc-helpers'; import { ipcSchema } from '../shared/ipc-schema'; // 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]>) + [CK in keyof IpcMain<S>[GK]]: IpcMain<S>[GK][CK] extends Notifier<infer T> + ? undefined | ((arg: T) => ReturnType<IpcMain<S>[GK][CK]>) : IpcMain<S>[GK][CK]; }; }; diff --git a/gui/src/renderer/.eslintignore b/gui/src/renderer/.eslintignore deleted file mode 100644 index a9ba028cee..0000000000 --- a/gui/src/renderer/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -.eslintrc.js diff --git a/gui/src/renderer/.eslintrc.js b/gui/src/renderer/.eslintrc.js deleted file mode 100644 index c38aa97590..0000000000 --- a/gui/src/renderer/.eslintrc.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - env: { - browser: true, - }, -}; diff --git a/gui/src/renderer/components/AppButton.tsx b/gui/src/renderer/components/AppButton.tsx index a3edc78ad3..45c93e1b2a 100644 --- a/gui/src/renderer/components/AppButton.tsx +++ b/gui/src/renderer/components/AppButton.tsx @@ -54,7 +54,10 @@ const BaseButton = React.memo(function BaseButtonT(props: IProps) { if (groups.label === undefined && typeof child === 'string') { return { ...groups, label: <Label textOffset={textOffset}>{child}</Label> }; } else if (React.isValidElement(child) && child.type === Label) { - return { ...groups, label: React.cloneElement(child, { textOffset }) }; + return { + ...groups, + label: React.cloneElement(child as React.ReactElement<ILabelProps>, { textOffset }), + }; } else if (groups.label === undefined) { return { ...groups, left: [...groups.left, child] }; } else { diff --git a/gui/src/renderer/components/ErrorBoundary.tsx b/gui/src/renderer/components/ErrorBoundary.tsx index 7014175ffa..40615e44f4 100644 --- a/gui/src/renderer/components/ErrorBoundary.tsx +++ b/gui/src/renderer/components/ErrorBoundary.tsx @@ -33,7 +33,7 @@ export default class ErrorBoundary extends React.Component<IProps, IState> { public render() { if (this.state.hasError) { - const reachBackMessage: React.ReactNodeArray = + const reachBackMessage: React.ReactNode[] = // TRANSLATORS: The message displayed to the user in case of critical error in the GUI // TRANSLATORS: Available placeholders: // TRANSLATORS: %(email)s - support email diff --git a/gui/src/renderer/components/LocationList.tsx b/gui/src/renderer/components/LocationList.tsx index 729cb59f3c..19c3eca0a5 100644 --- a/gui/src/renderer/components/LocationList.tsx +++ b/gui/src/renderer/components/LocationList.tsx @@ -43,6 +43,7 @@ interface ILocationListProps<SpecialValueType> { selectedValue?: LocationSelection<SpecialValueType>; selectedElementRef?: React.Ref<React.ReactInstance>; onSelect?: (value: LocationSelection<SpecialValueType>) => void; + children?: React.ReactNode; } export default class LocationList<SpecialValueType> extends React.Component< @@ -244,6 +245,7 @@ interface ISpecialLocationProps<T> { onSelect?: (value: T) => void; info?: string; forwardedRef?: React.Ref<HTMLButtonElement>; + children?: React.ReactNode; } export class SpecialLocation<T> extends React.Component<ISpecialLocationProps<T>> { diff --git a/gui/src/renderer/components/Login.tsx b/gui/src/renderer/components/Login.tsx index 0b30b1c167..6c69074a0c 100644 --- a/gui/src/renderer/components/Login.tsx +++ b/gui/src/renderer/components/Login.tsx @@ -379,7 +379,7 @@ function AccountDropdownItem(props: IAccountDropdownItemProps) { }, [props.onSelect, props.value]); const handleRemove = useCallback( - (event) => { + (event: React.MouseEvent<HTMLButtonElement>) => { // Prevent login form from submitting event.preventDefault(); props.onRemove(props.value); diff --git a/gui/src/renderer/components/ProblemReport.tsx b/gui/src/renderer/components/ProblemReport.tsx index c2e501e109..aa89365fd5 100644 --- a/gui/src/renderer/components/ProblemReport.tsx +++ b/gui/src/renderer/components/ProblemReport.tsx @@ -385,7 +385,7 @@ export default class ProblemReport extends React.Component< } private renderSent() { - const reachBackMessage: React.ReactNodeArray = + const reachBackMessage: React.ReactNode[] = // TRANSLATORS: The message displayed to the user after submitting the problem report, given that the user left his or her email for us to reach back. // TRANSLATORS: Available placeholders: // TRANSLATORS: %(email)s diff --git a/gui/src/renderer/components/ScopeBar.tsx b/gui/src/renderer/components/ScopeBar.tsx index be5420b0b5..10b177c2c3 100644 --- a/gui/src/renderer/components/ScopeBar.tsx +++ b/gui/src/renderer/components/ScopeBar.tsx @@ -16,7 +16,7 @@ interface IScopeBarProps { defaultSelectedIndex?: number; onChange?: (selectedIndex: number) => void; className?: string; - children: React.ReactNode; + children: React.ReactElement<IScopeBarItemProps>[]; } export function ScopeBar(props: IScopeBarProps) { diff --git a/gui/src/renderer/components/SvgMap.tsx b/gui/src/renderer/components/SvgMap.tsx index 00745bede2..680facb558 100644 --- a/gui/src/renderer/components/SvgMap.tsx +++ b/gui/src/renderer/components/SvgMap.tsx @@ -1,5 +1,5 @@ import { geoMercator, GeoProjection } from 'd3-geo'; -import rbush from 'rbush'; +import RBush, { BBox as RBushBBox } from 'rbush'; import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import { ComposableMap, Geographies, Geography, Marker } from 'react-simple-maps'; @@ -8,16 +8,16 @@ import geometryTreeData from '../../../assets/geo/geometry.rbush.json'; import statesProvincesLinesData from '../../../assets/geo/states-provinces-lines.json'; import statesProvincesLinesTreeData from '../../../assets/geo/states-provinces-lines.rbush.json'; -interface IGeometryLeaf extends rbush.BBox { +interface IGeometryLeaf extends RBushBBox { id: string; } -interface IProvinceAndStateLineLeaf extends rbush.BBox { +interface IProvinceAndStateLineLeaf extends RBushBBox { id: string; } -const geometryTree = rbush<IGeometryLeaf>().fromJSON(geometryTreeData); -const provincesStatesLinesTree = rbush<IProvinceAndStateLineLeaf>().fromJSON( +const geometryTree = new RBush<IGeometryLeaf>().fromJSON(geometryTreeData); +const provincesStatesLinesTree = new RBush<IProvinceAndStateLineLeaf>().fromJSON( statesProvincesLinesTreeData, ); diff --git a/gui/src/renderer/components/TransitionContainer.tsx b/gui/src/renderer/components/TransitionContainer.tsx index 22ef1665eb..5fbfe61a55 100644 --- a/gui/src/renderer/components/TransitionContainer.tsx +++ b/gui/src/renderer/components/TransitionContainer.tsx @@ -6,6 +6,7 @@ import { WillExit } from '../lib/will-exit'; interface ITransitioningViewProps { viewId: string; + children?: React.ReactNode; } type TransitioningView = React.ReactElement<ITransitioningViewProps>; diff --git a/gui/src/renderer/context.tsx b/gui/src/renderer/context.tsx index 0867618136..3b5fcc14fb 100644 --- a/gui/src/renderer/context.tsx +++ b/gui/src/renderer/context.tsx @@ -15,24 +15,15 @@ const missingContextError = new Error( 'The context value is empty. Make sure to wrap the component in AppContext.Provider.', ); -export default function withAppContext<Props>(BaseComponent: React.ComponentType<Props>) { - // Exclude the IAppContext from props since those are injected props - const wrappedComponent = (props: Omit<Props, keyof IAppContext>) => { - return ( - <AppContext.Consumer> - {(context) => { - if (context) { - // Enforce type because Typescript does not recognize that - // (Props ~ IAppContext & IAppContext) is identical to Props. - const mergedProps = ({ ...props, ...context } as unknown) as Props; +type PropsWithoutAppContext<Props> = Omit<Props, 'app'>; - return <BaseComponent {...mergedProps} />; - } else { - throw missingContextError; - } - }} - </AppContext.Consumer> - ); +export default function withAppContext<Props>( + BaseComponent: React.ComponentType<PropsWithoutAppContext<Props> & IAppContext>, +) { + // Exclude the IAppContext from props since those are injected props + const wrappedComponent = (props: PropsWithoutAppContext<Props>) => { + const appContext = useAppContext(); + return <BaseComponent app={appContext} {...props} />; }; if (window.env.development) { diff --git a/gui/src/renderer/index.ts b/gui/src/renderer/index.ts index 815095408f..fbf8ebcdba 100644 --- a/gui/src/renderer/index.ts +++ b/gui/src/renderer/index.ts @@ -1,7 +1,8 @@ -import ReactDOM from 'react-dom'; +import { createRoot } from 'react-dom/client'; import App from './app'; const app = new App(); const container = document.getElementById('app'); -ReactDOM.render(app.renderView(), container); +const root = createRoot(container!); +root.render(app.renderView()); diff --git a/gui/src/shared/ipc-helpers.ts b/gui/src/shared/ipc-helpers.ts index 1680b45d11..fda5c2d3b5 100644 --- a/gui/src/shared/ipc-helpers.ts +++ b/gui/src/shared/ipc-helpers.ts @@ -5,7 +5,9 @@ import { capitalize } from './string-helpers'; type Handler<T, R> = (callback: (arg: T) => R) => void; type Sender<T, R> = (arg: T) => R; -type Notifier<T> = (webContents: WebContents | undefined, arg: T) => void; +// Remove export after upgrading to Electron 21+ and removal of code to curry notifiers with +// webContents in ../main/ipc-event-channel.ts. +export type Notifier<T> = (webContents: WebContents | undefined, arg: T) => void; type Listener<T> = (callback: (arg: T) => void) => void; interface MainToRenderer<T> { |
