reducers typescripting

This commit is contained in:
muerwre 2019-02-12 12:26:04 +07:00
parent 4c6526efc9
commit 85b8860862
15 changed files with 496 additions and 316 deletions

5
package-lock.json generated
View file

@ -765,6 +765,11 @@
"resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.7.tgz",
"integrity": "sha512-rzOhiQ55WzAiFgXRtitP/ZUT8iVNyllEpylJ5zHzR4vArUvMB39GTk+Zon/uAM0JxEFAWnwsxC2gH8s+tZ3Myg=="
},
"@types/node": {
"version": "11.9.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.9.0.tgz",
"integrity": "sha512-ry4DOrC+xenhQbzk1iIPzCZGhhPGEFv7ia7Iu6XXSLVluiJIe9FfG7Iu3mObH9mpxEXCWLCMU4JWbCCR9Oy1Zg=="
},
"@types/prop-types": {
"version": "15.5.8",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.5.8.tgz",

View file

@ -52,9 +52,9 @@
},
"dependencies": {
"@types/classnames": "^2.2.7",
"@types/node": "^11.9.0",
"@types/react": "^16.7.20",
"@types/react-dom": "^16.0.11",
"typesafe-actions": "^3.0.0",
"axios": "^0.18.0",
"babel-runtime": "^6.26.0",
"bluebird": "^3.5.3",
@ -102,6 +102,7 @@
"styled-theming": "^2.2.0",
"tt-react-custom-scrollbars": "^4.2.1-tt2",
"typeface-pt-sans": "0.0.54",
"typesafe-actions": "^3.0.0",
"webpack-git-hash": "^1.0.2"
},
"flow-coverage-report": {

View file

@ -1,21 +0,0 @@
export const ROLES = {
guest: 'guest',
vk: 'vk',
};
export const DEFAULT_USER = {
new_messages: 0,
place_types: {},
random_url: '',
role: ROLES.guest,
routes: {},
success: false,
id: null,
token: null,
userdata: {
name: '',
agent: '',
ip: '',
photo: '',
}
};

45
src/constants/auth.ts Normal file
View file

@ -0,0 +1,45 @@
type valueof<T> = T[keyof T]
export interface IRoles {
guest: string,
vk: string,
}
export interface IUser {
new_messages: number,
place_types: {},
random_url: string,
role: IRoles[keyof IRoles],
routes: {},
success: boolean,
id?: string,
token?: string,
userdata: {
name: string,
agent: string,
ip: string,
photo: string,
}
}
export const ROLES: IRoles = {
guest: 'guest',
vk: 'vk',
};
export const DEFAULT_USER: IUser = {
new_messages: 0,
place_types: {},
random_url: '',
role: ROLES.guest,
routes: {},
success: false,
id: null,
token: null,
userdata: {
name: '',
agent: '',
ip: '',
photo: '',
}
};

View file

@ -1,12 +0,0 @@
// @flow
export const DIALOGS = ({
NONE: 'NONE',
MAP_LIST: 'MAP_LIST',
APP_INFO: 'APP_INFO',
}: { [key: String]: String });
export const TABS = ({
mine: 'Мои',
all: 'Общие',
// starred: 'Выбранные',
}: { [key: String]: String });

21
src/constants/dialogs.ts Normal file
View file

@ -0,0 +1,21 @@
export interface IDialogs {
NONE: string,
MAP_LIST: string,
APP_INFO: string,
}
export interface IMapTabs {
mine: string,
all: string,
}
export const DIALOGS: IDialogs = ({
NONE: 'NONE',
MAP_LIST: 'MAP_LIST',
APP_INFO: 'APP_INFO',
});
export const TABS: IMapTabs = ({
mine: 'Мои',
all: 'Общие',
});

View file

@ -1,3 +1,7 @@
export interface ILogos {
[x: string]: [string, string, string],
}
export const LOGOS = {
default: ['Без лого', null, 'bottom-right'],
nvs: ['НВС', require('../sprites/logos/lgo.png'), 'bottom-right'],

View file

@ -1,6 +1,8 @@
// @flow
export interface IModes {
[x: string]: string,
}
export const MODES = ({
export const MODES: IModes = {
POLY: 'POLY',
STICKERS: 'STICKERS',
STICKERS_SELECT: 'STICKERS_SELECT',
@ -12,6 +14,5 @@ export const MODES = ({
SAVE: 'SAVE',
CONFIRM_CANCEL: 'CONFIRM_CANCEL',
PROVIDER: 'PROVIDER',
SHOT_PREFETCH: 'SHOT_PREFETCH',
}: { [key: String]: String });
};

View file

@ -1,5 +1,24 @@
export interface IPRovider {
name: string,
url: string,
range: Array<string | number>,
}
export interface ITileMaps {
WATERCOLOR: IPRovider,
DGIS: IPRovider,
DEFAULT: IPRovider,
DARQ: IPRovider,
BLANK: IPRovider,
HOT: IPRovider,
YSAT: IPRovider,
YMAP: IPRovider,
SAT: IPRovider,
}
// Стили карт
const TILEMAPS = {
const TILEMAPS: ITileMaps = {
WATERCOLOR: {
name: 'Watercolor',
url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg',
@ -47,17 +66,19 @@ const TILEMAPS = {
},
};
const ENABLED = ['BLANK', 'DEFAULT', 'DGIS', 'HOT'];
const ENABLED: Array<keyof ITileMaps> = ['BLANK', 'DEFAULT', 'DGIS', 'HOT'];
export const DEFAULT_PROVIDER = ENABLED[0];
export const PROVIDERS = ENABLED.reduce((obj, provider) => ({
export const DEFAULT_PROVIDER: keyof ITileMaps = ENABLED[0];
export const PROVIDERS: Partial<ITileMaps> = ENABLED.reduce((obj, provider) => ({
...obj,
[provider]: TILEMAPS[provider],
}), {});
export const replaceProviderUrl = (provider, { x, y, zoom }) => {
const { url, range } = (PROVIDERS[provider] || PROVIDERS[DEFAULT_PROVIDER]);
const random = (range && range.length >= 2) ? range[Math.round((Math.random() * (range.length - 1)))] : 1;
const random: (number | string) = (range && range.length >= 2)
? range[Math.round((Math.random() * (range.length - 1)))]
: 1;
return url.replace('{x}', x).replace('{y}', y).replace('{z}', zoom).replace('{s}', random);
return url.replace('{x}', x).replace('{y}', y).replace('{z}', zoom).replace('{s}', String(random));
};

View file

@ -1,8 +1,28 @@
// Стикеры
// import L from "leaflet";
export interface ISticker {
off: number,
title: string,
title_long: string,
}
export interface IStickerPack {
title: string,
url: string,
size: number,
layers: {
[x: string]: ISticker,
}
}
export interface IStickers {
base: IStickerPack,
real: IStickerPack,
pin: IStickerPack,
}
// export const stickers = ['green', 'basic', 'green-small'];
export const STICKERS = {
export const STICKERS: IStickers = {
base: {
title: 'Простые',
url: require('$sprites/stickers/stickers-base.svg'),

View file

@ -1,4 +1,4 @@
import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
import { createStore, applyMiddleware, combineReducers, compose, Store } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
@ -8,8 +8,9 @@ import { userReducer } from '$redux/user/reducer';
import { userSaga } from '$redux/user/sagas';
import { createBrowserHistory } from 'history';
import { locationChanged } from '$redux/user/actions';
import { PersistConfig, Persistor } from "redux-persist/es/types";
const userPersistConfig = {
const userPersistConfig: PersistConfig = {
key: 'user',
whitelist: ['user', 'logo', 'provider', 'speed'],
storage,
@ -19,15 +20,11 @@ const userPersistConfig = {
export const sagaMiddleware = createSagaMiddleware();
// redux extension composer
/* eslint-disable no-underscore-dangle */
const composeEnhancers =
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
(<any>window).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? (<any>window).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
: compose;
/* eslint-enable no-underscore-dangle */
// export const history = createHistory();
export const store = createStore(
combineReducers({
@ -37,7 +34,7 @@ export const store = createStore(
composeEnhancers(applyMiddleware(/* routerMiddleware(history), */ sagaMiddleware))
);
export function configureStore() {
export function configureStore(): { store: Store<any>, persistor: Persistor } {
sagaMiddleware.run(userSaga);
const persistor = persistStore(store);

View file

@ -1,9 +1,9 @@
import { ACTIONS } from '$redux/user/constants';
import { IUser } from "$constants/auth";
export const setUser = user => ({ type: ACTIONS.SET_USER, user });
export const setUser = (user: IUser) => ({ type: ACTIONS.SET_USER, user });
export const userLogout = () => ({ type: ACTIONS.USER_LOGOUT });
export const setEditing = editing => ({ type: ACTIONS.SET_EDITING, editing });
export const setMode = mode => ({ type: ACTIONS.SET_MODE, mode });
export const setDistance = distance => ({ type: ACTIONS.SET_DISTANCE, distance });
@ -61,4 +61,3 @@ export const searchSetLoading = loading => ({ type: ACTIONS.SEARCH_SET_LOADING,
export const searchPutRoutes = payload => ({ type: ACTIONS.SEARCH_PUT_ROUTES, ...payload });
export const setMarkersShown = markers_shown => ({ type: ACTIONS.SET_MARKERS_SHOWN, markers_shown });

View file

@ -1,6 +1,8 @@
// @flow
export interface IActions {
[x: string]: string,
}
export const ACTIONS = ({
export const ACTIONS: IActions = {
SET_USER: 'SET_USER',
USER_LOGOUT: 'USER_LOGOUT',
@ -65,4 +67,4 @@ export const ACTIONS = ({
SET_SPEED: 'SET_SPEED',
SET_MARKERS_SHOWN: 'SET_MARKERS_SHOWN',
}: { [key: String]: String });
};

View file

@ -1,256 +0,0 @@
// @flow
import { createReducer } from 'reduxsauce';
import { ACTIONS } from '$redux/user/constants';
import { DEFAULT_USER } from '$constants/auth';
import { MODES } from '$constants/modes';
import { DEFAULT_LOGO } from '$constants/logos';
import { TIPS } from '$constants/tips';
import { DEFAULT_PROVIDER } from '$constants/providers';
import { DIALOGS, TABS } from '$constants/dialogs';
const getEstimated = (distance, speed = 15) => {
const time = (distance && (distance / speed)) || 0;
return (time && parseFloat(time.toFixed(1)));
};
const setUser = (state, { user }) => ({
...state,
user: {
...state.user,
...user,
},
});
const setEditing = (state, { editing }) => ({ ...state, editing });
const setChanged = (state, { changed }) => ({ ...state, changed });
const setMode = (state, { mode }) => ({ ...state, mode });
const setDistance = (state, { distance }) => ({
...state,
distance,
estimated: getEstimated(distance, state.speed),
});
const setRouterPoints = (state, { routerPoints }) => ({ ...state, routerPoints });
const setActiveSticker = (state, { activeSticker }) => ({
...state,
activeSticker: activeSticker || { set: null, sticker: null }
});
const setLogo = (state, { logo }) => ({ ...state, logo });
const setTitle = (state, { title }) => ({ ...state, title });
const setAddress = (state, { address }) => ({ ...state, address });
const setAddressOrigin = (state, { address_origin }) => ({ ...state, address_origin });
const sendSaveRequest = state => ({ ...state, save_processing: true, });
const setSaveError = (state, { save_error }) => ({
...state, save_error, save_finished: false, save_processing: false
});
const setSaveOverwrite = state => ({
...state,
save_overwriting: true,
save_finished: false,
save_processing: false,
save_error: TIPS.SAVE_OVERWRITE,
});
const setSaveSuccess = (state, { save_error }) => ({
...state, save_overwriting: false, save_finished: true, save_processing: false, save_error
});
const resetSaveDialog = state => ({
...state, save_overwriting: false, save_finished: false, save_processing: false, save_error: '',
});
const showRenderer = state => ({
...state,
renderer: { ...state.renderer, renderer_active: true }
});
const hideRenderer = state => ({
...state,
renderer: { ...state.renderer, renderer_active: false }
});
const setRenderer = (state, { payload }) => ({
...state,
renderer: { ...state.renderer, ...payload }
});
const setProvider = (state, { provider }) => ({ ...state, provider });
const setDialog = (state, { dialog }) => ({
...state,
dialog,
});
const setDialogActive = (state, { dialog_active }) => ({
...state,
dialog_active: dialog_active || !state.dialog_active,
});
const setReady = (state, { ready = true }) => ({
...state,
ready,
});
const searchSetTitle = (state, { title = '' }) => ({
...state,
routes: {
...state.routes,
filter: {
...state.routes.filter,
title,
distance: [0, 10000],
}
}
});
const searchSetDistance = (state, { distance = [0, 9999] }) => ({
...state,
routes: {
...state.routes,
filter: {
...state.routes.filter,
distance,
}
}
});
const searchSetTab = (state, { tab = TABS[Object.keys(TABS)[0]] }) => ({
...state,
routes: {
...state.routes,
filter: {
...state.routes.filter,
tab: Object.keys(TABS).indexOf(tab) >= 0 ? tab : TABS[Object.keys(TABS)[0]],
}
}
});
const searchPutRoutes = (state, { list = [], min, max }) => ({
...state,
routes: {
...state.routes,
list,
filter: {
...state.routes.filter,
distance: (state.routes.filter.min === state.routes.filter.max)
? [min, max]
: state.routes.filter.distance,
min,
max,
}
}
});
const searchSetLoading = (state, { loading = false }) => ({
...state,
routes: {
...state.routes,
loading,
}
});
const setPublic = (state, { is_public = false }) => ({ ...state, is_public });
const setSpeed = (state, { speed = 15 }) => ({
...state,
speed,
estimated: getEstimated(state.distance, speed),
});
const setMarkersShown = (state, { markers_shown = true }) => ({ ...state, markers_shown });
const HANDLERS = ({
[ACTIONS.SET_USER]: setUser,
[ACTIONS.SET_EDITING]: setEditing,
[ACTIONS.SET_CHANGED]: setChanged,
[ACTIONS.SET_MODE]: setMode,
[ACTIONS.SET_DISTANCE]: setDistance,
[ACTIONS.SET_ROUTER_POINTS]: setRouterPoints,
[ACTIONS.SET_ACTIVE_STICKER]: setActiveSticker,
[ACTIONS.SET_LOGO]: setLogo,
[ACTIONS.SET_TITLE]: setTitle,
[ACTIONS.SET_ADDRESS]: setAddress,
[ACTIONS.SET_ADDRESS_ORIGIN]: setAddressOrigin,
[ACTIONS.SET_SAVE_ERROR]: setSaveError,
[ACTIONS.SET_SAVE_OVERWRITE]: setSaveOverwrite,
[ACTIONS.SET_SAVE_SUCCESS]: setSaveSuccess,
[ACTIONS.SEND_SAVE_REQUEST]: sendSaveRequest,
[ACTIONS.RESET_SAVE_DIALOG]: resetSaveDialog,
[ACTIONS.SHOW_RENDERER]: showRenderer,
[ACTIONS.HIDE_RENDERER]: hideRenderer,
[ACTIONS.SET_RENDERER]: setRenderer,
[ACTIONS.SET_PROVIDER]: setProvider,
[ACTIONS.SET_DIALOG]: setDialog,
[ACTIONS.SET_DIALOG_ACTIVE]: setDialogActive,
[ACTIONS.SET_READY]: setReady,
[ACTIONS.SEARCH_SET_TITLE]: searchSetTitle,
[ACTIONS.SEARCH_SET_DISTANCE]: searchSetDistance,
[ACTIONS.SEARCH_SET_TAB]: searchSetTab,
[ACTIONS.SEARCH_PUT_ROUTES]: searchPutRoutes,
[ACTIONS.SEARCH_SET_LOADING]: searchSetLoading,
[ACTIONS.SET_PUBLIC]: setPublic,
[ACTIONS.SET_SPEED]: setSpeed,
[ACTIONS.SET_MARKERS_SHOWN]: setMarkersShown,
}: { [key: String]: Function });
export const INITIAL_STATE = {
ready: false,
user: { ...DEFAULT_USER },
editing: false,
mode: MODES.NONE,
logo: DEFAULT_LOGO,
routerPoints: 0,
distance: 0,
estimated: 0,
speed: 15,
activeSticker: { set: null, sticker: null },
title: '',
address: '',
address_origin: '',
changed: false,
provider: DEFAULT_PROVIDER,
is_public: false,
markers_shown: true,
save_error: '',
save_finished: false,
save_overwriting: false,
save_processing: false,
dialog: DIALOGS.NONE,
dialog_active: false,
renderer: {
data: '',
width: 0,
height: 0,
renderer_active: false,
info: '',
progress: 0,
},
routes: {
limit: 0,
loading: false, // <-- maybe delete this
list: [],
filter: {
title: '',
starred: false,
distance: [0, 10000],
author: '',
tab: '',
min: 0,
max: 10000,
}
},
};
export const userReducer = createReducer(INITIAL_STATE, HANDLERS);

353
src/redux/user/reducer.ts Normal file
View file

@ -0,0 +1,353 @@
// @flow
import { createReducer } from 'reduxsauce';
import { ACTIONS } from '$redux/user/constants';
import { DEFAULT_USER, IUser } from '$constants/auth';
import { MODES } from '$constants/modes';
import { DEFAULT_LOGO, LOGOS } from '$constants/logos';
import { TIPS } from '$constants/tips';
import { DEFAULT_PROVIDER, PROVIDERS } from '$constants/providers';
import { DIALOGS, IDialogs, TABS } from '$constants/dialogs';
import * as ActionCreators from '$redux/user/actions';
import { IStickers } from "$constants/stickers";
interface IRootReducer {
ready: boolean,
user: IUser,
editing: boolean,
mode: keyof typeof MODES,
logo: keyof typeof LOGOS,
routerPoints: number,
distance: number,
estimated: number,
speed: number,
activeSticker: { set?: keyof IStickers, sticker?: string },
title: string,
address: string,
address_origin: string,
changed: boolean,
provider: keyof typeof PROVIDERS,
is_public: boolean,
markers_shown: boolean,
save_error: string,
save_finished: boolean,
save_overwriting: boolean,
save_processing: boolean,
dialog: IDialogs[keyof IDialogs],
dialog_active: boolean,
renderer: {
data: string,
width: number,
height: number
renderer_active: boolean,
info: string,
progress: number,
},
routes: {
limit: 0,
loading: boolean,
list: [],
filter: {
title: '',
starred: boolean,
distance: [number, number],
author: '',
tab: '',
min: number,
max: number,
}
},
}
export type IRootState = Readonly<IRootReducer>;
type UnsafeReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
export interface ActionHandler<T> {
(state: IRootState, payload: UnsafeReturnType<T>): IRootState;
}
const getEstimated = (distance: number, speed: number = 15): number => {
const time = (distance && (distance / speed)) || 0;
return (time && parseFloat(time.toFixed(1)));
};
const setUser: ActionHandler<typeof ActionCreators.setUser> = (state, { user }) => ({
...state,
user: {
...state.user,
...user,
},
});
const setEditing: ActionHandler<typeof ActionCreators.setEditing> = (state, { editing }) => ({
...state, editing
});
const setChanged: ActionHandler<typeof ActionCreators.setChanged> = (state, { changed }) => ({
...state,
changed
});
const setMode: ActionHandler<typeof ActionCreators.setMode> = (state, { mode }) => ({
...state,
mode
});
const setDistance: ActionHandler<typeof ActionCreators.setDistance> = (state, { distance }) => ({
...state,
distance,
estimated: getEstimated(distance, state.speed),
});
const setRouterPoints: ActionHandler<typeof ActionCreators.setRouterPoints> = (state, { routerPoints }) => ({
...state,
routerPoints,
});
const setActiveSticker: ActionHandler<typeof ActionCreators.setActiveSticker> = (state, { activeSticker }) => ({
...state,
activeSticker: activeSticker || { set: null, sticker: null }
});
const setLogo: ActionHandler<typeof ActionCreators.setLogo> = (state, { logo }) => ({
...state,
logo
});
const setTitle: ActionHandler<typeof ActionCreators.setTitle> = (state, { title }) => ({
...state,
title
});
const setAddress: ActionHandler<typeof ActionCreators.setAddress> = (state, { address }) => ({
...state,
address
});
const setAddressOrigin: ActionHandler<typeof ActionCreators.setAddressOrigin> = (state, { address_origin }) => ({
...state,
address_origin
});
const sendSaveRequest: ActionHandler<typeof ActionCreators.sendSaveRequest> = (state) => ({
...state,
save_processing: true,
});
const setSaveError: ActionHandler<typeof ActionCreators.setSaveError> = (state, { save_error }) => ({
...state, save_error, save_finished: false, save_processing: false
});
const setSaveOverwrite: ActionHandler<typeof ActionCreators.setSaveOverwrite> = (state) => ({
...state,
save_overwriting: true,
save_finished: false,
save_processing: false,
save_error: TIPS.SAVE_OVERWRITE,
});
const setSaveSuccess: ActionHandler<typeof ActionCreators.setSaveSuccess> = (state, { save_error }) => ({
...state, save_overwriting: false, save_finished: true, save_processing: false, save_error
});
const resetSaveDialog: ActionHandler<typeof ActionCreators.resetSaveDialog> = (state) => ({
...state, save_overwriting: false, save_finished: false, save_processing: false, save_error: '',
});
//
// const showRenderer: ActionHandler<typeof ActionCreators.showRenderer> = (state) => ({
// ...state,
// renderer: {
// ...state.renderer,
// renderer_active: true
// }
// });
const hideRenderer: ActionHandler<typeof ActionCreators.hideRenderer> = (state) => ({
...state,
renderer: { ...state.renderer, renderer_active: false }
});
const setRenderer: ActionHandler<typeof ActionCreators.setRenderer> = (state, { payload }) => ({
...state,
renderer: { ...state.renderer, ...payload }
});
const setProvider: ActionHandler<typeof ActionCreators.setProvider> = (state, { provider }) => ({ ...state, provider });
const setDialog: ActionHandler<typeof ActionCreators.setDialog> = (state, { dialog }) => ({
...state,
dialog,
});
const setDialogActive: ActionHandler<typeof ActionCreators.setDialogActive> = (state, { dialog_active }) => ({
...state,
dialog_active: dialog_active || !state.dialog_active,
});
const setReady: ActionHandler<typeof ActionCreators.setReady> = (state, { ready = true }) => ({
...state,
ready,
});
const searchSetTitle: ActionHandler<typeof ActionCreators.searchSetTitle> = (state, { title = '' }) => ({
...state,
routes: {
...state.routes,
filter: {
...state.routes.filter,
title,
distance: [0, 10000],
}
}
});
const searchSetDistance: ActionHandler<typeof ActionCreators.searchSetDistance> = (state, { distance = [0, 9999] }) => ({
...state,
routes: {
...state.routes,
filter: {
...state.routes.filter,
distance,
}
}
});
const searchSetTab: ActionHandler<typeof ActionCreators.searchSetTab> = (state, { tab = TABS[Object.keys(TABS)[0]] }) => ({
...state,
routes: {
...state.routes,
filter: {
...state.routes.filter,
tab: Object.keys(TABS).indexOf(tab) >= 0 ? tab : TABS[Object.keys(TABS)[0]],
}
}
});
const searchPutRoutes: ActionHandler<typeof ActionCreators.searchPutRoutes> = (state, { list = [], min, max }) => ({
...state,
routes: {
...state.routes,
list,
filter: {
...state.routes.filter,
distance: (state.routes.filter.min === state.routes.filter.max)
? [min, max]
: state.routes.filter.distance,
min,
max,
}
}
});
const searchSetLoading: ActionHandler<typeof ActionCreators.searchSetLoading> = (state, { loading = false }) => ({
...state,
routes: {
...state.routes,
loading,
}
});
const setPublic: ActionHandler<typeof ActionCreators.setPublic> = (state, { is_public = false }) => ({ ...state, is_public });
const setSpeed: ActionHandler<typeof ActionCreators.setSpeed> = (state, { speed = 15 }) => ({
...state,
speed,
estimated: getEstimated(state.distance, speed),
});
const setMarkersShown: ActionHandler<typeof ActionCreators.setMarkersShown> = (state, { markers_shown = true }) => ({ ...state, markers_shown });
const HANDLERS = ({
[ACTIONS.SET_USER]: setUser,
[ACTIONS.SET_EDITING]: setEditing,
[ACTIONS.SET_CHANGED]: setChanged,
[ACTIONS.SET_MODE]: setMode,
[ACTIONS.SET_DISTANCE]: setDistance,
[ACTIONS.SET_ROUTER_POINTS]: setRouterPoints,
[ACTIONS.SET_ACTIVE_STICKER]: setActiveSticker,
[ACTIONS.SET_LOGO]: setLogo,
[ACTIONS.SET_TITLE]: setTitle,
[ACTIONS.SET_ADDRESS]: setAddress,
[ACTIONS.SET_ADDRESS_ORIGIN]: setAddressOrigin,
[ACTIONS.SET_SAVE_ERROR]: setSaveError,
[ACTIONS.SET_SAVE_OVERWRITE]: setSaveOverwrite,
[ACTIONS.SET_SAVE_SUCCESS]: setSaveSuccess,
[ACTIONS.SEND_SAVE_REQUEST]: sendSaveRequest,
[ACTIONS.RESET_SAVE_DIALOG]: resetSaveDialog,
[ACTIONS.HIDE_RENDERER]: hideRenderer,
[ACTIONS.SET_RENDERER]: setRenderer,
[ACTIONS.SET_PROVIDER]: setProvider,
[ACTIONS.SET_DIALOG]: setDialog,
[ACTIONS.SET_DIALOG_ACTIVE]: setDialogActive,
[ACTIONS.SET_READY]: setReady,
[ACTIONS.SEARCH_SET_TITLE]: searchSetTitle,
[ACTIONS.SEARCH_SET_DISTANCE]: searchSetDistance,
[ACTIONS.SEARCH_SET_TAB]: searchSetTab,
[ACTIONS.SEARCH_PUT_ROUTES]: searchPutRoutes,
[ACTIONS.SEARCH_SET_LOADING]: searchSetLoading,
[ACTIONS.SET_PUBLIC]: setPublic,
[ACTIONS.SET_SPEED]: setSpeed,
[ACTIONS.SET_MARKERS_SHOWN]: setMarkersShown,
});
export const INITIAL_STATE: IRootReducer = {
ready: false,
user: { ...DEFAULT_USER },
editing: false,
mode: MODES.NONE,
logo: DEFAULT_LOGO,
routerPoints: 0,
distance: 0,
estimated: 0,
speed: 15,
activeSticker: { set: null, sticker: null },
title: '',
address: '',
address_origin: '',
changed: false,
provider: DEFAULT_PROVIDER,
is_public: false,
markers_shown: true,
save_error: '',
save_finished: false,
save_overwriting: false,
save_processing: false,
dialog: DIALOGS.NONE,
dialog_active: false,
renderer: {
data: '',
width: 0,
height: 0,
renderer_active: false,
info: '',
progress: 0,
},
routes: {
limit: 0,
loading: false, // <-- maybe delete this
list: [],
filter: {
title: '',
starred: false,
distance: [0, 10000],
author: '',
tab: '',
min: 0,
max: 10000,
}
},
};
export const userReducer = createReducer(INITIAL_STATE, HANDLERS);