Close active elems (react-query refactor) (#1926)

* Refactor closeAny and closeAllActiveElements

* Add close lightbox

* Switch to hooks

* Fixes
This commit is contained in:
Paul Frazee 2023-11-16 08:18:59 -08:00 committed by GitHub
parent 0de8d40981
commit a84b2f9f2f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 101 additions and 66 deletions

View file

@ -31,10 +31,10 @@ const LightboxContext = React.createContext<{
const LightboxControlContext = React.createContext<{
openLightbox: (lightbox: Lightbox) => void
closeLightbox: () => void
closeLightbox: () => boolean
}>({
openLightbox: () => {},
closeLightbox: () => {},
closeLightbox: () => false,
})
export function Provider({children}: React.PropsWithChildren<{}>) {
@ -50,8 +50,10 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
)
const closeLightbox = React.useCallback(() => {
let wasActive = !!activeLightbox
setActiveLightbox(null)
}, [setActiveLightbox])
return wasActive
}, [setActiveLightbox, activeLightbox])
const state = React.useMemo(
() => ({

View file

@ -213,10 +213,12 @@ const ModalContext = React.createContext<{
const ModalControlContext = React.createContext<{
openModal: (modal: Modal) => void
closeModal: () => void
closeModal: () => boolean
closeAllModals: () => void
}>({
openModal: () => {},
closeModal: () => {},
closeModal: () => false,
closeAllModals: () => {},
})
/**
@ -226,6 +228,13 @@ export let unstable__openModal: (modal: Modal) => void = () => {
throw new Error(`ModalContext is not initialized`)
}
/**
* @deprecated DO NOT USE THIS unless you have no other choice.
*/
export let unstable__closeModal: () => boolean = () => {
throw new Error(`ModalContext is not initialized`)
}
export function Provider({children}: React.PropsWithChildren<{}>) {
const [isModalActive, setIsModalActive] = React.useState(false)
const [activeModals, setActiveModals] = React.useState<Modal[]>([])
@ -238,17 +247,25 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
[setIsModalActive, setActiveModals],
)
unstable__openModal = openModal
const closeModal = React.useCallback(() => {
let totalActiveModals = 0
let wasActive = isModalActive
setActiveModals(activeModals => {
activeModals = activeModals.slice(0, -1)
totalActiveModals = activeModals.length
return activeModals
})
setIsModalActive(totalActiveModals > 0)
}, [setIsModalActive, setActiveModals])
return wasActive
}, [setIsModalActive, setActiveModals, isModalActive])
const closeAllModals = React.useCallback(() => {
setActiveModals([])
setIsModalActive(false)
}, [setActiveModals, setIsModalActive])
unstable__openModal = openModal
unstable__closeModal = closeModal
const state = React.useMemo(
() => ({
@ -262,8 +279,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
() => ({
openModal,
closeModal,
closeAllModals,
}),
[openModal, closeModal],
[openModal, closeModal, closeAllModals],
)
return (

View file

@ -21,19 +21,6 @@ export class ShellUiModel {
this.setupLoginModals()
}
/**
* returns true if something was closed
* (used by the android hardware back btn)
*/
closeAnyActiveElement(): boolean {
return false
}
/**
* used to clear out any modals, eg for a navigation
*/
closeAllActiveElements() {}
setupLoginModals() {
this.rootStore.onSessionReady(() => {
if (shouldRequestEmailConfirmation(this.rootStore.session)) {

View file

@ -34,13 +34,15 @@ export interface ComposerOpts {
type StateContext = ComposerOpts | undefined
type ControlsContext = {
openComposer: (opts: ComposerOpts) => void
closeComposer: () => void
closeComposer: () => boolean
}
const stateContext = React.createContext<StateContext>(undefined)
const controlsContext = React.createContext<ControlsContext>({
openComposer(_opts: ComposerOpts) {},
closeComposer() {},
closeComposer() {
return false
},
})
export function Provider({children}: React.PropsWithChildren<{}>) {
@ -51,11 +53,14 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
setState(opts)
},
closeComposer() {
let wasOpen = !!state
setState(undefined)
return wasOpen
},
}),
[setState],
[setState, state],
)
return (
<stateContext.Provider value={state}>
<controlsContext.Provider value={api}>

View file

@ -8,6 +8,7 @@ const setContext = React.createContext<SetContext>((_: boolean) => {})
export function Provider({children}: React.PropsWithChildren<{}>) {
const [state, setState] = React.useState(false)
return (
<stateContext.Provider value={state}>
<setContext.Provider value={setState}>{children}</setContext.Provider>

45
src/state/util.ts Normal file
View file

@ -0,0 +1,45 @@
import {useCallback} from 'react'
import {useLightboxControls} from './lightbox'
import {useModalControls} from './modals'
import {useComposerControls} from './shell/composer'
import {useSetDrawerOpen} from './shell/drawer-open'
/**
* returns true if something was closed
* (used by the android hardware back btn)
*/
export function useCloseAnyActiveElement() {
const {closeLightbox} = useLightboxControls()
const {closeModal} = useModalControls()
const {closeComposer} = useComposerControls()
const setDrawerOpen = useSetDrawerOpen()
return useCallback(() => {
if (closeLightbox()) {
return true
}
if (closeModal()) {
return true
}
if (closeComposer()) {
return true
}
setDrawerOpen(false)
return false
}, [closeLightbox, closeModal, closeComposer, setDrawerOpen])
}
/**
* used to clear out any modals, eg for a navigation
*/
export function useCloseAllActiveElements() {
const {closeLightbox} = useLightboxControls()
const {closeAllModals} = useModalControls()
const {closeComposer} = useComposerControls()
const setDrawerOpen = useSetDrawerOpen()
return useCallback(() => {
closeLightbox()
closeAllModals()
closeComposer()
setDrawerOpen(false)
}, [closeLightbox, closeAllModals, closeComposer, setDrawerOpen])
}