diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2021-11-19 15:38:15 +0100 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2021-11-23 15:38:23 +0100 |
| commit | eb6292bf3ad39d75672fc99b82e45318e5f34125 (patch) | |
| tree | f8ef07f59cc7ba18b331ad7c2668cefeea53dd49 | |
| parent | 2a45478095df7fae4dcebed362dfed66af17f1b7 (diff) | |
| download | mullvadvpn-eb6292bf3ad39d75672fc99b82e45318e5f34125.tar.xz mullvadvpn-eb6292bf3ad39d75672fc99b82e45318e5f34125.zip | |
Use list component in CustomDnsSettings
| -rw-r--r-- | gui/src/renderer/components/CustomDnsSettings.tsx | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/gui/src/renderer/components/CustomDnsSettings.tsx b/gui/src/renderer/components/CustomDnsSettings.tsx index a6f409ea5c..c0d1a66f5c 100644 --- a/gui/src/renderer/components/CustomDnsSettings.tsx +++ b/gui/src/renderer/components/CustomDnsSettings.tsx @@ -1,10 +1,10 @@ -import React, { useCallback, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { sprintf } from 'sprintf-js'; import { colors } from '../../config.json'; import { messages } from '../../shared/gettext'; import { useAppContext } from '../context'; import { IpAddress } from '../lib/ip'; -import { useBoolean } from '../lib/utilityHooks'; +import { useBoolean, useMounted } from '../lib/utilityHooks'; import { formatMarkdown } from '../markdown-formatter'; import { useSelector } from '../redux/store'; import Accordion from './Accordion'; @@ -29,6 +29,7 @@ import { StyledRemoveButton, StyledRemoveIcon, } from './CustomDnsSettingsStyles'; +import List, { stringValueAsKey } from './List'; import { ModalAlert, ModalAlertType } from './Modal'; export default function CustomDnsSettings() { @@ -38,6 +39,7 @@ export default function CustomDnsSettings() { const [inputVisible, showInput, hideInput] = useBoolean(false); const [invalid, setInvalid, setValid] = useBoolean(false); const [confirmAction, setConfirmAction] = useState<() => Promise<void>>(); + const [savingEdit, setSavingEdit] = useState(false); const willShowConfirmationDialog = useRef(false); const featureAvailable = useMemo( @@ -135,6 +137,8 @@ export default function CustomDnsSettings() { } const edit = async () => { + setSavingEdit(true); + const addresses = dns.customOptions.addresses.map((address) => oldAddress === address ? newAddress : address, ); @@ -177,6 +181,8 @@ export default function CustomDnsSettings() { [dns, setDnsOptions], ); + useEffect(() => setSavingEdit(false), [dns.customOptions.addresses]); + return ( <> <StyledCustomDnsSwitchContainer disabled={!featureAvailable}> @@ -197,17 +203,20 @@ export default function CustomDnsSettings() { </StyledCustomDnsSwitchContainer> <Accordion expanded={featureAvailable && (dns.state === 'custom' || inputVisible)}> <Cell.Section role="listbox"> - {dns.customOptions.addresses.map((item, i) => { - return ( + <List + items={dns.customOptions.addresses} + getKey={stringValueAsKey} + skipAddTransition={true} + skipRemoveTransition={savingEdit}> + {(item) => ( <CellListItem - key={i} onRemove={onRemove} onChange={onEdit} willShowConfirmationDialog={willShowConfirmationDialog}> {item} </CellListItem> - ); - })} + )} + </List> </Cell.Section> {inputVisible && ( @@ -294,6 +303,7 @@ interface ICellListItemProps { function CellListItem(props: ICellListItemProps) { const [editing, startEditing, stopEditing] = useBoolean(false); const [invalid, setInvalid, setValid] = useBoolean(false); + const isMounted = useMounted(); const inputContainerRef = useRef() as React.RefObject<HTMLDivElement>; @@ -309,7 +319,9 @@ function CellListItem(props: ICellListItemProps) { } else { try { await props.onChange(props.children, value); - stopEditing(); + if (isMounted()) { + stopEditing(); + } } catch { setInvalid(); } |
