about summary refs log tree commit diff
path: root/src/state
diff options
context:
space:
mode:
Diffstat (limited to 'src/state')
-rw-r--r--src/state/lightbox.tsx8
-rw-r--r--src/state/modals/index.tsx30
-rw-r--r--src/state/models/ui/shell.ts13
-rw-r--r--src/state/shell/composer.tsx11
-rw-r--r--src/state/shell/drawer-open.tsx1
-rw-r--r--src/state/util.ts45
6 files changed, 83 insertions, 25 deletions
diff --git a/src/state/lightbox.tsx b/src/state/lightbox.tsx
index 613cd638e..d5528ac28 100644
--- a/src/state/lightbox.tsx
+++ b/src/state/lightbox.tsx
@@ -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(
     () => ({
diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx
index 9dd3e4195..fa86aaa31 100644
--- a/src/state/modals/index.tsx
+++ b/src/state/modals/index.tsx
@@ -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 (
diff --git a/src/state/models/ui/shell.ts b/src/state/models/ui/shell.ts
index 1631b8f9c..18287c953 100644
--- a/src/state/models/ui/shell.ts
+++ b/src/state/models/ui/shell.ts
@@ -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)) {
diff --git a/src/state/shell/composer.tsx b/src/state/shell/composer.tsx
index a350bd7f3..70d77a7e0 100644
--- a/src/state/shell/composer.tsx
+++ b/src/state/shell/composer.tsx
@@ -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}>
diff --git a/src/state/shell/drawer-open.tsx b/src/state/shell/drawer-open.tsx
index a2322f680..061ff53d7 100644
--- a/src/state/shell/drawer-open.tsx
+++ b/src/state/shell/drawer-open.tsx
@@ -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>
diff --git a/src/state/util.ts b/src/state/util.ts
new file mode 100644
index 000000000..57f4331b0
--- /dev/null
+++ b/src/state/util.ts
@@ -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])
+}