diff options
author | Eric Bailey <git@esb.lol> | 2024-04-09 17:08:02 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-09 15:08:02 -0700 |
commit | c96bc92042e2d5cb2a28736fd7a9dd2593a7b040 (patch) | |
tree | a3ee36404ff38f446459c3b77187c9ec183f267e /src/components/Dialog/index.tsx | |
parent | a49a5a351d2b58631d067c0524c5ebb097a3d5fe (diff) | |
download | voidsky-c96bc92042e2d5cb2a28736fd7a9dd2593a7b040.tar.zst |
Small logic cleanups (#3449)
* Small logic cleanups * Small logic cleanups (#3451) * remove a few things * oops * stop swallowing the error * queue callbacks * oops * log error if caught * no need to be nullable * move isClosing=true up * reset `isClosing` and `closeCallbacks` on close completion and open * run queued callbacks on `open` if there are any pending * rm unnecessary ref and check * ensure order of calls is always correct * call `snapToIndex()` on open * add tester to storybook --------- Co-authored-by: Hailey <me@haileyok.com>
Diffstat (limited to 'src/components/Dialog/index.tsx')
-rw-r--r-- | src/components/Dialog/index.tsx | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx index 07e101f85..55798db7f 100644 --- a/src/components/Dialog/index.tsx +++ b/src/components/Dialog/index.tsx @@ -83,7 +83,7 @@ export function Outer({ const sheetOptions = nativeOptions?.sheet || {} const hasSnapPoints = !!sheetOptions.snapPoints const insets = useSafeAreaInsets() - const closeCallback = React.useRef<() => void>() + const closeCallbacks = React.useRef<(() => void)[]>([]) const {setDialogIsOpen} = useDialogStateControlContext() /* @@ -96,22 +96,51 @@ export function Outer({ */ const isOpen = openIndex > -1 + const callQueuedCallbacks = React.useCallback(() => { + for (const cb of closeCallbacks.current) { + try { + cb() + } catch (e: any) { + logger.error('Error running close callback', e) + } + } + + closeCallbacks.current = [] + }, []) + const open = React.useCallback<DialogControlProps['open']>( ({index} = {}) => { + // Run any leftover callbacks that might have been queued up before calling `.open()` + callQueuedCallbacks() + setDialogIsOpen(control.id, true) // can be set to any index of `snapPoints`, but `0` is the first i.e. "open" setOpenIndex(index || 0) + sheet.current?.snapToIndex(index || 0) }, - [setOpenIndex, setDialogIsOpen, control.id], + [setDialogIsOpen, control.id, callQueuedCallbacks], ) + // This is the function that we call when we want to dismiss the dialog. const close = React.useCallback<DialogControlProps['close']>(cb => { - if (cb && typeof cb === 'function') { - closeCallback.current = cb + if (typeof cb === 'function') { + closeCallbacks.current.push(cb) } sheet.current?.close() }, []) + // This is the actual thing we are doing once we "confirm" the dialog. We want the dialog's close animation to + // happen before we run this. It is passed to the `BottomSheet` component. + const onCloseAnimationComplete = React.useCallback(() => { + // This removes the dialog from our list of stored dialogs. Not super necessary on iOS, but on Android this + // tells us that we need to toggle the accessibility overlay setting + setDialogIsOpen(control.id, false) + setOpenIndex(-1) + + callQueuedCallbacks() + onClose?.() + }, [callQueuedCallbacks, control.id, onClose, setDialogIsOpen]) + useImperativeHandle( control.ref, () => ({ @@ -121,21 +150,6 @@ export function Outer({ [open, close], ) - const onCloseInner = React.useCallback(() => { - try { - closeCallback.current?.() - } catch (e: any) { - logger.error(`Dialog closeCallback failed`, { - message: e.message, - }) - } finally { - closeCallback.current = undefined - } - setDialogIsOpen(control.id, false) - onClose?.() - setOpenIndex(-1) - }, [control.id, onClose, setDialogIsOpen]) - const context = React.useMemo(() => ({close}), [close]) return ( @@ -163,7 +177,7 @@ export function Outer({ backdropComponent={Backdrop} handleIndicatorStyle={{backgroundColor: t.palette.primary_500}} handleStyle={{display: 'none'}} - onClose={onCloseInner}> + onClose={onCloseAnimationComplete}> <Context.Provider value={context}> <View style={[ |