diff --git a/src/App.native.tsx b/src/App.native.tsx
index 036ecff60e..104a7ecaec 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -38,7 +38,6 @@ import {
} from '#/state/geolocation'
import {GlobalGestureEventsProvider} from '#/state/global-gesture-events'
import {Provider as HomeBadgeProvider} from '#/state/home-badge'
-import {Provider as InvitesStateProvider} from '#/state/invites'
import {Provider as LightboxStateProvider} from '#/state/lightbox'
import {MessagesProvider} from '#/state/messages'
import {Provider as ModalStateProvider} from '#/state/modals'
@@ -225,24 +224,22 @@ function App() {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App.web.tsx b/src/App.web.tsx
index c86960172a..569c9be799 100644
--- a/src/App.web.tsx
+++ b/src/App.web.tsx
@@ -26,7 +26,6 @@ import {
Provider as GeolocationProvider,
} from '#/state/geolocation'
import {Provider as HomeBadgeProvider} from '#/state/home-badge'
-import {Provider as InvitesStateProvider} from '#/state/invites'
import {Provider as LightboxStateProvider} from '#/state/lightbox'
import {MessagesProvider} from '#/state/messages'
import {Provider as ModalStateProvider} from '#/state/modals'
@@ -199,19 +198,17 @@ function App() {
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/state/invites.tsx b/src/state/invites.tsx
deleted file mode 100644
index 4f12cb12f4..0000000000
--- a/src/state/invites.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import React from 'react'
-
-import * as persisted from '#/state/persisted'
-
-type StateContext = persisted.Schema['invites']
-type ApiContext = {
- setInviteCopied: (code: string) => void
-}
-
-const stateContext = React.createContext(
- persisted.defaults.invites,
-)
-stateContext.displayName = 'InvitesStateContext'
-const apiContext = React.createContext({
- setInviteCopied(_: string) {},
-})
-apiContext.displayName = 'InvitesApiContext'
-
-export function Provider({children}: React.PropsWithChildren<{}>) {
- const [state, setState] = React.useState(persisted.get('invites'))
-
- const api = React.useMemo(
- () => ({
- setInviteCopied(code: string) {
- setState(state => {
- state = {
- ...state,
- copiedInvites: state.copiedInvites.includes(code)
- ? state.copiedInvites
- : state.copiedInvites.concat([code]),
- }
- persisted.write('invites', state)
- return state
- })
- },
- }),
- [setState],
- )
-
- React.useEffect(() => {
- return persisted.onUpdate('invites', nextInvites => {
- setState(nextInvites)
- })
- }, [setState])
-
- return (
-
- {children}
-
- )
-}
-
-export function useInvitesState() {
- return React.useContext(stateContext)
-}
-
-export function useInvitesAPI() {
- return React.useContext(apiContext)
-}
diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx
index 661ab3a15a..dab90c0af3 100644
--- a/src/state/modals/index.tsx
+++ b/src/state/modals/index.tsx
@@ -15,14 +15,6 @@ export interface DeleteAccountModal {
name: 'delete-account'
}
-export interface WaitlistModal {
- name: 'waitlist'
-}
-
-export interface InviteCodesModal {
- name: 'invite-codes'
-}
-
export interface ContentLanguagesSettingsModal {
name: 'content-languages-settings'
}
@@ -40,10 +32,6 @@ export type Modal =
// Lists
| UserAddRemoveListsModal
- // Bluesky access
- | WaitlistModal
- | InviteCodesModal
-
const ModalContext = React.createContext<{
isModalActive: boolean
activeModals: Modal[]
diff --git a/src/state/queries/invites.ts b/src/state/queries/invites.ts
deleted file mode 100644
index ed7fc534f9..0000000000
--- a/src/state/queries/invites.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import {type ComAtprotoServerDefs} from '@atproto/api'
-import {useQuery} from '@tanstack/react-query'
-
-import {cleanError} from '#/lib/strings/errors'
-import {STALE} from '#/state/queries'
-import {useAgent} from '#/state/session'
-
-function isInviteAvailable(invite: ComAtprotoServerDefs.InviteCode): boolean {
- return invite.available - invite.uses.length > 0 && !invite.disabled
-}
-
-const inviteCodesQueryKeyRoot = 'inviteCodes'
-
-export type InviteCodesQueryResponse = Exclude<
- ReturnType['data'],
- undefined
->
-export function useInviteCodesQuery() {
- const agent = useAgent()
- return useQuery({
- staleTime: STALE.MINUTES.FIVE,
- queryKey: [inviteCodesQueryKeyRoot],
- queryFn: async () => {
- const res = await agent.com.atproto.server
- .getAccountInviteCodes({})
- .catch(e => {
- if (cleanError(e) === 'Bad token scope') {
- return null
- } else {
- throw e
- }
- })
-
- if (res === null) {
- return {
- disabled: true,
- all: [],
- available: [],
- used: [],
- }
- }
-
- if (!res.data?.codes) {
- throw new Error(`useInviteCodesQuery: no codes returned`)
- }
-
- const available = res.data.codes.filter(isInviteAvailable)
- const used = res.data.codes
- .filter(code => !isInviteAvailable(code))
- .sort((a, b) => {
- return (
- new Date(b.uses[0].usedAt).getTime() -
- new Date(a.uses[0].usedAt).getTime()
- )
- })
-
- return {
- disabled: false,
- all: [...available, ...used],
- available,
- used,
- }
- },
- })
-}
diff --git a/src/view/com/modals/CreateOrEditList.tsx b/src/view/com/modals/CreateOrEditList.tsx
deleted file mode 100644
index 3687dce901..0000000000
--- a/src/view/com/modals/CreateOrEditList.tsx
+++ /dev/null
@@ -1,403 +0,0 @@
-import {useCallback, useMemo, useState} from 'react'
-import {
- ActivityIndicator,
- KeyboardAvoidingView,
- ScrollView,
- StyleSheet,
- TextInput,
- TouchableOpacity,
- View,
-} from 'react-native'
-import {LinearGradient} from 'expo-linear-gradient'
-import {type AppBskyGraphDefs, RichText as RichTextAPI} from '@atproto/api'
-import {msg, Trans} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-
-import {usePalette} from '#/lib/hooks/usePalette'
-import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
-import {cleanError, isNetworkError} from '#/lib/strings/errors'
-import {enforceLen} from '#/lib/strings/helpers'
-import {richTextToString} from '#/lib/strings/rich-text-helpers'
-import {shortenLinks, stripInvalidMentions} from '#/lib/strings/rich-text-manip'
-import {colors, gradients, s} from '#/lib/styles'
-import {useTheme} from '#/lib/ThemeContext'
-import {type ImageMeta} from '#/state/gallery'
-import {useModalControls} from '#/state/modals'
-import {
- useListCreateMutation,
- useListMetadataMutation,
-} from '#/state/queries/list'
-import {useAgent} from '#/state/session'
-import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
-import {Text} from '#/view/com/util/text/Text'
-import * as Toast from '#/view/com/util/Toast'
-import {EditableUserAvatar} from '#/view/com/util/UserAvatar'
-
-const MAX_NAME = 64 // todo
-const MAX_DESCRIPTION = 300 // todo
-
-export const snapPoints = ['fullscreen']
-
-export function Component({
- purpose,
- onSave,
- list,
-}: {
- purpose?: string
- onSave?: (uri: string) => void
- list?: AppBskyGraphDefs.ListView
-}) {
- const {closeModal} = useModalControls()
- const {isMobile} = useWebMediaQueries()
- const [error, setError] = useState('')
- const pal = usePalette('default')
- const theme = useTheme()
- const {_} = useLingui()
- const listCreateMutation = useListCreateMutation()
- const listMetadataMutation = useListMetadataMutation()
- const agent = useAgent()
-
- const activePurpose = useMemo(() => {
- if (list?.purpose) {
- return list.purpose
- }
- if (purpose) {
- return purpose
- }
- return 'app.bsky.graph.defs#curatelist'
- }, [list, purpose])
- const isCurateList = activePurpose === 'app.bsky.graph.defs#curatelist'
-
- const [isProcessing, setProcessing] = useState(false)
- const [name, setName] = useState(list?.name || '')
-
- const [descriptionRt, setDescriptionRt] = useState(() => {
- const text = list?.description
- const facets = list?.descriptionFacets
-
- if (!text || !facets) {
- return new RichTextAPI({text: text || ''})
- }
-
- // We want to be working with a blank state here, so let's get the
- // serialized version and turn it back into a RichText
- const serialized = richTextToString(new RichTextAPI({text, facets}), false)
-
- const richText = new RichTextAPI({text: serialized})
- richText.detectFacetsWithoutResolution()
-
- return richText
- })
- const graphemeLength = useMemo(() => {
- return shortenLinks(descriptionRt).graphemeLength
- }, [descriptionRt])
- const isDescriptionOver = graphemeLength > MAX_DESCRIPTION
-
- const [avatar, setAvatar] = useState(list?.avatar)
- const [newAvatar, setNewAvatar] = useState()
-
- const onDescriptionChange = useCallback(
- (newText: string) => {
- const richText = new RichTextAPI({text: newText})
- richText.detectFacetsWithoutResolution()
-
- setDescriptionRt(richText)
- },
- [setDescriptionRt],
- )
-
- const onPressCancel = useCallback(() => {
- closeModal()
- }, [closeModal])
-
- const onSelectNewAvatar = useCallback(
- (img: ImageMeta | null) => {
- if (!img) {
- setNewAvatar(null)
- setAvatar(undefined)
- return
- }
- try {
- setNewAvatar(img)
- setAvatar(img.path)
- } catch (e: any) {
- setError(cleanError(e))
- }
- },
- [setNewAvatar, setAvatar, setError],
- )
-
- const onPressSave = useCallback(async () => {
- const nameTrimmed = name.trim()
- if (!nameTrimmed) {
- setError(_(msg`Name is required`))
- return
- }
- setProcessing(true)
- if (error) {
- setError('')
- }
- try {
- let richText = new RichTextAPI(
- {text: descriptionRt.text.trimEnd()},
- {cleanNewlines: true},
- )
-
- await richText.detectFacets(agent)
- richText = shortenLinks(richText)
- richText = stripInvalidMentions(richText)
-
- if (list) {
- await listMetadataMutation.mutateAsync({
- uri: list.uri,
- name: nameTrimmed,
- description: richText.text,
- descriptionFacets: richText.facets,
- avatar: newAvatar,
- })
- Toast.show(
- isCurateList
- ? _(msg({message: 'User list updated', context: 'toast'}))
- : _(msg({message: 'Moderation list updated', context: 'toast'})),
- )
- onSave?.(list.uri)
- } else {
- const res = await listCreateMutation.mutateAsync({
- purpose: activePurpose,
- name,
- description: richText.text,
- descriptionFacets: richText.facets,
- avatar: newAvatar,
- })
- Toast.show(
- isCurateList
- ? _(msg({message: 'User list created', context: 'toast'}))
- : _(msg({message: 'Moderation list created', context: 'toast'})),
- )
- onSave?.(res.uri)
- }
- closeModal()
- } catch (e: any) {
- if (isNetworkError(e)) {
- setError(
- _(
- msg`Failed to create the list. Check your internet connection and try again.`,
- ),
- )
- } else {
- setError(cleanError(e))
- }
- }
- setProcessing(false)
- }, [
- setProcessing,
- setError,
- error,
- onSave,
- closeModal,
- activePurpose,
- isCurateList,
- name,
- descriptionRt,
- newAvatar,
- list,
- listMetadataMutation,
- listCreateMutation,
- _,
- agent,
- ])
-
- return (
-
-
-
- {isCurateList ? (
- list ? (
- Edit User List
- ) : (
- New User List
- )
- ) : list ? (
- Edit Moderation List
- ) : (
- New Moderation List
- )}
-
- {error !== '' && (
-
-
-
- )}
-
- List Avatar
-
-
-
-
-
-
-
-
- List Name
-
-
- setName(enforceLen(v, MAX_NAME))}
- accessible={true}
- accessibilityLabel={_(msg`Name`)}
- accessibilityHint=""
- accessibilityLabelledBy="list-name"
- />
-
-
-
-
- Description
-
-
- {graphemeLength}/{MAX_DESCRIPTION}
-
-
-
-
- {isProcessing ? (
-
-
-
- ) : (
-
-
-
- Save
-
-
-
- )}
-
-
-
- Cancel
-
-
-
-
-
-
- )
-}
-
-const styles = StyleSheet.create({
- title: {
- textAlign: 'center',
- fontWeight: '600',
- fontSize: 24,
- marginBottom: 18,
- },
- labelWrapper: {
- flexDirection: 'row',
- gap: 8,
- alignItems: 'center',
- justifyContent: 'space-between',
- paddingHorizontal: 4,
- paddingBottom: 4,
- marginTop: 20,
- },
- label: {
- fontWeight: '600',
- },
- form: {
- paddingHorizontal: 6,
- },
- textInput: {
- borderWidth: 1,
- borderRadius: 6,
- paddingHorizontal: 14,
- paddingVertical: 10,
- fontSize: 16,
- },
- textArea: {
- borderWidth: 1,
- borderRadius: 6,
- paddingHorizontal: 12,
- paddingTop: 10,
- fontSize: 16,
- height: 100,
- textAlignVertical: 'top',
- },
- btn: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- width: '100%',
- borderRadius: 32,
- padding: 10,
- marginBottom: 10,
- },
- avi: {
- width: 84,
- height: 84,
- borderWidth: 2,
- borderRadius: 42,
- marginTop: 4,
- },
- errorContainer: {marginTop: 20},
-})
diff --git a/src/view/com/modals/CropImage.web.tsx b/src/view/com/modals/CropImage.web.tsx
deleted file mode 100644
index 78c0466f0b..0000000000
--- a/src/view/com/modals/CropImage.web.tsx
+++ /dev/null
@@ -1,145 +0,0 @@
-import React from 'react'
-import {StyleSheet, TouchableOpacity, View} from 'react-native'
-import {manipulateAsync, SaveFormat} from 'expo-image-manipulator'
-import {LinearGradient} from 'expo-linear-gradient'
-import {msg, Trans} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-import ReactCrop, {type PercentCrop} from 'react-image-crop'
-
-import {usePalette} from '#/lib/hooks/usePalette'
-import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
-import {type PickerImage} from '#/lib/media/picker.shared'
-import {getDataUriSize} from '#/lib/media/util'
-import {gradients, s} from '#/lib/styles'
-import {useModalControls} from '#/state/modals'
-import {Text} from '#/view/com/util/text/Text'
-
-export const snapPoints = ['0%']
-
-export function Component({
- uri,
- aspect,
- circular,
- onSelect,
-}: {
- uri: string
- aspect?: number
- circular?: boolean
- onSelect: (img?: PickerImage) => void
-}) {
- const pal = usePalette('default')
- const {_} = useLingui()
-
- const {closeModal} = useModalControls()
- const {isMobile} = useWebMediaQueries()
-
- const imageRef = React.useRef(null)
- const [crop, setCrop] = React.useState()
-
- const isEmpty = !crop || (crop.width || crop.height) === 0
-
- const onPressCancel = () => {
- onSelect(undefined)
- closeModal()
- }
- const onPressDone = async () => {
- const img = imageRef.current!
-
- const result = await manipulateAsync(
- uri,
- isEmpty
- ? []
- : [
- {
- crop: {
- originX: (crop.x * img.naturalWidth) / 100,
- originY: (crop.y * img.naturalHeight) / 100,
- width: (crop.width * img.naturalWidth) / 100,
- height: (crop.height * img.naturalHeight) / 100,
- },
- },
- ],
- {
- base64: true,
- format: SaveFormat.JPEG,
- },
- )
-
- onSelect({
- path: result.uri,
- mime: 'image/jpeg',
- size: result.base64 !== undefined ? getDataUriSize(result.base64) : 0,
- width: result.width,
- height: result.height,
- })
-
- closeModal()
- }
-
- return (
-
-
- setCrop(percentCrop)}
- circularCrop={circular}>
-
-
-
-
-
-
- Cancel
-
-
-
-
-
-
- Done
-
-
-
-
-
- )
-}
-
-const styles = StyleSheet.create({
- cropper: {
- marginLeft: 'auto',
- marginRight: 'auto',
- borderWidth: 1,
- borderRadius: 4,
- overflow: 'hidden',
- alignItems: 'center',
- },
- ctrls: {
- flexDirection: 'row',
- alignItems: 'center',
- marginTop: 10,
- },
- btns: {
- flexDirection: 'row',
- alignItems: 'center',
- marginTop: 10,
- },
- btn: {
- borderRadius: 4,
- paddingVertical: 8,
- paddingHorizontal: 24,
- },
-})
diff --git a/src/view/com/modals/InviteCodes.tsx b/src/view/com/modals/InviteCodes.tsx
deleted file mode 100644
index 93f7490625..0000000000
--- a/src/view/com/modals/InviteCodes.tsx
+++ /dev/null
@@ -1,287 +0,0 @@
-import React from 'react'
-import {
- ActivityIndicator,
- StyleSheet,
- TouchableOpacity,
- View,
-} from 'react-native'
-import {setStringAsync} from 'expo-clipboard'
-import {type ComAtprotoServerDefs} from '@atproto/api'
-import {
- FontAwesomeIcon,
- type FontAwesomeIconStyle,
-} from '@fortawesome/react-native-fontawesome'
-import {msg, Trans} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-
-import {usePalette} from '#/lib/hooks/usePalette'
-import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
-import {makeProfileLink} from '#/lib/routes/links'
-import {cleanError} from '#/lib/strings/errors'
-import {isWeb} from '#/platform/detection'
-import {useInvitesAPI, useInvitesState} from '#/state/invites'
-import {useModalControls} from '#/state/modals'
-import {
- type InviteCodesQueryResponse,
- useInviteCodesQuery,
-} from '#/state/queries/invites'
-import {ErrorMessage} from '../util/error/ErrorMessage'
-import {Button} from '../util/forms/Button'
-import {Link} from '../util/Link'
-import {Text} from '../util/text/Text'
-import * as Toast from '../util/Toast'
-import {UserInfoText} from '../util/UserInfoText'
-import {ScrollView} from './util'
-
-export const snapPoints = ['70%']
-
-export function Component() {
- const {isLoading, data: invites, error} = useInviteCodesQuery()
-
- return error ? (
-
- ) : isLoading || !invites ? (
-
-
-
- ) : (
-
- )
-}
-
-export function Inner({invites}: {invites: InviteCodesQueryResponse}) {
- const pal = usePalette('default')
- const {_} = useLingui()
- const {closeModal} = useModalControls()
- const {isTabletOrDesktop} = useWebMediaQueries()
-
- const onClose = React.useCallback(() => {
- closeModal()
- }, [closeModal])
-
- if (invites.all.length === 0) {
- return (
-
-
-
-
- You don't have any invite codes yet! We'll send you some when
- you've been on Bluesky for a little longer.
-
-
-
-
-
-
-
-
- )
- }
-
- return (
-
-
- Invite a Friend
-
-
-
- Each code works once. You'll receive more invite codes periodically.
-
-
-
- {invites.available.map((invite, i) => (
-
- ))}
- {invites.used.map((invite, i) => (
-
- ))}
-
-
-
-
-
- )
-}
-
-function InviteCode({
- testID,
- invite,
- used,
- invites,
-}: {
- testID: string
- invite: ComAtprotoServerDefs.InviteCode
- used?: boolean
- invites: InviteCodesQueryResponse
-}) {
- const pal = usePalette('default')
- const {_} = useLingui()
- const invitesState = useInvitesState()
- const {setInviteCopied} = useInvitesAPI()
- const uses = invite.uses
-
- const onPress = React.useCallback(() => {
- setStringAsync(invite.code)
- Toast.show(_(msg`Copied to clipboard`), 'clipboard-check')
- setInviteCopied(invite.code)
- }, [setInviteCopied, invite, _])
-
- return (
-
-
-
- {invite.code}
-
-
- {!used && invitesState.copiedInvites.includes(invite.code) && (
-
- Copied
-
- )}
- {!used && (
-
- )}
-
- {uses.length > 0 ? (
-
-
- Used by:{' '}
- {uses.map((use, i) => (
-
-
- {i !== uses.length - 1 && , }
-
- ))}
-
-
- ) : null}
-
- )
-}
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- paddingBottom: isWeb ? 0 : 50,
- },
- title: {
- textAlign: 'center',
- marginTop: 12,
- marginBottom: 12,
- },
- description: {
- textAlign: 'center',
- paddingHorizontal: 42,
- marginBottom: 14,
- },
-
- scrollContainer: {
- flex: 1,
- borderTopWidth: 1,
- marginTop: 4,
- marginBottom: 16,
- },
-
- flex1: {
- flex: 1,
- },
- empty: {
- paddingHorizontal: 20,
- paddingVertical: 20,
- borderRadius: 16,
- marginHorizontal: 24,
- marginTop: 10,
- },
- emptyText: {
- textAlign: 'center',
- },
-
- inviteCode: {
- flexDirection: 'row',
- alignItems: 'center',
- },
- codeCopied: {
- marginRight: 8,
- },
- strikeThrough: {
- textDecorationLine: 'line-through',
- textDecorationStyle: 'solid',
- },
-
- btnContainer: {
- flexDirection: 'row',
- justifyContent: 'center',
- },
- btnContainerDesktop: {
- marginTop: 14,
- },
- btn: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- borderRadius: 32,
- paddingHorizontal: 60,
- paddingVertical: 14,
- },
- btnLabel: {
- fontSize: 18,
- },
-})
diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx
index d44f79a740..4ebec459dd 100644
--- a/src/view/com/modals/Modal.tsx
+++ b/src/view/com/modals/Modal.tsx
@@ -8,7 +8,6 @@ import {useModalControls, useModals} from '#/state/modals'
import {FullWindowOverlay} from '#/components/FullWindowOverlay'
import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop'
import * as DeleteAccountModal from './DeleteAccount'
-import * as InviteCodesModal from './InviteCodes'
import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings'
import * as UserAddRemoveListsModal from './UserAddRemoveLists'
@@ -49,9 +48,6 @@ export function ModalsContainer() {
} else if (activeModal?.name === 'delete-account') {
snapPoints = DeleteAccountModal.snapPoints
element =
- } else if (activeModal?.name === 'invite-codes') {
- snapPoints = InviteCodesModal.snapPoints
- element =
} else if (activeModal?.name === 'content-languages-settings') {
snapPoints = ContentLanguagesSettingsModal.snapPoints
element =
diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx
index 555b184b7a..bdf8269925 100644
--- a/src/view/com/modals/Modal.web.tsx
+++ b/src/view/com/modals/Modal.web.tsx
@@ -7,7 +7,6 @@ import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {type Modal as ModalIface} from '#/state/modals'
import {useModalControls, useModals} from '#/state/modals'
import * as DeleteAccountModal from './DeleteAccount'
-import * as InviteCodesModal from './InviteCodes'
import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings'
import * as UserAddRemoveLists from './UserAddRemoveLists'
@@ -51,8 +50,6 @@ function Modal({modal}: {modal: ModalIface}) {
element =
} else if (modal.name === 'delete-account') {
element =
- } else if (modal.name === 'invite-codes') {
- element =
} else if (modal.name === 'content-languages-settings') {
element =
} else {
diff --git a/src/view/com/testing/TestCtrls.e2e.tsx b/src/view/com/testing/TestCtrls.e2e.tsx
index 3fc1032ed5..2b12d62a7f 100644
--- a/src/view/com/testing/TestCtrls.e2e.tsx
+++ b/src/view/com/testing/TestCtrls.e2e.tsx
@@ -3,7 +3,6 @@ import {LogBox, Pressable, View, TextInput} from 'react-native'
import {useQueryClient} from '@tanstack/react-query'
import {BLUESKY_PROXY_HEADER} from '#/lib/constants'
-import {useModalControls} from '#/state/modals'
import {useSessionApi, useAgent} from '#/state/session'
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
import {useOnboardingDispatch} from '#/state/shell/onboarding'
@@ -23,7 +22,6 @@ export function TestCtrls() {
const agent = useAgent()
const queryClient = useQueryClient()
const {logoutEveryAccount, login} = useSessionApi()
- const {openModal} = useModalControls()
const onboardingDispatch = useOnboardingDispatch()
const {setShowLoggedOut} = useLoggedOutViewControls()
const onPressSignInAlice = async () => {
@@ -121,12 +119,6 @@ export function TestCtrls() {
accessibilityRole="button"
style={BTN}
/>
- openModal({name: 'invite-codes'})}
- accessibilityRole="button"
- style={BTN}
- />
setShowLoggedOut(true)}