-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathreducers.js
More file actions
228 lines (208 loc) · 5.95 KB
/
reducers.js
File metadata and controls
228 lines (208 loc) · 5.95 KB
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
'use strict'
import { combineReducers } from 'redux'
import { extend as extendI18n } from 'twake-i18n'
// initial loading
export const LOADING_APP = 'LOADING_APP'
export const LOADING_APP_INTENT = 'LOADING_APP_INTENT'
export const FETCH_APPS = 'FETCH_APPS'
export const FETCH_APPS_SUCCESS = 'FETCH_APPS_SUCCESS'
export const FETCH_APPS_FAILURE = 'FETCH_APPS_FAILURE'
export const FETCH_APP = 'FETCH_APP'
export const FETCH_APP_SUCCESS = 'FETCH_APP_SUCCESS'
export const FETCH_APP_FAILURE = 'FETCH_APP_FAILURE'
// store an app state, to handle app version switch cancelling
export const RESTORE_APP = 'RESTORE_APP'
export const SAVE_APP = 'SAVE_APP'
export const FETCH_REGISTRY_APPS_SUCCESS = 'FETCH_REGISTRY_APPS_SUCCESS'
export const UNINSTALL_APP = 'UNINSTALL_APP'
export const UNINSTALL_APP_SUCCESS = 'UNINSTALL_APP_SUCCESS'
export const UNINSTALL_APP_FAILURE = 'UNINSTALL_APP_FAILURE'
export const INSTALL_APP = 'INSTALL_APP'
export const INSTALL_APP_SUCCESS = 'INSTALL_APP_SUCCESS'
export const INSTALL_APP_FAILURE = 'INSTALL_APP_FAILURE'
export function _sortAlphabetically(array, property) {
return array.sort((a, b) => a[property].localeCompare(b[property]))
}
export function _isValidApp(app) {
return !!app && !!app.slug && !!app.source && !!app.version
}
export function _consolidateApps(stateApps, newAppsInfos, lang) {
const apps = new Map()
stateApps.forEach(app => apps.set(app.slug, app))
newAppsInfos.forEach(app => {
const appFromState = apps.get(app.slug)
// handle maintenance locales
let appLocales = app.locales
if (appLocales && appFromState && appFromState.locales) {
for (let locale in appFromState.locales) {
appLocales[locale] = Object.assign(
{},
appFromState.locales[locale],
app.locales[locale]
)
}
}
if (appLocales && appLocales[lang]) {
// access app locales from 'apps.slug.[...]'
extendI18n({ apps: { [app.slug]: appLocales[lang] } })
}
if (appFromState) {
apps.set(
app.slug,
Object.assign({}, appFromState, app, {
locales: appLocales
})
)
} else {
apps.set(app.slug, app)
}
})
return Array.from(apps.values()).filter(app => app)
}
export const list = (state = [], action = {}) => {
switch (action.type) {
case RESTORE_APP:
if (_isValidApp(action.app)) {
return _sortAlphabetically(
_consolidateApps(
// we completely replace it, so we remove the current from state
state.filter(a => a.slug !== action.app.slug),
[action.app],
action.lang
),
'slug'
)
} else {
// eslint-disable-next-line no-console
console.warn(
`Failed attempt to restore a saved app state (app: ${action.app &&
action.app.slug}).`
)
return state
}
case FETCH_APP_SUCCESS:
return _sortAlphabetically(
_consolidateApps(state, [action.app], action.lang),
'slug'
)
case FETCH_REGISTRY_APPS_SUCCESS:
case FETCH_APPS_SUCCESS:
return _sortAlphabetically(
_consolidateApps(state, action.apps, action.lang),
'slug'
)
case UNINSTALL_APP_SUCCESS:
return state.map(app =>
app.slug === action.slug ? { ...app, installed: false } : app
)
case INSTALL_APP_SUCCESS: {
return _sortAlphabetically(
state.map(app => {
if (app.slug === action.installedApp.slug) {
const nextApp = { ...app, ...action.installedApp, installed: true }
// the available update is now installed
if (nextApp.availableVersion) delete nextApp.availableVersion
return nextApp
}
return app
}),
'slug'
)
}
default:
return state
}
}
export const savedApp = (state = null, action = {}) => {
switch (action.type) {
case SAVE_APP:
return _isValidApp(action.app) ? action.app : state
case RESTORE_APP:
case INSTALL_APP_SUCCESS: // after install we clean the previously saved app
return null
default:
return state
}
}
export const isFetching = (state = false, action = {}) => {
switch (action.type) {
case LOADING_APP:
case FETCH_APPS:
return true
case FETCH_APPS_SUCCESS:
case FETCH_APPS_FAILURE:
return false
default:
return state
}
}
export const isAppFetching = (state = false, action = {}) => {
switch (action.type) {
case LOADING_APP_INTENT:
case FETCH_APP:
return true
case RESTORE_APP: // restoring the saved app cancels the app fetching
return _isValidApp(action.app) ? false : state
case FETCH_APP_SUCCESS:
case FETCH_APP_FAILURE:
return false
default:
return state
}
}
export const isInstalling = (state = false, action = {}) => {
switch (action.type) {
case INSTALL_APP:
return action.slug
case INSTALL_APP_SUCCESS:
case INSTALL_APP_FAILURE:
return false
default:
return state
}
}
export const isUninstalling = (state = false, action = {}) => {
switch (action.type) {
case UNINSTALL_APP:
return true
case UNINSTALL_APP_SUCCESS:
case UNINSTALL_APP_FAILURE:
return false
default:
return state
}
}
export const actionError = (state = null, action = {}) => {
switch (action.type) {
case UNINSTALL_APP_FAILURE:
case INSTALL_APP_FAILURE:
return action.error
case UNINSTALL_APP_SUCCESS:
case INSTALL_APP_SUCCESS:
return null
default:
return state
}
}
export const fetchError = (state = null, action = {}) => {
switch (action.type) {
case FETCH_APPS_FAILURE:
case FETCH_APP_FAILURE:
return action.error
case FETCH_APPS_SUCCESS:
case FETCH_APP_SUCCESS:
return null
default:
return state
}
}
export const appsReducers = combineReducers({
list,
actionError,
fetchError,
isFetching,
isAppFetching,
isInstalling,
isUninstalling,
savedApp
})