forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 💫
1import {createContext, useCallback, useContext, useEffect, useMemo} from 'react'
2
3import {useGetAndRegisterPushToken} from '#/lib/notifications/notifications'
4import {useAgent} from '#/state/session'
5import {Provider as RedirectOverlayProvider} from '#/ageAssurance/components/RedirectOverlay'
6import {
7 AgeAssuranceDataProvider,
8 useAgeAssuranceDataContext,
9} from '#/ageAssurance/data'
10import {logger} from '#/ageAssurance/logger'
11import {
12 useAgeAssuranceState,
13 useOnAgeAssuranceAccessUpdate,
14} from '#/ageAssurance/state'
15import {
16 AgeAssuranceAccess,
17 type AgeAssuranceState,
18 AgeAssuranceStatus,
19} from '#/ageAssurance/types'
20import {
21 maybeRestrictChatSettings,
22 useAgeAssuranceRegionConfigWithFallback,
23} from '#/ageAssurance/util'
24
25export {
26 prefetchConfig as prefetchAgeAssuranceConfig,
27 prefetchAgeAssuranceData,
28 refetchServerState as refetchAgeAssuranceServerState,
29 usePatchOtherRequiredData as usePatchAgeAssuranceOtherRequiredData,
30 usePatchServerState as usePatchAgeAssuranceServerState,
31} from '#/ageAssurance/data'
32export {logger} from '#/ageAssurance/logger'
33export {MIN_ACCESS_AGE} from '#/ageAssurance/util'
34
35const AgeAssuranceStateContext = createContext<{
36 Access: typeof AgeAssuranceAccess
37 Status: typeof AgeAssuranceStatus
38 state: AgeAssuranceState
39 flags: {
40 adultContentDisabled: boolean
41 chatDisabled: boolean
42 isOverRegionMinAccessAge: boolean
43 isOverAppMinAccessAge: boolean
44 }
45}>({
46 Access: AgeAssuranceAccess,
47 Status: AgeAssuranceStatus,
48 state: {
49 lastInitiatedAt: undefined,
50 status: AgeAssuranceStatus.Unknown,
51 access: AgeAssuranceAccess.Full,
52 },
53 flags: {
54 adultContentDisabled: false,
55 chatDisabled: false,
56 isOverRegionMinAccessAge: false,
57 isOverAppMinAccessAge: false,
58 },
59})
60
61/**
62 * THE MAIN AGE ASSURANCE CONTEXT HOOK
63 *
64 * Prefer this to using any of the lower-level data-provider hooks.
65 */
66export function useAgeAssurance() {
67 return useContext(AgeAssuranceStateContext)
68}
69
70export function Provider({children}: {children: React.ReactNode}) {
71 return (
72 <AgeAssuranceDataProvider>
73 <InnerProvider>
74 <RedirectOverlayProvider>{children}</RedirectOverlayProvider>
75 </InnerProvider>
76 </AgeAssuranceDataProvider>
77 )
78}
79
80function InnerProvider({children}: {children: React.ReactNode}) {
81 const agent = useAgent()
82 const state = useAgeAssuranceState()
83 const {data} = useAgeAssuranceDataContext()
84 const config = useAgeAssuranceRegionConfigWithFallback()
85 const getAndRegisterPushToken = useGetAndRegisterPushToken()
86
87 const handleAccessUpdate = useCallback(
88 (s: AgeAssuranceState) => {
89 const isAgeRestricted = s.access !== AgeAssuranceAccess.Full
90 if (isAgeRestricted) {
91 void getAndRegisterPushToken({isAgeRestricted})
92 maybeRestrictChatSettings({agent})
93 }
94 },
95 [agent, getAndRegisterPushToken],
96 )
97 useOnAgeAssuranceAccessUpdate(handleAccessUpdate)
98
99 useEffect(() => {
100 logger.debug(`useAgeAssuranceState`, {state})
101 }, [state])
102
103 return (
104 <AgeAssuranceStateContext.Provider
105 value={useMemo(() => {
106 const chatDisabled = false
107 const isUnderAdultAge = false
108 const isOverRegionMinAccessAge = true
109 const isOverAppMinAccessAge = true
110 const adultContentDisabled = isUnderAdultAge
111 return {
112 Access: AgeAssuranceAccess,
113 Status: AgeAssuranceStatus,
114 state,
115 flags: {
116 adultContentDisabled,
117 chatDisabled,
118 isOverRegionMinAccessAge,
119 isOverAppMinAccessAge,
120 },
121 }
122 }, [state, data, config])}>
123 {children}
124 </AgeAssuranceStateContext.Provider>
125 )
126}