diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2023-10-24 20:17:42 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2023-10-30 18:02:26 +0100 |
| commit | ea4b8a36c0eacdda848e1a1f3a8af388be026551 (patch) | |
| tree | 77c84523dc27512a50817c6979061c88e5117af3 /gui/src | |
| parent | 17de249b6b4ab6f417d9b3b97c9764a09170f2ba (diff) | |
| download | mullvadvpn-ea4b8a36c0eacdda848e1a1f3a8af388be026551.tar.xz mullvadvpn-ea4b8a36c0eacdda848e1a1f3a8af388be026551.zip | |
Move ref cast to hook
Diffstat (limited to 'gui/src')
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)), []); } |
