mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import React from 'react'
2import {View} from 'react-native'
3import {msg, Trans} from '@lingui/macro'
4import {useLingui} from '@lingui/react'
5
6import * as persisted from '#/state/persisted'
7import {BSKY_SERVICE} from 'lib/constants'
8import {atoms as a, useBreakpoints, useTheme} from '#/alf'
9import {Button, ButtonText} from '#/components/Button'
10import * as Dialog from '#/components/Dialog'
11import * as TextField from '#/components/forms/TextField'
12import * as ToggleButton from '#/components/forms/ToggleButton'
13import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
14import {P, Text} from '#/components/Typography'
15
16export function ServerInputDialog({
17 control,
18 onSelect,
19}: {
20 control: Dialog.DialogOuterProps['control']
21 onSelect: (url: string) => void
22}) {
23 const {_} = useLingui()
24 const t = useTheme()
25 const {gtMobile} = useBreakpoints()
26 const [pdsAddressHistory, setPdsAddressHistory] = React.useState<string[]>(
27 persisted.get('pdsAddressHistory') || [],
28 )
29 const [fixedOption, setFixedOption] = React.useState([BSKY_SERVICE])
30 const [customAddress, setCustomAddress] = React.useState('')
31
32 const onClose = React.useCallback(() => {
33 let url
34 if (fixedOption[0] === 'custom') {
35 url = customAddress.trim().toLowerCase()
36 if (!url) {
37 return
38 }
39 } else {
40 url = fixedOption[0]
41 }
42 if (!url.startsWith('http://') && !url.startsWith('https://')) {
43 if (url === 'localhost' || url.startsWith('localhost:')) {
44 url = `http://${url}`
45 } else {
46 url = `https://${url}`
47 }
48 }
49
50 if (fixedOption[0] === 'custom') {
51 if (!pdsAddressHistory.includes(url)) {
52 const newHistory = [url, ...pdsAddressHistory.slice(0, 4)]
53 setPdsAddressHistory(newHistory)
54 persisted.write('pdsAddressHistory', newHistory)
55 }
56 }
57
58 onSelect(url)
59 }, [
60 fixedOption,
61 customAddress,
62 onSelect,
63 pdsAddressHistory,
64 setPdsAddressHistory,
65 ])
66
67 return (
68 <Dialog.Outer
69 control={control}
70 nativeOptions={{sheet: {snapPoints: ['100%']}}}
71 onClose={onClose}>
72 <Dialog.Handle />
73
74 <Dialog.ScrollableInner
75 accessibilityDescribedBy="dialog-description"
76 accessibilityLabelledBy="dialog-title">
77 <View style={[a.relative, a.gap_md, a.w_full]}>
78 <Text nativeID="dialog-title" style={[a.text_2xl, a.font_bold]}>
79 <Trans>Choose Service</Trans>
80 </Text>
81 <P nativeID="dialog-description" style={[a.text_sm]}>
82 <Trans>Select the service that hosts your data.</Trans>
83 </P>
84
85 <ToggleButton.Group
86 label="Preferences"
87 values={fixedOption}
88 onChange={setFixedOption}>
89 <ToggleButton.Button name={BSKY_SERVICE} label={_(msg`Bluesky`)}>
90 <ToggleButton.ButtonText>
91 {_(msg`Bluesky`)}
92 </ToggleButton.ButtonText>
93 </ToggleButton.Button>
94 <ToggleButton.Button
95 testID="customSelectBtn"
96 name="custom"
97 label={_(msg`Custom`)}>
98 <ToggleButton.ButtonText>
99 {_(msg`Custom`)}
100 </ToggleButton.ButtonText>
101 </ToggleButton.Button>
102 </ToggleButton.Group>
103
104 {fixedOption[0] === 'custom' && (
105 <View
106 style={[
107 a.border,
108 t.atoms.border_contrast_low,
109 a.rounded_sm,
110 a.px_md,
111 a.py_md,
112 ]}>
113 <TextField.LabelText nativeID="address-input-label">
114 <Trans>Server address</Trans>
115 </TextField.LabelText>
116 <TextField.Root>
117 <TextField.Icon icon={Globe} />
118 <Dialog.Input
119 testID="customServerTextInput"
120 value={customAddress}
121 onChangeText={setCustomAddress}
122 label="my-server.com"
123 accessibilityLabelledBy="address-input-label"
124 autoCapitalize="none"
125 keyboardType="url"
126 />
127 </TextField.Root>
128 {pdsAddressHistory.length > 0 && (
129 <View style={[a.flex_row, a.flex_wrap, a.mt_xs]}>
130 {pdsAddressHistory.map(uri => (
131 <Button
132 key={uri}
133 variant="ghost"
134 color="primary"
135 label={uri}
136 style={[a.px_sm, a.py_xs, a.rounded_sm, a.gap_sm]}
137 onPress={() => setCustomAddress(uri)}>
138 <ButtonText>{uri}</ButtonText>
139 </Button>
140 ))}
141 </View>
142 )}
143 </View>
144 )}
145
146 <View style={[a.py_xs]}>
147 <P
148 style={[
149 t.atoms.text_contrast_medium,
150 a.text_sm,
151 a.leading_snug,
152 a.flex_1,
153 ]}>
154 <Trans>
155 Bluesky is an open network where you can choose your hosting
156 provider. Custom hosting is now available in beta for
157 developers.
158 </Trans>
159 </P>
160 </View>
161
162 <View style={gtMobile && [a.flex_row, a.justify_end]}>
163 <Button
164 testID="doneBtn"
165 variant="outline"
166 color="primary"
167 size="small"
168 onPress={() => control.close()}
169 label={_(msg`Done`)}>
170 <ButtonText>{_(msg`Done`)}</ButtonText>
171 </Button>
172 </View>
173 </View>
174 </Dialog.ScrollableInner>
175 </Dialog.Outer>
176 )
177}