import {useEffect, useMemo, useState} from 'react'
import {useWindowDimensions, View} from 'react-native'
import Animated, {
FadeIn,
FadeOut,
LayoutAnimationConfig,
LinearTransition,
SlideInRight,
SlideOutLeft,
} from 'react-native-reanimated'
import {ComAtprotoServerCreateAppPassword} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useMutation} from '@tanstack/react-query'
import {isWeb} from '#/platform/detection'
import {useAppPasswordCreateMutation} from '#/state/queries/app-passwords'
import {atoms as a, native, useTheme} from '#/alf'
import {Admonition} from '#/components/Admonition'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import * as TextInput from '#/components/forms/TextField'
import * as Toggle from '#/components/forms/Toggle'
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron'
import {SquareBehindSquare4_Stroke2_Corner0_Rounded as CopyIcon} from '#/components/icons/SquareBehindSquare4'
import {Text} from '#/components/Typography'
import {CopyButton} from './CopyButton'
export function AddAppPasswordDialog({
control,
passwords,
}: {
control: Dialog.DialogControlProps
passwords: string[]
}) {
const {height} = useWindowDimensions()
return (
)
}
function CreateDialogInner({passwords}: {passwords: string[]}) {
const control = Dialog.useDialogContext()
const t = useTheme()
const {_} = useLingui()
const autogeneratedName = useRandomName()
const [name, setName] = useState('')
const [privileged, setPrivileged] = useState(false)
const {
mutateAsync: actuallyCreateAppPassword,
error: apiError,
data,
} = useAppPasswordCreateMutation()
const regexFailError = useMemo(
() =>
new DisplayableError(
_(
msg`App password names can only contain letters, numbers, spaces, dashes, and underscores`,
),
),
[_],
)
const {
mutate: createAppPassword,
error: validationError,
isPending,
} = useMutation<
ComAtprotoServerCreateAppPassword.AppPassword,
Error | DisplayableError
>({
mutationFn: async () => {
const chosenName = name.trim() || autogeneratedName
if (chosenName.length < 4) {
throw new DisplayableError(
_(msg`App password names must be at least 4 characters long`),
)
}
if (passwords.find(p => p === chosenName)) {
throw new DisplayableError(_(msg`App password name must be unique`))
}
return await actuallyCreateAppPassword({name: chosenName, privileged})
},
})
const [hasBeenCopied, setHasBeenCopied] = useState(false)
useEffect(() => {
if (hasBeenCopied) {
const timeout = setTimeout(() => setHasBeenCopied(false), 100)
return () => clearTimeout(timeout)
}
}, [hasBeenCopied])
const error =
validationError || (!name.match(/^[a-zA-Z0-9-_ ]*$/) && regexFailError)
return (
{!data ? (
Add App Password
Please enter a unique name for this app password or use our
randomly generated one.
createAppPassword()}
blurOnSubmit
autoCorrect={false}
autoComplete="off"
autoCapitalize="none"
autoFocus
/>
{error instanceof DisplayableError && (
{error.message}
)}
Allow access to your direct messages
{!!apiError ||
(error && !(error instanceof DisplayableError) && (
Failed to create app password. Please try again.
))}
) : (
Here is your app password!
Use this to sign into the other app along with your handle.
{data.password}
For security reasons, you won't be able to view this again. If
you lose this app password, you'll need to generate a new one.
)}
)
}
class DisplayableError extends Error {
constructor(message: string) {
super(message)
this.name = 'DisplayableError'
}
}
function useRandomName() {
return useState(
() => shadesOfBlue[Math.floor(Math.random() * shadesOfBlue.length)],
)[0]
}
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',
]