Protect against non functions being passed to close callback (#3019)

zio/stable
Eric Bailey 2024-02-28 13:27:54 -06:00 committed by GitHub
parent 0c3d55db6f
commit d2c6edacb6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 21 additions and 12 deletions

View File

@ -11,6 +11,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {useTheme, atoms as a, flatten} from '#/alf' import {useTheme, atoms as a, flatten} from '#/alf'
import {Portal} from '#/components/Portal' import {Portal} from '#/components/Portal'
import {createInput} from '#/components/forms/TextField' import {createInput} from '#/components/forms/TextField'
import {logger} from '#/logger'
import { import {
DialogOuterProps, DialogOuterProps,
@ -56,7 +57,7 @@ export function Outer({
) )
const close = React.useCallback<DialogControlProps['close']>(cb => { const close = React.useCallback<DialogControlProps['close']>(cb => {
if (cb) { if (cb && typeof cb === 'function') {
closeCallback.current = cb closeCallback.current = cb
} }
sheet.current?.close() sheet.current?.close()
@ -74,8 +75,16 @@ export function Outer({
const onChange = React.useCallback( const onChange = React.useCallback(
(index: number) => { (index: number) => {
if (index === -1) { if (index === -1) {
closeCallback.current?.() try {
closeCallback.current = undefined closeCallback.current?.()
} catch (e: any) {
logger.error(`Dialog closeCallback failed`, {
message: e.message,
})
} finally {
closeCallback.current = undefined
}
onClose?.() onClose?.()
setOpenIndex(-1) setOpenIndex(-1)
} }

View File

@ -190,7 +190,7 @@ export function Close() {
variant="ghost" variant="ghost"
color="secondary" color="secondary"
shape="round" shape="round"
onPress={close} onPress={() => close()}
label={_(msg`Close active dialog`)}> label={_(msg`Close active dialog`)}>
<ButtonIcon icon={X} size="md" /> <ButtonIcon icon={X} size="md" />
</Button> </Button>

View File

@ -6,8 +6,13 @@ import {ViewStyleProp} from '#/alf'
type A11yProps = Required<AccessibilityProps> type A11yProps = Required<AccessibilityProps>
export type DialogControlProps = {
open: (options?: DialogControlOpenOptions) => void
close: (callback?: () => void) => void
}
export type DialogContextProps = { export type DialogContextProps = {
close: () => void close: DialogControlProps['close']
} }
export type DialogControlOpenOptions = { export type DialogControlOpenOptions = {
@ -20,11 +25,6 @@ export type DialogControlOpenOptions = {
index?: number index?: number
} }
export type DialogControlProps = {
open: (options?: DialogControlOpenOptions) => void
close: (callback?: () => void) => void
}
export type DialogOuterProps = { export type DialogOuterProps = {
control: { control: {
ref: React.RefObject<DialogControlProps> ref: React.RefObject<DialogControlProps>

View File

@ -89,7 +89,7 @@ export function Cancel({
color="secondary" color="secondary"
size="small" size="small"
label={_(msg`Cancel`)} label={_(msg`Cancel`)}
onPress={close}> onPress={() => close()}>
{children} {children}
</Button> </Button>
) )

View File

@ -114,7 +114,7 @@ export function AdultContentEnabledPref({
</Trans> </Trans>
</Prompt.Description> </Prompt.Description>
<Prompt.Actions> <Prompt.Actions>
<Prompt.Action onPress={prompt.close}>OK</Prompt.Action> <Prompt.Action onPress={() => prompt.close()}>OK</Prompt.Action>
</Prompt.Actions> </Prompt.Actions>
</Prompt.Outer> </Prompt.Outer>
</> </>