cozy-bar 0.0.0-development
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/LICENSE +21 -0
- package/README.md +174 -0
- package/dist/cozy-bar.min.js +77 -0
- package/dist/cozy-bar.min.js.map +1 -0
- package/package.json +165 -0
- package/src/assets/icons/16/icon-storage-16.svg +3 -0
- package/src/assets/icons/24/icon-arrow-left.svg +3 -0
- package/src/assets/icons/32/icon-claudy.svg +1 -0
- package/src/assets/icons/apps/icon-collect.svg +25 -0
- package/src/assets/icons/apps/icon-drive.svg +17 -0
- package/src/assets/icons/apps/icon-market-soon.svg +25 -0
- package/src/assets/icons/apps/icon-photos.svg +19 -0
- package/src/assets/icons/apps/icon-soon.svg +21 -0
- package/src/assets/icons/apps/icon-store.svg +19 -0
- package/src/assets/icons/claudyActions/icon-bills.svg +6 -0
- package/src/assets/icons/claudyActions/icon-laptop.svg +7 -0
- package/src/assets/icons/claudyActions/icon-phone.svg +8 -0
- package/src/assets/icons/claudyActions/icon-question-mark.svg +6 -0
- package/src/assets/icons/comingsoon/icon-bank.svg +12 -0
- package/src/assets/icons/comingsoon/icon-sante.svg +12 -0
- package/src/assets/icons/comingsoon/icon-store.svg +6 -0
- package/src/assets/icons/icon-cozy.svg +3 -0
- package/src/assets/icons/icon-shield.svg +3 -0
- package/src/assets/icons/spinner.svg +4 -0
- package/src/assets/sprites/icon-apps.svg +1 -0
- package/src/assets/sprites/icon-cozy-home.svg +16 -0
- package/src/components/Apps/AppItem.jsx +117 -0
- package/src/components/Apps/AppItemPlaceholder.jsx +12 -0
- package/src/components/Apps/AppNavButtons.jsx +94 -0
- package/src/components/Apps/AppsContent.jsx +91 -0
- package/src/components/Apps/ButtonCozyHome.jsx +30 -0
- package/src/components/Apps/ButtonCozyHome.spec.jsx +53 -0
- package/src/components/Apps/IconCozyHome.jsx +38 -0
- package/src/components/Apps/index.jsx +72 -0
- package/src/components/Banner.jsx +41 -0
- package/src/components/Bar.jsx +295 -0
- package/src/components/Bar.spec.jsx +133 -0
- package/src/components/Claudy.jsx +81 -0
- package/src/components/ClaudyIcon.jsx +18 -0
- package/src/components/Drawer.jsx +227 -0
- package/src/components/Drawer.spec.jsx +98 -0
- package/src/components/SearchBar.jsx +358 -0
- package/src/components/Settings/SettingsContent.jsx +163 -0
- package/src/components/Settings/StorageData.jsx +29 -0
- package/src/components/Settings/helper.js +8 -0
- package/src/components/Settings/index.jsx +220 -0
- package/src/components/StorageIcon.jsx +16 -0
- package/src/components/SupportModal.jsx +59 -0
- package/src/components/__snapshots__/Bar.spec.jsx.snap +302 -0
- package/src/config/claudyActions.json +20 -0
- package/src/config/persistWhitelist.json +4 -0
- package/src/dom.js +80 -0
- package/src/index.jsx +242 -0
- package/src/index.spec.jsx +34 -0
- package/src/lib/api/helpers.js +13 -0
- package/src/lib/api/index.jsx +145 -0
- package/src/lib/exceptions.js +89 -0
- package/src/lib/expiringMemoize.js +13 -0
- package/src/lib/icon.js +77 -0
- package/src/lib/intents.js +16 -0
- package/src/lib/logger.js +11 -0
- package/src/lib/middlewares/appsI18n.js +57 -0
- package/src/lib/realtime.js +43 -0
- package/src/lib/reducers/apps.js +175 -0
- package/src/lib/reducers/apps.spec.js +59 -0
- package/src/lib/reducers/content.js +50 -0
- package/src/lib/reducers/context.js +86 -0
- package/src/lib/reducers/index.js +73 -0
- package/src/lib/reducers/locale.js +22 -0
- package/src/lib/reducers/settings.js +111 -0
- package/src/lib/reducers/theme.js +48 -0
- package/src/lib/reducers/unserializable.js +26 -0
- package/src/lib/stack-client.js +401 -0
- package/src/lib/stack.js +79 -0
- package/src/lib/store/index.js +44 -0
- package/src/locales/de.json +57 -0
- package/src/locales/en.json +57 -0
- package/src/locales/es.json +57 -0
- package/src/locales/fr.json +57 -0
- package/src/locales/it.json +57 -0
- package/src/locales/ja.json +57 -0
- package/src/locales/nl_NL.json +57 -0
- package/src/locales/pl.json +57 -0
- package/src/locales/ru.json +57 -0
- package/src/locales/sq.json +57 -0
- package/src/locales/zh_CN.json +57 -0
- package/src/proptypes/index.js +10 -0
- package/src/queries/index.js +16 -0
- package/src/styles/apps.css +248 -0
- package/src/styles/banner.css +64 -0
- package/src/styles/bar.css +106 -0
- package/src/styles/base.css +21 -0
- package/src/styles/claudy.css +98 -0
- package/src/styles/drawer.css +126 -0
- package/src/styles/index.styl +33 -0
- package/src/styles/indicators.css +58 -0
- package/src/styles/nav.css +81 -0
- package/src/styles/navigation_item.css +34 -0
- package/src/styles/searchbar.css +156 -0
- package/src/styles/settings.css +34 -0
- package/src/styles/storage.css +22 -0
- package/src/styles/supportModal.css +20 -0
- package/src/styles/theme.styl +25 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const SET_CONTENT = 'SET_CONTENT'
|
|
2
|
+
const UNSET_CONTENT = 'UNSET_CONTENT'
|
|
3
|
+
|
|
4
|
+
const getLastItemInMap = map => Array.from(map)[map.size - 1]
|
|
5
|
+
|
|
6
|
+
// action creator
|
|
7
|
+
export const setContent = (location, content, id) => ({
|
|
8
|
+
type: SET_CONTENT,
|
|
9
|
+
location,
|
|
10
|
+
content,
|
|
11
|
+
id
|
|
12
|
+
})
|
|
13
|
+
export const unsetContent = (location, id) => ({
|
|
14
|
+
type: UNSET_CONTENT,
|
|
15
|
+
location,
|
|
16
|
+
id
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
// reducer
|
|
20
|
+
export const getDefaultState = () => ({
|
|
21
|
+
left: new Map(),
|
|
22
|
+
center: new Map(),
|
|
23
|
+
right: new Map(),
|
|
24
|
+
search: new Map()
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
export const reducer = (state = getDefaultState(), action) => {
|
|
28
|
+
if (!action.location || typeof action.id === undefined) return state
|
|
29
|
+
switch (action.type) {
|
|
30
|
+
case SET_CONTENT: {
|
|
31
|
+
const currentState = state[action.location]
|
|
32
|
+
currentState.set(action.id, action.content)
|
|
33
|
+
return { ...state, [action.location]: currentState }
|
|
34
|
+
}
|
|
35
|
+
case UNSET_CONTENT: {
|
|
36
|
+
const currentState = state[action.location]
|
|
37
|
+
if (!currentState.get(action.id)) {
|
|
38
|
+
return state
|
|
39
|
+
}
|
|
40
|
+
currentState.delete(action.id)
|
|
41
|
+
return { ...state, [action.location]: currentState }
|
|
42
|
+
}
|
|
43
|
+
default:
|
|
44
|
+
return state
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// selectors
|
|
49
|
+
export const getContent = (state, location) =>
|
|
50
|
+
getLastItemInMap(state[location]) && getLastItemInMap(state[location])[1]
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import stack from 'lib/stack'
|
|
2
|
+
import CLAUDY_ACTIONS from 'config/claudyActions.json'
|
|
3
|
+
import { LOG_OUT } from 'lib/reducers/settings'
|
|
4
|
+
import flag from 'cozy-flags'
|
|
5
|
+
|
|
6
|
+
const FETCH_CONTEXT = 'FETCH_CONTEXT'
|
|
7
|
+
const FETCH_CONTEXT_SUCCESS = 'FETCH_CONTEXT_SUCCESS'
|
|
8
|
+
const RECEIVE_NO_CONTEXT = 'RECEIVE_NO_CONTEXT'
|
|
9
|
+
|
|
10
|
+
// selectors
|
|
11
|
+
export const getHelpLink = state => {
|
|
12
|
+
return state.helpLink
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const getClaudyActions = state => {
|
|
16
|
+
return state.claudyActions
|
|
17
|
+
}
|
|
18
|
+
export const shouldEnableClaudy = state => {
|
|
19
|
+
const claudyActions = getClaudyActions(state)
|
|
20
|
+
return !!claudyActions && !!claudyActions.length
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// actions
|
|
24
|
+
export const fetchContext = () => async (dispatch, getState) => {
|
|
25
|
+
dispatch({ type: FETCH_CONTEXT })
|
|
26
|
+
if (getState().context.contextNotExist) {
|
|
27
|
+
return dispatch({ type: FETCH_CONTEXT_SUCCESS, context: null })
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const context = await stack.get.context()
|
|
31
|
+
return dispatch({ type: FETCH_CONTEXT_SUCCESS, context })
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (error.status && error.status === 404) {
|
|
34
|
+
dispatch({ type: RECEIVE_NO_CONTEXT })
|
|
35
|
+
}
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
37
|
+
console.warn('Cannot get Cozy context')
|
|
38
|
+
return null
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// reducers
|
|
43
|
+
const defaultState = {
|
|
44
|
+
claudyActions: [],
|
|
45
|
+
contextNotExist: false,
|
|
46
|
+
helpLink: null,
|
|
47
|
+
isFetching: false
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const reducer = (state = defaultState, action) => {
|
|
51
|
+
switch (action.type) {
|
|
52
|
+
case FETCH_CONTEXT:
|
|
53
|
+
return { ...state, isFetching: true }
|
|
54
|
+
case FETCH_CONTEXT_SUCCESS: {
|
|
55
|
+
const attr =
|
|
56
|
+
action.context && action.context.data && action.context.data.attributes
|
|
57
|
+
const contextActions = flag('bar.claudy.force-all-actions')
|
|
58
|
+
? Object.keys(CLAUDY_ACTIONS)
|
|
59
|
+
: attr && attr['claudy_actions']
|
|
60
|
+
// get an arrays of action
|
|
61
|
+
const claudyActions = contextActions
|
|
62
|
+
.map(slug => {
|
|
63
|
+
if (CLAUDY_ACTIONS.hasOwnProperty(slug)) {
|
|
64
|
+
// adding also the action slug
|
|
65
|
+
return Object.assign({}, CLAUDY_ACTIONS[slug], { slug })
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
.filter(action => action)
|
|
69
|
+
return {
|
|
70
|
+
...state,
|
|
71
|
+
helpLink: (attr && attr['help_link']) || null,
|
|
72
|
+
claudyActions,
|
|
73
|
+
isFetching: false,
|
|
74
|
+
contextNotExist: false
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
case RECEIVE_NO_CONTEXT:
|
|
78
|
+
return { ...state, contextNotExist: true }
|
|
79
|
+
case LOG_OUT:
|
|
80
|
+
return defaultState
|
|
81
|
+
default:
|
|
82
|
+
return state
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export default reducer
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { combineReducers } from 'redux'
|
|
2
|
+
import * as content from 'lib/reducers/content'
|
|
3
|
+
import * as locale from 'lib/reducers/locale'
|
|
4
|
+
import * as theme from 'lib/reducers/theme'
|
|
5
|
+
import * as unserializable from 'lib/reducers/unserializable'
|
|
6
|
+
import appsReducer, * as apps from 'lib/reducers/apps'
|
|
7
|
+
import settingsReducer, * as settings from 'lib/reducers/settings'
|
|
8
|
+
import contextReducer, * as context from 'lib/reducers/context'
|
|
9
|
+
|
|
10
|
+
const proxy = (attr, method) => {
|
|
11
|
+
return (state, ...args) => {
|
|
12
|
+
return method(state[attr], ...args)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const setContent = content.setContent
|
|
17
|
+
const unsetContent = content.unsetContent
|
|
18
|
+
const setLocale = locale.setLocale
|
|
19
|
+
const setTheme = theme.setTheme
|
|
20
|
+
const setWebviewContext = unserializable.setWebviewContext
|
|
21
|
+
const fetchApps = apps.fetchApps
|
|
22
|
+
const setInfos = apps.setInfos
|
|
23
|
+
const fetchSettingsData = settings.fetchSettingsData
|
|
24
|
+
const logOut = settings.logOut
|
|
25
|
+
const fetchContext = context.fetchContext
|
|
26
|
+
export {
|
|
27
|
+
setContent,
|
|
28
|
+
unsetContent,
|
|
29
|
+
setLocale,
|
|
30
|
+
setTheme,
|
|
31
|
+
setWebviewContext,
|
|
32
|
+
fetchApps,
|
|
33
|
+
setInfos,
|
|
34
|
+
fetchSettingsData,
|
|
35
|
+
logOut,
|
|
36
|
+
fetchContext
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const getContent = proxy('content', content.getContent)
|
|
40
|
+
export const getLocale = proxy('locale', locale.getLocale)
|
|
41
|
+
export const getTheme = proxy('theme', theme.getTheme)
|
|
42
|
+
export const getApps = proxy('apps', apps.getApps)
|
|
43
|
+
export const getHomeApp = proxy('apps', apps.getHomeApp)
|
|
44
|
+
export const isFetchingApps = proxy('apps', apps.isFetchingApps)
|
|
45
|
+
export const isCurrentApp = proxy('apps', apps.isCurrentApp)
|
|
46
|
+
export const hasFetched = proxy('apps', apps.hasFetched)
|
|
47
|
+
export const getStorageData = proxy('settings', settings.getStorageData)
|
|
48
|
+
export const getSettingsAppURL = proxy('settings', settings.getSettingsAppURL)
|
|
49
|
+
export const isSettingsBusy = proxy('settings', settings.isSettingsBusy)
|
|
50
|
+
export const isFetchingSettings = proxy('settings', settings.isFetchingSettings)
|
|
51
|
+
export const getHelpLink = proxy('context', context.getHelpLink)
|
|
52
|
+
export const getClaudyActions = proxy('context', context.getClaudyActions)
|
|
53
|
+
export const shouldEnableClaudy = proxy('context', context.shouldEnableClaudy)
|
|
54
|
+
export const getWebviewContext = proxy(
|
|
55
|
+
'unserializable',
|
|
56
|
+
unserializable.getWebviewContext
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
// realtime handlers
|
|
60
|
+
export const onRealtimeCreate = apps.receiveApp
|
|
61
|
+
export const onRealtimeDelete = apps.deleteApp
|
|
62
|
+
|
|
63
|
+
export const reducers = {
|
|
64
|
+
apps: appsReducer,
|
|
65
|
+
content: content.reducer,
|
|
66
|
+
context: contextReducer,
|
|
67
|
+
locale: locale.reducer,
|
|
68
|
+
settings: settingsReducer,
|
|
69
|
+
theme: theme.reducer,
|
|
70
|
+
unserializable: unserializable.reducer
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default combineReducers(reducers)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const SET_LOCALE = 'SET_LOCALE'
|
|
2
|
+
|
|
3
|
+
// action creator
|
|
4
|
+
export const setLocale = lang => ({
|
|
5
|
+
type: SET_LOCALE,
|
|
6
|
+
lang
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
const getDefaultLang = () => {
|
|
10
|
+
return document.documentElement.getAttribute('lang') || 'en'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const reducer = (state = getDefaultLang(), action) => {
|
|
14
|
+
if (action.type === SET_LOCALE) {
|
|
15
|
+
return action.lang
|
|
16
|
+
} else {
|
|
17
|
+
return state
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// selector
|
|
22
|
+
export const getLocale = state => state
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import stack from 'lib/stack'
|
|
2
|
+
|
|
3
|
+
const FETCH_SETTINGS = 'FETCH_SETTINGS'
|
|
4
|
+
const FETCH_SETTINGS_BUSY = 'FETCH_SETTINGS_BUSY'
|
|
5
|
+
const FETCH_SETTINGS_SUCCESS = 'FETCH_SETTINGS_SUCCESS'
|
|
6
|
+
const RECEIVE_NO_CONTEXT = 'RECEIVE_NO_CONTEXT'
|
|
7
|
+
const RECEIVE_STORAGE = 'RECEIVE_STORAGE'
|
|
8
|
+
const RECEIVE_SETTINGS_URL = 'RECEIVE_SETTINGS_URL'
|
|
9
|
+
|
|
10
|
+
export const LOG_OUT = 'LOG_OUT'
|
|
11
|
+
|
|
12
|
+
const BUSY_DELAY = 450
|
|
13
|
+
|
|
14
|
+
// selectors
|
|
15
|
+
export const getStorageData = state => {
|
|
16
|
+
return state.storageData
|
|
17
|
+
}
|
|
18
|
+
export const getSettingsAppURL = state => {
|
|
19
|
+
return state.settingsAppURL
|
|
20
|
+
}
|
|
21
|
+
export const isSettingsBusy = state => {
|
|
22
|
+
return state.isBusy
|
|
23
|
+
}
|
|
24
|
+
export const isFetchingSettings = state => {
|
|
25
|
+
return state.isFetching
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// actions
|
|
29
|
+
const fetchStorageData = () => async dispatch => {
|
|
30
|
+
try {
|
|
31
|
+
const storageData = await stack.get.storageData()
|
|
32
|
+
return dispatch({ type: RECEIVE_STORAGE, storageData })
|
|
33
|
+
} catch (e) {
|
|
34
|
+
// eslint-disable-next-line no-console
|
|
35
|
+
console.warn && console.warn('Cannot get Cozy storage informations')
|
|
36
|
+
return null
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const fetchSettingsAppURL = () => async (dispatch, getState) => {
|
|
41
|
+
// If the `settings` app is available, it will used to add the links 'Profile' and 'Connected Devices'
|
|
42
|
+
if (getState().settings.settingsAppURL) {
|
|
43
|
+
return dispatch({
|
|
44
|
+
type: RECEIVE_SETTINGS_URL,
|
|
45
|
+
settingsAppURL: getState().settings.settingsAppURL
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const settingsAppURL = await stack.get.settingsAppURL()
|
|
50
|
+
return dispatch({ type: RECEIVE_SETTINGS_URL, settingsAppURL })
|
|
51
|
+
} catch (e) {
|
|
52
|
+
// eslint-disable-next-line no-console
|
|
53
|
+
console.warn('Settings app is unavailable, settings links are disabled')
|
|
54
|
+
return null
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const fetchSettingsData = (displayBusy = true) => async dispatch => {
|
|
59
|
+
dispatch({ type: FETCH_SETTINGS })
|
|
60
|
+
// put the busy status after BUSY_DELAY secs
|
|
61
|
+
const busySpinner = setTimeout(() => {
|
|
62
|
+
// we do not display the busy status in the drawer
|
|
63
|
+
if (displayBusy) dispatch({ type: FETCH_SETTINGS_BUSY })
|
|
64
|
+
}, BUSY_DELAY)
|
|
65
|
+
await dispatch(fetchStorageData())
|
|
66
|
+
await dispatch(fetchSettingsAppURL())
|
|
67
|
+
clearTimeout(busySpinner)
|
|
68
|
+
dispatch({ type: FETCH_SETTINGS_SUCCESS })
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const logOut = () => async dispatch => {
|
|
72
|
+
dispatch({ type: LOG_OUT })
|
|
73
|
+
try {
|
|
74
|
+
await stack.logout()
|
|
75
|
+
} catch (e) {
|
|
76
|
+
// eslint-disable-next-line no-console
|
|
77
|
+
console.warn('Error while logging out in the cozy-bar', e)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// reducers
|
|
82
|
+
const defaultState = {
|
|
83
|
+
contextNotExist: false,
|
|
84
|
+
isFetching: false,
|
|
85
|
+
isBusy: false,
|
|
86
|
+
settingsAppURL: null,
|
|
87
|
+
storageData: null
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const reducer = (state = defaultState, action) => {
|
|
91
|
+
switch (action.type) {
|
|
92
|
+
case FETCH_SETTINGS:
|
|
93
|
+
return { ...state, isFetching: true }
|
|
94
|
+
case FETCH_SETTINGS_BUSY:
|
|
95
|
+
return { ...state, isBusy: true }
|
|
96
|
+
case FETCH_SETTINGS_SUCCESS:
|
|
97
|
+
return { ...state, isFetching: false, isBusy: false }
|
|
98
|
+
case RECEIVE_NO_CONTEXT:
|
|
99
|
+
return { ...state, contextNotExist: true }
|
|
100
|
+
case RECEIVE_STORAGE:
|
|
101
|
+
return { ...state, storageData: action.storageData }
|
|
102
|
+
case RECEIVE_SETTINGS_URL:
|
|
103
|
+
return { ...state, settingsAppURL: action.settingsAppURL }
|
|
104
|
+
case LOG_OUT:
|
|
105
|
+
return defaultState
|
|
106
|
+
default:
|
|
107
|
+
return state
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default reducer
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const SET_THEME = 'SET_THEME'
|
|
2
|
+
const DEFAULT_THEME = 'default'
|
|
3
|
+
const PRIMARY_THEME = 'primary'
|
|
4
|
+
const THEMES = [DEFAULT_THEME, PRIMARY_THEME]
|
|
5
|
+
const EMPTY_OVERRIDES = {}
|
|
6
|
+
|
|
7
|
+
// Theme state is { name, overrides }
|
|
8
|
+
// where both have the form described in `setTheme`
|
|
9
|
+
const DEFAULT_STATE = { name: DEFAULT_THEME, overrides: EMPTY_OVERRIDES }
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Change the cozy-bar theme
|
|
13
|
+
*
|
|
14
|
+
* Today, the value 'primary' will change the background color
|
|
15
|
+
* of the bar in the mobile view. It will then use the
|
|
16
|
+
* `--primaryColor` CSS variable and the `--primaryContrastTextColor`
|
|
17
|
+
* for the text.
|
|
18
|
+
*
|
|
19
|
+
* @function
|
|
20
|
+
* @param {String} name - either 'default' or 'primary'
|
|
21
|
+
* @param {Object} overrides - overrides of default values for the theme
|
|
22
|
+
* default to an empty object (no overrides)
|
|
23
|
+
* It will only overrides the values for the
|
|
24
|
+
* 'primary' specific theme/view
|
|
25
|
+
* @param {Object} overrides.primaryColor - the background color
|
|
26
|
+
* @param {Object} overrides.primaryContrastTextColor - the text color
|
|
27
|
+
* @returns {Object} action `{ type: SET_THEME, theme: {name, overrides} }
|
|
28
|
+
*/
|
|
29
|
+
export const setTheme = (name, overrides = EMPTY_OVERRIDES) => ({
|
|
30
|
+
type: SET_THEME,
|
|
31
|
+
theme: { name, overrides }
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
export const getDefaultTheme = () => DEFAULT_STATE
|
|
35
|
+
|
|
36
|
+
export const reducer = (state = getDefaultTheme(), action) => {
|
|
37
|
+
if (action.type === SET_THEME) {
|
|
38
|
+
if (THEMES.includes(action.theme.name)) {
|
|
39
|
+
return action.theme
|
|
40
|
+
}
|
|
41
|
+
return { ...action.theme, name: DEFAULT_THEME }
|
|
42
|
+
} else {
|
|
43
|
+
return state
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// selector
|
|
48
|
+
export const getTheme = state => state
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const SET_WEBVIEW_CONTEXT = 'SET_WEBVIEW_CONTEXT'
|
|
2
|
+
|
|
3
|
+
// selectors
|
|
4
|
+
export const getWebviewContext = state => {
|
|
5
|
+
return state.webviewContext
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// actions
|
|
9
|
+
export const setWebviewContext = payload => ({
|
|
10
|
+
type: SET_WEBVIEW_CONTEXT,
|
|
11
|
+
payload
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
// reducers
|
|
15
|
+
const defaultState = {
|
|
16
|
+
webviewContext: undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const reducer = (state = defaultState, action) => {
|
|
20
|
+
switch (action.type) {
|
|
21
|
+
case SET_WEBVIEW_CONTEXT:
|
|
22
|
+
return { ...state, webviewContext: action.payload }
|
|
23
|
+
default:
|
|
24
|
+
return state
|
|
25
|
+
}
|
|
26
|
+
}
|