summaryrefslogtreecommitdiffhomepage
path: root/gui
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2023-10-24 20:17:42 +0200
committerOskar Nyberg <oskar@mullvad.net>2023-10-30 18:02:26 +0100
commitea4b8a36c0eacdda848e1a1f3a8af388be026551 (patch)
tree77c84523dc27512a50817c6979061c88e5117af3 /gui
parent17de249b6b4ab6f417d9b3b97c9764a09170f2ba (diff)
downloadmullvadvpn-ea4b8a36c0eacdda848e1a1f3a8af388be026551.tar.xz
mullvadvpn-ea4b8a36c0eacdda848e1a1f3a8af388be026551.zip
Move ref cast to hook
Diffstat (limited to 'gui')
-rw-r--r--gui/src/renderer/components/CustomDnsSettings.tsx10
-rw-r--r--gui/src/renderer/components/FormattableTextInput.tsx6
-rw-r--r--gui/src/renderer/components/MacOsScrollbarDetection.tsx5
-rw-r--r--gui/src/renderer/components/NotificationBanner.tsx3
-rw-r--r--gui/src/renderer/components/SearchBar.tsx5
-rw-r--r--gui/src/renderer/components/SplitTunnelingSettings.tsx6
-rw-r--r--gui/src/renderer/components/cell/Input.tsx10
-rw-r--r--gui/src/renderer/components/cell/Selector.tsx3
-rw-r--r--gui/src/renderer/components/select-location/CustomLists.tsx8
-rw-r--r--gui/src/renderer/components/select-location/LocationRow.tsx4
-rw-r--r--gui/src/renderer/components/select-location/ScrollPositionContext.tsx4
-rw-r--r--gui/src/renderer/lib/utilityHooks.ts4
12 files changed, 38 insertions, 30 deletions
diff --git a/gui/src/renderer/components/CustomDnsSettings.tsx b/gui/src/renderer/components/CustomDnsSettings.tsx
index 824e010970..6b8024c9e2 100644
--- a/gui/src/renderer/components/CustomDnsSettings.tsx
+++ b/gui/src/renderer/components/CustomDnsSettings.tsx
@@ -6,7 +6,7 @@ import { messages } from '../../shared/gettext';
import { useAppContext } from '../context';
import { formatHtml } from '../lib/html-formatter';
import { IpAddress } from '../lib/ip';
-import { useBoolean, useMounted } from '../lib/utilityHooks';
+import { useBoolean, useMounted, useStyledRef } from '../lib/utilityHooks';
import { useSelector } from '../redux/store';
import Accordion from './Accordion';
import * as AppButton from './AppButton';
@@ -57,9 +57,9 @@ export default function CustomDnsSettings() {
[dns],
);
- const switchRef = useRef() as React.RefObject<HTMLDivElement>;
- const addButtonRef = useRef() as React.RefObject<HTMLButtonElement>;
- const inputContainerRef = useRef() as React.RefObject<HTMLDivElement>;
+ const switchRef = useStyledRef<HTMLDivElement>();
+ const addButtonRef = useStyledRef<HTMLButtonElement>();
+ const inputContainerRef = useStyledRef<HTMLDivElement>();
const confirm = useCallback(() => {
void confirmAction?.();
@@ -323,7 +323,7 @@ function CellListItem(props: ICellListItemProps) {
const [invalid, setInvalid, setValid] = useBoolean(false);
const isMounted = useMounted();
- const inputContainerRef = useRef() as React.RefObject<HTMLDivElement>;
+ const inputContainerRef = useStyledRef<HTMLDivElement>();
const onRemove = useCallback(() => props.onRemove(props.children), [
props.onRemove,
diff --git a/gui/src/renderer/components/FormattableTextInput.tsx b/gui/src/renderer/components/FormattableTextInput.tsx
index 133a6692e0..f6c259c4c4 100644
--- a/gui/src/renderer/components/FormattableTextInput.tsx
+++ b/gui/src/renderer/components/FormattableTextInput.tsx
@@ -1,6 +1,6 @@
-import React, { useCallback, useEffect, useRef } from 'react';
+import React, { useCallback, useEffect } from 'react';
-import { useCombinedRefs } from '../lib/utilityHooks';
+import { useCombinedRefs, useStyledRef } from '../lib/utilityHooks';
interface IFormattableTextInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
allowedCharacters: string;
@@ -28,7 +28,7 @@ function FormattableTextInput(
...otherProps
} = props;
- const ref = useRef() as React.RefObject<HTMLInputElement>;
+ const ref = useStyledRef<HTMLInputElement>();
const combinedRef = useCombinedRefs(ref, forwardedRef);
const unformat = useCallback(
diff --git a/gui/src/renderer/components/MacOsScrollbarDetection.tsx b/gui/src/renderer/components/MacOsScrollbarDetection.tsx
index de636827bd..aebb144f9b 100644
--- a/gui/src/renderer/components/MacOsScrollbarDetection.tsx
+++ b/gui/src/renderer/components/MacOsScrollbarDetection.tsx
@@ -1,8 +1,9 @@
-import React, { useEffect, useRef } from 'react';
+import { useEffect } from 'react';
import styled from 'styled-components';
import { MacOsScrollbarVisibility } from '../../shared/ipc-schema';
import useActions from '../lib/actionsHook';
+import { useStyledRef } from '../lib/utilityHooks';
import { useSelector } from '../redux/store';
import userInterface from '../redux/userinterface/actions';
@@ -21,7 +22,7 @@ const StyledContainer = styled.div({
export default function MacOsScrollbarDetection() {
const visibility = useSelector((state) => state.userInterface.macOsScrollbarVisibility);
const { setMacOsScrollbarVisibility } = useActions(userInterface);
- const ref = useRef() as React.RefObject<HTMLDivElement>;
+ const ref = useStyledRef<HTMLDivElement>();
useEffect(() => {
if (visibility === MacOsScrollbarVisibility.automatic) {
diff --git a/gui/src/renderer/components/NotificationBanner.tsx b/gui/src/renderer/components/NotificationBanner.tsx
index 18e18ce4f5..0c63d3ba2d 100644
--- a/gui/src/renderer/components/NotificationBanner.tsx
+++ b/gui/src/renderer/components/NotificationBanner.tsx
@@ -4,6 +4,7 @@ import styled from 'styled-components';
import { colors } from '../../config.json';
import { messages } from '../../shared/gettext';
import { InAppNotificationIndicatorType } from '../../shared/notifications/notification';
+import { useStyledRef } from '../lib/utilityHooks';
import * as AppButton from './AppButton';
import { tinyText } from './common-styles';
import ImageView from './ImageView';
@@ -156,7 +157,7 @@ export function NotificationBanner(props: INotificationBannerProps) {
const [contentHeight, setContentHeight] = useState<number>();
const [alignBottom, setAlignBottom] = useState(false);
- const contentRef = useRef() as React.RefObject<HTMLDivElement>;
+ const contentRef = useStyledRef<HTMLDivElement>();
// Save last non-undefined children to be able to show them during the hide-transition.
const prevChildren = useRef<React.ReactNode>();
diff --git a/gui/src/renderer/components/SearchBar.tsx b/gui/src/renderer/components/SearchBar.tsx
index 7983441ed8..fbe7d3573a 100644
--- a/gui/src/renderer/components/SearchBar.tsx
+++ b/gui/src/renderer/components/SearchBar.tsx
@@ -1,8 +1,9 @@
-import { useCallback, useEffect, useRef } from 'react';
+import { useCallback, useEffect } from 'react';
import styled from 'styled-components';
import { colors } from '../../config.json';
import { messages } from '../../shared/gettext';
+import { useStyledRef } from '../lib/utilityHooks';
import { normalText } from './common-styles';
import ImageView from './ImageView';
@@ -73,7 +74,7 @@ interface ISearchBarProps {
}
export default function SearchBar(props: ISearchBarProps) {
- const inputRef = useRef() as React.RefObject<HTMLInputElement>;
+ const inputRef = useStyledRef<HTMLInputElement>();
const onInput = useCallback(
(event: React.FormEvent) => {
diff --git a/gui/src/renderer/components/SplitTunnelingSettings.tsx b/gui/src/renderer/components/SplitTunnelingSettings.tsx
index 9b674df4fc..aa1f82b2fc 100644
--- a/gui/src/renderer/components/SplitTunnelingSettings.tsx
+++ b/gui/src/renderer/components/SplitTunnelingSettings.tsx
@@ -1,4 +1,4 @@
-import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useSelector } from 'react-redux';
import { sprintf } from 'sprintf-js';
@@ -12,7 +12,7 @@ import { messages } from '../../shared/gettext';
import { useAppContext } from '../context';
import { useHistory } from '../lib/history';
import { formatHtml } from '../lib/html-formatter';
-import { useAsyncEffect } from '../lib/utilityHooks';
+import { useAsyncEffect, useStyledRef } from '../lib/utilityHooks';
import { IReduxState } from '../redux/store';
import Accordion from './Accordion';
import * as AppButton from './AppButton';
@@ -49,7 +49,7 @@ import Switch from './Switch';
export default function SplitTunneling() {
const { pop } = useHistory();
const [browsing, setBrowsing] = useState(false);
- const scrollbarsRef = useRef() as React.RefObject<CustomScrollbarsRef>;
+ const scrollbarsRef = useStyledRef<CustomScrollbarsRef>();
const scrollToTop = useCallback(() => scrollbarsRef.current?.scrollToTop(true), [scrollbarsRef]);
diff --git a/gui/src/renderer/components/cell/Input.tsx b/gui/src/renderer/components/cell/Input.tsx
index bff8364d21..55260f6703 100644
--- a/gui/src/renderer/components/cell/Input.tsx
+++ b/gui/src/renderer/components/cell/Input.tsx
@@ -1,8 +1,8 @@
-import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
+import React, { useCallback, useContext, useEffect, useState } from 'react';
import styled from 'styled-components';
import { colors } from '../../../config.json';
-import { useBoolean, useCombinedRefs } from '../../lib/utilityHooks';
+import { useBoolean, useCombinedRefs, useStyledRef } from '../../lib/utilityHooks';
import { normalText } from '../common-styles';
import ImageView from '../ImageView';
import { BackAction } from '../KeyboardNavigation';
@@ -68,7 +68,7 @@ function InputWithRef(props: IInputProps, forwardedRef: React.Ref<HTMLInputEleme
const [internalValue, setInternalValue] = useState(props.value ?? props.initialValue ?? '');
const value = props.value ?? internalValue;
- const inputRef = useRef() as React.RefObject<HTMLInputElement>;
+ const inputRef = useStyledRef<HTMLInputElement>();
const combinedRef = useCombinedRefs(inputRef, forwardedRef);
const onSubmit = useCallback(
@@ -197,7 +197,7 @@ function AutoSizingTextInputWithRef(props: IInputProps, forwardedRef: React.Ref<
const { onFocus, onBlur, ...otherProps } = props;
const [focused, setFocused, setBlurred] = useBoolean(false);
- const inputRef = useRef() as React.RefObject<HTMLInputElement>;
+ const inputRef = useStyledRef<HTMLInputElement>();
const combinedRef = useCombinedRefs(inputRef, forwardedRef);
const onBlurWrapper = useCallback(
@@ -304,7 +304,7 @@ interface IRowInputProps {
export function RowInput(props: IRowInputProps) {
const [value, setValue] = useState(props.initialValue ?? '');
- const textAreaRef = useRef() as React.RefObject<HTMLTextAreaElement>;
+ const textAreaRef = useStyledRef<HTMLTextAreaElement>();
const [focused, setFocused, setBlurred] = useBoolean(false);
const submit = useCallback(() => props.onSubmit(value), [props.onSubmit, value]);
diff --git a/gui/src/renderer/components/cell/Selector.tsx b/gui/src/renderer/components/cell/Selector.tsx
index 5eb9762eb3..0842ce2c0e 100644
--- a/gui/src/renderer/components/cell/Selector.tsx
+++ b/gui/src/renderer/components/cell/Selector.tsx
@@ -3,6 +3,7 @@ import styled from 'styled-components';
import { colors } from '../../../config.json';
import { messages } from '../../../shared/gettext';
+import { useStyledRef } from '../../lib/utilityHooks';
import { AriaDetails, AriaInput, AriaLabel } from '../AriaGroup';
import { normalText } from '../common-styles';
import InfoButton from '../InfoButton';
@@ -212,7 +213,7 @@ export function SelectorWithCustomItem<T, U>(props: SelectorWithCustomItemProps<
const [customValue, setCustomValue] = useState(itemIsSelected ? undefined : `${value}`);
const customIsSelected = customValue !== undefined;
- const inputRef = useRef() as React.RefObject<HTMLInputElement>;
+ const inputRef = useStyledRef<HTMLInputElement>();
const handleClickCustom = useCallback(() => {
inputRef.current?.focus();
diff --git a/gui/src/renderer/components/select-location/CustomLists.tsx b/gui/src/renderer/components/select-location/CustomLists.tsx
index b87de1fe46..358070ae46 100644
--- a/gui/src/renderer/components/select-location/CustomLists.tsx
+++ b/gui/src/renderer/components/select-location/CustomLists.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useEffect, useRef, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';
import { colors } from '../../../config.json';
@@ -6,7 +6,7 @@ import { CustomListError, CustomLists, RelayLocation } from '../../../shared/dae
import { messages } from '../../../shared/gettext';
import log from '../../../shared/logging';
import { useAppContext } from '../../context';
-import { useBoolean } from '../../lib/utilityHooks';
+import { useBoolean, useStyledRef } from '../../lib/utilityHooks';
import Accordion from '../Accordion';
import * as Cell from '../cell';
import { measurements } from '../common-styles';
@@ -118,8 +118,8 @@ interface AddListFormProps {
function AddListForm(props: AddListFormProps) {
const [name, setName] = useState('');
const [error, setError, unsetError] = useBoolean();
- const containerRef = useRef<HTMLDivElement>() as React.RefObject<HTMLDivElement>;
- const inputRef = useRef<HTMLInputElement>() as React.RefObject<HTMLInputElement>;
+ const containerRef = useStyledRef<HTMLDivElement>();
+ const inputRef = useStyledRef<HTMLInputElement>();
// Errors should be reset when editing the value
const onChange = useCallback((value: string) => {
diff --git a/gui/src/renderer/components/select-location/LocationRow.tsx b/gui/src/renderer/components/select-location/LocationRow.tsx
index 514fd19207..7ebae688a6 100644
--- a/gui/src/renderer/components/select-location/LocationRow.tsx
+++ b/gui/src/renderer/components/select-location/LocationRow.tsx
@@ -11,7 +11,7 @@ import {
import { messages } from '../../../shared/gettext';
import log from '../../../shared/logging';
import { useAppContext } from '../../context';
-import { useBoolean } from '../../lib/utilityHooks';
+import { useBoolean, useStyledRef } from '../../lib/utilityHooks';
import { useSelector } from '../../redux/store';
import Accordion from '../Accordion';
import * as Cell from '../cell';
@@ -152,7 +152,7 @@ interface IProps<C extends LocationSpecification> {
// Renders the rows and its children for countries, cities and relays
function LocationRow<C extends LocationSpecification>(props: IProps<C>) {
const hasChildren = getLocationChildren(props.source).some((child) => child.visible);
- const buttonRef = useRef<HTMLButtonElement>() as React.RefObject<HTMLButtonElement>;
+ const buttonRef = useStyledRef<HTMLButtonElement>();
const userInvokedExpand = useRef(false);
const { updateCustomList, deleteCustomList } = useAppContext();
diff --git a/gui/src/renderer/components/select-location/ScrollPositionContext.tsx b/gui/src/renderer/components/select-location/ScrollPositionContext.tsx
index 973e4484b6..04fcd0bccc 100644
--- a/gui/src/renderer/components/select-location/ScrollPositionContext.tsx
+++ b/gui/src/renderer/components/select-location/ScrollPositionContext.tsx
@@ -1,6 +1,6 @@
import React, { useCallback, useContext, useEffect, useMemo, useRef } from 'react';
-import { useNormalRelaySettings } from '../../lib/utilityHooks';
+import { useNormalRelaySettings, useStyledRef } from '../../lib/utilityHooks';
import { CustomScrollbarsRef } from '../CustomScrollbars';
import { LocationType } from './select-location-types';
import { useSelectLocationContext } from './SelectLocationContainer';
@@ -39,7 +39,7 @@ export function ScrollPositionContextProvider(props: ScrollPositionContextProps)
const scrollPositions = useRef<Partial<Record<LocationType, ScrollPosition>>>({});
const scrollViewRef = useRef<CustomScrollbarsRef>(null);
- const spacePreAllocationViewRef = useRef() as React.RefObject<SpacePreAllocationView>;
+ const spacePreAllocationViewRef = useStyledRef<SpacePreAllocationView>();
const selectedLocationRef = useRef<HTMLDivElement>(null);
const saveScrollPosition = useCallback(() => {
diff --git a/gui/src/renderer/lib/utilityHooks.ts b/gui/src/renderer/lib/utilityHooks.ts
index 378a6d5ae5..49f508a883 100644
--- a/gui/src/renderer/lib/utilityHooks.ts
+++ b/gui/src/renderer/lib/utilityHooks.ts
@@ -16,6 +16,10 @@ export function useMounted() {
return isMounted;
}
+export function useStyledRef<T>(): React.RefObject<T> {
+ return useRef() as React.RefObject<T>;
+}
+
export function useCombinedRefs<T>(...refs: (React.Ref<T> | undefined)[]): React.RefCallback<T> {
return useCallback((element: T | null) => refs.forEach((ref) => assignToRef(element, ref)), []);
}