mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 02:56:41 +07:00
reducers typescripting
This commit is contained in:
parent
4c6526efc9
commit
85b8860862
15 changed files with 496 additions and 316 deletions
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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
45
src/constants/auth.ts
Normal 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: '',
|
||||
}
|
||||
};
|
|
@ -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
21
src/constants/dialogs.ts
Normal 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: 'Общие',
|
||||
});
|
|
@ -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'],
|
|
@ -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 });
|
||||
};
|
|
@ -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));
|
||||
};
|
|
@ -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'),
|
|
@ -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);
|
|
@ -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 });
|
||||
|
|
@ -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 });
|
||||
};
|
|
@ -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
353
src/redux/user/reducer.ts
Normal 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);
|
Loading…
Add table
Add a link
Reference in a new issue