Skip to content

Commit

Permalink
avoid portal perf pitfall
Browse files Browse the repository at this point in the history
  • Loading branch information
mozzius committed Jan 26, 2025
1 parent 355c50f commit 5ca3b96
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 158 deletions.
4 changes: 2 additions & 2 deletions src/components/forms/HostingProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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}) => {
Expand Down
343 changes: 187 additions & 156 deletions src/view/com/auth/server-input/index.tsx
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -24,177 +24,208 @@ 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(() => {
let url
if (fixedOption[0] === 'custom') {
url = customAddress.trim().toLowerCase()
if (!url) {
return
}
} else {
url = fixedOption[0]
}
if (!url.startsWith('http://') && !url.startsWith('https://')) {
if (url === 'localhost' || url.startsWith('localhost:')) {
url = `http://${url}`
useImperativeHandle(formRef, () => ({
getFormState: () => {
let url
if (fixedOption === 'custom') {
url = customAddress.trim().toLowerCase()
if (!url) {
return null
}
} else {
url = `https://${url}`
url = fixedOption
}
if (!url.startsWith('http://') && !url.startsWith('https://')) {
if (url === 'localhost' || url.startsWith('localhost:')) {
url = `http://${url}`
} else {
url = `https://${url}`
}
}
}

if (fixedOption[0] === 'custom') {
if (!pdsAddressHistory.includes(url)) {
const newHistory = [url, ...pdsAddressHistory.slice(0, 4)]
setPdsAddressHistory(newHistory)
persisted.write('pdsAddressHistory', newHistory)
if (fixedOption === 'custom') {
if (!pdsAddressHistory.includes(url)) {
const newHistory = [url, ...pdsAddressHistory.slice(0, 4)]
setPdsAddressHistory(newHistory)
persisted.write('pdsAddressHistory', newHistory)
}
}
}

onSelect(url)
}, [
fixedOption,
customAddress,
onSelect,
pdsAddressHistory,
setPdsAddressHistory,
])
return url
},
}))

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">
<View style={[a.relative, a.gap_md, a.w_full]}>
<Text nativeID="dialog-title" style={[a.text_2xl, a.font_bold]}>
<Trans>Choose your account provider</Trans>
</Text>
<ToggleButton.Group
label="Preferences"
values={fixedOption}
onChange={setFixedOption}>
<ToggleButton.Button name={BSKY_SERVICE} label={_(msg`Bluesky`)}>
<ToggleButton.ButtonText>
{_(msg`Bluesky`)}
</ToggleButton.ButtonText>
</ToggleButton.Button>
<ToggleButton.Button
testID="customSelectBtn"
name="custom"
label={_(msg`Custom`)}>
<ToggleButton.ButtonText>
{_(msg`Custom`)}
</ToggleButton.ButtonText>
</ToggleButton.Button>
</ToggleButton.Group>

{fixedOption[0] === BSKY_SERVICE && isFirstTimeUser && (
<Admonition type="tip">
<Dialog.ScrollableInner
accessibilityDescribedBy="dialog-description"
accessibilityLabelledBy="dialog-title">
<View style={[a.relative, a.gap_md, a.w_full]}>
<Text nativeID="dialog-title" style={[a.text_2xl, a.font_bold]}>
<Trans>Choose your account provider</Trans>
</Text>
<ToggleButton.Group
label="Preferences"
values={[fixedOption]}
onChange={values => setFixedOption(values[0])}>
<ToggleButton.Button name={BSKY_SERVICE} label={_(msg`Bluesky`)}>
<ToggleButton.ButtonText>{_(msg`Bluesky`)}</ToggleButton.ButtonText>
</ToggleButton.Button>
<ToggleButton.Button
testID="customSelectBtn"
name="custom"
label={_(msg`Custom`)}>
<ToggleButton.ButtonText>{_(msg`Custom`)}</ToggleButton.ButtonText>
</ToggleButton.Button>
</ToggleButton.Group>

{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.
</Trans>
</Admonition>
)}

{fixedOption === 'custom' && (
<View
style={[
a.border,
t.atoms.border_contrast_low,
a.rounded_sm,
a.px_md,
a.py_md,
]}>
<TextField.LabelText nativeID="address-input-label">
<Trans>Server address</Trans>
</TextField.LabelText>
<TextField.Root>
<TextField.Icon icon={Globe} />
<Dialog.Input
testID="customServerTextInput"
value={customAddress}
onChangeText={setCustomAddress}
label="my-server.com"
accessibilityLabelledBy="address-input-label"
autoCapitalize="none"
keyboardType="url"
/>
</TextField.Root>
{pdsAddressHistory.length > 0 && (
<View style={[a.flex_row, a.flex_wrap, a.mt_xs]}>
{pdsAddressHistory.map(uri => (
<Button
key={uri}
variant="ghost"
color="primary"
label={uri}
style={[a.px_sm, a.py_xs, a.rounded_sm, a.gap_sm]}
onPress={() => setCustomAddress(uri)}>
<ButtonText>{uri}</ButtonText>
</Button>
))}
</View>
)}
</View>
)}

<View style={[a.py_xs]}>
<P
style={[
t.atoms.text_contrast_medium,
a.text_sm,
a.leading_snug,
a.flex_1,
]}>
{isFirstTimeUser ? (
<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.
If you're a developer, you can host your own server.
</Trans>
</Admonition>
)}

{fixedOption[0] === 'custom' && (
<View
style={[
a.border,
t.atoms.border_contrast_low,
a.rounded_sm,
a.px_md,
a.py_md,
]}>
<TextField.LabelText nativeID="address-input-label">
<Trans>Server address</Trans>
</TextField.LabelText>
<TextField.Root>
<TextField.Icon icon={Globe} />
<Dialog.Input
testID="customServerTextInput"
value={customAddress}
onChangeText={setCustomAddress}
label="my-server.com"
accessibilityLabelledBy="address-input-label"
autoCapitalize="none"
keyboardType="url"
/>
</TextField.Root>
{pdsAddressHistory.length > 0 && (
<View style={[a.flex_row, a.flex_wrap, a.mt_xs]}>
{pdsAddressHistory.map(uri => (
<Button
key={uri}
variant="ghost"
color="primary"
label={uri}
style={[a.px_sm, a.py_xs, a.rounded_sm, a.gap_sm]}
onPress={() => setCustomAddress(uri)}>
<ButtonText>{uri}</ButtonText>
</Button>
))}
</View>
)}
</View>
)}

<View style={[a.py_xs]}>
<P
style={[
t.atoms.text_contrast_medium,
a.text_sm,
a.leading_snug,
a.flex_1,
]}>
{isFirstTimeUser ? (
<Trans>
If you're a developer, you can host your own server.
</Trans>
) : (
<Trans>
Bluesky is an open network where you can choose your hosting
provider. If you're a developer, you can host your own server.
</Trans>
)}{' '}
<InlineLinkText
label={_(msg`Learn more about self hosting your PDS.`)}
to="https://atproto.com/guides/self-hosting">
<Trans>Learn more.</Trans>
</InlineLinkText>
</P>
</View>
) : (
<Trans>
Bluesky is an open network where you can choose your hosting
provider. If you're a developer, you can host your own server.
</Trans>
)}{' '}
<InlineLinkText
label={_(msg`Learn more about self hosting your PDS.`)}
to="https://atproto.com/guides/self-hosting">
<Trans>Learn more.</Trans>
</InlineLinkText>
</P>
</View>

<View style={gtMobile && [a.flex_row, a.justify_end]}>
<Button
testID="doneBtn"
variant="outline"
color="primary"
size="small"
onPress={() => control.close()}
label={_(msg`Done`)}>
<ButtonText>{_(msg`Done`)}</ButtonText>
</Button>
</View>
<View style={gtMobile && [a.flex_row, a.justify_end]}>
<Button
testID="doneBtn"
variant="outline"
color="primary"
size="small"
onPress={() => control.close()}
label={_(msg`Done`)}>
<ButtonText>{_(msg`Done`)}</ButtonText>
</Button>
</View>
</Dialog.ScrollableInner>
</Dialog.Outer>
</View>
</Dialog.ScrollableInner>
)
}

0 comments on commit 5ca3b96

Please sign in to comment.