mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import React from 'react'
2import {AccessibilityInfo} from 'react-native'
3
4import {isWeb} from '#/platform/detection'
5import {PlatformInfo} from '../../modules/expo-bluesky-swiss-army'
6
7const Context = React.createContext({
8 reduceMotionEnabled: false,
9 screenReaderEnabled: false,
10})
11
12export function useA11y() {
13 return React.useContext(Context)
14}
15
16export function Provider({children}: React.PropsWithChildren<{}>) {
17 const [reduceMotionEnabled, setReduceMotionEnabled] = React.useState(() =>
18 PlatformInfo.getIsReducedMotionEnabled(),
19 )
20 const [screenReaderEnabled, setScreenReaderEnabled] = React.useState(false)
21
22 React.useEffect(() => {
23 const reduceMotionChangedSubscription = AccessibilityInfo.addEventListener(
24 'reduceMotionChanged',
25 enabled => {
26 setReduceMotionEnabled(enabled)
27 },
28 )
29 const screenReaderChangedSubscription = AccessibilityInfo.addEventListener(
30 'screenReaderChanged',
31 enabled => {
32 setScreenReaderEnabled(enabled)
33 },
34 )
35
36 ;(async () => {
37 const [_reduceMotionEnabled, _screenReaderEnabled] = await Promise.all([
38 AccessibilityInfo.isReduceMotionEnabled(),
39 AccessibilityInfo.isScreenReaderEnabled(),
40 ])
41 setReduceMotionEnabled(_reduceMotionEnabled)
42 setScreenReaderEnabled(_screenReaderEnabled)
43 })()
44
45 return () => {
46 reduceMotionChangedSubscription.remove()
47 screenReaderChangedSubscription.remove()
48 }
49 }, [])
50
51 const ctx = React.useMemo(() => {
52 return {
53 reduceMotionEnabled,
54 /**
55 * Always returns true on web. For now, we're using this for mobile a11y,
56 * so we reset to false on web.
57 *
58 * @see https://github.com/necolas/react-native-web/discussions/2072
59 */
60 screenReaderEnabled: isWeb ? false : screenReaderEnabled,
61 }
62 }, [reduceMotionEnabled, screenReaderEnabled])
63
64 return <Context.Provider value={ctx}>{children}</Context.Provider>
65}