Fix slow Hosting Provider dialog (#7594)

* avoid portal perf pitfall

* add dep array
This commit is contained in:
Samuel Newman
2025-02-03 14:50:21 -08:00
committed by GitHub
parent 24a4ab2b0f
commit 083a5c9667
2 changed files with 197 additions and 162 deletions
+2 -2
View File
@@ -71,10 +71,10 @@ export function HostingProvider({
a.flex_row,
a.align_center,
a.rounded_sm,
a.px_md,
a.pl_md,
a.pr_sm,
a.gap_xs,
{paddingVertical: isAndroid ? 14 : 9},
{paddingVertical: isAndroid ? 14 : 8},
]}
onPress={onPressSelectService}>
{({hovered, pressed}) => {
+75 -40
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback, useImperativeHandle, useRef, useState} from 'react'
import {View} from 'react-native'
import {useWindowDimensions} from 'react-native'
import {msg, Trans} from '@lingui/macro'
@@ -24,28 +24,74 @@ export function ServerInputDialog({
control: Dialog.DialogOuterProps['control']
onSelect: (url: string) => void
}) {
const {height} = useWindowDimensions()
const formRef = useRef<DialogInnerRef>(null)
// persist these options between dialog open/close
const [fixedOption, setFixedOption] = useState(BSKY_SERVICE)
const [previousCustomAddress, setPreviousCustomAddress] = useState('')
const onClose = useCallback(() => {
const result = formRef.current?.getFormState()
if (result) {
onSelect(result)
if (result !== BSKY_SERVICE) {
setPreviousCustomAddress(result)
}
}
}, [onSelect])
return (
<Dialog.Outer
control={control}
onClose={onClose}
nativeOptions={{minHeight: height / 2}}>
<Dialog.Handle />
<DialogInner
formRef={formRef}
fixedOption={fixedOption}
setFixedOption={setFixedOption}
initialCustomAddress={previousCustomAddress}
/>
</Dialog.Outer>
)
}
type DialogInnerRef = {getFormState: () => string | null}
function DialogInner({
formRef,
fixedOption,
setFixedOption,
initialCustomAddress,
}: {
formRef: React.Ref<DialogInnerRef>
fixedOption: string
setFixedOption: (opt: string) => void
initialCustomAddress: string
}) {
const control = Dialog.useDialogContext()
const {_} = useLingui()
const t = useTheme()
const {height} = useWindowDimensions()
const {accounts} = useSession()
const {gtMobile} = useBreakpoints()
const [pdsAddressHistory, setPdsAddressHistory] = React.useState<string[]>(
const [customAddress, setCustomAddress] = useState(initialCustomAddress)
const [pdsAddressHistory, setPdsAddressHistory] = useState<string[]>(
persisted.get('pdsAddressHistory') || [],
)
const [fixedOption, setFixedOption] = React.useState([BSKY_SERVICE])
const [customAddress, setCustomAddress] = React.useState('')
const {accounts} = useSession()
const isFirstTimeUser = accounts.length === 0
const onClose = React.useCallback(() => {
useImperativeHandle(
formRef,
() => ({
getFormState: () => {
let url
if (fixedOption[0] === 'custom') {
if (fixedOption === 'custom') {
url = customAddress.trim().toLowerCase()
if (!url) {
return
return null
}
} else {
url = fixedOption[0]
url = fixedOption
}
if (!url.startsWith('http://') && !url.startsWith('https://')) {
if (url === 'localhost' || url.startsWith('localhost:')) {
@@ -55,7 +101,7 @@ export function ServerInputDialog({
}
}
if (fixedOption[0] === 'custom') {
if (fixedOption === 'custom') {
if (!pdsAddressHistory.includes(url)) {
const newHistory = [url, ...pdsAddressHistory.slice(0, 4)]
setPdsAddressHistory(newHistory)
@@ -63,21 +109,15 @@ export function ServerInputDialog({
}
}
onSelect(url)
}, [
fixedOption,
customAddress,
onSelect,
pdsAddressHistory,
setPdsAddressHistory,
])
return url
},
}),
[customAddress, fixedOption, pdsAddressHistory],
)
const isFirstTimeUser = accounts.length === 0
return (
<Dialog.Outer
control={control}
onClose={onClose}
nativeOptions={{minHeight: height / 2}}>
<Dialog.Handle />
<Dialog.ScrollableInner
accessibilityDescribedBy="dialog-description"
accessibilityLabelledBy="dialog-title">
@@ -87,34 +127,30 @@ export function ServerInputDialog({
</Text>
<ToggleButton.Group
label="Preferences"
values={fixedOption}
onChange={setFixedOption}>
values={[fixedOption]}
onChange={values => setFixedOption(values[0])}>
<ToggleButton.Button name={BSKY_SERVICE} label={_(msg`Bluesky`)}>
<ToggleButton.ButtonText>
{_(msg`Bluesky`)}
</ToggleButton.ButtonText>
<ToggleButton.ButtonText>{_(msg`Bluesky`)}</ToggleButton.ButtonText>
</ToggleButton.Button>
<ToggleButton.Button
testID="customSelectBtn"
name="custom"
label={_(msg`Custom`)}>
<ToggleButton.ButtonText>
{_(msg`Custom`)}
</ToggleButton.ButtonText>
<ToggleButton.ButtonText>{_(msg`Custom`)}</ToggleButton.ButtonText>
</ToggleButton.Button>
</ToggleButton.Group>
{fixedOption[0] === BSKY_SERVICE && isFirstTimeUser && (
{fixedOption === BSKY_SERVICE && isFirstTimeUser && (
<Admonition type="tip">
<Trans>
Bluesky is an open network where you can choose your own
provider. If you're new here, we recommend sticking with the
default Bluesky Social option.
Bluesky is an open network where you can choose your own provider.
If you're new here, we recommend sticking with the default Bluesky
Social option.
</Trans>
</Admonition>
)}
{fixedOption[0] === 'custom' && (
{fixedOption === 'custom' && (
<View
style={[
a.border,
@@ -195,6 +231,5 @@ export function ServerInputDialog({
</View>
</View>
</Dialog.ScrollableInner>
</Dialog.Outer>
)
}