-
Notifications
You must be signed in to change notification settings - Fork 53
/
NavigationTabsReducer.js
103 lines (95 loc) · 3.13 KB
/
NavigationTabsReducer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule NavigationTabsReducer
* @flow
*/
'use strict';
const NavigationFindReducer = require('./NavigationFindReducer');
const NavigationStateUtils = require('./NavigationStateUtils');
import type {
NavigationReducer,
NavigationState,
} from 'NavigationTypeDefinition';
const ActionTypes = {
JUMP_TO: 'react-native/NavigationExperimental/tabs-jumpTo',
};
export type JumpToAction = {
type: typeof ActionTypes.JUMP_TO,
index: number,
};
function NavigationTabsJumpToAction(index: number): JumpToAction {
return {
type: ActionTypes.JUMP_TO,
index,
};
}
type TabsReducerConfig = {
key: string;
initialIndex: number;
tabReducers: Array<NavigationReducer>;
};
function NavigationTabsReducer({key, initialIndex, tabReducers}: TabsReducerConfig): NavigationReducer {
return function(lastNavState: ?NavigationState, action: ?any): NavigationState {
if (!lastNavState) {
lastNavState = {
children: tabReducers.map(reducer => reducer(null, null)),
index: initialIndex || 0,
key,
};
}
const lastParentNavState = NavigationStateUtils.getParent(lastNavState);
if (!action || !lastParentNavState) {
return lastNavState;
}
if (
action.type === ActionTypes.JUMP_TO &&
action.index !== lastParentNavState.index
) {
return NavigationStateUtils.jumpToIndex(
lastParentNavState,
action.index,
);
}
const subReducers = tabReducers.map((tabReducer, tabIndex) => {
return function(navState: ?NavigationState, tabAction: any): NavigationState {
if (!navState) {
return lastParentNavState;
}
const parentState = NavigationStateUtils.getParent(navState);
const tabState = parentState && parentState.children[tabIndex];
const nextTabState = tabReducer(tabState, tabAction);
if (nextTabState && tabState !== nextTabState) {
const tabs = parentState && parentState.children || [];
tabs[tabIndex] = nextTabState;
return {
...lastParentNavState,
tabs,
index: tabIndex,
};
}
return lastParentNavState;
};
});
let selectedTabReducer = subReducers.splice(lastParentNavState.index, 1)[0];
subReducers.unshift(function(navState: ?NavigationState, action: any): NavigationState {
if (navState && action.type === 'BackAction') {
return NavigationStateUtils.jumpToIndex(
lastParentNavState,
initialIndex || 0
);
}
return lastParentNavState;
});
subReducers.unshift(selectedTabReducer);
const findReducer = NavigationFindReducer(subReducers, lastParentNavState);
return findReducer(lastParentNavState, action);
};
}
NavigationTabsReducer.JumpToAction = NavigationTabsJumpToAction;
module.exports = NavigationTabsReducer;