-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathreducer.js
126 lines (123 loc) · 3.48 KB
/
reducer.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { types } from './actions'
const initialState = {
action: null,
options: {},
data: {},
routes: [],
drawerOpen: false,
navActionRenderer: null,
navActionHandler: null,
navTitle: null,
appBarSize: 54,
transitioning: false,
$$_blurEventListeners: {},
$$_focusEventListeners: {},
$$_unloadEventListeners: {},
$$_routeIsChanging: false,
$$_previousWillFocusListener: null,
$$_previousDidFocusListener: null,
}
const getUpdate = (action, state) => {
let routes
let { route, reset, data = {}, ...options } = action.options
if (action.type === types.ROUTE_POP) {
routes = state.routes.filter((_, i) => i !== state.routes.length - 1)
route = routes[routes.length - 1]
if (!route) {
throw new Error('Cannot pop the topmost route, route stack contains only 1 child.')
}
} else {
if (action.type === types.ROUTE_PUSH) {
routes = [...state.routes, route]
} else if (action.type === types.ROUTE_REPLACE) {
routes = state.routes.filter((_, i) => i !== state.routes.length - 1).concat(route)
} else if (action.type === types.ROUTE_RESET) {
routes = [route]
}
}
return {
action: action.type,
options,
routes,
data,
navActionRenderer: null,
navActionHandler: null,
$$_routeIsChanging: true,
}
}
export default function (state = initialState, action = {}) {
switch (action.type) {
case types.ROUTE_PUSH:
case types.ROUTE_POP:
case types.ROUTE_REPLACE:
case types.ROUTE_RESET:
return {
...state,
...getUpdate(action, state),
}
case types.SET_NAV_ACTION:
return {
...state,
navActionRenderer: action.renderer,
navActionHandler: action.handler,
}
case types.SET_NAV_TITLE:
return {
...state,
navTitle: action.title,
}
case types.OPEN_DRAWER:
return {
...state,
drawerOpen: true,
}
case types.CLOSE_DRAWER:
return {
...state,
drawerOpen: false,
}
case types.ADD_BLUR_LISTENER:
case types.ADD_FOCUS_LISTENER:
case types.ADD_UNLOAD_LISTENER:
/* Get current route id */
const routeId = state.routes[state.routes.length - 1]
const addListeners = `$$_${action.type.replace(/.+_([a-z]+)_.+/gi, '$1').toLowerCase()}EventListeners`
return {
...state,
[addListeners]: {
...state[addListeners],
[routeId]: action.listener,
}
}
case types.REMOVE_BLUR_LISTENER:
case types.REMOVE_FOCUS_LISTENER:
case types.REMOVE_UNLOAD_LISTENER:
const listenerType = `$$_${action.type.replace(/.+_([a-z]+)_.+/gi, '$1').toLowerCase()}EventListeners`
const filtered = Object.keys(state[listenerType]).reduce((listeners, route) =>{
const current = state[listenerType][route] === action.listener ? {} : { [route]: state[listenerType][route] }
return { ...listeners, ...current, }
}, {})
return {
...state,
[listenerType]: filtered,
}
case '$$_SET_PAGE_TRANSITIONING':
return {
...state,
transitioning: action.transitioning,
}
case '$$_DISPATCH_ROUTE_CHANGING':
return {
...state,
$$_routeIsChanging: action.changing,
}
case '$$_SET_PREVIOUS_LISTENERS':
return {
...state,
$$_previousWillFocusListener: action.onWillFocusListener,
$$_previousDidFocusListener: action.onDidFocusListener,
}
default:
return state
}
}