@react-navigation/routers 8.0.0-alpha.6 → 8.0.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/module/StackRouter.js +113 -137
- package/lib/module/StackRouter.js.map +1 -1
- package/lib/typescript/src/StackRouter.d.ts +3 -9
- package/lib/typescript/src/StackRouter.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +0 -10
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/StackRouter.tsx +221 -172
- package/src/types.tsx +0 -11
package/src/StackRouter.tsx
CHANGED
|
@@ -6,7 +6,6 @@ import { createRouteFromAction } from './createRouteFromAction';
|
|
|
6
6
|
import type {
|
|
7
7
|
CommonNavigationAction,
|
|
8
8
|
DefaultRouterOptions,
|
|
9
|
-
NavigationRoute,
|
|
10
9
|
NavigationState,
|
|
11
10
|
ParamListBase,
|
|
12
11
|
Route,
|
|
@@ -62,15 +61,10 @@ export type StackNavigationState<ParamList extends ParamListBase> =
|
|
|
62
61
|
* Type of the router, in this case, it's stack.
|
|
63
62
|
*/
|
|
64
63
|
type: 'stack';
|
|
65
|
-
/**
|
|
66
|
-
* List of routes, which are supposed to be preloaded before navigating to.
|
|
67
|
-
*/
|
|
68
|
-
preloadedRoutes: NavigationRoute<ParamList, keyof ParamList>[];
|
|
69
64
|
/**
|
|
70
65
|
* List of route keys to retain in the stack.
|
|
71
66
|
* When a retained route gets removed from the stack,
|
|
72
|
-
* it'll be
|
|
73
|
-
* So it preserves the route and can be navigated to again.
|
|
67
|
+
* it'll be kept in routes and can be navigated to again.
|
|
74
68
|
*/
|
|
75
69
|
retainedRouteKeys: string[];
|
|
76
70
|
};
|
|
@@ -141,8 +135,7 @@ export type StackActionHelpers<ParamList extends ParamListBase> = {
|
|
|
141
135
|
/**
|
|
142
136
|
* Enable or disable retaining the current route in the stack.
|
|
143
137
|
* When a retained route gets removed from the stack,
|
|
144
|
-
* it'll be
|
|
145
|
-
* So it preserves the route and can be navigated to again.
|
|
138
|
+
* it'll be kept in routes and can be navigated to again.
|
|
146
139
|
*
|
|
147
140
|
* @param enable Whether to retain the current route in the stack or not.
|
|
148
141
|
*/
|
|
@@ -199,7 +192,7 @@ function retainRoutes<ParamList extends ParamListBase>(
|
|
|
199
192
|
|
|
200
193
|
const retainedRouteKeySet = new Set(nextState.retainedRouteKeys);
|
|
201
194
|
const nextRouteKeySet = new Set(nextState.routes.map((route) => route.key));
|
|
202
|
-
const retainedRoutes = previousState.
|
|
195
|
+
const retainedRoutes = getActiveRoutes(previousState).filter(
|
|
203
196
|
(route) =>
|
|
204
197
|
retainedRouteKeySet.has(route.key) && !nextRouteKeySet.has(route.key)
|
|
205
198
|
);
|
|
@@ -212,15 +205,73 @@ function retainRoutes<ParamList extends ParamListBase>(
|
|
|
212
205
|
retainedRoutes.map((route) => route.key)
|
|
213
206
|
);
|
|
214
207
|
|
|
215
|
-
return
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
208
|
+
return getStateWithRoutes(
|
|
209
|
+
nextState,
|
|
210
|
+
getActiveRoutes(nextState),
|
|
211
|
+
getPreloadedRoutes(nextState),
|
|
212
|
+
retainedRoutes.concat(
|
|
213
|
+
getRetainedRoutes(nextState).filter(
|
|
219
214
|
(route) => !removedRetainedRouteKeys.has(route.key)
|
|
220
215
|
)
|
|
216
|
+
)
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const getActiveRoutes = <ParamList extends ParamListBase>(
|
|
221
|
+
state: StackNavigationState<ParamList>
|
|
222
|
+
) => state.routes.slice(0, state.index + 1);
|
|
223
|
+
|
|
224
|
+
const getInactiveRoutes = <ParamList extends ParamListBase>(
|
|
225
|
+
state: StackNavigationState<ParamList>
|
|
226
|
+
) => state.routes.slice(state.index + 1);
|
|
227
|
+
|
|
228
|
+
const getPreloadedRoutes = <ParamList extends ParamListBase>(
|
|
229
|
+
state: StackNavigationState<ParamList>
|
|
230
|
+
) => {
|
|
231
|
+
const retainedRouteKeySet = new Set(state.retainedRouteKeys);
|
|
232
|
+
|
|
233
|
+
return getInactiveRoutes(state).filter(
|
|
234
|
+
(route) => !retainedRouteKeySet.has(route.key)
|
|
235
|
+
);
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const getRetainedRoutes = <ParamList extends ParamListBase>(
|
|
239
|
+
state: StackNavigationState<ParamList>
|
|
240
|
+
) => {
|
|
241
|
+
const retainedRouteKeySet = new Set(state.retainedRouteKeys);
|
|
242
|
+
|
|
243
|
+
return getInactiveRoutes(state).filter((route) =>
|
|
244
|
+
retainedRouteKeySet.has(route.key)
|
|
245
|
+
);
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const getStateWithRoutes = <ParamList extends ParamListBase>(
|
|
249
|
+
state: StackNavigationState<ParamList>,
|
|
250
|
+
activeRoutes: Route<string>[],
|
|
251
|
+
preloadedRoutes = getPreloadedRoutes(state),
|
|
252
|
+
retainedRoutes = getRetainedRoutes(state)
|
|
253
|
+
) => {
|
|
254
|
+
const routeKeySet = new Set(activeRoutes.map((route) => route.key));
|
|
255
|
+
const retainedRouteKeySet = new Set(state.retainedRouteKeys);
|
|
256
|
+
|
|
257
|
+
const filteredRetainedRoutes = retainedRoutes.filter(
|
|
258
|
+
(route) => !routeKeySet.has(route.key)
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
const filteredPreloadedRoutes = preloadedRoutes.filter(
|
|
262
|
+
(route) =>
|
|
263
|
+
!retainedRouteKeySet.has(route.key) && !routeKeySet.has(route.key)
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
...state,
|
|
268
|
+
index: activeRoutes.length - 1,
|
|
269
|
+
routes: activeRoutes.concat(
|
|
270
|
+
filteredRetainedRoutes,
|
|
271
|
+
filteredPreloadedRoutes
|
|
221
272
|
),
|
|
222
273
|
};
|
|
223
|
-
}
|
|
274
|
+
};
|
|
224
275
|
|
|
225
276
|
export function StackRouter(options: StackRouterOptions) {
|
|
226
277
|
const router: Router<
|
|
@@ -244,7 +295,6 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
244
295
|
key: `stack-${nanoid()}`,
|
|
245
296
|
index: 0,
|
|
246
297
|
routeNames,
|
|
247
|
-
preloadedRoutes: [],
|
|
248
298
|
retainedRouteKeys: [],
|
|
249
299
|
routes: [
|
|
250
300
|
{
|
|
@@ -277,29 +327,6 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
277
327
|
: route.params,
|
|
278
328
|
}));
|
|
279
329
|
|
|
280
|
-
const preloadedRoutes =
|
|
281
|
-
state.preloadedRoutes
|
|
282
|
-
?.filter((route) => routeNames.includes(route.name))
|
|
283
|
-
.map(
|
|
284
|
-
(route) =>
|
|
285
|
-
({
|
|
286
|
-
...route,
|
|
287
|
-
key: route.key || `${route.name}-${nanoid()}`,
|
|
288
|
-
params:
|
|
289
|
-
routeParamList[route.name] !== undefined
|
|
290
|
-
? {
|
|
291
|
-
...routeParamList[route.name],
|
|
292
|
-
...route.params,
|
|
293
|
-
}
|
|
294
|
-
: route.params,
|
|
295
|
-
}) as Route<string>
|
|
296
|
-
) ?? [];
|
|
297
|
-
|
|
298
|
-
const retainedRouteKeys =
|
|
299
|
-
state.retainedRouteKeys?.filter((key) =>
|
|
300
|
-
[...routes, ...preloadedRoutes].some((route) => route.key === key)
|
|
301
|
-
) ?? [];
|
|
302
|
-
|
|
303
330
|
if (routes.length === 0) {
|
|
304
331
|
const initialRouteName =
|
|
305
332
|
options.initialRouteName !== undefined
|
|
@@ -313,14 +340,22 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
313
340
|
});
|
|
314
341
|
}
|
|
315
342
|
|
|
343
|
+
const index = Math.min(
|
|
344
|
+
Math.max(state.index ?? routes.length - 1, 0),
|
|
345
|
+
routes.length - 1
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
const routeKeys = new Set(routes.map((route) => route.key));
|
|
349
|
+
const retainedRouteKeys =
|
|
350
|
+
state.retainedRouteKeys?.filter((key) => routeKeys.has(key)) ?? [];
|
|
351
|
+
|
|
316
352
|
return {
|
|
317
353
|
stale: false,
|
|
318
354
|
type: 'stack',
|
|
319
355
|
key: `stack-${nanoid()}`,
|
|
320
|
-
index
|
|
356
|
+
index,
|
|
321
357
|
routeNames,
|
|
322
358
|
routes,
|
|
323
|
-
preloadedRoutes,
|
|
324
359
|
retainedRouteKeys,
|
|
325
360
|
};
|
|
326
361
|
},
|
|
@@ -329,13 +364,19 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
329
364
|
state,
|
|
330
365
|
{ routeNames, routeParamList, routeKeyChanges }
|
|
331
366
|
) {
|
|
332
|
-
const routes = state.
|
|
367
|
+
const routes = getActiveRoutes(state).filter(
|
|
368
|
+
(route) =>
|
|
369
|
+
routeNames.includes(route.name) &&
|
|
370
|
+
!routeKeyChanges.includes(route.name)
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
const preloadedRoutes = getPreloadedRoutes(state).filter(
|
|
333
374
|
(route) =>
|
|
334
375
|
routeNames.includes(route.name) &&
|
|
335
376
|
!routeKeyChanges.includes(route.name)
|
|
336
377
|
);
|
|
337
378
|
|
|
338
|
-
const
|
|
379
|
+
const retainedRoutes = getRetainedRoutes(state).filter(
|
|
339
380
|
(route) =>
|
|
340
381
|
routeNames.includes(route.name) &&
|
|
341
382
|
!routeKeyChanges.includes(route.name)
|
|
@@ -356,45 +397,53 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
356
397
|
}
|
|
357
398
|
|
|
358
399
|
const routeKeys = new Set(
|
|
359
|
-
[...routes, ...preloadedRoutes].map(
|
|
400
|
+
[...routes, ...preloadedRoutes, ...retainedRoutes].map(
|
|
401
|
+
(route) => route.key
|
|
402
|
+
)
|
|
360
403
|
);
|
|
361
404
|
|
|
362
405
|
const retainedRouteKeys = state.retainedRouteKeys.filter((key) =>
|
|
363
406
|
routeKeys.has(key)
|
|
364
407
|
);
|
|
365
408
|
|
|
366
|
-
return
|
|
367
|
-
|
|
368
|
-
|
|
409
|
+
return getStateWithRoutes(
|
|
410
|
+
{
|
|
411
|
+
...state,
|
|
412
|
+
routeNames,
|
|
413
|
+
retainedRouteKeys,
|
|
414
|
+
},
|
|
369
415
|
routes,
|
|
370
416
|
preloadedRoutes,
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
};
|
|
417
|
+
retainedRoutes
|
|
418
|
+
);
|
|
374
419
|
},
|
|
375
420
|
|
|
376
421
|
getStateForRouteFocus(state, key) {
|
|
377
|
-
const
|
|
422
|
+
const routes = getActiveRoutes(state);
|
|
423
|
+
const index = routes.findIndex((r) => r.key === key);
|
|
378
424
|
|
|
379
425
|
if (index === -1 || index === state.index) {
|
|
380
426
|
return state;
|
|
381
427
|
}
|
|
382
428
|
|
|
383
|
-
return retainRoutes(
|
|
384
|
-
|
|
385
|
-
index
|
|
386
|
-
|
|
387
|
-
});
|
|
429
|
+
return retainRoutes(
|
|
430
|
+
state,
|
|
431
|
+
getStateWithRoutes(state, routes.slice(0, index + 1))
|
|
432
|
+
);
|
|
388
433
|
},
|
|
389
434
|
|
|
390
435
|
getStateForAction(state, action, options) {
|
|
391
436
|
const { routeParamList } = options;
|
|
392
437
|
|
|
438
|
+
const routes = getActiveRoutes(state);
|
|
439
|
+
const preloadedRoutes = getPreloadedRoutes(state);
|
|
440
|
+
const inactiveRoutes = getInactiveRoutes(state);
|
|
441
|
+
|
|
393
442
|
switch (action.type) {
|
|
394
443
|
case 'REPLACE': {
|
|
395
444
|
const currentIndex =
|
|
396
445
|
action.target === state.key && action.source
|
|
397
|
-
?
|
|
446
|
+
? routes.findIndex((r) => r.key === action.source)
|
|
398
447
|
: state.index;
|
|
399
448
|
|
|
400
449
|
if (currentIndex === -1) {
|
|
@@ -408,8 +457,8 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
408
457
|
const getId = options.routeGetIdList[action.payload.name];
|
|
409
458
|
const id = getId?.({ params: action.payload.params });
|
|
410
459
|
|
|
411
|
-
// Re-use
|
|
412
|
-
let route =
|
|
460
|
+
// Re-use inactive route if available
|
|
461
|
+
let route = inactiveRoutes.find(
|
|
413
462
|
(route) =>
|
|
414
463
|
route.name === action.payload.name &&
|
|
415
464
|
id === getId?.({ params: route.params })
|
|
@@ -419,15 +468,14 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
419
468
|
route = createRouteFromAction({ action, routeParamList });
|
|
420
469
|
}
|
|
421
470
|
|
|
422
|
-
return retainRoutes(
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
});
|
|
471
|
+
return retainRoutes(
|
|
472
|
+
state,
|
|
473
|
+
getStateWithRoutes(
|
|
474
|
+
state,
|
|
475
|
+
routes.map((r, i) => (i === currentIndex ? route : r)),
|
|
476
|
+
preloadedRoutes.filter((r) => r.key !== route.key)
|
|
477
|
+
)
|
|
478
|
+
);
|
|
431
479
|
}
|
|
432
480
|
|
|
433
481
|
case 'PUSH':
|
|
@@ -442,7 +490,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
442
490
|
let route: Route<string> | undefined;
|
|
443
491
|
|
|
444
492
|
if (action.type === 'NAVIGATE') {
|
|
445
|
-
const currentRoute =
|
|
493
|
+
const currentRoute = routes[state.index];
|
|
446
494
|
|
|
447
495
|
if (id !== undefined) {
|
|
448
496
|
if (
|
|
@@ -451,8 +499,8 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
451
499
|
) {
|
|
452
500
|
route = currentRoute;
|
|
453
501
|
} else if (action.payload.pop) {
|
|
454
|
-
for (let i =
|
|
455
|
-
const r =
|
|
502
|
+
for (let i = routes.length - 1; i >= 0; i--) {
|
|
503
|
+
const r = routes[i];
|
|
456
504
|
|
|
457
505
|
if (r.name !== action.payload.name) {
|
|
458
506
|
continue;
|
|
@@ -489,7 +537,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
489
537
|
if (action.payload.name === currentRoute.name) {
|
|
490
538
|
route = currentRoute;
|
|
491
539
|
} else if (action.payload.pop) {
|
|
492
|
-
route =
|
|
540
|
+
route = routes.findLast(
|
|
493
541
|
(route) => route.name === action.payload.name
|
|
494
542
|
);
|
|
495
543
|
}
|
|
@@ -497,7 +545,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
497
545
|
}
|
|
498
546
|
|
|
499
547
|
if (!route) {
|
|
500
|
-
route =
|
|
548
|
+
route = inactiveRoutes.find(
|
|
501
549
|
(route) =>
|
|
502
550
|
route.name === action.payload.name &&
|
|
503
551
|
id === getId?.({ params: route.params })
|
|
@@ -520,16 +568,16 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
520
568
|
params = createParamsFromAction({ action, routeParamList });
|
|
521
569
|
}
|
|
522
570
|
|
|
523
|
-
let
|
|
571
|
+
let nextRoutes: Route<string>[];
|
|
524
572
|
|
|
525
573
|
if (route) {
|
|
526
574
|
if (action.type === 'NAVIGATE' && action.payload.pop) {
|
|
527
|
-
|
|
575
|
+
nextRoutes = [];
|
|
528
576
|
|
|
529
577
|
// Get all routes until the matching one
|
|
530
|
-
for (const r of
|
|
578
|
+
for (const r of routes) {
|
|
531
579
|
if (r.key === route.key) {
|
|
532
|
-
|
|
580
|
+
nextRoutes.push({
|
|
533
581
|
...route,
|
|
534
582
|
path:
|
|
535
583
|
action.payload.path !== undefined
|
|
@@ -540,11 +588,22 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
540
588
|
break;
|
|
541
589
|
}
|
|
542
590
|
|
|
543
|
-
|
|
591
|
+
nextRoutes.push(r);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
if (!nextRoutes.some((r) => r.key === route.key)) {
|
|
595
|
+
nextRoutes.push({
|
|
596
|
+
...route,
|
|
597
|
+
path:
|
|
598
|
+
action.payload.path !== undefined
|
|
599
|
+
? action.payload.path
|
|
600
|
+
: route.path,
|
|
601
|
+
params,
|
|
602
|
+
});
|
|
544
603
|
}
|
|
545
604
|
} else {
|
|
546
|
-
|
|
547
|
-
|
|
605
|
+
nextRoutes = routes.filter((r) => r.key !== route.key);
|
|
606
|
+
nextRoutes.push({
|
|
548
607
|
...route,
|
|
549
608
|
path:
|
|
550
609
|
action.type === 'NAVIGATE' &&
|
|
@@ -555,8 +614,8 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
555
614
|
});
|
|
556
615
|
}
|
|
557
616
|
} else {
|
|
558
|
-
|
|
559
|
-
...
|
|
617
|
+
nextRoutes = [
|
|
618
|
+
...routes,
|
|
560
619
|
{
|
|
561
620
|
key: `${action.payload.name}-${nanoid()}`,
|
|
562
621
|
name: action.payload.name,
|
|
@@ -567,23 +626,25 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
567
626
|
];
|
|
568
627
|
}
|
|
569
628
|
|
|
570
|
-
return retainRoutes(
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
629
|
+
return retainRoutes(
|
|
630
|
+
state,
|
|
631
|
+
getStateWithRoutes(
|
|
632
|
+
state,
|
|
633
|
+
nextRoutes,
|
|
634
|
+
preloadedRoutes.filter(
|
|
635
|
+
(route) => nextRoutes[nextRoutes.length - 1].key !== route.key
|
|
636
|
+
)
|
|
637
|
+
)
|
|
638
|
+
);
|
|
578
639
|
}
|
|
579
640
|
|
|
580
641
|
case 'POP': {
|
|
581
642
|
let currentIndex =
|
|
582
643
|
action.target === state.key && action.source
|
|
583
|
-
?
|
|
644
|
+
? routes.findIndex((r) => r.key === action.source)
|
|
584
645
|
: state.index;
|
|
585
646
|
|
|
586
|
-
let route =
|
|
647
|
+
let route = routes[currentIndex];
|
|
587
648
|
|
|
588
649
|
/**
|
|
589
650
|
* When popping entries,
|
|
@@ -596,11 +657,11 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
596
657
|
*/
|
|
597
658
|
if (route.history?.length || currentIndex > 0) {
|
|
598
659
|
let count = action.payload.count;
|
|
599
|
-
let
|
|
660
|
+
let nextRoutes = routes;
|
|
600
661
|
|
|
601
662
|
while (count > 0 && (route.history?.length || currentIndex > 0)) {
|
|
602
663
|
if (route.history?.length) {
|
|
603
|
-
|
|
664
|
+
nextRoutes = [...nextRoutes];
|
|
604
665
|
|
|
605
666
|
const end = Math.min(count, route.history.length);
|
|
606
667
|
const last = route.history.at(-end);
|
|
@@ -609,7 +670,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
609
670
|
|
|
610
671
|
count = count - removed;
|
|
611
672
|
|
|
612
|
-
|
|
673
|
+
nextRoutes[currentIndex] = {
|
|
613
674
|
...route,
|
|
614
675
|
params: last?.type === 'params' ? last.params : route.params,
|
|
615
676
|
history,
|
|
@@ -617,33 +678,29 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
617
678
|
}
|
|
618
679
|
|
|
619
680
|
if (currentIndex > 0 && count > 0) {
|
|
620
|
-
const length =
|
|
681
|
+
const length = nextRoutes.length;
|
|
621
682
|
const end = Math.max(currentIndex - count + 1, 1);
|
|
622
683
|
|
|
623
|
-
|
|
684
|
+
nextRoutes = nextRoutes
|
|
624
685
|
.slice(0, end)
|
|
625
|
-
.concat(
|
|
686
|
+
.concat(nextRoutes.slice(currentIndex + 1));
|
|
626
687
|
|
|
627
|
-
const removed = length -
|
|
688
|
+
const removed = length - nextRoutes.length;
|
|
628
689
|
|
|
629
690
|
count = count - removed;
|
|
630
|
-
currentIndex =
|
|
631
|
-
route =
|
|
691
|
+
currentIndex = nextRoutes.length - 1;
|
|
692
|
+
route = nextRoutes[currentIndex];
|
|
632
693
|
}
|
|
633
694
|
}
|
|
634
695
|
|
|
635
|
-
return retainRoutes(state,
|
|
636
|
-
...state,
|
|
637
|
-
index: routes.length - 1,
|
|
638
|
-
routes,
|
|
639
|
-
});
|
|
696
|
+
return retainRoutes(state, getStateWithRoutes(state, nextRoutes));
|
|
640
697
|
}
|
|
641
698
|
|
|
642
699
|
return null;
|
|
643
700
|
}
|
|
644
701
|
|
|
645
702
|
case 'POP_TO_TOP': {
|
|
646
|
-
let route =
|
|
703
|
+
let route = routes[0];
|
|
647
704
|
|
|
648
705
|
if (state.index > 0 || route.history?.length) {
|
|
649
706
|
if (route.history?.length) {
|
|
@@ -653,11 +710,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
653
710
|
};
|
|
654
711
|
}
|
|
655
712
|
|
|
656
|
-
return retainRoutes(state,
|
|
657
|
-
...state,
|
|
658
|
-
index: 0,
|
|
659
|
-
routes: [route],
|
|
660
|
-
});
|
|
713
|
+
return retainRoutes(state, getStateWithRoutes(state, [route]));
|
|
661
714
|
}
|
|
662
715
|
|
|
663
716
|
return null;
|
|
@@ -666,7 +719,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
666
719
|
case 'POP_TO': {
|
|
667
720
|
const currentIndex =
|
|
668
721
|
action.target === state.key && action.source
|
|
669
|
-
?
|
|
722
|
+
? routes.findLastIndex((r) => r.key === action.source)
|
|
670
723
|
: state.index;
|
|
671
724
|
|
|
672
725
|
if (currentIndex === -1) {
|
|
@@ -686,7 +739,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
686
739
|
|
|
687
740
|
if (id !== undefined) {
|
|
688
741
|
for (let i = currentIndex; i >= 0; i--) {
|
|
689
|
-
const r =
|
|
742
|
+
const r = routes[i];
|
|
690
743
|
|
|
691
744
|
if (r.name !== action.payload.name) {
|
|
692
745
|
continue;
|
|
@@ -714,11 +767,11 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
714
767
|
}
|
|
715
768
|
}
|
|
716
769
|
}
|
|
717
|
-
} else if (
|
|
770
|
+
} else if (routes[currentIndex].name === action.payload.name) {
|
|
718
771
|
index = currentIndex;
|
|
719
772
|
} else {
|
|
720
773
|
for (let i = currentIndex; i >= 0; i--) {
|
|
721
|
-
if (
|
|
774
|
+
if (routes[i].name === action.payload.name) {
|
|
722
775
|
index = i;
|
|
723
776
|
break;
|
|
724
777
|
}
|
|
@@ -727,8 +780,8 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
727
780
|
|
|
728
781
|
// If the route doesn't exist, remove the current route and add the new one
|
|
729
782
|
if (index === -1) {
|
|
730
|
-
// Re-use
|
|
731
|
-
let route =
|
|
783
|
+
// Re-use inactive route if available
|
|
784
|
+
let route = inactiveRoutes.find(
|
|
732
785
|
(route) =>
|
|
733
786
|
route.name === action.payload.name &&
|
|
734
787
|
id === getId?.({ params: route.params })
|
|
@@ -738,19 +791,19 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
738
791
|
route = createRouteFromAction({ action, routeParamList });
|
|
739
792
|
}
|
|
740
793
|
|
|
741
|
-
const
|
|
794
|
+
const nextRoutes = routes.slice(0, currentIndex).concat(route);
|
|
742
795
|
|
|
743
|
-
return retainRoutes(
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
(r) => r.key !== route.key
|
|
749
|
-
)
|
|
750
|
-
|
|
796
|
+
return retainRoutes(
|
|
797
|
+
state,
|
|
798
|
+
getStateWithRoutes(
|
|
799
|
+
state,
|
|
800
|
+
nextRoutes,
|
|
801
|
+
preloadedRoutes.filter((r) => r.key !== route.key)
|
|
802
|
+
)
|
|
803
|
+
);
|
|
751
804
|
}
|
|
752
805
|
|
|
753
|
-
const route =
|
|
806
|
+
const route = routes[index];
|
|
754
807
|
|
|
755
808
|
let baseParams = route.params;
|
|
756
809
|
let history = route.history;
|
|
@@ -776,20 +829,19 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
776
829
|
params = createParamsFromAction({ action, routeParamList });
|
|
777
830
|
}
|
|
778
831
|
|
|
779
|
-
return retainRoutes(
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
...state.routes.slice(0, index),
|
|
832
|
+
return retainRoutes(
|
|
833
|
+
state,
|
|
834
|
+
getStateWithRoutes(state, [
|
|
835
|
+
...routes.slice(0, index),
|
|
784
836
|
params !== baseParams || historyIndex !== undefined
|
|
785
837
|
? { ...route, params, history }
|
|
786
|
-
:
|
|
787
|
-
]
|
|
788
|
-
|
|
838
|
+
: routes[index],
|
|
839
|
+
])
|
|
840
|
+
);
|
|
789
841
|
}
|
|
790
842
|
|
|
791
843
|
case 'GO_BACK':
|
|
792
|
-
if (state.index > 0 ||
|
|
844
|
+
if (state.index > 0 || routes[state.index].history?.length) {
|
|
793
845
|
return router.getStateForAction(
|
|
794
846
|
state,
|
|
795
847
|
{
|
|
@@ -805,12 +857,9 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
805
857
|
return null;
|
|
806
858
|
|
|
807
859
|
case 'RETAIN': {
|
|
808
|
-
const routeKey = action.source ??
|
|
860
|
+
const routeKey = action.source ?? routes[state.index].key;
|
|
809
861
|
|
|
810
|
-
if (
|
|
811
|
-
!state.routes.some((route) => route.key === routeKey) &&
|
|
812
|
-
!state.preloadedRoutes.some((route) => route.key === routeKey)
|
|
813
|
-
) {
|
|
862
|
+
if (!state.routes.some((route) => route.key === routeKey)) {
|
|
814
863
|
return null;
|
|
815
864
|
}
|
|
816
865
|
|
|
@@ -829,15 +878,16 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
829
878
|
return state;
|
|
830
879
|
}
|
|
831
880
|
|
|
832
|
-
return
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
881
|
+
return getStateWithRoutes(
|
|
882
|
+
{
|
|
883
|
+
...state,
|
|
884
|
+
retainedRouteKeys: state.retainedRouteKeys.filter(
|
|
885
|
+
(key) => key !== routeKey
|
|
886
|
+
),
|
|
887
|
+
},
|
|
888
|
+
routes,
|
|
889
|
+
preloadedRoutes.filter((route) => route.key !== routeKey)
|
|
890
|
+
);
|
|
841
891
|
}
|
|
842
892
|
|
|
843
893
|
case 'PRELOAD': {
|
|
@@ -848,56 +898,59 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
848
898
|
let route: Route<string> | undefined;
|
|
849
899
|
|
|
850
900
|
if (action.payload.reuse) {
|
|
851
|
-
route =
|
|
901
|
+
route = preloadedRoutes.findLast(
|
|
852
902
|
(route) =>
|
|
853
903
|
route.name === action.payload.name &&
|
|
854
904
|
(id === undefined || id === getId?.({ params: route.params }))
|
|
855
905
|
);
|
|
856
906
|
|
|
857
907
|
if (route) {
|
|
858
|
-
return
|
|
859
|
-
|
|
860
|
-
|
|
908
|
+
return getStateWithRoutes(
|
|
909
|
+
state,
|
|
910
|
+
routes,
|
|
911
|
+
preloadedRoutes.map((r) =>
|
|
861
912
|
r.key === route?.key && r.params !== params
|
|
862
913
|
? { ...r, params }
|
|
863
914
|
: r
|
|
864
|
-
)
|
|
865
|
-
|
|
915
|
+
)
|
|
916
|
+
);
|
|
866
917
|
}
|
|
867
918
|
}
|
|
868
919
|
|
|
869
920
|
if (id !== undefined) {
|
|
870
|
-
route =
|
|
921
|
+
route = routes.findLast(
|
|
871
922
|
(route) =>
|
|
872
923
|
route.name === action.payload.name &&
|
|
873
924
|
id === getId?.({ params: route.params })
|
|
874
925
|
);
|
|
875
926
|
} else if (action.payload.reuse) {
|
|
876
|
-
route =
|
|
927
|
+
route = routes.findLast(
|
|
877
928
|
(route) => route.name === action.payload.name
|
|
878
929
|
);
|
|
879
930
|
}
|
|
880
931
|
|
|
881
932
|
if (route) {
|
|
882
|
-
return
|
|
883
|
-
|
|
884
|
-
routes
|
|
933
|
+
return getStateWithRoutes(
|
|
934
|
+
state,
|
|
935
|
+
routes.map((r) =>
|
|
885
936
|
r.key === route.key && r.params !== params
|
|
886
937
|
? { ...r, params }
|
|
887
938
|
: r
|
|
888
939
|
),
|
|
889
|
-
|
|
940
|
+
preloadedRoutes
|
|
941
|
+
);
|
|
890
942
|
} else {
|
|
891
|
-
return
|
|
892
|
-
|
|
893
|
-
|
|
943
|
+
return getStateWithRoutes(
|
|
944
|
+
state,
|
|
945
|
+
routes,
|
|
946
|
+
preloadedRoutes
|
|
894
947
|
.filter(
|
|
895
948
|
(r) =>
|
|
896
949
|
r.name !== action.payload.name ||
|
|
897
950
|
id !== getId?.({ params: r.params })
|
|
898
951
|
)
|
|
899
|
-
.concat(createRouteFromAction({ action, routeParamList }))
|
|
900
|
-
|
|
952
|
+
.concat(createRouteFromAction({ action, routeParamList }))
|
|
953
|
+
);
|
|
901
954
|
}
|
|
902
955
|
}
|
|
903
956
|
|
|
@@ -906,10 +959,6 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
906
959
|
}
|
|
907
960
|
},
|
|
908
961
|
|
|
909
|
-
getRoutesFromState(state) {
|
|
910
|
-
return [...state.routes, ...state.preloadedRoutes];
|
|
911
|
-
},
|
|
912
|
-
|
|
913
962
|
actionCreators: StackActions,
|
|
914
963
|
};
|
|
915
964
|
|