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