-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathuseReactNavigationDevTools.ts
More file actions
78 lines (69 loc) · 2.47 KB
/
useReactNavigationDevTools.ts
File metadata and controls
78 lines (69 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import type { NavigationContainerRef } from '@react-navigation/core';
import { useReduxDevToolsExtension } from '@react-navigation/devtools';
import { useDevToolsPluginClient, type EventSubscription } from 'expo/devtools';
import { useEffect, useRef } from 'react';
import { ReduxExtensionAdapter } from './ReduxExtensionAdapter';
export function useReactNavigationDevTools(
ref: React.RefObject<NavigationContainerRef<any> | null>
) {
const client = useDevToolsPluginClient('react-navigation');
const adapterRef = useRef(new ReduxExtensionAdapter());
// @ts-ignore: Override global
globalThis.__REDUX_DEVTOOLS_EXTENSION__ = {
connect: () => adapterRef.current,
};
// @ts-ignore: useReduxDevToolsExtension does not accept null ref from NavigationContainerRefWithCurrent
useReduxDevToolsExtension(ref);
useEffect(() => {
adapterRef.current.setClient(client);
const on = (event: string, listener: (params: any) => Promise<any>) => {
return client?.addMessageListener(event, async (params) => {
try {
const result = await listener(params);
if (params.id) {
client?.sendMessage(`ack:${event}`, { id: params.id, result });
}
} catch {}
});
};
const subscriptions: (EventSubscription | undefined)[] = [];
subscriptions.push(
on('navigation.invoke', ({ method, args = [] }) => {
switch (method) {
case 'resetRoot':
return adapterRef.current?.resetRoot(args[0]);
default:
// @ts-ignore: this might not exist
return ref.current?.[method](...args);
}
})
);
subscriptions.push(
on('linking.invoke', ({ method, args = [] }) => {
const linking: any = ref.current
? // @ts-ignore: this might not exist
global.REACT_NAVIGATION_DEVTOOLS?.get(ref.current)?.linking
: null;
switch (method) {
case 'getStateFromPath':
case 'getPathFromState':
case 'getActionFromState':
return linking?.[method](
args[0],
args[1]?.trim()
? // eslint-disable-next-line no-eval
eval(`(function() { return ${args[1]}; }())`)
: linking.config
);
default:
return linking?.[method](...args);
}
})
);
return () => {
for (const subscription of subscriptions) {
subscription?.remove();
}
};
}, [client]);
}