@react-navigation/routers 8.0.0-alpha.6 → 8.0.0-alpha.8
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/BaseRouter.js +3 -2
- package/lib/module/BaseRouter.js.map +1 -1
- package/lib/module/StackRouter.js +141 -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/BaseRouter.tsx +4 -4
- package/src/StackRouter.tsx +241 -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(
|
|
333
368
|
(route) =>
|
|
334
369
|
routeNames.includes(route.name) &&
|
|
335
370
|
!routeKeyChanges.includes(route.name)
|
|
336
371
|
);
|
|
337
372
|
|
|
338
|
-
const preloadedRoutes = state.
|
|
373
|
+
const preloadedRoutes = getPreloadedRoutes(state).filter(
|
|
374
|
+
(route) =>
|
|
375
|
+
routeNames.includes(route.name) &&
|
|
376
|
+
!routeKeyChanges.includes(route.name)
|
|
377
|
+
);
|
|
378
|
+
|
|
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 })
|
|
@@ -417,17 +466,22 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
417
466
|
|
|
418
467
|
if (!route) {
|
|
419
468
|
route = createRouteFromAction({ action, routeParamList });
|
|
469
|
+
} else {
|
|
470
|
+
const params = createParamsFromAction({ action, routeParamList });
|
|
471
|
+
|
|
472
|
+
if (route.params !== params) {
|
|
473
|
+
route = { ...route, params };
|
|
474
|
+
}
|
|
420
475
|
}
|
|
421
476
|
|
|
422
|
-
return retainRoutes(
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
});
|
|
477
|
+
return retainRoutes(
|
|
478
|
+
state,
|
|
479
|
+
getStateWithRoutes(
|
|
480
|
+
state,
|
|
481
|
+
routes.map((r, i) => (i === currentIndex ? route : r)),
|
|
482
|
+
preloadedRoutes.filter((r) => r.key !== route.key)
|
|
483
|
+
)
|
|
484
|
+
);
|
|
431
485
|
}
|
|
432
486
|
|
|
433
487
|
case 'PUSH':
|
|
@@ -442,7 +496,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
442
496
|
let route: Route<string> | undefined;
|
|
443
497
|
|
|
444
498
|
if (action.type === 'NAVIGATE') {
|
|
445
|
-
const currentRoute =
|
|
499
|
+
const currentRoute = routes[state.index];
|
|
446
500
|
|
|
447
501
|
if (id !== undefined) {
|
|
448
502
|
if (
|
|
@@ -451,8 +505,8 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
451
505
|
) {
|
|
452
506
|
route = currentRoute;
|
|
453
507
|
} else if (action.payload.pop) {
|
|
454
|
-
for (let i =
|
|
455
|
-
const r =
|
|
508
|
+
for (let i = routes.length - 1; i >= 0; i--) {
|
|
509
|
+
const r = routes[i];
|
|
456
510
|
|
|
457
511
|
if (r.name !== action.payload.name) {
|
|
458
512
|
continue;
|
|
@@ -489,7 +543,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
489
543
|
if (action.payload.name === currentRoute.name) {
|
|
490
544
|
route = currentRoute;
|
|
491
545
|
} else if (action.payload.pop) {
|
|
492
|
-
route =
|
|
546
|
+
route = routes.findLast(
|
|
493
547
|
(route) => route.name === action.payload.name
|
|
494
548
|
);
|
|
495
549
|
}
|
|
@@ -497,7 +551,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
497
551
|
}
|
|
498
552
|
|
|
499
553
|
if (!route) {
|
|
500
|
-
route =
|
|
554
|
+
route = inactiveRoutes.find(
|
|
501
555
|
(route) =>
|
|
502
556
|
route.name === action.payload.name &&
|
|
503
557
|
id === getId?.({ params: route.params })
|
|
@@ -520,16 +574,16 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
520
574
|
params = createParamsFromAction({ action, routeParamList });
|
|
521
575
|
}
|
|
522
576
|
|
|
523
|
-
let
|
|
577
|
+
let nextRoutes: Route<string>[];
|
|
524
578
|
|
|
525
579
|
if (route) {
|
|
526
580
|
if (action.type === 'NAVIGATE' && action.payload.pop) {
|
|
527
|
-
|
|
581
|
+
nextRoutes = [];
|
|
528
582
|
|
|
529
583
|
// Get all routes until the matching one
|
|
530
|
-
for (const r of
|
|
584
|
+
for (const r of routes) {
|
|
531
585
|
if (r.key === route.key) {
|
|
532
|
-
|
|
586
|
+
nextRoutes.push({
|
|
533
587
|
...route,
|
|
534
588
|
path:
|
|
535
589
|
action.payload.path !== undefined
|
|
@@ -540,11 +594,22 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
540
594
|
break;
|
|
541
595
|
}
|
|
542
596
|
|
|
543
|
-
|
|
597
|
+
nextRoutes.push(r);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
if (!nextRoutes.some((r) => r.key === route.key)) {
|
|
601
|
+
nextRoutes.push({
|
|
602
|
+
...route,
|
|
603
|
+
path:
|
|
604
|
+
action.payload.path !== undefined
|
|
605
|
+
? action.payload.path
|
|
606
|
+
: route.path,
|
|
607
|
+
params,
|
|
608
|
+
});
|
|
544
609
|
}
|
|
545
610
|
} else {
|
|
546
|
-
|
|
547
|
-
|
|
611
|
+
nextRoutes = routes.filter((r) => r.key !== route.key);
|
|
612
|
+
nextRoutes.push({
|
|
548
613
|
...route,
|
|
549
614
|
path:
|
|
550
615
|
action.type === 'NAVIGATE' &&
|
|
@@ -555,8 +620,8 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
555
620
|
});
|
|
556
621
|
}
|
|
557
622
|
} else {
|
|
558
|
-
|
|
559
|
-
...
|
|
623
|
+
nextRoutes = [
|
|
624
|
+
...routes,
|
|
560
625
|
{
|
|
561
626
|
key: `${action.payload.name}-${nanoid()}`,
|
|
562
627
|
name: action.payload.name,
|
|
@@ -567,23 +632,29 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
567
632
|
];
|
|
568
633
|
}
|
|
569
634
|
|
|
570
|
-
return retainRoutes(
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
635
|
+
return retainRoutes(
|
|
636
|
+
state,
|
|
637
|
+
getStateWithRoutes(
|
|
638
|
+
state,
|
|
639
|
+
nextRoutes,
|
|
640
|
+
preloadedRoutes.filter(
|
|
641
|
+
(route) => nextRoutes[nextRoutes.length - 1].key !== route.key
|
|
642
|
+
)
|
|
643
|
+
)
|
|
644
|
+
);
|
|
578
645
|
}
|
|
579
646
|
|
|
580
647
|
case 'POP': {
|
|
581
648
|
let currentIndex =
|
|
582
649
|
action.target === state.key && action.source
|
|
583
|
-
?
|
|
650
|
+
? routes.findIndex((r) => r.key === action.source)
|
|
584
651
|
: state.index;
|
|
585
652
|
|
|
586
|
-
|
|
653
|
+
if (currentIndex === -1) {
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
let route = routes[currentIndex];
|
|
587
658
|
|
|
588
659
|
/**
|
|
589
660
|
* When popping entries,
|
|
@@ -596,11 +667,11 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
596
667
|
*/
|
|
597
668
|
if (route.history?.length || currentIndex > 0) {
|
|
598
669
|
let count = action.payload.count;
|
|
599
|
-
let
|
|
670
|
+
let nextRoutes = routes;
|
|
600
671
|
|
|
601
672
|
while (count > 0 && (route.history?.length || currentIndex > 0)) {
|
|
602
673
|
if (route.history?.length) {
|
|
603
|
-
|
|
674
|
+
nextRoutes = [...nextRoutes];
|
|
604
675
|
|
|
605
676
|
const end = Math.min(count, route.history.length);
|
|
606
677
|
const last = route.history.at(-end);
|
|
@@ -609,7 +680,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
609
680
|
|
|
610
681
|
count = count - removed;
|
|
611
682
|
|
|
612
|
-
|
|
683
|
+
nextRoutes[currentIndex] = {
|
|
613
684
|
...route,
|
|
614
685
|
params: last?.type === 'params' ? last.params : route.params,
|
|
615
686
|
history,
|
|
@@ -617,33 +688,29 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
617
688
|
}
|
|
618
689
|
|
|
619
690
|
if (currentIndex > 0 && count > 0) {
|
|
620
|
-
const length =
|
|
691
|
+
const length = nextRoutes.length;
|
|
621
692
|
const end = Math.max(currentIndex - count + 1, 1);
|
|
622
693
|
|
|
623
|
-
|
|
694
|
+
nextRoutes = nextRoutes
|
|
624
695
|
.slice(0, end)
|
|
625
|
-
.concat(
|
|
696
|
+
.concat(nextRoutes.slice(currentIndex + 1));
|
|
626
697
|
|
|
627
|
-
const removed = length -
|
|
698
|
+
const removed = length - nextRoutes.length;
|
|
628
699
|
|
|
629
700
|
count = count - removed;
|
|
630
|
-
currentIndex =
|
|
631
|
-
route =
|
|
701
|
+
currentIndex = nextRoutes.length - 1;
|
|
702
|
+
route = nextRoutes[currentIndex];
|
|
632
703
|
}
|
|
633
704
|
}
|
|
634
705
|
|
|
635
|
-
return retainRoutes(state,
|
|
636
|
-
...state,
|
|
637
|
-
index: routes.length - 1,
|
|
638
|
-
routes,
|
|
639
|
-
});
|
|
706
|
+
return retainRoutes(state, getStateWithRoutes(state, nextRoutes));
|
|
640
707
|
}
|
|
641
708
|
|
|
642
709
|
return null;
|
|
643
710
|
}
|
|
644
711
|
|
|
645
712
|
case 'POP_TO_TOP': {
|
|
646
|
-
let route =
|
|
713
|
+
let route = routes[0];
|
|
647
714
|
|
|
648
715
|
if (state.index > 0 || route.history?.length) {
|
|
649
716
|
if (route.history?.length) {
|
|
@@ -653,11 +720,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
653
720
|
};
|
|
654
721
|
}
|
|
655
722
|
|
|
656
|
-
return retainRoutes(state,
|
|
657
|
-
...state,
|
|
658
|
-
index: 0,
|
|
659
|
-
routes: [route],
|
|
660
|
-
});
|
|
723
|
+
return retainRoutes(state, getStateWithRoutes(state, [route]));
|
|
661
724
|
}
|
|
662
725
|
|
|
663
726
|
return null;
|
|
@@ -666,7 +729,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
666
729
|
case 'POP_TO': {
|
|
667
730
|
const currentIndex =
|
|
668
731
|
action.target === state.key && action.source
|
|
669
|
-
?
|
|
732
|
+
? routes.findLastIndex((r) => r.key === action.source)
|
|
670
733
|
: state.index;
|
|
671
734
|
|
|
672
735
|
if (currentIndex === -1) {
|
|
@@ -686,7 +749,7 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
686
749
|
|
|
687
750
|
if (id !== undefined) {
|
|
688
751
|
for (let i = currentIndex; i >= 0; i--) {
|
|
689
|
-
const r =
|
|
752
|
+
const r = routes[i];
|
|
690
753
|
|
|
691
754
|
if (r.name !== action.payload.name) {
|
|
692
755
|
continue;
|
|
@@ -714,11 +777,11 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
714
777
|
}
|
|
715
778
|
}
|
|
716
779
|
}
|
|
717
|
-
} else if (
|
|
780
|
+
} else if (routes[currentIndex].name === action.payload.name) {
|
|
718
781
|
index = currentIndex;
|
|
719
782
|
} else {
|
|
720
783
|
for (let i = currentIndex; i >= 0; i--) {
|
|
721
|
-
if (
|
|
784
|
+
if (routes[i].name === action.payload.name) {
|
|
722
785
|
index = i;
|
|
723
786
|
break;
|
|
724
787
|
}
|
|
@@ -727,8 +790,8 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
727
790
|
|
|
728
791
|
// If the route doesn't exist, remove the current route and add the new one
|
|
729
792
|
if (index === -1) {
|
|
730
|
-
// Re-use
|
|
731
|
-
let route =
|
|
793
|
+
// Re-use inactive route if available
|
|
794
|
+
let route = inactiveRoutes.find(
|
|
732
795
|
(route) =>
|
|
733
796
|
route.name === action.payload.name &&
|
|
734
797
|
id === getId?.({ params: route.params })
|
|
@@ -736,21 +799,27 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
736
799
|
|
|
737
800
|
if (!route) {
|
|
738
801
|
route = createRouteFromAction({ action, routeParamList });
|
|
802
|
+
} else {
|
|
803
|
+
const params = createParamsFromAction({ action, routeParamList });
|
|
804
|
+
|
|
805
|
+
if (route.params !== params) {
|
|
806
|
+
route = { ...route, params };
|
|
807
|
+
}
|
|
739
808
|
}
|
|
740
809
|
|
|
741
|
-
const
|
|
810
|
+
const nextRoutes = routes.slice(0, currentIndex).concat(route);
|
|
742
811
|
|
|
743
|
-
return retainRoutes(
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
(r) => r.key !== route.key
|
|
749
|
-
)
|
|
750
|
-
|
|
812
|
+
return retainRoutes(
|
|
813
|
+
state,
|
|
814
|
+
getStateWithRoutes(
|
|
815
|
+
state,
|
|
816
|
+
nextRoutes,
|
|
817
|
+
preloadedRoutes.filter((r) => r.key !== route.key)
|
|
818
|
+
)
|
|
819
|
+
);
|
|
751
820
|
}
|
|
752
821
|
|
|
753
|
-
const route =
|
|
822
|
+
const route = routes[index];
|
|
754
823
|
|
|
755
824
|
let baseParams = route.params;
|
|
756
825
|
let history = route.history;
|
|
@@ -776,20 +845,19 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
776
845
|
params = createParamsFromAction({ action, routeParamList });
|
|
777
846
|
}
|
|
778
847
|
|
|
779
|
-
return retainRoutes(
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
...state.routes.slice(0, index),
|
|
848
|
+
return retainRoutes(
|
|
849
|
+
state,
|
|
850
|
+
getStateWithRoutes(state, [
|
|
851
|
+
...routes.slice(0, index),
|
|
784
852
|
params !== baseParams || historyIndex !== undefined
|
|
785
853
|
? { ...route, params, history }
|
|
786
|
-
:
|
|
787
|
-
]
|
|
788
|
-
|
|
854
|
+
: routes[index],
|
|
855
|
+
])
|
|
856
|
+
);
|
|
789
857
|
}
|
|
790
858
|
|
|
791
859
|
case 'GO_BACK':
|
|
792
|
-
if (state.index > 0 ||
|
|
860
|
+
if (state.index > 0 || routes[state.index].history?.length) {
|
|
793
861
|
return router.getStateForAction(
|
|
794
862
|
state,
|
|
795
863
|
{
|
|
@@ -805,12 +873,9 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
805
873
|
return null;
|
|
806
874
|
|
|
807
875
|
case 'RETAIN': {
|
|
808
|
-
const routeKey = action.source ??
|
|
876
|
+
const routeKey = action.source ?? routes[state.index].key;
|
|
809
877
|
|
|
810
|
-
if (
|
|
811
|
-
!state.routes.some((route) => route.key === routeKey) &&
|
|
812
|
-
!state.preloadedRoutes.some((route) => route.key === routeKey)
|
|
813
|
-
) {
|
|
878
|
+
if (!state.routes.some((route) => route.key === routeKey)) {
|
|
814
879
|
return null;
|
|
815
880
|
}
|
|
816
881
|
|
|
@@ -829,18 +894,23 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
829
894
|
return state;
|
|
830
895
|
}
|
|
831
896
|
|
|
832
|
-
return
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
897
|
+
return getStateWithRoutes(
|
|
898
|
+
{
|
|
899
|
+
...state,
|
|
900
|
+
retainedRouteKeys: state.retainedRouteKeys.filter(
|
|
901
|
+
(key) => key !== routeKey
|
|
902
|
+
),
|
|
903
|
+
},
|
|
904
|
+
routes,
|
|
905
|
+
preloadedRoutes.filter((route) => route.key !== routeKey)
|
|
906
|
+
);
|
|
841
907
|
}
|
|
842
908
|
|
|
843
909
|
case 'PRELOAD': {
|
|
910
|
+
if (!state.routeNames.includes(action.payload.name)) {
|
|
911
|
+
return null;
|
|
912
|
+
}
|
|
913
|
+
|
|
844
914
|
const getId = options.routeGetIdList[action.payload.name];
|
|
845
915
|
const id = getId?.({ params: action.payload.params });
|
|
846
916
|
const params = createParamsFromAction({ action, routeParamList });
|
|
@@ -848,56 +918,59 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
848
918
|
let route: Route<string> | undefined;
|
|
849
919
|
|
|
850
920
|
if (action.payload.reuse) {
|
|
851
|
-
route =
|
|
921
|
+
route = preloadedRoutes.findLast(
|
|
852
922
|
(route) =>
|
|
853
923
|
route.name === action.payload.name &&
|
|
854
924
|
(id === undefined || id === getId?.({ params: route.params }))
|
|
855
925
|
);
|
|
856
926
|
|
|
857
927
|
if (route) {
|
|
858
|
-
return
|
|
859
|
-
|
|
860
|
-
|
|
928
|
+
return getStateWithRoutes(
|
|
929
|
+
state,
|
|
930
|
+
routes,
|
|
931
|
+
preloadedRoutes.map((r) =>
|
|
861
932
|
r.key === route?.key && r.params !== params
|
|
862
933
|
? { ...r, params }
|
|
863
934
|
: r
|
|
864
|
-
)
|
|
865
|
-
|
|
935
|
+
)
|
|
936
|
+
);
|
|
866
937
|
}
|
|
867
938
|
}
|
|
868
939
|
|
|
869
940
|
if (id !== undefined) {
|
|
870
|
-
route =
|
|
941
|
+
route = routes.findLast(
|
|
871
942
|
(route) =>
|
|
872
943
|
route.name === action.payload.name &&
|
|
873
944
|
id === getId?.({ params: route.params })
|
|
874
945
|
);
|
|
875
946
|
} else if (action.payload.reuse) {
|
|
876
|
-
route =
|
|
947
|
+
route = routes.findLast(
|
|
877
948
|
(route) => route.name === action.payload.name
|
|
878
949
|
);
|
|
879
950
|
}
|
|
880
951
|
|
|
881
952
|
if (route) {
|
|
882
|
-
return
|
|
883
|
-
|
|
884
|
-
routes
|
|
953
|
+
return getStateWithRoutes(
|
|
954
|
+
state,
|
|
955
|
+
routes.map((r) =>
|
|
885
956
|
r.key === route.key && r.params !== params
|
|
886
957
|
? { ...r, params }
|
|
887
958
|
: r
|
|
888
959
|
),
|
|
889
|
-
|
|
960
|
+
preloadedRoutes
|
|
961
|
+
);
|
|
890
962
|
} else {
|
|
891
|
-
return
|
|
892
|
-
|
|
893
|
-
|
|
963
|
+
return getStateWithRoutes(
|
|
964
|
+
state,
|
|
965
|
+
routes,
|
|
966
|
+
preloadedRoutes
|
|
894
967
|
.filter(
|
|
895
968
|
(r) =>
|
|
896
969
|
r.name !== action.payload.name ||
|
|
897
970
|
id !== getId?.({ params: r.params })
|
|
898
971
|
)
|
|
899
|
-
.concat(createRouteFromAction({ action, routeParamList }))
|
|
900
|
-
|
|
972
|
+
.concat(createRouteFromAction({ action, routeParamList }))
|
|
973
|
+
);
|
|
901
974
|
}
|
|
902
975
|
}
|
|
903
976
|
|
|
@@ -906,10 +979,6 @@ export function StackRouter(options: StackRouterOptions) {
|
|
|
906
979
|
}
|
|
907
980
|
},
|
|
908
981
|
|
|
909
|
-
getRoutesFromState(state) {
|
|
910
|
-
return [...state.routes, ...state.preloadedRoutes];
|
|
911
|
-
},
|
|
912
|
-
|
|
913
982
|
actionCreators: StackActions,
|
|
914
983
|
};
|
|
915
984
|
|