[Settings] Ungate, and remove old settings (#6144)

* move export car dialog

* move disableemail2fadialog

* delete old settings screens

* fix type error

* Update Navigation.tsx

* Delete AccountDropdownBtn.tsx

* remove old change handle modal

* delete add app paswords

* forgot to actually delete the change handle modal
This commit is contained in:
Samuel Newman
2024-11-08 22:42:18 +00:00
committed by GitHub
parent e8a03058bb
commit 5da3f29498
22 changed files with 16 additions and 3768 deletions
-307
View File
@@ -1,307 +0,0 @@
import React, {useState} from 'react'
import {StyleSheet, TextInput, TouchableOpacity, View} from 'react-native'
import {setStringAsync} from 'expo-clipboard'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {usePalette} from '#/lib/hooks/usePalette'
import {s} from '#/lib/styles'
import {logger} from '#/logger'
import {isNative} from '#/platform/detection'
import {useModalControls} from '#/state/modals'
import {
useAppPasswordCreateMutation,
useAppPasswordsQuery,
} from '#/state/queries/app-passwords'
import {Button} from '#/view/com/util/forms/Button'
import {Text} from '#/view/com/util/text/Text'
import * as Toast from '#/view/com/util/Toast'
import {atoms as a} from '#/alf'
import * as Toggle from '#/components/forms/Toggle'
export const snapPoints = ['90%']
const shadesOfBlue: string[] = [
'AliceBlue',
'Aqua',
'Aquamarine',
'Azure',
'BabyBlue',
'Blue',
'BlueViolet',
'CadetBlue',
'CornflowerBlue',
'Cyan',
'DarkBlue',
'DarkCyan',
'DarkSlateBlue',
'DeepSkyBlue',
'DodgerBlue',
'ElectricBlue',
'LightBlue',
'LightCyan',
'LightSkyBlue',
'LightSteelBlue',
'MediumAquaMarine',
'MediumBlue',
'MediumSlateBlue',
'MidnightBlue',
'Navy',
'PowderBlue',
'RoyalBlue',
'SkyBlue',
'SlateBlue',
'SteelBlue',
'Teal',
'Turquoise',
]
export function Component({}: {}) {
const pal = usePalette('default')
const {_} = useLingui()
const {closeModal} = useModalControls()
const {data: passwords} = useAppPasswordsQuery()
const {mutateAsync: mutateAppPassword, isPending} =
useAppPasswordCreateMutation()
const [name, setName] = useState(
shadesOfBlue[Math.floor(Math.random() * shadesOfBlue.length)],
)
const [appPassword, setAppPassword] = useState<string>()
const [wasCopied, setWasCopied] = useState(false)
const [privileged, setPrivileged] = useState(false)
const onCopy = React.useCallback(() => {
if (appPassword) {
setStringAsync(appPassword)
Toast.show(_(msg`Copied to clipboard`), 'clipboard-check')
setWasCopied(true)
}
}, [appPassword, _])
const onDone = React.useCallback(() => {
closeModal()
}, [closeModal])
const createAppPassword = async () => {
// if name is all whitespace, we don't allow it
if (!name || !name.trim()) {
Toast.show(
_(
msg`Please enter a name for your app password. All spaces is not allowed.`,
),
'xmark',
)
return
}
// if name is too short (under 4 chars), we don't allow it
if (name.length < 4) {
Toast.show(
_(msg`App Password names must be at least 4 characters long.`),
'xmark',
)
return
}
if (passwords?.find(p => p.name === name)) {
Toast.show(_(msg`This name is already in use`), 'xmark')
return
}
try {
const newPassword = await mutateAppPassword({name, privileged})
if (newPassword) {
setAppPassword(newPassword.password)
} else {
Toast.show(_(msg`Failed to create app password.`), 'xmark')
// TODO: better error handling (?)
}
} catch (e) {
Toast.show(_(msg`Failed to create app password.`), 'xmark')
logger.error('Failed to create app password', {message: e})
}
}
const _onChangeText = (text: string) => {
// sanitize input
// we only all alphanumeric characters, spaces, dashes, and underscores
// if the user enters anything else, we ignore it and shake the input container
// also, it cannot start with a space
if (text.match(/^[a-zA-Z0-9-_ ]*$/)) {
setName(text)
} else {
Toast.show(
_(
msg`App Password names can only contain letters, numbers, spaces, dashes, and underscores.`,
),
'xmark',
)
}
}
return (
<View style={[styles.container, pal.view]} testID="addAppPasswordsModal">
{!appPassword ? (
<>
<View>
<Text type="lg" style={[pal.text]}>
<Trans>
Please enter a unique name for this App Password or use our
randomly generated one.
</Trans>
</Text>
<View style={[pal.btn, styles.textInputWrapper]}>
<TextInput
style={[styles.input, pal.text]}
onChangeText={_onChangeText}
value={name}
placeholder={_(msg`Enter a name for this App Password`)}
placeholderTextColor={pal.colors.textLight}
autoCorrect={false}
autoComplete="off"
autoCapitalize="none"
autoFocus={true}
maxLength={32}
selectTextOnFocus={true}
blurOnSubmit={true}
editable={!isPending}
returnKeyType="done"
onSubmitEditing={createAppPassword}
accessible={true}
accessibilityLabel={_(msg`Name`)}
accessibilityHint={_(msg`Input name for app password`)}
/>
</View>
</View>
<Text type="xs" style={[pal.textLight, s.mb10, s.mt2]}>
<Trans>
Can only contain letters, numbers, spaces, dashes, and
underscores. Must be at least 4 characters long, but no more than
32 characters long.
</Trans>
</Text>
<Toggle.Item
type="checkbox"
label={_(msg`Allow access to your direct messages`)}
value={privileged}
onChange={val => setPrivileged(val)}
name="privileged"
style={a.my_md}>
<Toggle.Checkbox />
<Toggle.LabelText>
<Trans>Allow access to your direct messages</Trans>
</Toggle.LabelText>
</Toggle.Item>
</>
) : (
<>
<View>
<Text type="lg" style={[pal.text]}>
<Text type="lg-bold" style={[pal.text, s.mr5]}>
<Trans>Here is your app password.</Trans>
</Text>
<Trans>
Use this to sign into the other app along with your handle.
</Trans>
</Text>
<TouchableOpacity
style={[pal.border, styles.passwordContainer, pal.btn]}
onPress={onCopy}
accessibilityRole="button"
accessibilityLabel={_(msg`Copy`)}
accessibilityHint={_(msg`Copies app password`)}>
<Text type="2xl-bold" style={[pal.text]}>
{appPassword}
</Text>
{wasCopied ? (
<Text style={[pal.textLight]}>
<Trans>Copied</Trans>
</Text>
) : (
<FontAwesomeIcon
icon={['far', 'clone']}
style={pal.text as FontAwesomeIconStyle}
size={18}
/>
)}
</TouchableOpacity>
</View>
<Text type="lg" style={[pal.textLight, s.mb10]}>
<Trans>
For security reasons, you won't be able to view this again. If you
lose this password, you'll need to generate a new one.
</Trans>
</Text>
</>
)}
<View style={styles.btnContainer}>
<Button
type="primary"
label={!appPassword ? _(msg`Create App Password`) : _(msg`Done`)}
style={styles.btn}
labelStyle={styles.btnLabel}
onPress={!appPassword ? createAppPassword : onDone}
/>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingBottom: isNative ? 50 : 0,
paddingHorizontal: 16,
},
textInputWrapper: {
borderRadius: 8,
flexDirection: 'row',
alignItems: 'center',
marginTop: 16,
marginBottom: 8,
},
input: {
flex: 1,
width: '100%',
paddingVertical: 10,
paddingHorizontal: 8,
fontSize: 17,
letterSpacing: 0.25,
fontWeight: '400',
borderRadius: 10,
},
passwordContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 8,
paddingHorizontal: 16,
alignItems: 'center',
borderRadius: 10,
marginTop: 16,
marginBottom: 12,
},
btnContainer: {
flexDirection: 'row',
justifyContent: 'center',
marginTop: 12,
},
btn: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 32,
paddingHorizontal: 60,
paddingVertical: 14,
},
btnLabel: {
fontSize: 18,
},
groupContent: {
borderTopWidth: 1,
flexDirection: 'row',
alignItems: 'center',
},
})
-614
View File
@@ -1,614 +0,0 @@
import React, {useState} from 'react'
import {
ActivityIndicator,
StyleSheet,
TouchableOpacity,
View,
} from 'react-native'
import {setStringAsync} from 'expo-clipboard'
import {ComAtprotoServerDescribeServer} from '@atproto/api'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {usePalette} from '#/lib/hooks/usePalette'
import {cleanError} from '#/lib/strings/errors'
import {createFullHandle, makeValidHandle} from '#/lib/strings/handles'
import {s} from '#/lib/styles'
import {useTheme} from '#/lib/ThemeContext'
import {logger} from '#/logger'
import {useModalControls} from '#/state/modals'
import {useFetchDid, useUpdateHandleMutation} from '#/state/queries/handle'
import {useServiceQuery} from '#/state/queries/service'
import {SessionAccount, useAgent, useSession} from '#/state/session'
import {ErrorMessage} from '../util/error/ErrorMessage'
import {Button} from '../util/forms/Button'
import {SelectableBtn} from '../util/forms/SelectableBtn'
import {Text} from '../util/text/Text'
import * as Toast from '../util/Toast'
import {ScrollView, TextInput} from './util'
export const snapPoints = ['100%']
export type Props = {onChanged: () => void}
export function Component(props: Props) {
const {currentAccount} = useSession()
const agent = useAgent()
const {
isLoading,
data: serviceInfo,
error: serviceInfoError,
} = useServiceQuery(agent.service.toString())
return isLoading || !currentAccount ? (
<View style={{padding: 18}}>
<ActivityIndicator />
</View>
) : serviceInfoError || !serviceInfo ? (
<ErrorMessage message={cleanError(serviceInfoError)} />
) : (
<Inner
{...props}
currentAccount={currentAccount}
serviceInfo={serviceInfo}
/>
)
}
export function Inner({
currentAccount,
serviceInfo,
onChanged,
}: Props & {
currentAccount: SessionAccount
serviceInfo: ComAtprotoServerDescribeServer.OutputSchema
}) {
const {_} = useLingui()
const pal = usePalette('default')
const {closeModal} = useModalControls()
const {mutateAsync: updateHandle, isPending: isUpdateHandlePending} =
useUpdateHandleMutation()
const agent = useAgent()
const [error, setError] = useState<string>('')
const [isCustom, setCustom] = React.useState<boolean>(false)
const [handle, setHandle] = React.useState<string>('')
const [canSave, setCanSave] = React.useState<boolean>(false)
const userDomain = serviceInfo.availableUserDomains?.[0]
// events
// =
const onPressCancel = React.useCallback(() => {
closeModal()
}, [closeModal])
const onToggleCustom = React.useCallback(() => {
// toggle between a provided domain vs a custom one
setHandle('')
setCanSave(false)
setCustom(!isCustom)
}, [setCustom, isCustom])
const onPressSave = React.useCallback(async () => {
if (!userDomain) {
logger.error(`ChangeHandle: userDomain is undefined`, {
service: serviceInfo,
})
setError(`The service you've selected has no domains configured.`)
return
}
try {
const newHandle = isCustom ? handle : createFullHandle(handle, userDomain)
logger.debug(`Updating handle to ${newHandle}`)
await updateHandle({
handle: newHandle,
})
await agent.resumeSession(agent.session!)
closeModal()
onChanged()
} catch (err: any) {
setError(cleanError(err))
logger.error('Failed to update handle', {handle, message: err})
} finally {
}
}, [
setError,
handle,
userDomain,
isCustom,
onChanged,
closeModal,
updateHandle,
serviceInfo,
agent,
])
// rendering
// =
return (
<View style={[s.flex1, pal.view]}>
<View style={[styles.title, pal.border]}>
<View style={styles.titleLeft}>
<TouchableOpacity
onPress={onPressCancel}
accessibilityRole="button"
accessibilityLabel={_(msg`Cancel change handle`)}
accessibilityHint={_(msg`Exits handle change process`)}
onAccessibilityEscape={onPressCancel}>
<Text type="lg" style={pal.textLight}>
<Trans>Cancel</Trans>
</Text>
</TouchableOpacity>
</View>
<Text
type="2xl-bold"
style={[styles.titleMiddle, pal.text]}
numberOfLines={1}>
<Trans>Change Handle</Trans>
</Text>
<View style={styles.titleRight}>
{isUpdateHandlePending ? (
<ActivityIndicator />
) : canSave ? (
<TouchableOpacity
onPress={onPressSave}
accessibilityRole="button"
accessibilityLabel={_(msg`Save handle change`)}
accessibilityHint={_(msg`Saves handle change to ${handle}`)}>
<Text type="2xl-medium" style={pal.link}>
<Trans>Save</Trans>
</Text>
</TouchableOpacity>
) : undefined}
</View>
</View>
<ScrollView style={styles.inner}>
{error !== '' && (
<View style={styles.errorContainer}>
<ErrorMessage message={error} />
</View>
)}
{isCustom ? (
<CustomHandleForm
currentAccount={currentAccount}
handle={handle}
isProcessing={isUpdateHandlePending}
canSave={canSave}
onToggleCustom={onToggleCustom}
setHandle={setHandle}
setCanSave={setCanSave}
onPressSave={onPressSave}
/>
) : (
<ProvidedHandleForm
handle={handle}
userDomain={userDomain}
isProcessing={isUpdateHandlePending}
onToggleCustom={onToggleCustom}
setHandle={setHandle}
setCanSave={setCanSave}
/>
)}
</ScrollView>
</View>
)
}
/**
* The form for using a domain allocated by the PDS
*/
function ProvidedHandleForm({
userDomain,
handle,
isProcessing,
setHandle,
onToggleCustom,
setCanSave,
}: {
userDomain: string
handle: string
isProcessing: boolean
setHandle: (v: string) => void
onToggleCustom: () => void
setCanSave: (v: boolean) => void
}) {
const pal = usePalette('default')
const theme = useTheme()
const {_} = useLingui()
// events
// =
const onChangeHandle = React.useCallback(
(v: string) => {
const newHandle = makeValidHandle(v)
setHandle(newHandle)
setCanSave(newHandle.length > 0)
},
[setHandle, setCanSave],
)
// rendering
// =
return (
<>
<View style={[pal.btn, styles.textInputWrapper]}>
<FontAwesomeIcon
icon="at"
style={[pal.textLight, styles.textInputIcon]}
/>
<TextInput
testID="setHandleInput"
style={[pal.text, styles.textInput]}
placeholder={_(msg`e.g. alice`)}
placeholderTextColor={pal.colors.textLight}
autoCapitalize="none"
keyboardAppearance={theme.colorScheme}
value={handle}
onChangeText={onChangeHandle}
editable={!isProcessing}
accessible={true}
accessibilityLabel={_(msg`Handle`)}
accessibilityHint={_(msg`Sets Bluesky username`)}
/>
</View>
<Text type="md" style={[pal.textLight, s.pl10, s.pt10]}>
<Trans>
Your full handle will be{' '}
<Text type="md-bold" style={pal.textLight}>
@{createFullHandle(handle, userDomain)}
</Text>
</Trans>
</Text>
<TouchableOpacity
onPress={onToggleCustom}
accessibilityRole="button"
accessibilityLabel={_(msg`Hosting provider`)}
accessibilityHint={_(msg`Opens modal for using custom domain`)}>
<Text type="md-medium" style={[pal.link, s.pl10, s.pt5]}>
<Trans>I have my own domain</Trans>
</Text>
</TouchableOpacity>
</>
)
}
/**
* The form for using a custom domain
*/
function CustomHandleForm({
currentAccount,
handle,
canSave,
isProcessing,
setHandle,
onToggleCustom,
onPressSave,
setCanSave,
}: {
currentAccount: SessionAccount
handle: string
canSave: boolean
isProcessing: boolean
setHandle: (v: string) => void
onToggleCustom: () => void
onPressSave: () => void
setCanSave: (v: boolean) => void
}) {
const pal = usePalette('default')
const palSecondary = usePalette('secondary')
const palError = usePalette('error')
const theme = useTheme()
const {_} = useLingui()
const [isVerifying, setIsVerifying] = React.useState(false)
const [error, setError] = React.useState<string>('')
const [isDNSForm, setDNSForm] = React.useState<boolean>(true)
const fetchDid = useFetchDid()
// events
// =
const onPressCopy = React.useCallback(() => {
setStringAsync(isDNSForm ? `did=${currentAccount.did}` : currentAccount.did)
Toast.show(_(msg`Copied to clipboard`), 'clipboard-check')
}, [currentAccount, isDNSForm, _])
const onChangeHandle = React.useCallback(
(v: string) => {
setHandle(v)
setCanSave(false)
},
[setHandle, setCanSave],
)
const onPressVerify = React.useCallback(async () => {
if (canSave) {
onPressSave()
}
try {
setIsVerifying(true)
setError('')
const did = await fetchDid(handle)
if (did === currentAccount.did) {
setCanSave(true)
} else {
setError(`Incorrect DID returned (got ${did})`)
}
} catch (err: any) {
setError(cleanError(err))
logger.error('Failed to verify domain', {handle, error: err})
} finally {
setIsVerifying(false)
}
}, [
handle,
currentAccount,
setIsVerifying,
setCanSave,
setError,
canSave,
onPressSave,
fetchDid,
])
// rendering
// =
return (
<>
<Text type="md" style={[pal.text, s.pb5, s.pl5]} nativeID="customDomain">
<Trans>Enter the domain you want to use</Trans>
</Text>
<View style={[pal.btn, styles.textInputWrapper]}>
<FontAwesomeIcon
icon="at"
style={[pal.textLight, styles.textInputIcon]}
/>
<TextInput
testID="setHandleInput"
style={[pal.text, styles.textInput]}
placeholder={_(msg`e.g. alice.com`)}
placeholderTextColor={pal.colors.textLight}
autoCapitalize="none"
keyboardAppearance={theme.colorScheme}
value={handle}
onChangeText={onChangeHandle}
editable={!isProcessing}
accessibilityLabelledBy="customDomain"
accessibilityLabel={_(msg`Custom domain`)}
accessibilityHint={_(msg`Input your preferred hosting provider`)}
/>
</View>
<View style={styles.spacer} />
<View style={[styles.selectableBtns]}>
<SelectableBtn
selected={isDNSForm}
label={_(msg`DNS Panel`)}
left
onSelect={() => setDNSForm(true)}
accessibilityHint={_(msg`Use the DNS panel`)}
style={s.flex1}
/>
<SelectableBtn
selected={!isDNSForm}
label={_(msg`No DNS Panel`)}
right
onSelect={() => setDNSForm(false)}
accessibilityHint={_(msg`Use a file on your server`)}
style={s.flex1}
/>
</View>
<View style={styles.spacer} />
{isDNSForm ? (
<>
<Text type="md" style={[pal.text, s.pb5, s.pl5]}>
<Trans>Add the following DNS record to your domain:</Trans>
</Text>
<View style={[styles.dnsTable, pal.btn]}>
<Text type="md-medium" style={[styles.dnsLabel, pal.text]}>
<Trans>Host:</Trans>
</Text>
<View style={[styles.dnsValue]}>
<Text type="mono" style={[styles.monoText, pal.text]}>
_atproto
</Text>
</View>
<Text type="md-medium" style={[styles.dnsLabel, pal.text]}>
<Trans>Type:</Trans>
</Text>
<View style={[styles.dnsValue]}>
<Text type="mono" style={[styles.monoText, pal.text]}>
TXT
</Text>
</View>
<Text type="md-medium" style={[styles.dnsLabel, pal.text]}>
<Trans>Value:</Trans>
</Text>
<View style={[styles.dnsValue]}>
<Text type="mono" style={[styles.monoText, pal.text]}>
did={currentAccount.did}
</Text>
</View>
</View>
<Text type="md" style={[pal.text, s.pt20, s.pl5]}>
<Trans>This should create a domain record at:</Trans>
</Text>
<Text type="mono" style={[styles.monoText, pal.text, s.pt5, s.pl5]}>
_atproto.{handle}
</Text>
</>
) : (
<>
<Text type="md" style={[pal.text, s.pb5, s.pl5]}>
<Trans>Upload a text file to:</Trans>
</Text>
<View style={[styles.valueContainer, pal.btn]}>
<View style={[styles.dnsValue]}>
<Text type="mono" style={[styles.monoText, pal.text]}>
https://{handle}/.well-known/atproto-did
</Text>
</View>
</View>
<View style={styles.spacer} />
<Text type="md" style={[pal.text, s.pb5, s.pl5]}>
<Trans>That contains the following:</Trans>
</Text>
<View style={[styles.valueContainer, pal.btn]}>
<View style={[styles.dnsValue]}>
<Text type="mono" style={[styles.monoText, pal.text]}>
{currentAccount.did}
</Text>
</View>
</View>
</>
)}
<View style={styles.spacer} />
<Button type="default" style={[s.p20, s.mb10]} onPress={onPressCopy}>
<Text type="xl" style={[pal.link, s.textCenter]}>
<Trans>
Copy {isDNSForm ? _(msg`Domain Value`) : _(msg`File Contents`)}
</Trans>
</Text>
</Button>
{canSave === true && (
<View style={[styles.message, palSecondary.view]}>
<Text type="md-medium" style={palSecondary.text}>
<Trans>Domain verified!</Trans>
</Text>
</View>
)}
{error ? (
<View style={[styles.message, palError.view]}>
<Text type="md-medium" style={palError.text}>
{error}
</Text>
</View>
) : null}
<Button
type="primary"
style={[s.p20, isVerifying && styles.dimmed]}
onPress={onPressVerify}>
{isVerifying ? (
<ActivityIndicator color="white" />
) : (
<Text type="xl-medium" style={[s.white, s.textCenter]}>
{canSave
? _(msg`Update to ${handle}`)
: isDNSForm
? _(msg`Verify DNS Record`)
: _(msg`Verify Text File`)}
</Text>
)}
</Button>
<View style={styles.spacer} />
<TouchableOpacity
onPress={onToggleCustom}
accessibilityLabel={_(msg`Use default provider`)}
accessibilityHint={_(msg`Use bsky.social as hosting provider`)}>
<Text type="md-medium" style={[pal.link, s.pl10, s.pt5]}>
<Trans>Nevermind, create a handle for me</Trans>
</Text>
</TouchableOpacity>
</>
)
}
const styles = StyleSheet.create({
inner: {
padding: 14,
},
footer: {
padding: 14,
},
spacer: {
height: 20,
},
dimmed: {
opacity: 0.7,
},
selectableBtns: {
flexDirection: 'row',
},
title: {
flexDirection: 'row',
alignItems: 'center',
paddingTop: 25,
paddingHorizontal: 20,
paddingBottom: 15,
borderBottomWidth: 1,
},
titleLeft: {
width: 80,
},
titleRight: {
width: 80,
flexDirection: 'row',
justifyContent: 'flex-end',
},
titleMiddle: {
flex: 1,
textAlign: 'center',
fontSize: 21,
},
textInputWrapper: {
borderRadius: 8,
flexDirection: 'row',
alignItems: 'center',
},
textInputIcon: {
marginLeft: 12,
},
textInput: {
flex: 1,
width: '100%',
paddingVertical: 10,
paddingHorizontal: 8,
fontSize: 17,
letterSpacing: 0.25,
fontWeight: '400',
borderRadius: 10,
},
valueContainer: {
borderRadius: 4,
paddingVertical: 16,
},
dnsTable: {
borderRadius: 4,
paddingTop: 2,
paddingBottom: 16,
},
dnsLabel: {
paddingHorizontal: 14,
paddingTop: 10,
},
dnsValue: {
paddingHorizontal: 14,
borderRadius: 4,
},
monoText: {
fontSize: 18,
lineHeight: 20,
},
message: {
paddingHorizontal: 12,
paddingVertical: 10,
borderRadius: 8,
marginBottom: 10,
},
btn: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
borderRadius: 32,
padding: 10,
marginBottom: 10,
},
errorContainer: {marginBottom: 10},
})
-8
View File
@@ -7,9 +7,7 @@ import {usePalette} from '#/lib/hooks/usePalette'
import {useModalControls, useModals} from '#/state/modals'
import {FullWindowOverlay} from '#/components/FullWindowOverlay'
import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop'
import * as AddAppPassword from './AddAppPasswords'
import * as ChangeEmailModal from './ChangeEmail'
import * as ChangeHandleModal from './ChangeHandle'
import * as ChangePasswordModal from './ChangePassword'
import * as CreateOrEditListModal from './CreateOrEditList'
import * as DeleteAccountModal from './DeleteAccount'
@@ -69,15 +67,9 @@ export function ModalsContainer() {
} else if (activeModal?.name === 'delete-account') {
snapPoints = DeleteAccountModal.snapPoints
element = <DeleteAccountModal.Component />
} else if (activeModal?.name === 'change-handle') {
snapPoints = ChangeHandleModal.snapPoints
element = <ChangeHandleModal.Component {...activeModal} />
} else if (activeModal?.name === 'invite-codes') {
snapPoints = InviteCodesModal.snapPoints
element = <InviteCodesModal.Component />
} else if (activeModal?.name === 'add-app-password') {
snapPoints = AddAppPassword.snapPoints
element = <AddAppPassword.Component />
} else if (activeModal?.name === 'content-languages-settings') {
snapPoints = ContentLanguagesSettingsModal.snapPoints
element = <ContentLanguagesSettingsModal.Component />
-6
View File
@@ -7,9 +7,7 @@ import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import type {Modal as ModalIface} from '#/state/modals'
import {useModalControls, useModals} from '#/state/modals'
import * as AddAppPassword from './AddAppPasswords'
import * as ChangeEmailModal from './ChangeEmail'
import * as ChangeHandleModal from './ChangeHandle'
import * as ChangePasswordModal from './ChangePassword'
import * as CreateOrEditListModal from './CreateOrEditList'
import * as CropImageModal from './CropImage.web'
@@ -74,12 +72,8 @@ function Modal({modal}: {modal: ModalIface}) {
element = <CropImageModal.Component {...modal} />
} else if (modal.name === 'delete-account') {
element = <DeleteAccountModal.Component />
} else if (modal.name === 'change-handle') {
element = <ChangeHandleModal.Component {...modal} />
} else if (modal.name === 'invite-codes') {
element = <InviteCodesModal.Component />
} else if (modal.name === 'add-app-password') {
element = <AddAppPassword.Component />
} else if (modal.name === 'content-languages-settings') {
element = <ContentLanguagesSettingsModal.Component />
} else if (modal.name === 'post-languages-settings') {