mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {
2 createContext,
3 useCallback,
4 useContext,
5 useEffect,
6 useMemo,
7 useRef,
8} from 'react'
9import {
10 KeyboardProvider,
11 useKeyboardController,
12} from 'react-native-keyboard-controller'
13import {useFocusEffect} from '@react-navigation/native'
14
15const KeyboardControllerRefCountContext = createContext<{
16 incrementRefCount: () => void
17 decrementRefCount: () => void
18}>({
19 incrementRefCount: () => {},
20 decrementRefCount: () => {},
21})
22
23export function KeyboardControllerProvider({
24 children,
25}: {
26 children: React.ReactNode
27}) {
28 return (
29 <KeyboardProvider
30 enabled={false}
31 // I don't think this is necessary, but Chesterton's fence and all that -sfn
32 statusBarTranslucent={true}>
33 <KeyboardControllerProviderInner>
34 {children}
35 </KeyboardControllerProviderInner>
36 </KeyboardProvider>
37 )
38}
39
40function KeyboardControllerProviderInner({
41 children,
42}: {
43 children: React.ReactNode
44}) {
45 const {setEnabled} = useKeyboardController()
46 const refCount = useRef(0)
47
48 const value = useMemo(
49 () => ({
50 incrementRefCount: () => {
51 refCount.current++
52 setEnabled(refCount.current > 0)
53 },
54 decrementRefCount: () => {
55 refCount.current--
56 setEnabled(refCount.current > 0)
57
58 if (__DEV__ && refCount.current < 0) {
59 console.error('KeyboardController ref count < 0')
60 }
61 },
62 }),
63 [setEnabled],
64 )
65
66 return (
67 <KeyboardControllerRefCountContext.Provider value={value}>
68 {children}
69 </KeyboardControllerRefCountContext.Provider>
70 )
71}
72
73export function useEnableKeyboardController(shouldEnable: boolean) {
74 const {incrementRefCount, decrementRefCount} = useContext(
75 KeyboardControllerRefCountContext,
76 )
77
78 useEffect(() => {
79 if (!shouldEnable) {
80 return
81 }
82 incrementRefCount()
83 return () => {
84 decrementRefCount()
85 }
86 }, [shouldEnable, incrementRefCount, decrementRefCount])
87}
88
89/**
90 * Like `useEnableKeyboardController`, but using `useFocusEffect`
91 */
92export function useEnableKeyboardControllerScreen(shouldEnable: boolean) {
93 const {incrementRefCount, decrementRefCount} = useContext(
94 KeyboardControllerRefCountContext,
95 )
96
97 useFocusEffect(
98 useCallback(() => {
99 if (!shouldEnable) {
100 return
101 }
102 incrementRefCount()
103 return () => {
104 decrementRefCount()
105 }
106 }, [shouldEnable, incrementRefCount, decrementRefCount]),
107 )
108}