@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/lib/module/BaseRouter.js
CHANGED
|
@@ -47,11 +47,12 @@ export const BaseRouter = {
|
|
|
47
47
|
case 'RESET':
|
|
48
48
|
{
|
|
49
49
|
const nextState = action.payload;
|
|
50
|
-
|
|
50
|
+
const routeNamesSet = new Set(state.routeNames);
|
|
51
|
+
if (nextState.routes.length === 0 || nextState.routes.some(route => !routeNamesSet.has(route.name))) {
|
|
51
52
|
return null;
|
|
52
53
|
}
|
|
53
54
|
if (nextState.stale === false) {
|
|
54
|
-
if (state.routeNames.length !== nextState.routeNames.length || nextState.routeNames.some(name => !
|
|
55
|
+
if (state.routeNames.length !== nextState.routeNames.length || nextState.routeNames.some(name => !routeNamesSet.has(name))) {
|
|
55
56
|
return null;
|
|
56
57
|
}
|
|
57
58
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["nanoid","BaseRouter","getStateForAction","state","action","type","index","source","routes","findIndex","r","key","map","i","params","payload","history","nextState","length","some","route","
|
|
1
|
+
{"version":3,"names":["nanoid","BaseRouter","getStateForAction","state","action","type","index","source","routes","findIndex","r","key","map","i","params","payload","history","nextState","routeNamesSet","Set","routeNames","length","some","route","has","name","stale","shouldActionChangeFocus"],"sourceRoot":"../../src","sources":["BaseRouter.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -61,16 +61,34 @@ function retainRoutes(previousState, nextState) {
|
|
|
61
61
|
}
|
|
62
62
|
const retainedRouteKeySet = new Set(nextState.retainedRouteKeys);
|
|
63
63
|
const nextRouteKeySet = new Set(nextState.routes.map(route => route.key));
|
|
64
|
-
const retainedRoutes = previousState.
|
|
64
|
+
const retainedRoutes = getActiveRoutes(previousState).filter(route => retainedRouteKeySet.has(route.key) && !nextRouteKeySet.has(route.key));
|
|
65
65
|
if (!retainedRoutes.length) {
|
|
66
66
|
return nextState;
|
|
67
67
|
}
|
|
68
68
|
const removedRetainedRouteKeys = new Set(retainedRoutes.map(route => route.key));
|
|
69
|
+
return getStateWithRoutes(nextState, getActiveRoutes(nextState), getPreloadedRoutes(nextState), retainedRoutes.concat(getRetainedRoutes(nextState).filter(route => !removedRetainedRouteKeys.has(route.key))));
|
|
70
|
+
}
|
|
71
|
+
const getActiveRoutes = state => state.routes.slice(0, state.index + 1);
|
|
72
|
+
const getInactiveRoutes = state => state.routes.slice(state.index + 1);
|
|
73
|
+
const getPreloadedRoutes = state => {
|
|
74
|
+
const retainedRouteKeySet = new Set(state.retainedRouteKeys);
|
|
75
|
+
return getInactiveRoutes(state).filter(route => !retainedRouteKeySet.has(route.key));
|
|
76
|
+
};
|
|
77
|
+
const getRetainedRoutes = state => {
|
|
78
|
+
const retainedRouteKeySet = new Set(state.retainedRouteKeys);
|
|
79
|
+
return getInactiveRoutes(state).filter(route => retainedRouteKeySet.has(route.key));
|
|
80
|
+
};
|
|
81
|
+
const getStateWithRoutes = (state, activeRoutes, preloadedRoutes = getPreloadedRoutes(state), retainedRoutes = getRetainedRoutes(state)) => {
|
|
82
|
+
const routeKeySet = new Set(activeRoutes.map(route => route.key));
|
|
83
|
+
const retainedRouteKeySet = new Set(state.retainedRouteKeys);
|
|
84
|
+
const filteredRetainedRoutes = retainedRoutes.filter(route => !routeKeySet.has(route.key));
|
|
85
|
+
const filteredPreloadedRoutes = preloadedRoutes.filter(route => !retainedRouteKeySet.has(route.key) && !routeKeySet.has(route.key));
|
|
69
86
|
return {
|
|
70
|
-
...
|
|
71
|
-
|
|
87
|
+
...state,
|
|
88
|
+
index: activeRoutes.length - 1,
|
|
89
|
+
routes: activeRoutes.concat(filteredRetainedRoutes, filteredPreloadedRoutes)
|
|
72
90
|
};
|
|
73
|
-
}
|
|
91
|
+
};
|
|
74
92
|
export function StackRouter(options) {
|
|
75
93
|
const router = {
|
|
76
94
|
...BaseRouter,
|
|
@@ -86,7 +104,6 @@ export function StackRouter(options) {
|
|
|
86
104
|
key: `stack-${nanoid()}`,
|
|
87
105
|
index: 0,
|
|
88
106
|
routeNames,
|
|
89
|
-
preloadedRoutes: [],
|
|
90
107
|
retainedRouteKeys: [],
|
|
91
108
|
routes: [{
|
|
92
109
|
key: `${initialRouteName}-${nanoid()}`,
|
|
@@ -111,15 +128,6 @@ export function StackRouter(options) {
|
|
|
111
128
|
...route.params
|
|
112
129
|
} : route.params
|
|
113
130
|
}));
|
|
114
|
-
const preloadedRoutes = state.preloadedRoutes?.filter(route => routeNames.includes(route.name)).map(route => ({
|
|
115
|
-
...route,
|
|
116
|
-
key: route.key || `${route.name}-${nanoid()}`,
|
|
117
|
-
params: routeParamList[route.name] !== undefined ? {
|
|
118
|
-
...routeParamList[route.name],
|
|
119
|
-
...route.params
|
|
120
|
-
} : route.params
|
|
121
|
-
})) ?? [];
|
|
122
|
-
const retainedRouteKeys = state.retainedRouteKeys?.filter(key => [...routes, ...preloadedRoutes].some(route => route.key === key)) ?? [];
|
|
123
131
|
if (routes.length === 0) {
|
|
124
132
|
const initialRouteName = options.initialRouteName !== undefined ? options.initialRouteName : routeNames[0];
|
|
125
133
|
routes.push({
|
|
@@ -128,14 +136,16 @@ export function StackRouter(options) {
|
|
|
128
136
|
params: routeParamList[initialRouteName]
|
|
129
137
|
});
|
|
130
138
|
}
|
|
139
|
+
const index = Math.min(Math.max(state.index ?? routes.length - 1, 0), routes.length - 1);
|
|
140
|
+
const routeKeys = new Set(routes.map(route => route.key));
|
|
141
|
+
const retainedRouteKeys = state.retainedRouteKeys?.filter(key => routeKeys.has(key)) ?? [];
|
|
131
142
|
return {
|
|
132
143
|
stale: false,
|
|
133
144
|
type: 'stack',
|
|
134
145
|
key: `stack-${nanoid()}`,
|
|
135
|
-
index
|
|
146
|
+
index,
|
|
136
147
|
routeNames,
|
|
137
148
|
routes,
|
|
138
|
-
preloadedRoutes,
|
|
139
149
|
retainedRouteKeys
|
|
140
150
|
};
|
|
141
151
|
},
|
|
@@ -144,8 +154,9 @@ export function StackRouter(options) {
|
|
|
144
154
|
routeParamList,
|
|
145
155
|
routeKeyChanges
|
|
146
156
|
}) {
|
|
147
|
-
const routes = state.
|
|
148
|
-
const preloadedRoutes = state.
|
|
157
|
+
const routes = getActiveRoutes(state).filter(route => routeNames.includes(route.name) && !routeKeyChanges.includes(route.name));
|
|
158
|
+
const preloadedRoutes = getPreloadedRoutes(state).filter(route => routeNames.includes(route.name) && !routeKeyChanges.includes(route.name));
|
|
159
|
+
const retainedRoutes = getRetainedRoutes(state).filter(route => routeNames.includes(route.name) && !routeKeyChanges.includes(route.name));
|
|
149
160
|
if (routes.length === 0) {
|
|
150
161
|
const initialRouteName = options.initialRouteName !== undefined && routeNames.includes(options.initialRouteName) ? options.initialRouteName : routeNames[0];
|
|
151
162
|
routes.push({
|
|
@@ -154,36 +165,33 @@ export function StackRouter(options) {
|
|
|
154
165
|
params: routeParamList[initialRouteName]
|
|
155
166
|
});
|
|
156
167
|
}
|
|
157
|
-
const routeKeys = new Set([...routes, ...preloadedRoutes].map(route => route.key));
|
|
168
|
+
const routeKeys = new Set([...routes, ...preloadedRoutes, ...retainedRoutes].map(route => route.key));
|
|
158
169
|
const retainedRouteKeys = state.retainedRouteKeys.filter(key => routeKeys.has(key));
|
|
159
|
-
return {
|
|
170
|
+
return getStateWithRoutes({
|
|
160
171
|
...state,
|
|
161
172
|
routeNames,
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
retainedRouteKeys,
|
|
165
|
-
index: Math.min(state.index, routes.length - 1)
|
|
166
|
-
};
|
|
173
|
+
retainedRouteKeys
|
|
174
|
+
}, routes, preloadedRoutes, retainedRoutes);
|
|
167
175
|
},
|
|
168
176
|
getStateForRouteFocus(state, key) {
|
|
169
|
-
const
|
|
177
|
+
const routes = getActiveRoutes(state);
|
|
178
|
+
const index = routes.findIndex(r => r.key === key);
|
|
170
179
|
if (index === -1 || index === state.index) {
|
|
171
180
|
return state;
|
|
172
181
|
}
|
|
173
|
-
return retainRoutes(state,
|
|
174
|
-
...state,
|
|
175
|
-
index,
|
|
176
|
-
routes: state.routes.slice(0, index + 1)
|
|
177
|
-
});
|
|
182
|
+
return retainRoutes(state, getStateWithRoutes(state, routes.slice(0, index + 1)));
|
|
178
183
|
},
|
|
179
184
|
getStateForAction(state, action, options) {
|
|
180
185
|
const {
|
|
181
186
|
routeParamList
|
|
182
187
|
} = options;
|
|
188
|
+
const routes = getActiveRoutes(state);
|
|
189
|
+
const preloadedRoutes = getPreloadedRoutes(state);
|
|
190
|
+
const inactiveRoutes = getInactiveRoutes(state);
|
|
183
191
|
switch (action.type) {
|
|
184
192
|
case 'REPLACE':
|
|
185
193
|
{
|
|
186
|
-
const currentIndex = action.target === state.key && action.source ?
|
|
194
|
+
const currentIndex = action.target === state.key && action.source ? routes.findIndex(r => r.key === action.source) : state.index;
|
|
187
195
|
if (currentIndex === -1) {
|
|
188
196
|
return null;
|
|
189
197
|
}
|
|
@@ -195,8 +203,8 @@ export function StackRouter(options) {
|
|
|
195
203
|
params: action.payload.params
|
|
196
204
|
});
|
|
197
205
|
|
|
198
|
-
// Re-use
|
|
199
|
-
let route =
|
|
206
|
+
// Re-use inactive route if available
|
|
207
|
+
let route = inactiveRoutes.find(route => route.name === action.payload.name && id === getId?.({
|
|
200
208
|
params: route.params
|
|
201
209
|
}));
|
|
202
210
|
if (!route) {
|
|
@@ -204,12 +212,19 @@ export function StackRouter(options) {
|
|
|
204
212
|
action,
|
|
205
213
|
routeParamList
|
|
206
214
|
});
|
|
215
|
+
} else {
|
|
216
|
+
const params = createParamsFromAction({
|
|
217
|
+
action,
|
|
218
|
+
routeParamList
|
|
219
|
+
});
|
|
220
|
+
if (route.params !== params) {
|
|
221
|
+
route = {
|
|
222
|
+
...route,
|
|
223
|
+
params
|
|
224
|
+
};
|
|
225
|
+
}
|
|
207
226
|
}
|
|
208
|
-
return retainRoutes(state,
|
|
209
|
-
...state,
|
|
210
|
-
routes: state.routes.map((r, i) => i === currentIndex ? route : r),
|
|
211
|
-
preloadedRoutes: state.preloadedRoutes.filter(r => r.key !== route.key)
|
|
212
|
-
});
|
|
227
|
+
return retainRoutes(state, getStateWithRoutes(state, routes.map((r, i) => i === currentIndex ? route : r), preloadedRoutes.filter(r => r.key !== route.key)));
|
|
213
228
|
}
|
|
214
229
|
case 'PUSH':
|
|
215
230
|
case 'NAVIGATE':
|
|
@@ -223,15 +238,15 @@ export function StackRouter(options) {
|
|
|
223
238
|
});
|
|
224
239
|
let route;
|
|
225
240
|
if (action.type === 'NAVIGATE') {
|
|
226
|
-
const currentRoute =
|
|
241
|
+
const currentRoute = routes[state.index];
|
|
227
242
|
if (id !== undefined) {
|
|
228
243
|
if (currentRoute.name === action.payload.name && id === getId?.({
|
|
229
244
|
params: currentRoute.params
|
|
230
245
|
})) {
|
|
231
246
|
route = currentRoute;
|
|
232
247
|
} else if (action.payload.pop) {
|
|
233
|
-
for (let i =
|
|
234
|
-
const r =
|
|
248
|
+
for (let i = routes.length - 1; i >= 0; i--) {
|
|
249
|
+
const r = routes[i];
|
|
235
250
|
if (r.name !== action.payload.name) {
|
|
236
251
|
continue;
|
|
237
252
|
}
|
|
@@ -265,12 +280,12 @@ export function StackRouter(options) {
|
|
|
265
280
|
if (action.payload.name === currentRoute.name) {
|
|
266
281
|
route = currentRoute;
|
|
267
282
|
} else if (action.payload.pop) {
|
|
268
|
-
route =
|
|
283
|
+
route = routes.findLast(route => route.name === action.payload.name);
|
|
269
284
|
}
|
|
270
285
|
}
|
|
271
286
|
}
|
|
272
287
|
if (!route) {
|
|
273
|
-
route =
|
|
288
|
+
route = inactiveRoutes.find(route => route.name === action.payload.name && id === getId?.({
|
|
274
289
|
params: route.params
|
|
275
290
|
}));
|
|
276
291
|
}
|
|
@@ -287,50 +302,55 @@ export function StackRouter(options) {
|
|
|
287
302
|
routeParamList
|
|
288
303
|
});
|
|
289
304
|
}
|
|
290
|
-
let
|
|
305
|
+
let nextRoutes;
|
|
291
306
|
if (route) {
|
|
292
307
|
if (action.type === 'NAVIGATE' && action.payload.pop) {
|
|
293
|
-
|
|
308
|
+
nextRoutes = [];
|
|
294
309
|
|
|
295
310
|
// Get all routes until the matching one
|
|
296
|
-
for (const r of
|
|
311
|
+
for (const r of routes) {
|
|
297
312
|
if (r.key === route.key) {
|
|
298
|
-
|
|
313
|
+
nextRoutes.push({
|
|
299
314
|
...route,
|
|
300
315
|
path: action.payload.path !== undefined ? action.payload.path : route.path,
|
|
301
316
|
params
|
|
302
317
|
});
|
|
303
318
|
break;
|
|
304
319
|
}
|
|
305
|
-
|
|
320
|
+
nextRoutes.push(r);
|
|
321
|
+
}
|
|
322
|
+
if (!nextRoutes.some(r => r.key === route.key)) {
|
|
323
|
+
nextRoutes.push({
|
|
324
|
+
...route,
|
|
325
|
+
path: action.payload.path !== undefined ? action.payload.path : route.path,
|
|
326
|
+
params
|
|
327
|
+
});
|
|
306
328
|
}
|
|
307
329
|
} else {
|
|
308
|
-
|
|
309
|
-
|
|
330
|
+
nextRoutes = routes.filter(r => r.key !== route.key);
|
|
331
|
+
nextRoutes.push({
|
|
310
332
|
...route,
|
|
311
333
|
path: action.type === 'NAVIGATE' && action.payload.path !== undefined ? action.payload.path : route.path,
|
|
312
334
|
params
|
|
313
335
|
});
|
|
314
336
|
}
|
|
315
337
|
} else {
|
|
316
|
-
|
|
338
|
+
nextRoutes = [...routes, {
|
|
317
339
|
key: `${action.payload.name}-${nanoid()}`,
|
|
318
340
|
name: action.payload.name,
|
|
319
341
|
path: action.type === 'NAVIGATE' ? action.payload.path : undefined,
|
|
320
342
|
params
|
|
321
343
|
}];
|
|
322
344
|
}
|
|
323
|
-
return retainRoutes(state,
|
|
324
|
-
...state,
|
|
325
|
-
index: routes.length - 1,
|
|
326
|
-
preloadedRoutes: state.preloadedRoutes.filter(route => routes[routes.length - 1].key !== route.key),
|
|
327
|
-
routes
|
|
328
|
-
});
|
|
345
|
+
return retainRoutes(state, getStateWithRoutes(state, nextRoutes, preloadedRoutes.filter(route => nextRoutes[nextRoutes.length - 1].key !== route.key)));
|
|
329
346
|
}
|
|
330
347
|
case 'POP':
|
|
331
348
|
{
|
|
332
|
-
let currentIndex = action.target === state.key && action.source ?
|
|
333
|
-
|
|
349
|
+
let currentIndex = action.target === state.key && action.source ? routes.findIndex(r => r.key === action.source) : state.index;
|
|
350
|
+
if (currentIndex === -1) {
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
let route = routes[currentIndex];
|
|
334
354
|
|
|
335
355
|
/**
|
|
336
356
|
* When popping entries,
|
|
@@ -343,42 +363,38 @@ export function StackRouter(options) {
|
|
|
343
363
|
*/
|
|
344
364
|
if (route.history?.length || currentIndex > 0) {
|
|
345
365
|
let count = action.payload.count;
|
|
346
|
-
let
|
|
366
|
+
let nextRoutes = routes;
|
|
347
367
|
while (count > 0 && (route.history?.length || currentIndex > 0)) {
|
|
348
368
|
if (route.history?.length) {
|
|
349
|
-
|
|
369
|
+
nextRoutes = [...nextRoutes];
|
|
350
370
|
const end = Math.min(count, route.history.length);
|
|
351
371
|
const last = route.history.at(-end);
|
|
352
372
|
const history = route.history.slice(0, -end);
|
|
353
373
|
const removed = route.history.length - history.length;
|
|
354
374
|
count = count - removed;
|
|
355
|
-
|
|
375
|
+
nextRoutes[currentIndex] = {
|
|
356
376
|
...route,
|
|
357
377
|
params: last?.type === 'params' ? last.params : route.params,
|
|
358
378
|
history
|
|
359
379
|
};
|
|
360
380
|
}
|
|
361
381
|
if (currentIndex > 0 && count > 0) {
|
|
362
|
-
const length =
|
|
382
|
+
const length = nextRoutes.length;
|
|
363
383
|
const end = Math.max(currentIndex - count + 1, 1);
|
|
364
|
-
|
|
365
|
-
const removed = length -
|
|
384
|
+
nextRoutes = nextRoutes.slice(0, end).concat(nextRoutes.slice(currentIndex + 1));
|
|
385
|
+
const removed = length - nextRoutes.length;
|
|
366
386
|
count = count - removed;
|
|
367
|
-
currentIndex =
|
|
368
|
-
route =
|
|
387
|
+
currentIndex = nextRoutes.length - 1;
|
|
388
|
+
route = nextRoutes[currentIndex];
|
|
369
389
|
}
|
|
370
390
|
}
|
|
371
|
-
return retainRoutes(state,
|
|
372
|
-
...state,
|
|
373
|
-
index: routes.length - 1,
|
|
374
|
-
routes
|
|
375
|
-
});
|
|
391
|
+
return retainRoutes(state, getStateWithRoutes(state, nextRoutes));
|
|
376
392
|
}
|
|
377
393
|
return null;
|
|
378
394
|
}
|
|
379
395
|
case 'POP_TO_TOP':
|
|
380
396
|
{
|
|
381
|
-
let route =
|
|
397
|
+
let route = routes[0];
|
|
382
398
|
if (state.index > 0 || route.history?.length) {
|
|
383
399
|
if (route.history?.length) {
|
|
384
400
|
route = {
|
|
@@ -386,17 +402,13 @@ export function StackRouter(options) {
|
|
|
386
402
|
history: undefined
|
|
387
403
|
};
|
|
388
404
|
}
|
|
389
|
-
return retainRoutes(state,
|
|
390
|
-
...state,
|
|
391
|
-
index: 0,
|
|
392
|
-
routes: [route]
|
|
393
|
-
});
|
|
405
|
+
return retainRoutes(state, getStateWithRoutes(state, [route]));
|
|
394
406
|
}
|
|
395
407
|
return null;
|
|
396
408
|
}
|
|
397
409
|
case 'POP_TO':
|
|
398
410
|
{
|
|
399
|
-
const currentIndex = action.target === state.key && action.source ?
|
|
411
|
+
const currentIndex = action.target === state.key && action.source ? routes.findLastIndex(r => r.key === action.source) : state.index;
|
|
400
412
|
if (currentIndex === -1) {
|
|
401
413
|
return null;
|
|
402
414
|
}
|
|
@@ -413,7 +425,7 @@ export function StackRouter(options) {
|
|
|
413
425
|
});
|
|
414
426
|
if (id !== undefined) {
|
|
415
427
|
for (let i = currentIndex; i >= 0; i--) {
|
|
416
|
-
const r =
|
|
428
|
+
const r = routes[i];
|
|
417
429
|
if (r.name !== action.payload.name) {
|
|
418
430
|
continue;
|
|
419
431
|
}
|
|
@@ -438,11 +450,11 @@ export function StackRouter(options) {
|
|
|
438
450
|
}
|
|
439
451
|
}
|
|
440
452
|
}
|
|
441
|
-
} else if (
|
|
453
|
+
} else if (routes[currentIndex].name === action.payload.name) {
|
|
442
454
|
index = currentIndex;
|
|
443
455
|
} else {
|
|
444
456
|
for (let i = currentIndex; i >= 0; i--) {
|
|
445
|
-
if (
|
|
457
|
+
if (routes[i].name === action.payload.name) {
|
|
446
458
|
index = i;
|
|
447
459
|
break;
|
|
448
460
|
}
|
|
@@ -451,8 +463,8 @@ export function StackRouter(options) {
|
|
|
451
463
|
|
|
452
464
|
// If the route doesn't exist, remove the current route and add the new one
|
|
453
465
|
if (index === -1) {
|
|
454
|
-
// Re-use
|
|
455
|
-
let route =
|
|
466
|
+
// Re-use inactive route if available
|
|
467
|
+
let route = inactiveRoutes.find(route => route.name === action.payload.name && id === getId?.({
|
|
456
468
|
params: route.params
|
|
457
469
|
}));
|
|
458
470
|
if (!route) {
|
|
@@ -460,16 +472,22 @@ export function StackRouter(options) {
|
|
|
460
472
|
action,
|
|
461
473
|
routeParamList
|
|
462
474
|
});
|
|
475
|
+
} else {
|
|
476
|
+
const params = createParamsFromAction({
|
|
477
|
+
action,
|
|
478
|
+
routeParamList
|
|
479
|
+
});
|
|
480
|
+
if (route.params !== params) {
|
|
481
|
+
route = {
|
|
482
|
+
...route,
|
|
483
|
+
params
|
|
484
|
+
};
|
|
485
|
+
}
|
|
463
486
|
}
|
|
464
|
-
const
|
|
465
|
-
return retainRoutes(state,
|
|
466
|
-
...state,
|
|
467
|
-
index: routes.length - 1,
|
|
468
|
-
routes,
|
|
469
|
-
preloadedRoutes: state.preloadedRoutes.filter(r => r.key !== route.key)
|
|
470
|
-
});
|
|
487
|
+
const nextRoutes = routes.slice(0, currentIndex).concat(route);
|
|
488
|
+
return retainRoutes(state, getStateWithRoutes(state, nextRoutes, preloadedRoutes.filter(r => r.key !== route.key)));
|
|
471
489
|
}
|
|
472
|
-
const route =
|
|
490
|
+
const route = routes[index];
|
|
473
491
|
let baseParams = route.params;
|
|
474
492
|
let history = route.history;
|
|
475
493
|
if (historyIndex !== undefined && route.history) {
|
|
@@ -489,18 +507,14 @@ export function StackRouter(options) {
|
|
|
489
507
|
routeParamList
|
|
490
508
|
});
|
|
491
509
|
}
|
|
492
|
-
return retainRoutes(state, {
|
|
493
|
-
...
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
params,
|
|
498
|
-
history
|
|
499
|
-
} : state.routes[index]]
|
|
500
|
-
});
|
|
510
|
+
return retainRoutes(state, getStateWithRoutes(state, [...routes.slice(0, index), params !== baseParams || historyIndex !== undefined ? {
|
|
511
|
+
...route,
|
|
512
|
+
params,
|
|
513
|
+
history
|
|
514
|
+
} : routes[index]]));
|
|
501
515
|
}
|
|
502
516
|
case 'GO_BACK':
|
|
503
|
-
if (state.index > 0 ||
|
|
517
|
+
if (state.index > 0 || routes[state.index].history?.length) {
|
|
504
518
|
return router.getStateForAction(state, {
|
|
505
519
|
type: 'POP',
|
|
506
520
|
payload: {
|
|
@@ -513,8 +527,8 @@ export function StackRouter(options) {
|
|
|
513
527
|
return null;
|
|
514
528
|
case 'RETAIN':
|
|
515
529
|
{
|
|
516
|
-
const routeKey = action.source ??
|
|
517
|
-
if (!state.routes.some(route => route.key === routeKey)
|
|
530
|
+
const routeKey = action.source ?? routes[state.index].key;
|
|
531
|
+
if (!state.routes.some(route => route.key === routeKey)) {
|
|
518
532
|
return null;
|
|
519
533
|
}
|
|
520
534
|
if (action.payload.enable) {
|
|
@@ -529,14 +543,16 @@ export function StackRouter(options) {
|
|
|
529
543
|
if (!state.retainedRouteKeys.includes(routeKey)) {
|
|
530
544
|
return state;
|
|
531
545
|
}
|
|
532
|
-
return {
|
|
546
|
+
return getStateWithRoutes({
|
|
533
547
|
...state,
|
|
534
|
-
preloadedRoutes: state.preloadedRoutes.filter(route => route.key !== routeKey),
|
|
535
548
|
retainedRouteKeys: state.retainedRouteKeys.filter(key => key !== routeKey)
|
|
536
|
-
};
|
|
549
|
+
}, routes, preloadedRoutes.filter(route => route.key !== routeKey));
|
|
537
550
|
}
|
|
538
551
|
case 'PRELOAD':
|
|
539
552
|
{
|
|
553
|
+
if (!state.routeNames.includes(action.payload.name)) {
|
|
554
|
+
return null;
|
|
555
|
+
}
|
|
540
556
|
const getId = options.routeGetIdList[action.payload.name];
|
|
541
557
|
const id = getId?.({
|
|
542
558
|
params: action.payload.params
|
|
@@ -547,53 +563,41 @@ export function StackRouter(options) {
|
|
|
547
563
|
});
|
|
548
564
|
let route;
|
|
549
565
|
if (action.payload.reuse) {
|
|
550
|
-
route =
|
|
566
|
+
route = preloadedRoutes.findLast(route => route.name === action.payload.name && (id === undefined || id === getId?.({
|
|
551
567
|
params: route.params
|
|
552
568
|
})));
|
|
553
569
|
if (route) {
|
|
554
|
-
return {
|
|
555
|
-
...
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
params
|
|
559
|
-
} : r)
|
|
560
|
-
};
|
|
570
|
+
return getStateWithRoutes(state, routes, preloadedRoutes.map(r => r.key === route?.key && r.params !== params ? {
|
|
571
|
+
...r,
|
|
572
|
+
params
|
|
573
|
+
} : r));
|
|
561
574
|
}
|
|
562
575
|
}
|
|
563
576
|
if (id !== undefined) {
|
|
564
|
-
route =
|
|
577
|
+
route = routes.findLast(route => route.name === action.payload.name && id === getId?.({
|
|
565
578
|
params: route.params
|
|
566
579
|
}));
|
|
567
580
|
} else if (action.payload.reuse) {
|
|
568
|
-
route =
|
|
581
|
+
route = routes.findLast(route => route.name === action.payload.name);
|
|
569
582
|
}
|
|
570
583
|
if (route) {
|
|
571
|
-
return {
|
|
572
|
-
...
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
params
|
|
576
|
-
} : r)
|
|
577
|
-
};
|
|
584
|
+
return getStateWithRoutes(state, routes.map(r => r.key === route.key && r.params !== params ? {
|
|
585
|
+
...r,
|
|
586
|
+
params
|
|
587
|
+
} : r), preloadedRoutes);
|
|
578
588
|
} else {
|
|
579
|
-
return {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
routeParamList
|
|
586
|
-
}))
|
|
587
|
-
};
|
|
589
|
+
return getStateWithRoutes(state, routes, preloadedRoutes.filter(r => r.name !== action.payload.name || id !== getId?.({
|
|
590
|
+
params: r.params
|
|
591
|
+
})).concat(createRouteFromAction({
|
|
592
|
+
action,
|
|
593
|
+
routeParamList
|
|
594
|
+
})));
|
|
588
595
|
}
|
|
589
596
|
}
|
|
590
597
|
default:
|
|
591
598
|
return BaseRouter.getStateForAction(state, action);
|
|
592
599
|
}
|
|
593
600
|
},
|
|
594
|
-
getRoutesFromState(state) {
|
|
595
|
-
return [...state.routes, ...state.preloadedRoutes];
|
|
596
|
-
},
|
|
597
601
|
actionCreators: StackActions
|
|
598
602
|
};
|
|
599
603
|
return router;
|