1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 |
|
8 | var _routers = require("@react-navigation/routers");
|
9 |
|
10 | var React = _interopRequireWildcard(require("react"));
|
11 |
|
12 | var _checkDuplicateRouteNames = _interopRequireDefault(require("./checkDuplicateRouteNames"));
|
13 |
|
14 | var _checkSerializable = _interopRequireDefault(require("./checkSerializable"));
|
15 |
|
16 | var _createNavigationContainerRef = require("./createNavigationContainerRef");
|
17 |
|
18 | var _EnsureSingleNavigator = _interopRequireDefault(require("./EnsureSingleNavigator"));
|
19 |
|
20 | var _findFocusedRoute = _interopRequireDefault(require("./findFocusedRoute"));
|
21 |
|
22 | var _NavigationBuilderContext = _interopRequireDefault(require("./NavigationBuilderContext"));
|
23 |
|
24 | var _NavigationContainerRefContext = _interopRequireDefault(require("./NavigationContainerRefContext"));
|
25 |
|
26 | var _NavigationContext = _interopRequireDefault(require("./NavigationContext"));
|
27 |
|
28 | var _NavigationRouteContext = _interopRequireDefault(require("./NavigationRouteContext"));
|
29 |
|
30 | var _NavigationStateContext = _interopRequireDefault(require("./NavigationStateContext"));
|
31 |
|
32 | var _UnhandledActionContext = _interopRequireDefault(require("./UnhandledActionContext"));
|
33 |
|
34 | var _useChildListeners = _interopRequireDefault(require("./useChildListeners"));
|
35 |
|
36 | var _useEventEmitter = _interopRequireDefault(require("./useEventEmitter"));
|
37 |
|
38 | var _useKeyedChildListeners = _interopRequireDefault(require("./useKeyedChildListeners"));
|
39 |
|
40 | var _useOptionsGetters = _interopRequireDefault(require("./useOptionsGetters"));
|
41 |
|
42 | var _useScheduleUpdate = require("./useScheduleUpdate");
|
43 |
|
44 | var _useSyncState = _interopRequireDefault(require("./useSyncState"));
|
45 |
|
46 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
47 |
|
48 | function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
49 |
|
50 | function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
51 |
|
52 | const serializableWarnings = [];
|
53 | const duplicateNameWarnings = [];
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | const getPartialState = state => {
|
61 | if (state === undefined) {
|
62 | return;
|
63 | }
|
64 |
|
65 |
|
66 | const {
|
67 | key,
|
68 | routeNames,
|
69 | ...partialState
|
70 | } = state;
|
71 | return { ...partialState,
|
72 | stale: true,
|
73 | routes: state.routes.map(route => {
|
74 | if (route.state === undefined) {
|
75 | return route;
|
76 | }
|
77 |
|
78 | return { ...route,
|
79 | state: getPartialState(route.state)
|
80 | };
|
81 | })
|
82 | };
|
83 | };
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 | const BaseNavigationContainer = React.forwardRef(function BaseNavigationContainer(_ref, ref) {
|
96 | let {
|
97 | initialState,
|
98 | onStateChange,
|
99 | onUnhandledAction,
|
100 | independent,
|
101 | children
|
102 | } = _ref;
|
103 | const parent = React.useContext(_NavigationStateContext.default);
|
104 |
|
105 | if (!parent.isDefault && !independent) {
|
106 | throw new Error("Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app, so this was probably an error. If this was intentional, pass 'independent={true}' explicitly. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them.");
|
107 | }
|
108 |
|
109 | const [state, getState, setState, scheduleUpdate, flushUpdates] = (0, _useSyncState.default)(() => getPartialState(initialState == null ? undefined : initialState));
|
110 | const isFirstMountRef = React.useRef(true);
|
111 | const navigatorKeyRef = React.useRef();
|
112 | const getKey = React.useCallback(() => navigatorKeyRef.current, []);
|
113 | const setKey = React.useCallback(key => {
|
114 | navigatorKeyRef.current = key;
|
115 | }, []);
|
116 | const {
|
117 | listeners,
|
118 | addListener
|
119 | } = (0, _useChildListeners.default)();
|
120 | const {
|
121 | keyedListeners,
|
122 | addKeyedListener
|
123 | } = (0, _useKeyedChildListeners.default)();
|
124 | const dispatch = React.useCallback(action => {
|
125 | if (listeners.focus[0] == null) {
|
126 | console.error(_createNavigationContainerRef.NOT_INITIALIZED_ERROR);
|
127 | } else {
|
128 | listeners.focus[0](navigation => navigation.dispatch(action));
|
129 | }
|
130 | }, [listeners.focus]);
|
131 | const canGoBack = React.useCallback(() => {
|
132 | if (listeners.focus[0] == null) {
|
133 | return false;
|
134 | }
|
135 |
|
136 | const {
|
137 | result,
|
138 | handled
|
139 | } = listeners.focus[0](navigation => navigation.canGoBack());
|
140 |
|
141 | if (handled) {
|
142 | return result;
|
143 | } else {
|
144 | return false;
|
145 | }
|
146 | }, [listeners.focus]);
|
147 | const resetRoot = React.useCallback(state => {
|
148 | var _state$key, _keyedListeners$getSt, _keyedListeners$getSt2;
|
149 |
|
150 | const target = (_state$key = state === null || state === void 0 ? void 0 : state.key) !== null && _state$key !== void 0 ? _state$key : (_keyedListeners$getSt = (_keyedListeners$getSt2 = keyedListeners.getState).root) === null || _keyedListeners$getSt === void 0 ? void 0 : _keyedListeners$getSt.call(_keyedListeners$getSt2).key;
|
151 |
|
152 | if (target == null) {
|
153 | console.error(_createNavigationContainerRef.NOT_INITIALIZED_ERROR);
|
154 | } else {
|
155 | listeners.focus[0](navigation => navigation.dispatch({ ..._routers.CommonActions.reset(state),
|
156 | target
|
157 | }));
|
158 | }
|
159 | }, [keyedListeners.getState, listeners.focus]);
|
160 | const getRootState = React.useCallback(() => {
|
161 | var _keyedListeners$getSt3, _keyedListeners$getSt4;
|
162 |
|
163 | return (_keyedListeners$getSt3 = (_keyedListeners$getSt4 = keyedListeners.getState).root) === null || _keyedListeners$getSt3 === void 0 ? void 0 : _keyedListeners$getSt3.call(_keyedListeners$getSt4);
|
164 | }, [keyedListeners.getState]);
|
165 | const getCurrentRoute = React.useCallback(() => {
|
166 | const state = getRootState();
|
167 |
|
168 | if (state == null) {
|
169 | return undefined;
|
170 | }
|
171 |
|
172 | const route = (0, _findFocusedRoute.default)(state);
|
173 | return route;
|
174 | }, [getRootState]);
|
175 | const emitter = (0, _useEventEmitter.default)();
|
176 | const {
|
177 | addOptionsGetter,
|
178 | getCurrentOptions
|
179 | } = (0, _useOptionsGetters.default)({});
|
180 | const navigation = React.useMemo(() => ({ ...Object.keys(_routers.CommonActions).reduce((acc, name) => {
|
181 | acc[name] = function () {
|
182 | return (
|
183 | dispatch(_routers.CommonActions[name](...arguments))
|
184 | );
|
185 | };
|
186 |
|
187 | return acc;
|
188 | }, {}),
|
189 | ...emitter.create('root'),
|
190 | dispatch,
|
191 | resetRoot,
|
192 | isFocused: () => true,
|
193 | canGoBack,
|
194 | getParent: () => undefined,
|
195 | getState: () => stateRef.current,
|
196 | getRootState,
|
197 | getCurrentRoute,
|
198 | getCurrentOptions,
|
199 | isReady: () => listeners.focus[0] != null
|
200 | }), [canGoBack, dispatch, emitter, getCurrentOptions, getCurrentRoute, getRootState, listeners.focus, resetRoot]);
|
201 | React.useImperativeHandle(ref, () => navigation, [navigation]);
|
202 | const onDispatchAction = React.useCallback((action, noop) => {
|
203 | emitter.emit({
|
204 | type: '__unsafe_action__',
|
205 | data: {
|
206 | action,
|
207 | noop,
|
208 | stack: stackRef.current
|
209 | }
|
210 | });
|
211 | }, [emitter]);
|
212 | const lastEmittedOptionsRef = React.useRef();
|
213 | const onOptionsChange = React.useCallback(options => {
|
214 | if (lastEmittedOptionsRef.current === options) {
|
215 | return;
|
216 | }
|
217 |
|
218 | lastEmittedOptionsRef.current = options;
|
219 | emitter.emit({
|
220 | type: 'options',
|
221 | data: {
|
222 | options
|
223 | }
|
224 | });
|
225 | }, [emitter]);
|
226 | const stackRef = React.useRef();
|
227 | const builderContext = React.useMemo(() => ({
|
228 | addListener,
|
229 | addKeyedListener,
|
230 | onDispatchAction,
|
231 | onOptionsChange,
|
232 | stackRef
|
233 | }), [addListener, addKeyedListener, onDispatchAction, onOptionsChange]);
|
234 | const scheduleContext = React.useMemo(() => ({
|
235 | scheduleUpdate,
|
236 | flushUpdates
|
237 | }), [scheduleUpdate, flushUpdates]);
|
238 | const isInitialRef = React.useRef(true);
|
239 | const getIsInitial = React.useCallback(() => isInitialRef.current, []);
|
240 | const context = React.useMemo(() => ({
|
241 | state,
|
242 | getState,
|
243 | setState,
|
244 | getKey,
|
245 | setKey,
|
246 | getIsInitial,
|
247 | addOptionsGetter
|
248 | }), [state, getState, setState, getKey, setKey, getIsInitial, addOptionsGetter]);
|
249 | const onStateChangeRef = React.useRef(onStateChange);
|
250 | const stateRef = React.useRef(state);
|
251 | React.useEffect(() => {
|
252 | isInitialRef.current = false;
|
253 | onStateChangeRef.current = onStateChange;
|
254 | stateRef.current = state;
|
255 | });
|
256 | React.useEffect(() => {
|
257 | const hydratedState = getRootState();
|
258 |
|
259 | if (process.env.NODE_ENV !== 'production') {
|
260 | if (hydratedState !== undefined) {
|
261 | const serializableResult = (0, _checkSerializable.default)(hydratedState);
|
262 |
|
263 | if (!serializableResult.serializable) {
|
264 | const {
|
265 | location,
|
266 | reason
|
267 | } = serializableResult;
|
268 | let path = '';
|
269 | let pointer = hydratedState;
|
270 | let params = false;
|
271 |
|
272 | for (let i = 0; i < location.length; i++) {
|
273 | const curr = location[i];
|
274 | const prev = location[i - 1];
|
275 | pointer = pointer[curr];
|
276 |
|
277 | if (!params && curr === 'state') {
|
278 | continue;
|
279 | } else if (!params && curr === 'routes') {
|
280 | if (path) {
|
281 | path += ' > ';
|
282 | }
|
283 | } else if (!params && typeof curr === 'number' && prev === 'routes') {
|
284 | var _pointer;
|
285 |
|
286 | path += (_pointer = pointer) === null || _pointer === void 0 ? void 0 : _pointer.name;
|
287 | } else if (!params) {
|
288 | path += ` > ${curr}`;
|
289 | params = true;
|
290 | } else {
|
291 | if (typeof curr === 'number' || /^[0-9]+$/.test(curr)) {
|
292 | path += `[${curr}]`;
|
293 | } else if (/^[a-z$_]+$/i.test(curr)) {
|
294 | path += `.${curr}`;
|
295 | } else {
|
296 | path += `[${JSON.stringify(curr)}]`;
|
297 | }
|
298 | }
|
299 | }
|
300 |
|
301 | const message = `Non-serializable values were found in the navigation state. Check:\n\n${path} (${reason})\n\nThis can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you can use 'navigation.setOptions' instead. See https://reactnavigation.org/docs/troubleshooting#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state for more details.`;
|
302 |
|
303 | if (!serializableWarnings.includes(message)) {
|
304 | serializableWarnings.push(message);
|
305 | console.warn(message);
|
306 | }
|
307 | }
|
308 |
|
309 | const duplicateRouteNamesResult = (0, _checkDuplicateRouteNames.default)(hydratedState);
|
310 |
|
311 | if (duplicateRouteNamesResult.length) {
|
312 | const message = `Found screens with the same name nested inside one another. Check:\n${duplicateRouteNamesResult.map(locations => `\n${locations.join(', ')}`)}\n\nThis can cause confusing behavior during navigation. Consider using unique names for each screen instead.`;
|
313 |
|
314 | if (!duplicateNameWarnings.includes(message)) {
|
315 | duplicateNameWarnings.push(message);
|
316 | console.warn(message);
|
317 | }
|
318 | }
|
319 | }
|
320 | }
|
321 |
|
322 | emitter.emit({
|
323 | type: 'state',
|
324 | data: {
|
325 | state
|
326 | }
|
327 | });
|
328 |
|
329 | if (!isFirstMountRef.current && onStateChangeRef.current) {
|
330 | onStateChangeRef.current(hydratedState);
|
331 | }
|
332 |
|
333 | isFirstMountRef.current = false;
|
334 | }, [getRootState, emitter, state]);
|
335 | const defaultOnUnhandledAction = React.useCallback(action => {
|
336 | if (process.env.NODE_ENV === 'production') {
|
337 | return;
|
338 | }
|
339 |
|
340 | const payload = action.payload;
|
341 | let message = `The action '${action.type}'${payload ? ` with payload ${JSON.stringify(action.payload)}` : ''} was not handled by any navigator.`;
|
342 |
|
343 | switch (action.type) {
|
344 | case 'NAVIGATE':
|
345 | case 'PUSH':
|
346 | case 'REPLACE':
|
347 | case 'JUMP_TO':
|
348 | if (payload !== null && payload !== void 0 && payload.name) {
|
349 | message += `\n\nDo you have a screen named '${payload.name}'?\n\nIf you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.`;
|
350 | } else {
|
351 | message += `\n\nYou need to pass the name of the screen to navigate to.\n\nSee https://reactnavigation.org/docs/navigation-actions for usage.`;
|
352 | }
|
353 |
|
354 | break;
|
355 |
|
356 | case 'GO_BACK':
|
357 | case 'POP':
|
358 | case 'POP_TO_TOP':
|
359 | message += `\n\nIs there any screen to go back to?`;
|
360 | break;
|
361 |
|
362 | case 'OPEN_DRAWER':
|
363 | case 'CLOSE_DRAWER':
|
364 | case 'TOGGLE_DRAWER':
|
365 | message += `\n\nIs your screen inside a Drawer navigator?`;
|
366 | break;
|
367 | }
|
368 |
|
369 | message += `\n\nThis is a development-only warning and won't be shown in production.`;
|
370 | console.error(message);
|
371 | }, []);
|
372 | let element = React.createElement(_NavigationContainerRefContext.default.Provider, {
|
373 | value: navigation
|
374 | }, React.createElement(_useScheduleUpdate.ScheduleUpdateContext.Provider, {
|
375 | value: scheduleContext
|
376 | }, React.createElement(_NavigationBuilderContext.default.Provider, {
|
377 | value: builderContext
|
378 | }, React.createElement(_NavigationStateContext.default.Provider, {
|
379 | value: context
|
380 | }, React.createElement(_UnhandledActionContext.default.Provider, {
|
381 | value: onUnhandledAction !== null && onUnhandledAction !== void 0 ? onUnhandledAction : defaultOnUnhandledAction
|
382 | }, React.createElement(_EnsureSingleNavigator.default, null, children))))));
|
383 |
|
384 | if (independent) {
|
385 |
|
386 | element = React.createElement(_NavigationRouteContext.default.Provider, {
|
387 | value: undefined
|
388 | }, React.createElement(_NavigationContext.default.Provider, {
|
389 | value: undefined
|
390 | }, element));
|
391 | }
|
392 |
|
393 | return element;
|
394 | });
|
395 | var _default = BaseNavigationContainer;
|
396 | exports.default = _default;
|
397 |
|
\ | No newline at end of file |