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})
22KeyboardControllerRefCountContext.displayName =
23 'KeyboardControllerRefCountContext'
24
25export function KeyboardControllerProvider({
26 children,
27}: {
28 children: React.ReactNode
29}) {
30 return (
31 <KeyboardProvider enabled={false}>
32 <KeyboardControllerProviderInner>
33 {children}
34 </KeyboardControllerProviderInner>
35 </KeyboardProvider>
36 )
37}
38
39function KeyboardControllerProviderInner({
40 children,
41}: {
42 children: React.ReactNode
43}) {
44 const {setEnabled} = useKeyboardController()
45 const refCount = useRef(0)
46
47 const value = useMemo(
48 () => ({
49 incrementRefCount: () => {
50 refCount.current++
51 setEnabled(refCount.current > 0)
52 },
53 decrementRefCount: () => {
54 refCount.current--
55 setEnabled(refCount.current > 0)
56
57 if (__DEV__ && refCount.current < 0) {
58 console.error('KeyboardController ref count < 0')
59 }
60 },
61 }),
62 [setEnabled],
63 )
64
65 return (
66 <KeyboardControllerRefCountContext.Provider value={value}>
67 {children}
68 </KeyboardControllerRefCountContext.Provider>
69 )
70}
71
72export function useEnableKeyboardController(shouldEnable: boolean) {
73 const {incrementRefCount, decrementRefCount} = useContext(
74 KeyboardControllerRefCountContext,
75 )
76
77 useEffect(() => {
78 if (!shouldEnable) {
79 return
80 }
81 incrementRefCount()
82 return () => {
83 decrementRefCount()
84 }
85 }, [shouldEnable, incrementRefCount, decrementRefCount])
86}
87
88/**
89 * Like `useEnableKeyboardController`, but using `useFocusEffect`
90 */
91export function useEnableKeyboardControllerScreen(shouldEnable: boolean) {
92 const {incrementRefCount, decrementRefCount} = useContext(
93 KeyboardControllerRefCountContext,
94 )
95
96 useFocusEffect(
97 useCallback(() => {
98 if (!shouldEnable) {
99 return
100 }
101 incrementRefCount()
102 return () => {
103 decrementRefCount()
104 }
105 }, [shouldEnable, incrementRefCount, decrementRefCount]),
106 )
107}