diff options
author | Samuel Newman <mozzius@protonmail.com> | 2024-11-08 22:42:18 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-08 22:42:18 +0000 |
commit | 5da3f29498fda9ab1181df19a718e37099cb2cf6 (patch) | |
tree | 4989300fe333edc3ad1c12c7b0d03e6ff5112ee3 /src/view/com | |
parent | e8a03058bb993bda993e78d24877884d39666d63 (diff) | |
download | voidsky-5da3f29498fda9ab1181df19a718e37099cb2cf6.tar.zst |
[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
Diffstat (limited to 'src/view/com')
-rw-r--r-- | src/view/com/modals/AddAppPasswords.tsx | 307 | ||||
-rw-r--r-- | src/view/com/modals/ChangeHandle.tsx | 614 | ||||
-rw-r--r-- | src/view/com/modals/Modal.tsx | 8 | ||||
-rw-r--r-- | src/view/com/modals/Modal.web.tsx | 6 | ||||
-rw-r--r-- | src/view/com/util/AccountDropdownBtn.tsx | 66 | ||||
-rw-r--r-- | src/view/com/util/List.web.tsx | 4 |
6 files changed, 3 insertions, 1002 deletions
diff --git a/src/view/com/modals/AddAppPasswords.tsx b/src/view/com/modals/AddAppPasswords.tsx deleted file mode 100644 index f7991f59b..000000000 --- a/src/view/com/modals/AddAppPasswords.tsx +++ /dev/null @@ -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', - }, -}) diff --git a/src/view/com/modals/ChangeHandle.tsx b/src/view/com/modals/ChangeHandle.tsx deleted file mode 100644 index 2181a94aa..000000000 --- a/src/view/com/modals/ChangeHandle.tsx +++ /dev/null @@ -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}, -}) diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index becb39ff3..78f4a0117 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -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 /> diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx index 46ced58d9..e9d9c01dd 100644 --- a/src/view/com/modals/Modal.web.tsx +++ b/src/view/com/modals/Modal.web.tsx @@ -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') { diff --git a/src/view/com/util/AccountDropdownBtn.tsx b/src/view/com/util/AccountDropdownBtn.tsx deleted file mode 100644 index e7985bccf..000000000 --- a/src/view/com/util/AccountDropdownBtn.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import React from 'react' -import {Pressable} from 'react-native' -import { - FontAwesomeIcon, - FontAwesomeIconStyle, -} from '@fortawesome/react-native-fontawesome' -import {msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -import {usePalette} from '#/lib/hooks/usePalette' -import {s} from '#/lib/styles' -import {SessionAccount, useSessionApi} from '#/state/session' -import {useDialogControl} from '#/components/Dialog' -import * as Prompt from '#/components/Prompt' -import * as Toast from '../../com/util/Toast' -import {DropdownItem, NativeDropdown} from './forms/NativeDropdown' - -export function AccountDropdownBtn({account}: {account: SessionAccount}) { - const pal = usePalette('default') - const {removeAccount} = useSessionApi() - const removePromptControl = useDialogControl() - const {_} = useLingui() - - const items: DropdownItem[] = [ - { - label: _(msg`Remove account`), - onPress: removePromptControl.open, - icon: { - ios: { - name: 'trash', - }, - android: 'ic_delete', - web: ['far', 'trash-can'], - }, - }, - ] - return ( - <> - <Pressable accessibilityRole="button" style={s.pl10}> - <NativeDropdown - testID="accountSettingsDropdownBtn" - items={items} - accessibilityLabel={_(msg`Account options`)} - accessibilityHint=""> - <FontAwesomeIcon - icon="ellipsis-h" - style={pal.textLight as FontAwesomeIconStyle} - /> - </NativeDropdown> - </Pressable> - <Prompt.Basic - control={removePromptControl} - title={_(msg`Remove from quick access?`)} - description={_( - msg`This will remove @${account.handle} from the quick access list.`, - )} - onConfirm={() => { - removeAccount(account) - Toast.show(_(msg`Account removed from quick access`)) - }} - confirmButtonCta={_(msg`Remove`)} - confirmButtonColor="negative" - /> - </> - ) -} diff --git a/src/view/com/util/List.web.tsx b/src/view/com/util/List.web.tsx index 59a79b531..5ddc4ea8a 100644 --- a/src/view/com/util/List.web.tsx +++ b/src/view/com/util/List.web.tsx @@ -448,7 +448,9 @@ let Row = function RowImpl<ItemT>({ onItemSeen: ((item: any) => void) | undefined }): React.ReactNode { const rowRef = React.useRef(null) - const intersectionTimeout = React.useRef<NodeJS.Timer | undefined>(undefined) + const intersectionTimeout = React.useRef< + ReturnType<typeof setTimeout> | undefined + >(undefined) const handleIntersection = useNonReactiveCallback( (entries: IntersectionObserverEntry[]) => { |