Bluesky app fork with some witchin' additions 馃挮
at post-text-option 96 lines 2.7 kB view raw
1import {createContext, useContext, useMemo, useState} from 'react' 2 3import {type AgeAssuranceRedirectDialogState} from '#/components/ageAssurance/AgeAssuranceRedirectDialog' 4import * as Dialog from '#/components/Dialog' 5import {type Screen} from '#/components/dialogs/EmailDialog/types' 6 7type Control = Dialog.DialogControlProps 8 9export type StatefulControl<T> = { 10 control: Control 11 open: (value: T) => void 12 clear: () => void 13 value: T | undefined 14} 15 16type ControlsContext = { 17 mutedWordsDialogControl: Control 18 signinDialogControl: Control 19 inAppBrowserConsentControl: StatefulControl<string> 20 emailDialogControl: StatefulControl<Screen> 21 linkWarningDialogControl: StatefulControl<{ 22 href: string 23 displayText: string 24 share?: boolean 25 }> 26 ageAssuranceRedirectDialogControl: StatefulControl<AgeAssuranceRedirectDialogState> 27} 28 29const ControlsContext = createContext<ControlsContext | null>(null) 30ControlsContext.displayName = 'GlobalDialogControlsContext' 31 32export function useGlobalDialogsControlContext() { 33 const ctx = useContext(ControlsContext) 34 if (!ctx) { 35 throw new Error( 36 'useGlobalDialogsControlContext must be used within a Provider', 37 ) 38 } 39 return ctx 40} 41 42export function Provider({children}: React.PropsWithChildren<{}>) { 43 const mutedWordsDialogControl = Dialog.useDialogControl() 44 const signinDialogControl = Dialog.useDialogControl() 45 const inAppBrowserConsentControl = useStatefulDialogControl<string>() 46 const emailDialogControl = useStatefulDialogControl<Screen>() 47 const linkWarningDialogControl = useStatefulDialogControl<{ 48 href: string 49 displayText: string 50 share?: boolean 51 }>() 52 const ageAssuranceRedirectDialogControl = 53 useStatefulDialogControl<AgeAssuranceRedirectDialogState>() 54 55 const ctx = useMemo<ControlsContext>( 56 () => ({ 57 mutedWordsDialogControl, 58 signinDialogControl, 59 inAppBrowserConsentControl, 60 emailDialogControl, 61 linkWarningDialogControl, 62 ageAssuranceRedirectDialogControl, 63 }), 64 [ 65 mutedWordsDialogControl, 66 signinDialogControl, 67 inAppBrowserConsentControl, 68 emailDialogControl, 69 linkWarningDialogControl, 70 ageAssuranceRedirectDialogControl, 71 ], 72 ) 73 74 return ( 75 <ControlsContext.Provider value={ctx}>{children}</ControlsContext.Provider> 76 ) 77} 78 79export function useStatefulDialogControl<T>( 80 initialValue?: T, 81): StatefulControl<T> { 82 const [value, setValue] = useState(initialValue) 83 const control = Dialog.useDialogControl() 84 return useMemo( 85 () => ({ 86 control, 87 open: (v: T) => { 88 setValue(v) 89 control.open() 90 }, 91 clear: () => setValue(initialValue), 92 value, 93 }), 94 [control, value, initialValue], 95 ) 96}