Add modal state provider, replace usage except methods (#1833)

* Add modal state provider, replace usage except methods

* Replace easy spots

* Fix sticky spots

* Replace final usages

* Memorize context objects

* Add more warnings
This commit is contained in:
Eric Bailey 2023-11-08 12:34:10 -06:00 committed by GitHub
parent 5eadadffbf
commit f18b15241a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
70 changed files with 634 additions and 498 deletions

View file

@ -17,6 +17,7 @@ import {useFocusEffect} from '@react-navigation/native'
import {ViewHeader} from '../com/util/ViewHeader'
import {CenteredView} from 'view/com/util/Views'
import {useSetMinimalShellMode} from '#/state/shell'
import {useModalControls} from '#/state/modals'
import {useLanguagePrefs} from '#/state/preferences'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppPasswords'>
@ -27,6 +28,7 @@ export const AppPasswords = withAuthRequired(
const setMinimalShellMode = useSetMinimalShellMode()
const {screen} = useAnalytics()
const {isTabletOrDesktop} = useWebMediaQueries()
const {openModal} = useModalControls()
useFocusEffect(
React.useCallback(() => {
@ -36,8 +38,8 @@ export const AppPasswords = withAuthRequired(
)
const onAdd = React.useCallback(async () => {
store.shell.openModal({name: 'add-app-password'})
}, [store])
openModal({name: 'add-app-password'})
}, [openModal])
// no app passwords (empty) state
if (store.me.appPasswords.length === 0) {
@ -162,10 +164,11 @@ function AppPassword({
}) {
const pal = usePalette('default')
const store = useStores()
const {openModal} = useModalControls()
const {contentLanguages} = useLanguagePrefs()
const onDelete = React.useCallback(async () => {
store.shell.openModal({
openModal({
name: 'confirm',
title: 'Delete App Password',
message: `Are you sure you want to delete the app password "${name}"?`,
@ -174,7 +177,7 @@ function AppPassword({
Toast.show('App password deleted')
},
})
}, [store, name])
}, [store, openModal, name])
const primaryLocale =
contentLanguages.length > 0 ? contentLanguages[0] : 'en-US'

View file

@ -2,7 +2,6 @@ import React from 'react'
import {StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {Text} from '../com/util/text/Text'
import {useStores} from 'state/index'
import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
@ -19,6 +18,7 @@ import {useFocusEffect} from '@react-navigation/native'
import {LANGUAGES} from 'lib/../locale/languages'
import RNPickerSelect, {PickerSelectProps} from 'react-native-picker-select'
import {useSetMinimalShellMode} from '#/state/shell'
import {useModalControls} from '#/state/modals'
import {useLanguagePrefs, useSetLanguagePrefs} from '#/state/preferences'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'LanguageSettings'>
@ -27,12 +27,12 @@ export const LanguageSettingsScreen = observer(function LanguageSettingsImpl(
_: Props,
) {
const pal = usePalette('default')
const store = useStores()
const langPrefs = useLanguagePrefs()
const setLangPrefs = useSetLanguagePrefs()
const {isTabletOrDesktop} = useWebMediaQueries()
const {screen, track} = useAnalytics()
const setMinimalShellMode = useSetMinimalShellMode()
const {openModal} = useModalControls()
useFocusEffect(
React.useCallback(() => {
@ -43,8 +43,8 @@ export const LanguageSettingsScreen = observer(function LanguageSettingsImpl(
const onPressContentLanguages = React.useCallback(() => {
track('Settings:ContentlanguagesButtonClicked')
store.shell.openModal({name: 'content-languages-settings'})
}, [track, store])
openModal({name: 'content-languages-settings'})
}, [track, openModal])
const onChangePrimaryLanguage = React.useCallback(
(value: Parameters<PickerSelectProps['onValueChange']>[0]) => {

View file

@ -17,6 +17,7 @@ import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {SimpleViewHeader} from 'view/com/util/SimpleViewHeader'
import {s} from 'lib/styles'
import {useSetMinimalShellMode} from '#/state/shell'
import {useModalControls} from '#/state/modals'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Lists'>
export const ListsScreen = withAuthRequired(
@ -26,6 +27,7 @@ export const ListsScreen = withAuthRequired(
const setMinimalShellMode = useSetMinimalShellMode()
const {isMobile} = useWebMediaQueries()
const navigation = useNavigation<NavigationProp>()
const {openModal} = useModalControls()
const listsLists: ListsListModel = React.useMemo(
() => new ListsListModel(store, 'my-curatelists'),
@ -40,7 +42,7 @@ export const ListsScreen = withAuthRequired(
)
const onPressNewList = React.useCallback(() => {
store.shell.openModal({
openModal({
name: 'create-or-edit-list',
purpose: 'app.bsky.graph.defs#curatelist',
onSave: (uri: string) => {
@ -53,7 +55,7 @@ export const ListsScreen = withAuthRequired(
} catch {}
},
})
}, [store, navigation])
}, [openModal, navigation])
return (
<View style={s.hContentRegion} testID="listsScreen">

View file

@ -8,7 +8,6 @@ import {
import {observer} from 'mobx-react-lite'
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
import {useStores} from 'state/index'
import {s} from 'lib/styles'
import {CenteredView} from '../com/util/Views'
import {ViewHeader} from '../com/util/ViewHeader'
@ -18,15 +17,16 @@ import {usePalette} from 'lib/hooks/usePalette'
import {useAnalytics} from 'lib/analytics/analytics'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {useSetMinimalShellMode} from '#/state/shell'
import {useModalControls} from '#/state/modals'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Moderation'>
export const ModerationScreen = withAuthRequired(
observer(function Moderation({}: Props) {
const pal = usePalette('default')
const store = useStores()
const setMinimalShellMode = useSetMinimalShellMode()
const {screen, track} = useAnalytics()
const {isTabletOrDesktop} = useWebMediaQueries()
const {openModal} = useModalControls()
useFocusEffect(
React.useCallback(() => {
@ -37,8 +37,8 @@ export const ModerationScreen = withAuthRequired(
const onPressContentFiltering = React.useCallback(() => {
track('Moderation:ContentfilteringButtonClicked')
store.shell.openModal({name: 'content-filtering-settings'})
}, [track, store])
openModal({name: 'content-filtering-settings'})
}, [track, openModal])
return (
<CenteredView

View file

@ -17,6 +17,7 @@ import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {SimpleViewHeader} from 'view/com/util/SimpleViewHeader'
import {s} from 'lib/styles'
import {useSetMinimalShellMode} from '#/state/shell'
import {useModalControls} from '#/state/modals'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'ModerationModlists'>
export const ModerationModlistsScreen = withAuthRequired(
@ -26,6 +27,7 @@ export const ModerationModlistsScreen = withAuthRequired(
const setMinimalShellMode = useSetMinimalShellMode()
const {isMobile} = useWebMediaQueries()
const navigation = useNavigation<NavigationProp>()
const {openModal} = useModalControls()
const mutelists: ListsListModel = React.useMemo(
() => new ListsListModel(store, 'my-modlists'),
@ -40,7 +42,7 @@ export const ModerationModlistsScreen = withAuthRequired(
)
const onPressNewList = React.useCallback(() => {
store.shell.openModal({
openModal({
name: 'create-or-edit-list',
purpose: 'app.bsky.graph.defs#modlist',
onSave: (uri: string) => {
@ -53,7 +55,7 @@ export const ModerationModlistsScreen = withAuthRequired(
} catch {}
},
})
}, [store, navigation])
}, [openModal, navigation])
return (
<View style={s.hContentRegion} testID="moderationModlistsScreen">

View file

@ -47,6 +47,7 @@ import {sanitizeHandle} from 'lib/strings/handles'
import {makeProfileLink} from 'lib/routes/links'
import {ComposeIcon2} from 'lib/icons'
import {logger} from '#/logger'
import {useModalControls} from '#/state/modals'
const SECTION_TITLES = ['Posts', 'About']
@ -137,6 +138,7 @@ export const ProfileFeedScreenInner = observer(
route,
feedOwnerDid,
}: Props & {feedOwnerDid: string}) {
const {openModal} = useModalControls()
const pal = usePalette('default')
const store = useStores()
const {track} = useAnalytics()
@ -210,12 +212,12 @@ export const ProfileFeedScreenInner = observer(
const onPressReport = React.useCallback(() => {
if (!feedInfo) return
store.shell.openModal({
openModal({
name: 'report',
uri: feedInfo.uri,
cid: feedInfo.cid,
})
}, [store, feedInfo])
}, [openModal, feedInfo])
const onCurrentPageSelected = React.useCallback(
(index: number) => {

View file

@ -46,6 +46,7 @@ import {ComposeIcon2} from 'lib/icons'
import {ListItems} from 'view/com/lists/ListItems'
import {logger} from '#/logger'
import {useSetMinimalShellMode} from '#/state/shell'
import {useModalControls} from '#/state/modals'
const SECTION_TITLES_CURATE = ['Posts', 'About']
const SECTION_TITLES_MOD = ['About']
@ -110,6 +111,7 @@ export const ProfileListScreenInner = observer(
const {rkey} = route.params
const feedSectionRef = React.useRef<SectionRef>(null)
const aboutSectionRef = React.useRef<SectionRef>(null)
const {openModal} = useModalControls()
const list: ListModel = useMemo(() => {
const model = new ListModel(
@ -136,7 +138,7 @@ export const ProfileListScreenInner = observer(
)
const onPressAddUser = useCallback(() => {
store.shell.openModal({
openModal({
name: 'list-add-user',
list,
onAdd() {
@ -145,7 +147,7 @@ export const ProfileListScreenInner = observer(
}
},
})
}, [store, list, feed])
}, [openModal, list, feed])
const onCurrentPageSelected = React.useCallback(
(index: number) => {
@ -268,8 +270,8 @@ const Header = observer(function HeaderImpl({
}) {
const pal = usePalette('default')
const palInverted = usePalette('inverted')
const store = useStores()
const navigation = useNavigation<NavigationProp>()
const {openModal, closeModal} = useModalControls()
const onTogglePinned = useCallback(async () => {
Haptics.default()
@ -280,7 +282,7 @@ const Header = observer(function HeaderImpl({
}, [list])
const onSubscribeMute = useCallback(() => {
store.shell.openModal({
openModal({
name: 'confirm',
title: 'Mute these accounts?',
message:
@ -297,10 +299,10 @@ const Header = observer(function HeaderImpl({
}
},
onPressCancel() {
store.shell.closeModal()
closeModal()
},
})
}, [store, list])
}, [openModal, closeModal, list])
const onUnsubscribeMute = useCallback(async () => {
try {
@ -314,7 +316,7 @@ const Header = observer(function HeaderImpl({
}, [list])
const onSubscribeBlock = useCallback(() => {
store.shell.openModal({
openModal({
name: 'confirm',
title: 'Block these accounts?',
message:
@ -331,10 +333,10 @@ const Header = observer(function HeaderImpl({
}
},
onPressCancel() {
store.shell.closeModal()
closeModal()
},
})
}, [store, list])
}, [openModal, closeModal, list])
const onUnsubscribeBlock = useCallback(async () => {
try {
@ -348,17 +350,17 @@ const Header = observer(function HeaderImpl({
}, [list])
const onPressEdit = useCallback(() => {
store.shell.openModal({
openModal({
name: 'create-or-edit-list',
list,
onSave() {
list.refresh()
},
})
}, [store, list])
}, [openModal, list])
const onPressDelete = useCallback(() => {
store.shell.openModal({
openModal({
name: 'confirm',
title: 'Delete List',
message: 'Are you sure?',
@ -372,16 +374,16 @@ const Header = observer(function HeaderImpl({
}
},
})
}, [store, list, navigation])
}, [openModal, list, navigation])
const onPressReport = useCallback(() => {
if (!list.data) return
store.shell.openModal({
openModal({
name: 'report',
uri: list.uri,
cid: list.data.cid,
})
}, [store, list])
}, [openModal, list])
const onPressShare = useCallback(() => {
const url = toShareUrl(`/profile/${list.creatorDid}/lists/${rkey}`)

View file

@ -46,6 +46,7 @@ import Clipboard from '@react-native-clipboard/clipboard'
import {makeProfileLink} from 'lib/routes/links'
import {AccountDropdownBtn} from 'view/com/util/AccountDropdownBtn'
import {logger} from '#/logger'
import {useModalControls} from '#/state/modals'
import {
useSetMinimalShellMode,
useColorMode,
@ -82,6 +83,7 @@ export const SettingsScreen = withAuthRequired(
const [debugHeaderEnabled, toggleDebugHeader] = useDebugHeaderSetting(
store.agent,
)
const {openModal} = useModalControls()
const primaryBg = useCustomPalette<ViewStyle>({
light: {backgroundColor: colors.blue0},
@ -117,7 +119,7 @@ export const SettingsScreen = withAuthRequired(
const onPressChangeHandle = React.useCallback(() => {
track('Settings:ChangeHandleButtonClicked')
store.shell.openModal({
openModal({
name: 'change-handle',
onChanged() {
setIsSwitching(true)
@ -135,12 +137,12 @@ export const SettingsScreen = withAuthRequired(
)
},
})
}, [track, store, setIsSwitching])
}, [track, store, openModal, setIsSwitching])
const onPressInviteCodes = React.useCallback(() => {
track('Settings:InvitecodesButtonClicked')
store.shell.openModal({name: 'invite-codes'})
}, [track, store])
openModal({name: 'invite-codes'})
}, [track, openModal])
const onPressLanguageSettings = React.useCallback(() => {
navigation.navigate('LanguageSettings')
@ -152,8 +154,8 @@ export const SettingsScreen = withAuthRequired(
}, [track, store])
const onPressDeleteAccount = React.useCallback(() => {
store.shell.openModal({name: 'delete-account'})
}, [store])
openModal({name: 'delete-account'})
}, [openModal])
const onPressResetPreferences = React.useCallback(async () => {
await store.preferences.reset()
@ -229,8 +231,7 @@ export const SettingsScreen = withAuthRequired(
<Text type="lg" style={pal.text}>
{store.session.currentSession?.email}{' '}
</Text>
<Link
onPress={() => store.shell.openModal({name: 'change-email'})}>
<Link onPress={() => openModal({name: 'change-email'})}>
<Text type="lg" style={pal.link}>
Change
</Text>
@ -240,10 +241,7 @@ export const SettingsScreen = withAuthRequired(
<Text type="lg-medium" style={pal.text}>
Birthday:{' '}
</Text>
<Link
onPress={() =>
store.shell.openModal({name: 'birth-date-settings'})
}>
<Link onPress={() => openModal({name: 'birth-date-settings'})}>
<Text type="lg" style={pal.link}>
Show
</Text>
@ -649,6 +647,7 @@ const EmailConfirmationNotice = observer(
const palInverted = usePalette('inverted')
const store = useStores()
const {isMobile} = useWebMediaQueries()
const {openModal} = useModalControls()
if (!store.session.emailNeedsConfirmation) {
return null
@ -684,7 +683,7 @@ const EmailConfirmationNotice = observer(
accessibilityRole="button"
accessibilityLabel="Verify my email"
accessibilityHint=""
onPress={() => store.shell.openModal({name: 'verify-email'})}>
onPress={() => openModal({name: 'verify-email'})}>
<FontAwesomeIcon
icon="envelope"
color={palInverted.colors.text}