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