diff options
Diffstat (limited to 'src/view/com/modals')
27 files changed, 127 insertions, 102 deletions
diff --git a/src/view/com/modals/AddAppPasswords.tsx b/src/view/com/modals/AddAppPasswords.tsx index 29763620f..621c61b90 100644 --- a/src/view/com/modals/AddAppPasswords.tsx +++ b/src/view/com/modals/AddAppPasswords.tsx @@ -13,6 +13,7 @@ import { import Clipboard from '@react-native-clipboard/clipboard' import * as Toast from '../util/Toast' import {logger} from '#/logger' +import {useModalControls} from '#/state/modals' export const snapPoints = ['70%'] @@ -54,6 +55,7 @@ const shadesOfBlue: string[] = [ export function Component({}: {}) { const pal = usePalette('default') const store = useStores() + const {closeModal} = useModalControls() const [name, setName] = useState( shadesOfBlue[Math.floor(Math.random() * shadesOfBlue.length)], ) @@ -69,8 +71,8 @@ export function Component({}: {}) { }, [appPassword]) const onDone = React.useCallback(() => { - store.shell.closeModal() - }, [store]) + closeModal() + }, [closeModal]) const createAppPassword = async () => { // if name is all whitespace, we don't allow it diff --git a/src/view/com/modals/AltImage.tsx b/src/view/com/modals/AltImage.tsx index c084e84a3..9c377a121 100644 --- a/src/view/com/modals/AltImage.tsx +++ b/src/view/com/modals/AltImage.tsx @@ -17,9 +17,9 @@ import {MAX_ALT_TEXT} from 'lib/constants' import {useTheme} from 'lib/ThemeContext' import {Text} from '../util/text/Text' import LinearGradient from 'react-native-linear-gradient' -import {useStores} from 'state/index' import {isAndroid, isWeb} from 'platform/detection' import {ImageModel} from 'state/models/media/image' +import {useModalControls} from '#/state/modals' export const snapPoints = ['fullscreen'] @@ -29,10 +29,10 @@ interface Props { export function Component({image}: Props) { const pal = usePalette('default') - const store = useStores() const theme = useTheme() const [altText, setAltText] = useState(image.altText) const windim = useWindowDimensions() + const {closeModal} = useModalControls() const imageStyles = useMemo<ImageStyle>(() => { const maxWidth = isWeb ? 450 : windim.width @@ -53,11 +53,11 @@ export function Component({image}: Props) { const onPressSave = useCallback(() => { image.setAltText(altText) - store.shell.closeModal() - }, [store, image, altText]) + closeModal() + }, [closeModal, image, altText]) const onPressCancel = () => { - store.shell.closeModal() + closeModal() } return ( diff --git a/src/view/com/modals/BirthDateSettings.tsx b/src/view/com/modals/BirthDateSettings.tsx index 6927ba8d2..7b0778f83 100644 --- a/src/view/com/modals/BirthDateSettings.tsx +++ b/src/view/com/modals/BirthDateSettings.tsx @@ -15,12 +15,14 @@ import {usePalette} from 'lib/hooks/usePalette' import {isWeb} from 'platform/detection' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {cleanError} from 'lib/strings/errors' +import {useModalControls} from '#/state/modals' export const snapPoints = ['50%'] export const Component = observer(function Component({}: {}) { const pal = usePalette('default') const store = useStores() + const {closeModal} = useModalControls() const [date, setDate] = useState<Date>( store.preferences.birthDate || new Date(), ) @@ -33,7 +35,7 @@ export const Component = observer(function Component({}: {}) { setIsProcessing(true) try { await store.preferences.setBirthDate(date) - store.shell.closeModal() + closeModal() } catch (e) { setError(cleanError(String(e))) } finally { diff --git a/src/view/com/modals/ChangeEmail.tsx b/src/view/com/modals/ChangeEmail.tsx index 012570556..ec37aeede 100644 --- a/src/view/com/modals/ChangeEmail.tsx +++ b/src/view/com/modals/ChangeEmail.tsx @@ -12,6 +12,7 @@ import {usePalette} from 'lib/hooks/usePalette' import {isWeb} from 'platform/detection' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {cleanError} from 'lib/strings/errors' +import {useModalControls} from '#/state/modals' enum Stages { InputEmail, @@ -32,6 +33,7 @@ export const Component = observer(function Component({}: {}) { const [isProcessing, setIsProcessing] = useState<boolean>(false) const [error, setError] = useState<string>('') const {isMobile} = useWebMediaQueries() + const {openModal, closeModal} = useModalControls() const onRequestChange = async () => { if (email === store.session.currentSession?.email) { @@ -90,8 +92,8 @@ export const Component = observer(function Component({}: {}) { } const onVerify = async () => { - store.shell.closeModal() - store.shell.openModal({name: 'verify-email'}) + closeModal() + openModal({name: 'verify-email'}) } return ( @@ -207,7 +209,7 @@ export const Component = observer(function Component({}: {}) { <Button testID="cancelBtn" type="default" - onPress={() => store.shell.closeModal()} + onPress={() => closeModal()} accessibilityLabel="Cancel" accessibilityHint="" label="Cancel" diff --git a/src/view/com/modals/ChangeHandle.tsx b/src/view/com/modals/ChangeHandle.tsx index c54c1c043..6184cb3b7 100644 --- a/src/view/com/modals/ChangeHandle.tsx +++ b/src/view/com/modals/ChangeHandle.tsx @@ -22,6 +22,7 @@ import {useTheme} from 'lib/ThemeContext' import {useAnalytics} from 'lib/analytics/analytics' import {cleanError} from 'lib/strings/errors' import {logger} from '#/logger' +import {useModalControls} from '#/state/modals' export const snapPoints = ['100%'] @@ -30,6 +31,7 @@ export function Component({onChanged}: {onChanged: () => void}) { const [error, setError] = useState<string>('') const pal = usePalette('default') const {track} = useAnalytics() + const {closeModal} = useModalControls() const [isProcessing, setProcessing] = useState<boolean>(false) const [retryDescribeTrigger, setRetryDescribeTrigger] = React.useState<any>( @@ -85,8 +87,8 @@ export function Component({onChanged}: {onChanged: () => void}) { // events // = const onPressCancel = React.useCallback(() => { - store.shell.closeModal() - }, [store]) + closeModal() + }, [closeModal]) const onPressRetryConnect = React.useCallback( () => setRetryDescribeTrigger({}), [setRetryDescribeTrigger], @@ -110,7 +112,7 @@ export function Component({onChanged}: {onChanged: () => void}) { await store.agent.updateHandle({ handle: newHandle, }) - store.shell.closeModal() + closeModal() onChanged() } catch (err: any) { setError(cleanError(err)) @@ -127,6 +129,7 @@ export function Component({onChanged}: {onChanged: () => void}) { isCustom, onChanged, track, + closeModal, ]) // rendering diff --git a/src/view/com/modals/Confirm.tsx b/src/view/com/modals/Confirm.tsx index c1324b1cb..6b942057b 100644 --- a/src/view/com/modals/Confirm.tsx +++ b/src/view/com/modals/Confirm.tsx @@ -6,13 +6,13 @@ import { View, } from 'react-native' import {Text} from '../util/text/Text' -import {useStores} from 'state/index' import {s, colors} from 'lib/styles' import {ErrorMessage} from '../util/error/ErrorMessage' import {cleanError} from 'lib/strings/errors' import {usePalette} from 'lib/hooks/usePalette' import {isWeb} from 'platform/detection' -import type {ConfirmModal} from 'state/models/ui/shell' +import type {ConfirmModal} from '#/state/modals' +import {useModalControls} from '#/state/modals' export const snapPoints = ['50%'] @@ -26,7 +26,7 @@ export function Component({ cancelBtnText, }: ConfirmModal) { const pal = usePalette('default') - const store = useStores() + const {closeModal} = useModalControls() const [isProcessing, setIsProcessing] = useState<boolean>(false) const [error, setError] = useState<string>('') const onPress = async () => { @@ -34,7 +34,7 @@ export function Component({ setIsProcessing(true) try { await onPressConfirm() - store.shell.closeModal() + closeModal() return } catch (e: any) { setError(cleanError(e)) diff --git a/src/view/com/modals/ContentFilteringSettings.tsx b/src/view/com/modals/ContentFilteringSettings.tsx index 9075d0272..0891a6473 100644 --- a/src/view/com/modals/ContentFilteringSettings.tsx +++ b/src/view/com/modals/ContentFilteringSettings.tsx @@ -16,6 +16,7 @@ import {isIOS} from 'platform/detection' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import * as Toast from '../util/Toast' import {logger} from '#/logger' +import {useModalControls} from '#/state/modals' export const snapPoints = ['90%'] @@ -24,14 +25,15 @@ export const Component = observer( const store = useStores() const {isMobile} = useWebMediaQueries() const pal = usePalette('default') + const {closeModal} = useModalControls() React.useEffect(() => { store.preferences.sync() }, [store]) const onPressDone = React.useCallback(() => { - store.shell.closeModal() - }, [store]) + closeModal() + }, [closeModal]) return ( <View testID="contentFilteringModal" style={[pal.view, styles.container]}> @@ -89,8 +91,9 @@ const AdultContentEnabledPref = observer( function AdultContentEnabledPrefImpl() { const store = useStores() const pal = usePalette('default') + const {openModal} = useModalControls() - const onSetAge = () => store.shell.openModal({name: 'birth-date-settings'}) + const onSetAge = () => openModal({name: 'birth-date-settings'}) const onToggleAdultContent = async () => { if (isIOS) { diff --git a/src/view/com/modals/CreateOrEditList.tsx b/src/view/com/modals/CreateOrEditList.tsx index 1ea12695f..cdad37770 100644 --- a/src/view/com/modals/CreateOrEditList.tsx +++ b/src/view/com/modals/CreateOrEditList.tsx @@ -24,6 +24,7 @@ import {useTheme} from 'lib/ThemeContext' import {useAnalytics} from 'lib/analytics/analytics' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {cleanError, isNetworkError} from 'lib/strings/errors' +import {useModalControls} from '#/state/modals' const MAX_NAME = 64 // todo const MAX_DESCRIPTION = 300 // todo @@ -40,6 +41,7 @@ export function Component({ list?: ListModel }) { const store = useStores() + const {closeModal} = useModalControls() const {isMobile} = useWebMediaQueries() const [error, setError] = useState<string>('') const pal = usePalette('default') @@ -67,8 +69,8 @@ export function Component({ const [newAvatar, setNewAvatar] = useState<RNImage | undefined | null>() const onPressCancel = useCallback(() => { - store.shell.closeModal() - }, [store]) + closeModal() + }, [closeModal]) const onSelectNewAvatar = useCallback( async (img: RNImage | null) => { @@ -123,7 +125,7 @@ export function Component({ Toast.show(`${purposeLabel} list created`) onSave?.(res.uri) } - store.shell.closeModal() + closeModal() } catch (e: any) { if (isNetworkError(e)) { setError( @@ -141,6 +143,7 @@ export function Component({ error, onSave, store, + closeModal, activePurpose, isCurateList, purposeLabel, diff --git a/src/view/com/modals/DeleteAccount.tsx b/src/view/com/modals/DeleteAccount.tsx index 50a4cd603..9a8a8b4b0 100644 --- a/src/view/com/modals/DeleteAccount.tsx +++ b/src/view/com/modals/DeleteAccount.tsx @@ -17,6 +17,7 @@ import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {ErrorMessage} from '../util/error/ErrorMessage' import {cleanError} from 'lib/strings/errors' import {resetToTab} from '../../../Navigation' +import {useModalControls} from '#/state/modals' export const snapPoints = ['60%'] @@ -24,6 +25,7 @@ export function Component({}: {}) { const pal = usePalette('default') const theme = useTheme() const store = useStores() + const {closeModal} = useModalControls() const {isMobile} = useWebMediaQueries() const [isEmailSent, setIsEmailSent] = React.useState<boolean>(false) const [confirmCode, setConfirmCode] = React.useState<string>('') @@ -55,14 +57,14 @@ export function Component({}: {}) { Toast.show('Your account has been deleted') resetToTab('HomeTab') store.session.clear() - store.shell.closeModal() + closeModal() } catch (e: any) { setError(cleanError(e)) } setIsProcessing(false) } const onCancel = () => { - store.shell.closeModal() + closeModal() } return ( <View style={[styles.container, pal.view]}> diff --git a/src/view/com/modals/EditImage.tsx b/src/view/com/modals/EditImage.tsx index dcb6668c7..a2a458f4c 100644 --- a/src/view/com/modals/EditImage.tsx +++ b/src/view/com/modals/EditImage.tsx @@ -6,7 +6,6 @@ import {gradients, s} from 'lib/styles' import {useTheme} from 'lib/ThemeContext' import {Text} from '../util/text/Text' import LinearGradient from 'react-native-linear-gradient' -import {useStores} from 'state/index' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import ImageEditor, {Position} from 'react-avatar-editor' import {TextInput} from './util' @@ -19,6 +18,7 @@ import {Slider} from '@miblanchard/react-native-slider' import {MaterialIcons} from '@expo/vector-icons' import {observer} from 'mobx-react-lite' import {getKeys} from 'lib/type-assertions' +import {useModalControls} from '#/state/modals' export const snapPoints = ['80%'] @@ -52,9 +52,9 @@ export const Component = observer(function EditImageImpl({ }: Props) { const pal = usePalette('default') const theme = useTheme() - const store = useStores() const windowDimensions = useWindowDimensions() const {isMobile} = useWebMediaQueries() + const {closeModal} = useModalControls() const { aspectRatio, @@ -128,8 +128,8 @@ export const Component = observer(function EditImageImpl({ }, [image]) const onCloseModal = useCallback(() => { - store.shell.closeModal() - }, [store.shell]) + closeModal() + }, [closeModal]) const onPressCancel = useCallback(async () => { await gallery.previous(image) diff --git a/src/view/com/modals/EditProfile.tsx b/src/view/com/modals/EditProfile.tsx index dfd5305f5..f08bb2326 100644 --- a/src/view/com/modals/EditProfile.tsx +++ b/src/view/com/modals/EditProfile.tsx @@ -13,7 +13,6 @@ import LinearGradient from 'react-native-linear-gradient' import {Image as RNImage} from 'react-native-image-crop-picker' import {Text} from '../util/text/Text' import {ErrorMessage} from '../util/error/ErrorMessage' -import {useStores} from 'state/index' import {ProfileModel} from 'state/models/content/profile' import {s, colors, gradients} from 'lib/styles' import {enforceLen} from 'lib/strings/helpers' @@ -27,6 +26,7 @@ import {useAnalytics} from 'lib/analytics/analytics' import {cleanError, isNetworkError} from 'lib/strings/errors' import Animated, {FadeOut} from 'react-native-reanimated' import {isWeb} from 'platform/detection' +import {useModalControls} from '#/state/modals' const AnimatedTouchableOpacity = Animated.createAnimatedComponent(TouchableOpacity) @@ -40,11 +40,11 @@ export function Component({ profileView: ProfileModel onUpdate?: () => void }) { - const store = useStores() const [error, setError] = useState<string>('') const pal = usePalette('default') const theme = useTheme() const {track} = useAnalytics() + const {closeModal} = useModalControls() const [isProcessing, setProcessing] = useState<boolean>(false) const [displayName, setDisplayName] = useState<string>( @@ -66,7 +66,7 @@ export function Component({ RNImage | undefined | null >() const onPressCancel = () => { - store.shell.closeModal() + closeModal() } const onSelectNewAvatar = useCallback( async (img: RNImage | null) => { @@ -123,7 +123,7 @@ export function Component({ ) Toast.show('Profile updated') onUpdate?.() - store.shell.closeModal() + closeModal() } catch (e: any) { if (isNetworkError(e)) { setError( @@ -141,7 +141,7 @@ export function Component({ error, profileView, onUpdate, - store, + closeModal, displayName, description, newUserAvatar, diff --git a/src/view/com/modals/InviteCodes.tsx b/src/view/com/modals/InviteCodes.tsx index a8aa164c3..227b25275 100644 --- a/src/view/com/modals/InviteCodes.tsx +++ b/src/view/com/modals/InviteCodes.tsx @@ -15,6 +15,7 @@ import {ScrollView} from './util' import {usePalette} from 'lib/hooks/usePalette' import {isWeb} from 'platform/detection' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' +import {useModalControls} from '#/state/modals' import {useInvitesState, useInvitesAPI} from '#/state/invites' import {UserInfoText} from '../util/UserInfoText' import {makeProfileLink} from '#/lib/routes/links' @@ -25,11 +26,12 @@ export const snapPoints = ['70%'] export function Component({}: {}) { const pal = usePalette('default') const store = useStores() + const {closeModal} = useModalControls() const {isTabletOrDesktop} = useWebMediaQueries() const onClose = React.useCallback(() => { - store.shell.closeModal() - }, [store]) + closeModal() + }, [closeModal]) if (store.me.invites.length === 0) { return ( diff --git a/src/view/com/modals/LinkWarning.tsx b/src/view/com/modals/LinkWarning.tsx index 67a156af4..751c69b3f 100644 --- a/src/view/com/modals/LinkWarning.tsx +++ b/src/view/com/modals/LinkWarning.tsx @@ -5,12 +5,12 @@ import {observer} from 'mobx-react-lite' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {Text} from '../util/text/Text' import {Button} from '../util/forms/Button' -import {useStores} from 'state/index' import {s, colors} from 'lib/styles' import {usePalette} from 'lib/hooks/usePalette' import {isWeb} from 'platform/detection' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {isPossiblyAUrl, splitApexDomain} from 'lib/strings/url-helpers' +import {useModalControls} from '#/state/modals' export const snapPoints = ['50%'] @@ -22,12 +22,12 @@ export const Component = observer(function Component({ href: string }) { const pal = usePalette('default') - const store = useStores() + const {closeModal} = useModalControls() const {isMobile} = useWebMediaQueries() const potentiallyMisleading = isPossiblyAUrl(text) const onPressVisit = () => { - store.shell.closeModal() + closeModal() Linking.openURL(href) } @@ -83,7 +83,7 @@ export const Component = observer(function Component({ <Button testID="cancelBtn" type="default" - onPress={() => store.shell.closeModal()} + onPress={() => closeModal()} accessibilityLabel="Cancel" accessibilityHint="" label="Cancel" diff --git a/src/view/com/modals/ListAddUser.tsx b/src/view/com/modals/ListAddUser.tsx index a04e2d186..8864ebc78 100644 --- a/src/view/com/modals/ListAddUser.tsx +++ b/src/view/com/modals/ListAddUser.tsx @@ -26,6 +26,7 @@ import {cleanError} from 'lib/strings/errors' import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeHandle} from 'lib/strings/handles' import {HITSLOP_20} from '#/lib/constants' +import {useModalControls} from '#/state/modals' export const snapPoints = ['90%'] @@ -38,6 +39,7 @@ export const Component = observer(function Component({ }) { const pal = usePalette('default') const store = useStores() + const {closeModal} = useModalControls() const {isMobile} = useWebMediaQueries() const [query, setQuery] = useState('') const autocompleteView = useMemo<UserAutocompleteModel>( @@ -146,7 +148,7 @@ export const Component = observer(function Component({ <Button testID="doneBtn" type="default" - onPress={() => store.shell.closeModal()} + onPress={() => closeModal()} accessibilityLabel="Done" accessibilityHint="" label="Done" diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index 5aaa09e87..c1999c5d6 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -3,13 +3,13 @@ import {StyleSheet} from 'react-native' import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context' import {observer} from 'mobx-react-lite' import BottomSheet from '@gorhom/bottom-sheet' -import {useStores} from 'state/index' import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop' import {usePalette} from 'lib/hooks/usePalette' import {timeout} from 'lib/async/timeout' import {navigate} from '../../../Navigation' import once from 'lodash.once' +import {useModals, useModalControls} from '#/state/modals' import * as ConfirmModal from './Confirm' import * as EditProfileModal from './EditProfile' import * as ProfilePreviewModal from './ProfilePreview' @@ -41,17 +41,17 @@ const DEFAULT_SNAPPOINTS = ['90%'] const HANDLE_HEIGHT = 24 export const ModalsContainer = observer(function ModalsContainer() { - const store = useStores() + const {isModalActive, activeModals} = useModals() + const {closeModal} = useModalControls() const bottomSheetRef = useRef<BottomSheet>(null) const pal = usePalette('default') const safeAreaInsets = useSafeAreaInsets() - const activeModal = - store.shell.activeModals[store.shell.activeModals.length - 1] + const activeModal = activeModals[activeModals.length - 1] const navigateOnce = once(navigate) - const onBottomSheetAnimate = (fromIndex: number, toIndex: number) => { + const onBottomSheetAnimate = (_fromIndex: number, toIndex: number) => { if (activeModal?.name === 'profile-preview' && toIndex === 1) { // begin loading the profile screen behind the scenes navigateOnce('Profile', {name: activeModal.did}) @@ -59,7 +59,7 @@ export const ModalsContainer = observer(function ModalsContainer() { } const onBottomSheetChange = async (snapPoint: number) => { if (snapPoint === -1) { - store.shell.closeModal() + closeModal() } else if (activeModal?.name === 'profile-preview' && snapPoint === 1) { await navigateOnce('Profile', {name: activeModal.did}) // There is no particular callback for when the view has actually been presented. @@ -67,21 +67,21 @@ export const ModalsContainer = observer(function ModalsContainer() { // It's acceptable because the data is already being fetched + it usually takes longer anyway. // TODO: Figure out why avatar/cover don't always show instantly from cache. await timeout(200) - store.shell.closeModal() + closeModal() } } const onClose = () => { bottomSheetRef.current?.close() - store.shell.closeModal() + closeModal() } useEffect(() => { - if (store.shell.isModalActive) { + if (isModalActive) { bottomSheetRef.current?.expand() } else { bottomSheetRef.current?.close() } - }, [store.shell.isModalActive, bottomSheetRef, activeModal?.name]) + }, [isModalActive, bottomSheetRef, activeModal?.name]) let needsSafeTopInset = false let snapPoints: (string | number)[] = DEFAULT_SNAPPOINTS @@ -184,12 +184,12 @@ export const ModalsContainer = observer(function ModalsContainer() { snapPoints={snapPoints} topInset={topInset} handleHeight={HANDLE_HEIGHT} - index={store.shell.isModalActive ? 0 : -1} + index={isModalActive ? 0 : -1} enablePanDownToClose android_keyboardInputMode="adjustResize" keyboardBlurBehavior="restore" backdropComponent={ - store.shell.isModalActive ? createCustomBackdrop(onClose) : undefined + isModalActive ? createCustomBackdrop(onClose) : undefined } handleIndicatorStyle={{backgroundColor: pal.text.color}} handleStyle={[styles.handle, pal.view]} diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx index ede845378..65c4ee444 100644 --- a/src/view/com/modals/Modal.web.tsx +++ b/src/view/com/modals/Modal.web.tsx @@ -1,11 +1,11 @@ import React from 'react' import {TouchableWithoutFeedback, StyleSheet, View} from 'react-native' import {observer} from 'mobx-react-lite' -import {useStores} from 'state/index' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import type {Modal as ModalIface} from 'state/models/ui/shell' +import type {Modal as ModalIface} from '#/state/modals' +import {useModals, useModalControls} from '#/state/modals' import * as ConfirmModal from './Confirm' import * as EditProfileModal from './EditProfile' import * as ProfilePreviewModal from './ProfilePreview' @@ -34,15 +34,15 @@ import * as ChangeEmailModal from './ChangeEmail' import * as LinkWarningModal from './LinkWarning' export const ModalsContainer = observer(function ModalsContainer() { - const store = useStores() + const {isModalActive, activeModals} = useModals() - if (!store.shell.isModalActive) { + if (!isModalActive) { return null } return ( <> - {store.shell.activeModals.map((modal, i) => ( + {activeModals.map((modal, i) => ( <Modal key={`modal-${i}`} modal={modal} /> ))} </> @@ -50,11 +50,12 @@ export const ModalsContainer = observer(function ModalsContainer() { }) function Modal({modal}: {modal: ModalIface}) { - const store = useStores() + const {isModalActive} = useModals() + const {closeModal} = useModalControls() const pal = usePalette('default') const {isMobile} = useWebMediaQueries() - if (!store.shell.isModalActive) { + if (!isModalActive) { return null } @@ -62,7 +63,7 @@ function Modal({modal}: {modal: ModalIface}) { if (modal.name === 'crop-image' || modal.name === 'edit-image') { return // dont close on mask presses during crop } - store.shell.closeModal() + closeModal() } const onInnerPress = () => { // TODO: can we use prevent default? diff --git a/src/view/com/modals/ModerationDetails.tsx b/src/view/com/modals/ModerationDetails.tsx index c01312d69..35ddfe2a1 100644 --- a/src/view/com/modals/ModerationDetails.tsx +++ b/src/view/com/modals/ModerationDetails.tsx @@ -1,7 +1,6 @@ import React from 'react' import {StyleSheet, View} from 'react-native' import {ModerationUI} from '@atproto/api' -import {useStores} from 'state/index' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {s} from 'lib/styles' import {Text} from '../util/text/Text' @@ -10,6 +9,7 @@ import {usePalette} from 'lib/hooks/usePalette' import {isWeb} from 'platform/detection' import {listUriToHref} from 'lib/strings/url-helpers' import {Button} from '../util/forms/Button' +import {useModalControls} from '#/state/modals' export const snapPoints = [300] @@ -20,7 +20,7 @@ export function Component({ context: 'account' | 'content' moderation: ModerationUI }) { - const store = useStores() + const {closeModal} = useModalControls() const {isMobile} = useWebMediaQueries() const pal = usePalette('default') @@ -99,10 +99,7 @@ export function Component({ {description} </Text> <View style={s.flex1} /> - <Button - type="primary" - style={styles.btn} - onPress={() => store.shell.closeModal()}> + <Button type="primary" style={styles.btn} onPress={() => closeModal()}> <Text type="button-lg" style={[pal.textLight, s.textCenter, s.white]}> Okay </Text> diff --git a/src/view/com/modals/Repost.tsx b/src/view/com/modals/Repost.tsx index b1862ecbd..13728b62b 100644 --- a/src/view/com/modals/Repost.tsx +++ b/src/view/com/modals/Repost.tsx @@ -1,12 +1,12 @@ import React from 'react' import {StyleSheet, TouchableOpacity, View} from 'react-native' import LinearGradient from 'react-native-linear-gradient' -import {useStores} from 'state/index' import {s, colors, gradients} from 'lib/styles' import {Text} from '../util/text/Text' import {usePalette} from 'lib/hooks/usePalette' import {RepostIcon} from 'lib/icons' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {useModalControls} from '#/state/modals' export const snapPoints = [250] @@ -20,10 +20,10 @@ export function Component({ isReposted: boolean // TODO: Add author into component }) { - const store = useStores() const pal = usePalette('default') + const {closeModal} = useModalControls() const onPress = async () => { - store.shell.closeModal() + closeModal() } return ( diff --git a/src/view/com/modals/SelfLabel.tsx b/src/view/com/modals/SelfLabel.tsx index 820f2895b..242b6a38a 100644 --- a/src/view/com/modals/SelfLabel.tsx +++ b/src/view/com/modals/SelfLabel.tsx @@ -2,7 +2,6 @@ import React, {useState} from 'react' import {StyleSheet, TouchableOpacity, View} from 'react-native' import {observer} from 'mobx-react-lite' import {Text} from '../util/text/Text' -import {useStores} from 'state/index' import {s, colors} from 'lib/styles' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' @@ -10,6 +9,7 @@ import {isWeb} from 'platform/detection' import {Button} from '../util/forms/Button' import {SelectableBtn} from '../util/forms/SelectableBtn' import {ScrollView} from 'view/com/modals/util' +import {useModalControls} from '#/state/modals' const ADULT_CONTENT_LABELS = ['sexual', 'nudity', 'porn'] @@ -25,7 +25,7 @@ export const Component = observer(function Component({ onChange: (labels: string[]) => void }) { const pal = usePalette('default') - const store = useStores() + const {closeModal} = useModalControls() const {isMobile} = useWebMediaQueries() const [selected, setSelected] = useState(labels) @@ -143,7 +143,7 @@ export const Component = observer(function Component({ <TouchableOpacity testID="confirmBtn" onPress={() => { - store.shell.closeModal() + closeModal() }} style={styles.btn} accessibilityRole="button" diff --git a/src/view/com/modals/ServerInput.tsx b/src/view/com/modals/ServerInput.tsx index 13b21fe22..0f8db30b6 100644 --- a/src/view/com/modals/ServerInput.tsx +++ b/src/view/com/modals/ServerInput.tsx @@ -6,26 +6,26 @@ import { } from '@fortawesome/react-native-fontawesome' import {ScrollView, TextInput} from './util' import {Text} from '../util/text/Text' -import {useStores} from 'state/index' import {s, colors} from 'lib/styles' import {usePalette} from 'lib/hooks/usePalette' import {useTheme} from 'lib/ThemeContext' import {LOCAL_DEV_SERVICE, STAGING_SERVICE, PROD_SERVICE} from 'state/index' import {LOGIN_INCLUDE_DEV_SERVERS} from 'lib/build-flags' +import {useModalControls} from '#/state/modals' export const snapPoints = ['80%'] export function Component({onSelect}: {onSelect: (url: string) => void}) { const theme = useTheme() const pal = usePalette('default') - const store = useStores() const [customUrl, setCustomUrl] = useState<string>('') + const {closeModal} = useModalControls() const doSelect = (url: string) => { if (!url.startsWith('http://') && !url.startsWith('https://')) { url = `https://${url}` } - store.shell.closeModal() + closeModal() onSelect(url) } diff --git a/src/view/com/modals/UserAddRemoveLists.tsx b/src/view/com/modals/UserAddRemoveLists.tsx index aeec2e87f..f86e88439 100644 --- a/src/view/com/modals/UserAddRemoveLists.tsx +++ b/src/view/com/modals/UserAddRemoveLists.tsx @@ -21,6 +21,7 @@ import {usePalette} from 'lib/hooks/usePalette' import {isWeb, isAndroid} from 'platform/detection' import isEqual from 'lodash.isequal' import {logger} from '#/logger' +import {useModalControls} from '#/state/modals' export const snapPoints = ['fullscreen'] @@ -36,6 +37,7 @@ export const Component = observer(function UserAddRemoveListsImpl({ onRemove?: (listUri: string) => void }) { const store = useStores() + const {closeModal} = useModalControls() const pal = usePalette('default') const palPrimary = usePalette('primary') const palInverted = usePalette('inverted') @@ -69,8 +71,8 @@ export const Component = observer(function UserAddRemoveListsImpl({ }, [memberships, listsList, store, setSelected, setMembershipsLoaded]) const onPressCancel = useCallback(() => { - store.shell.closeModal() - }, [store]) + closeModal() + }, [closeModal]) const onPressSave = useCallback(async () => { let changes @@ -87,8 +89,8 @@ export const Component = observer(function UserAddRemoveListsImpl({ for (const uri of changes.removed) { onRemove?.(uri) } - store.shell.closeModal() - }, [store, selected, memberships, onAdd, onRemove]) + closeModal() + }, [closeModal, selected, memberships, onAdd, onRemove]) const onToggleSelected = useCallback( (uri: string) => { diff --git a/src/view/com/modals/VerifyEmail.tsx b/src/view/com/modals/VerifyEmail.tsx index 9fe8811b0..3adaffb14 100644 --- a/src/view/com/modals/VerifyEmail.tsx +++ b/src/view/com/modals/VerifyEmail.tsx @@ -20,6 +20,7 @@ import {usePalette} from 'lib/hooks/usePalette' import {isWeb} from 'platform/detection' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {cleanError} from 'lib/strings/errors' +import {useModalControls} from '#/state/modals' export const snapPoints = ['90%'] @@ -43,6 +44,7 @@ export const Component = observer(function Component({ const [isProcessing, setIsProcessing] = useState<boolean>(false) const [error, setError] = useState<string>('') const {isMobile} = useWebMediaQueries() + const {openModal, closeModal} = useModalControls() const onSendEmail = async () => { setError('') @@ -67,7 +69,7 @@ export const Component = observer(function Component({ }) store.session.updateLocalAccountData({emailConfirmed: true}) Toast.show('Email verified') - store.shell.closeModal() + closeModal() } catch (e) { setError(cleanError(String(e))) } finally { @@ -76,8 +78,8 @@ export const Component = observer(function Component({ } const onEmailIncorrect = () => { - store.shell.closeModal() - store.shell.openModal({name: 'change-email'}) + closeModal() + openModal({name: 'change-email'}) } return ( @@ -224,7 +226,7 @@ export const Component = observer(function Component({ <Button testID="cancelBtn" type="default" - onPress={() => store.shell.closeModal()} + onPress={() => closeModal()} accessibilityLabel={ stage === Stages.Reminder ? 'Not right now' : 'Cancel' } diff --git a/src/view/com/modals/Waitlist.tsx b/src/view/com/modals/Waitlist.tsx index 0fb371fe4..219bdc583 100644 --- a/src/view/com/modals/Waitlist.tsx +++ b/src/view/com/modals/Waitlist.tsx @@ -12,19 +12,19 @@ import { } from '@fortawesome/react-native-fontawesome' import LinearGradient from 'react-native-linear-gradient' import {Text} from '../util/text/Text' -import {useStores} from 'state/index' import {s, gradients} from 'lib/styles' import {usePalette} from 'lib/hooks/usePalette' import {useTheme} from 'lib/ThemeContext' import {ErrorMessage} from '../util/error/ErrorMessage' import {cleanError} from 'lib/strings/errors' +import {useModalControls} from '#/state/modals' export const snapPoints = ['80%'] export function Component({}: {}) { const pal = usePalette('default') const theme = useTheme() - const store = useStores() + const {closeModal} = useModalControls() const [email, setEmail] = React.useState<string>('') const [isEmailSent, setIsEmailSent] = React.useState<boolean>(false) const [isProcessing, setIsProcessing] = React.useState<boolean>(false) @@ -54,7 +54,7 @@ export function Component({}: {}) { setIsProcessing(false) } const onCancel = () => { - store.shell.closeModal() + closeModal() } return ( diff --git a/src/view/com/modals/crop-image/CropImage.web.tsx b/src/view/com/modals/crop-image/CropImage.web.tsx index 8e35201d1..c88d002a9 100644 --- a/src/view/com/modals/crop-image/CropImage.web.tsx +++ b/src/view/com/modals/crop-image/CropImage.web.tsx @@ -7,10 +7,10 @@ import {Text} from 'view/com/util/text/Text' import {Dimensions} from 'lib/media/types' import {getDataUriSize} from 'lib/media/util' import {s, gradients} from 'lib/styles' -import {useStores} from 'state/index' import {usePalette} from 'lib/hooks/usePalette' import {SquareIcon, RectWideIcon, RectTallIcon} from 'lib/icons' import {Image as RNImage} from 'react-native-image-crop-picker' +import {useModalControls} from '#/state/modals' enum AspectRatio { Square = 'square', @@ -33,7 +33,7 @@ export function Component({ uri: string onSelect: (img?: RNImage) => void }) { - const store = useStores() + const {closeModal} = useModalControls() const pal = usePalette('default') const [as, setAs] = React.useState<AspectRatio>(AspectRatio.Square) const [scale, setScale] = React.useState<number>(1) @@ -43,7 +43,7 @@ export function Component({ const onPressCancel = () => { onSelect(undefined) - store.shell.closeModal() + closeModal() } const onPressDone = () => { const canvas = editorRef.current?.getImageScaledToCanvas() @@ -59,7 +59,7 @@ export function Component({ } else { onSelect(undefined) } - store.shell.closeModal() + closeModal() } let cropperStyle diff --git a/src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx b/src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx index 659245616..d37d51e47 100644 --- a/src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx +++ b/src/view/com/modals/lang-settings/ContentLanguagesSettings.tsx @@ -1,7 +1,6 @@ import React from 'react' import {StyleSheet, View} from 'react-native' import {ScrollView} from '../util' -import {useStores} from 'state/index' import {Text} from '../../util/text/Text' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' @@ -9,6 +8,7 @@ import {deviceLocales} from 'platform/detection' import {LANGUAGES, LANGUAGES_MAP_CODE2} from '../../../../locale/languages' import {LanguageToggle} from './LanguageToggle' import {ConfirmLanguagesButton} from './ConfirmLanguagesButton' +import {useModalControls} from '#/state/modals' import { useLanguagePrefs, useSetLanguagePrefs, @@ -18,14 +18,14 @@ import { export const snapPoints = ['100%'] export function Component({}: {}) { - const store = useStores() + const {closeModal} = useModalControls() const langPrefs = useLanguagePrefs() const setLangPrefs = useSetLanguagePrefs() const pal = usePalette('default') const {isMobile} = useWebMediaQueries() const onPressDone = React.useCallback(() => { - store.shell.closeModal() - }, [store]) + closeModal() + }, [closeModal]) const languages = React.useMemo(() => { const langs = LANGUAGES.filter( diff --git a/src/view/com/modals/lang-settings/PostLanguagesSettings.tsx b/src/view/com/modals/lang-settings/PostLanguagesSettings.tsx index 435fb9e1a..4a39da752 100644 --- a/src/view/com/modals/lang-settings/PostLanguagesSettings.tsx +++ b/src/view/com/modals/lang-settings/PostLanguagesSettings.tsx @@ -2,7 +2,6 @@ import React from 'react' import {StyleSheet, View} from 'react-native' import {observer} from 'mobx-react-lite' import {ScrollView} from '../util' -import {useStores} from 'state/index' import {Text} from '../../util/text/Text' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' @@ -10,6 +9,7 @@ import {deviceLocales} from 'platform/detection' import {LANGUAGES, LANGUAGES_MAP_CODE2} from '../../../../locale/languages' import {ConfirmLanguagesButton} from './ConfirmLanguagesButton' import {ToggleButton} from 'view/com/util/forms/ToggleButton' +import {useModalControls} from '#/state/modals' import { useLanguagePrefs, useSetLanguagePrefs, @@ -20,14 +20,14 @@ import { export const snapPoints = ['100%'] export const Component = observer(function PostLanguagesSettingsImpl() { - const store = useStores() + const {closeModal} = useModalControls() const langPrefs = useLanguagePrefs() const setLangPrefs = useSetLanguagePrefs() const pal = usePalette('default') const {isMobile} = useWebMediaQueries() const onPressDone = React.useCallback(() => { - store.shell.closeModal() - }, [store]) + closeModal() + }, [closeModal]) const languages = React.useMemo(() => { const langs = LANGUAGES.filter( diff --git a/src/view/com/modals/report/Modal.tsx b/src/view/com/modals/report/Modal.tsx index 98aa2d471..8dc3f53f7 100644 --- a/src/view/com/modals/report/Modal.tsx +++ b/src/view/com/modals/report/Modal.tsx @@ -14,6 +14,7 @@ import {SendReportButton} from './SendReportButton' import {InputIssueDetails} from './InputIssueDetails' import {ReportReasonOptions} from './ReasonOptions' import {CollectionId} from './types' +import {useModalControls} from '#/state/modals' const DMCA_LINK = 'https://blueskyweb.xyz/support/copyright' @@ -37,6 +38,7 @@ type ReportComponentProps = export function Component(content: ReportComponentProps) { const store = useStores() + const {closeModal} = useModalControls() const pal = usePalette('default') const {isMobile} = useWebMediaQueries() const [isProcessing, setIsProcessing] = useState(false) @@ -60,7 +62,7 @@ export function Component(content: ReportComponentProps) { try { if (issue === '__copyright__') { Linking.openURL(DMCA_LINK) - store.shell.closeModal() + closeModal() return } const $type = !isAccountReport @@ -76,7 +78,7 @@ export function Component(content: ReportComponentProps) { }) Toast.show("Thank you for your report! We'll look into it promptly.") - store.shell.closeModal() + closeModal() return } catch (e: any) { setError(cleanError(e)) |