mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 11:06:40 +07:00
moved editor to separate reducer
This commit is contained in:
parent
e950d98b73
commit
87670770b0
38 changed files with 1425 additions and 1069 deletions
120
src/redux/editor/actions.ts
Normal file
120
src/redux/editor/actions.ts
Normal file
|
@ -0,0 +1,120 @@
|
|||
import { EDITOR_ACTIONS } from './constants';
|
||||
import { IEditorState } from '.';
|
||||
import { IRoute } from '../map/types';
|
||||
import { KeyboardEvent } from 'react';
|
||||
|
||||
export const editorSetEditing = (editing: IEditorState['editing']) => ({
|
||||
type: EDITOR_ACTIONS.SET_EDITING,
|
||||
editing,
|
||||
});
|
||||
export const editorSetMode = (mode: IEditorState['mode']) => ({
|
||||
type: EDITOR_ACTIONS.SET_MODE,
|
||||
mode,
|
||||
});
|
||||
export const editorSetDistance = (distance: IEditorState['distance']) => ({
|
||||
type: EDITOR_ACTIONS.SET_DISTANCE,
|
||||
distance,
|
||||
});
|
||||
export const editorSetChanged = (changed: IEditorState['changed']) => ({
|
||||
type: EDITOR_ACTIONS.SET_CHANGED,
|
||||
changed,
|
||||
});
|
||||
export const editorSetSpeed = speed => ({ type: EDITOR_ACTIONS.SET_SPEED, speed });
|
||||
|
||||
export const editorStartEditing = () => ({ type: EDITOR_ACTIONS.START_EDITING });
|
||||
export const editorStopEditing = () => ({ type: EDITOR_ACTIONS.STOP_EDITING });
|
||||
|
||||
export const editorRouterCancel = () => ({ type: EDITOR_ACTIONS.ROUTER_CANCEL });
|
||||
export const editorRouterSubmit = () => ({ type: EDITOR_ACTIONS.ROUTER_SUBMIT });
|
||||
|
||||
export const editorClearPoly = () => ({ type: EDITOR_ACTIONS.CLEAR_POLY });
|
||||
export const editorClearStickers = () => ({ type: EDITOR_ACTIONS.CLEAR_STICKERS });
|
||||
export const editorClearAll = () => ({ type: EDITOR_ACTIONS.CLEAR_ALL });
|
||||
export const editorClearCancel = () => ({ type: EDITOR_ACTIONS.CLEAR_CANCEL });
|
||||
|
||||
export const editorSendSaveRequest = (payload: {
|
||||
title: IRoute['title'];
|
||||
address: IRoute['address'];
|
||||
is_public: IRoute['is_public'];
|
||||
description: IRoute['description'];
|
||||
force: boolean;
|
||||
}) => ({
|
||||
type: EDITOR_ACTIONS.SEND_SAVE_REQUEST,
|
||||
...payload,
|
||||
});
|
||||
|
||||
export const editorResetSaveDialog = () => ({ type: EDITOR_ACTIONS.RESET_SAVE_DIALOG });
|
||||
|
||||
export const editorSetSaveLoading = (save_loading: IEditorState['save_loading']) => ({
|
||||
type: EDITOR_ACTIONS.SET_SAVE_LOADING,
|
||||
save_loading,
|
||||
});
|
||||
|
||||
export const editorSetSaveSuccess = (payload: {
|
||||
address: IRoute['address'];
|
||||
title: IRoute['address'];
|
||||
is_public: IRoute['is_public'];
|
||||
description: IRoute['description'];
|
||||
|
||||
save_error: string;
|
||||
}) => ({ type: EDITOR_ACTIONS.SET_SAVE_SUCCESS, ...payload });
|
||||
|
||||
export const editorSetSaveError = (save_error: IEditorState['save_error']) => ({
|
||||
type: EDITOR_ACTIONS.SET_SAVE_ERROR,
|
||||
save_error,
|
||||
});
|
||||
export const editorSetSaveOverwrite = () => ({ type: EDITOR_ACTIONS.SET_SAVE_OVERWRITE });
|
||||
|
||||
export const editorHideRenderer = () => ({ type: EDITOR_ACTIONS.HIDE_RENDERER });
|
||||
export const editorSetRenderer = payload => ({ type: EDITOR_ACTIONS.SET_RENDERER, payload });
|
||||
export const editorTakeAShot = () => ({ type: EDITOR_ACTIONS.TAKE_A_SHOT });
|
||||
export const editorCropAShot = payload => ({ type: EDITOR_ACTIONS.CROP_A_SHOT, ...payload });
|
||||
export const editorSetDialog = dialog => ({ type: EDITOR_ACTIONS.SET_DIALOG, dialog });
|
||||
export const editorSetDialogActive = dialog_active => ({
|
||||
type: EDITOR_ACTIONS.SET_DIALOG_ACTIVE,
|
||||
dialog_active,
|
||||
});
|
||||
export const editorSetReady = ready => ({ type: EDITOR_ACTIONS.SET_READY, ready });
|
||||
|
||||
export const editorGetGPXTrack = () => ({ type: EDITOR_ACTIONS.GET_GPX_TRACK });
|
||||
export const editorSetMarkersShown = markers_shown => ({
|
||||
type: EDITOR_ACTIONS.SET_MARKERS_SHOWN,
|
||||
markers_shown,
|
||||
});
|
||||
export const editorSetIsEmpty = is_empty => ({ type: EDITOR_ACTIONS.SET_IS_EMPTY, is_empty });
|
||||
export const editorSetFeature = (features: { [x: string]: boolean }) => ({
|
||||
type: EDITOR_ACTIONS.SET_FEATURE,
|
||||
features,
|
||||
});
|
||||
|
||||
export const editorSetIsRouting = (is_routing: boolean) => ({
|
||||
type: EDITOR_ACTIONS.SET_IS_ROUTING,
|
||||
is_routing,
|
||||
});
|
||||
|
||||
export const editorSetRouterPoints = (routerPoints: IEditorState['routerPoints']) => ({
|
||||
type: EDITOR_ACTIONS.SET_ROUTER_POINTS,
|
||||
routerPoints,
|
||||
});
|
||||
|
||||
export const editorSetActiveSticker = (activeSticker: IEditorState['activeSticker']) => ({
|
||||
type: EDITOR_ACTIONS.SET_ACTIVE_STICKER,
|
||||
activeSticker,
|
||||
});
|
||||
|
||||
export const editorLocationChanged = location => ({
|
||||
type: EDITOR_ACTIONS.LOCATION_CHANGED,
|
||||
location,
|
||||
});
|
||||
|
||||
export const editorKeyPressed = ({
|
||||
key,
|
||||
target: { tagName },
|
||||
}: {
|
||||
key: string;
|
||||
target: { tagName: string };
|
||||
}) => ({
|
||||
type: EDITOR_ACTIONS.KEY_PRESSED,
|
||||
key,
|
||||
target: tagName,
|
||||
});
|
47
src/redux/editor/constants.ts
Normal file
47
src/redux/editor/constants.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
const P = 'EDITOR';
|
||||
|
||||
export const EDITOR_ACTIONS = {
|
||||
SET_EDITING: `${P}-SET_EDITING`,
|
||||
SET_MODE: `${P}-SET_MODE`,
|
||||
SET_DISTANCE: `${P}-SET_DISTANCE`,
|
||||
SET_CHANGED: `${P}-SET_CHANGED`,
|
||||
SET_SPEED: `${P}-SET_SPEED`,
|
||||
SET_ROUTER_POINTS: `${P}-SET_ROUTER_POINTS`,
|
||||
SET_ACTIVE_STICKER: `${P}-SET_ACTIVE_STICKER`,
|
||||
START_EDITING: `${P}-START_EDITING`,
|
||||
STOP_EDITING: `${P}-STOP_EDITING`,
|
||||
ROUTER_CANCEL: `${P}-ROUTER_CANCEL`,
|
||||
ROUTER_SUBMIT: `${P}-ROUTER_SUBMIT`,
|
||||
|
||||
CLEAR_POLY: `${P}-CLEAR_POLY`,
|
||||
CLEAR_STICKERS: `${P}-CLEAR_STICKERS`,
|
||||
CLEAR_ALL: `${P}-CLEAR_ALL`,
|
||||
CLEAR_CANCEL: `${P}-CLEAR_CANCEL`,
|
||||
|
||||
SEND_SAVE_REQUEST: `${P}-SEND_SAVE_REQUEST`,
|
||||
SET_SAVE_LOADING: `${P}-SET_SAVE_LOADING`,
|
||||
CANCEL_SAVE_REQUEST: `${P}-CANCEL_SAVE_REQUEST`,
|
||||
RESET_SAVE_DIALOG: `${P}-RESET_SAVE_DIALOG`,
|
||||
|
||||
SET_SAVE_SUCCESS: `${P}-SET_SAVE_SUCCESS`,
|
||||
SET_SAVE_ERROR: `${P}-SET_SAVE_ERROR`,
|
||||
SET_SAVE_OVERWRITE: `${P}-SET_SAVE_OVERWRITE`,
|
||||
|
||||
SHOW_RENDERER: `${P}-SHOW_RENDERER`,
|
||||
HIDE_RENDERER: `${P}-HIDE_RENDERER`,
|
||||
SET_RENDERER: `${P}-SET_RENDERER`,
|
||||
TAKE_A_SHOT: `${P}-TAKE_A_SHOT`,
|
||||
CROP_A_SHOT: `${P}-CROP_A_SHOT`,
|
||||
|
||||
SET_DIALOG: `${P}-SET_DIALOG`,
|
||||
SET_DIALOG_ACTIVE: `${P}-SET_DIALOG_ACTIVE`,
|
||||
LOCATION_CHANGED: `${P}-LOCATION_CHANGED`,
|
||||
SET_READY: `${P}-SET_READY`,
|
||||
|
||||
SET_MARKERS_SHOWN: `${P}-SET_MARKERS_SHOWN`,
|
||||
GET_GPX_TRACK: `${P}-GET_GPX_TRACK`,
|
||||
SET_IS_EMPTY: `${P}-SET_IS_EMPTY`,
|
||||
SET_FEATURE: `${P}-SET_FEATURE`,
|
||||
SET_IS_ROUTING: `${P}-SET_IS_ROUTING`,
|
||||
KEY_PRESSED: `${P}-KEY_PRESSED`,
|
||||
};
|
200
src/redux/editor/handlers.ts
Normal file
200
src/redux/editor/handlers.ts
Normal file
|
@ -0,0 +1,200 @@
|
|||
import { getEstimated } from '~/utils/format';
|
||||
import * as ACTIONS from '~/redux/editor/actions';
|
||||
import { EDITOR_ACTIONS } from '~/redux/editor/constants';
|
||||
import { IEditorState } from '~/redux/editor';
|
||||
import { TIPS } from '~/constants/tips';
|
||||
|
||||
const setEditing = (
|
||||
state,
|
||||
{ editing }: ReturnType<typeof ACTIONS.editorSetEditing>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
editing,
|
||||
});
|
||||
|
||||
const setChanged = (
|
||||
state,
|
||||
{ changed }: ReturnType<typeof ACTIONS.editorSetChanged>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
changed,
|
||||
});
|
||||
|
||||
const setMode = (state, { mode }: ReturnType<typeof ACTIONS.editorSetMode>): IEditorState => ({
|
||||
...state,
|
||||
mode,
|
||||
});
|
||||
|
||||
const setDistance = (
|
||||
state,
|
||||
{ distance }: ReturnType<typeof ACTIONS.editorSetDistance>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
distance,
|
||||
estimated: getEstimated(distance, state.speed),
|
||||
});
|
||||
|
||||
const setRouterPoints = (
|
||||
state,
|
||||
{ routerPoints }: ReturnType<typeof ACTIONS.editorSetRouterPoints>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
routerPoints,
|
||||
});
|
||||
|
||||
const setActiveSticker = (
|
||||
state,
|
||||
{ activeSticker }: ReturnType<typeof ACTIONS.editorSetActiveSticker>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
activeSticker: activeSticker || { set: null, sticker: null },
|
||||
});
|
||||
|
||||
const hideRenderer = (state): IEditorState => ({
|
||||
...state,
|
||||
renderer: { ...state.renderer, renderer_active: false },
|
||||
});
|
||||
|
||||
const setRenderer = (
|
||||
state,
|
||||
{ payload }: ReturnType<typeof ACTIONS.editorSetRenderer>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
renderer: { ...state.renderer, ...payload },
|
||||
});
|
||||
|
||||
const sendSaveRequest = (state): IEditorState => ({
|
||||
...state,
|
||||
save_processing: true,
|
||||
});
|
||||
|
||||
const setSaveError = (
|
||||
state,
|
||||
{ save_error }: ReturnType<typeof ACTIONS.editorSetSaveError>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
save_error,
|
||||
save_finished: false,
|
||||
save_processing: false,
|
||||
});
|
||||
|
||||
const setSaveLoading = (
|
||||
state,
|
||||
{ save_loading }: ReturnType<typeof ACTIONS.editorSetSaveLoading>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
save_loading,
|
||||
});
|
||||
|
||||
const setSaveOverwrite = (state): IEditorState => ({
|
||||
...state,
|
||||
save_overwriting: true,
|
||||
save_finished: false,
|
||||
save_processing: false,
|
||||
save_error: TIPS.SAVE_OVERWRITE,
|
||||
});
|
||||
|
||||
const setSaveSuccess = (
|
||||
state,
|
||||
{ save_error }: ReturnType<typeof ACTIONS.editorSetSaveSuccess>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
save_overwriting: false,
|
||||
save_finished: true,
|
||||
save_processing: false,
|
||||
save_error,
|
||||
});
|
||||
|
||||
const resetSaveDialog = (state): IEditorState => ({
|
||||
...state,
|
||||
save_overwriting: false,
|
||||
save_finished: false,
|
||||
save_processing: false,
|
||||
save_error: '',
|
||||
});
|
||||
|
||||
const setDialog = (state, { dialog }: ReturnType<typeof ACTIONS.editorSetDialog>): IEditorState => ({
|
||||
...state,
|
||||
dialog,
|
||||
});
|
||||
|
||||
const setDialogActive = (
|
||||
state,
|
||||
{ dialog_active }: ReturnType<typeof ACTIONS.editorSetDialogActive>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
dialog_active: dialog_active || !state.dialog_active,
|
||||
});
|
||||
|
||||
const setReady = (state, { ready = true }: ReturnType<typeof ACTIONS.editorSetReady>): IEditorState => ({
|
||||
...state,
|
||||
ready,
|
||||
});
|
||||
|
||||
const setSpeed = (
|
||||
state,
|
||||
{ speed = 15 }: ReturnType<typeof ACTIONS.editorSetSpeed>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
speed,
|
||||
estimated: getEstimated(state.distance, speed),
|
||||
});
|
||||
|
||||
const setMarkersShown = (
|
||||
state,
|
||||
{ markers_shown = true }: ReturnType<typeof ACTIONS.editorSetMarkersShown>
|
||||
): IEditorState => ({ ...state, markers_shown });
|
||||
|
||||
const setIsEmpty = (
|
||||
state,
|
||||
{ is_empty = true }: ReturnType<typeof ACTIONS.editorSetIsEmpty>
|
||||
): IEditorState => ({ ...state, is_empty });
|
||||
|
||||
const setFeature = (
|
||||
state,
|
||||
{ features }: ReturnType<typeof ACTIONS.editorSetFeature>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
features: {
|
||||
...state.features,
|
||||
...features,
|
||||
},
|
||||
});
|
||||
|
||||
const setIsRouting = (
|
||||
state,
|
||||
{ is_routing }: ReturnType<typeof ACTIONS.editorSetIsRouting>
|
||||
): IEditorState => ({
|
||||
...state,
|
||||
is_routing,
|
||||
});
|
||||
|
||||
export const EDITOR_HANDLERS = {
|
||||
[EDITOR_ACTIONS.SET_EDITING]: setEditing,
|
||||
[EDITOR_ACTIONS.SET_CHANGED]: setChanged,
|
||||
[EDITOR_ACTIONS.SET_MODE]: setMode,
|
||||
[EDITOR_ACTIONS.SET_DISTANCE]: setDistance,
|
||||
[EDITOR_ACTIONS.SET_ROUTER_POINTS]: setRouterPoints,
|
||||
[EDITOR_ACTIONS.SET_ACTIVE_STICKER]: setActiveSticker,
|
||||
|
||||
[EDITOR_ACTIONS.SET_SAVE_ERROR]: setSaveError,
|
||||
[EDITOR_ACTIONS.SET_SAVE_LOADING]: setSaveLoading,
|
||||
[EDITOR_ACTIONS.SET_SAVE_OVERWRITE]: setSaveOverwrite,
|
||||
[EDITOR_ACTIONS.SET_SAVE_SUCCESS]: setSaveSuccess,
|
||||
[EDITOR_ACTIONS.SEND_SAVE_REQUEST]: sendSaveRequest,
|
||||
[EDITOR_ACTIONS.RESET_SAVE_DIALOG]: resetSaveDialog,
|
||||
|
||||
[EDITOR_ACTIONS.HIDE_RENDERER]: hideRenderer,
|
||||
[EDITOR_ACTIONS.SET_RENDERER]: setRenderer,
|
||||
|
||||
[EDITOR_ACTIONS.SET_DIALOG]: setDialog,
|
||||
[EDITOR_ACTIONS.SET_DIALOG_ACTIVE]: setDialogActive,
|
||||
[EDITOR_ACTIONS.SET_READY]: setReady,
|
||||
|
||||
[EDITOR_ACTIONS.SET_SPEED]: setSpeed,
|
||||
[EDITOR_ACTIONS.SET_MARKERS_SHOWN]: setMarkersShown,
|
||||
[EDITOR_ACTIONS.SET_IS_EMPTY]: setIsEmpty,
|
||||
|
||||
[EDITOR_ACTIONS.SET_FEATURE]: setFeature,
|
||||
[EDITOR_ACTIONS.SET_IS_ROUTING]: setIsRouting,
|
||||
};
|
85
src/redux/editor/index.ts
Normal file
85
src/redux/editor/index.ts
Normal file
|
@ -0,0 +1,85 @@
|
|||
import { IDialogs } from '~/constants/dialogs';
|
||||
import { MODES } from '~/constants/modes';
|
||||
import { createReducer } from 'reduxsauce';
|
||||
import { EDITOR_HANDLERS } from './handlers';
|
||||
|
||||
export interface IEditorState {
|
||||
changed: boolean,
|
||||
editing: boolean,
|
||||
ready: boolean,
|
||||
markers_shown: boolean;
|
||||
|
||||
mode: typeof MODES[keyof typeof MODES],
|
||||
|
||||
dialog: IDialogs[keyof IDialogs],
|
||||
dialog_active: boolean,
|
||||
|
||||
routerPoints: number,
|
||||
distance: number,
|
||||
estimated: number,
|
||||
speed: number,
|
||||
activeSticker: { set?: string, sticker?: string },
|
||||
is_empty: boolean,
|
||||
is_published: boolean,
|
||||
is_routing: boolean,
|
||||
save_error: string,
|
||||
save_finished: boolean,
|
||||
save_overwriting: boolean,
|
||||
save_processing: boolean,
|
||||
save_loading: boolean,
|
||||
|
||||
features: {
|
||||
routing: boolean,
|
||||
},
|
||||
|
||||
renderer: {
|
||||
data: string,
|
||||
width: number,
|
||||
height: number
|
||||
renderer_active: boolean,
|
||||
info: string,
|
||||
progress: number,
|
||||
},
|
||||
}
|
||||
|
||||
const EDITOR_INITIAL_STATE = {
|
||||
changed: false,
|
||||
editing: false,
|
||||
ready: false,
|
||||
markers_shown: false,
|
||||
|
||||
mode: MODES.NONE,
|
||||
dialog: null,
|
||||
dialog_active: false,
|
||||
|
||||
routerPoints: 0,
|
||||
distance: 0,
|
||||
estimated: 0,
|
||||
speed: 15,
|
||||
activeSticker: { set: null, sticker: null },
|
||||
|
||||
is_published: false,
|
||||
is_empty: true,
|
||||
is_routing: false,
|
||||
|
||||
save_error: '',
|
||||
save_finished: false,
|
||||
save_overwriting: false,
|
||||
save_processing: false,
|
||||
save_loading: false,
|
||||
|
||||
features: {
|
||||
routing: false,
|
||||
},
|
||||
|
||||
renderer: {
|
||||
data: '',
|
||||
width: 0,
|
||||
height: 0,
|
||||
renderer_active: false,
|
||||
info: '',
|
||||
progress: 0,
|
||||
},
|
||||
}
|
||||
|
||||
export const editor = createReducer(EDITOR_INITIAL_STATE, EDITOR_HANDLERS);
|
256
src/redux/editor/sagas.ts
Normal file
256
src/redux/editor/sagas.ts
Normal file
|
@ -0,0 +1,256 @@
|
|||
import { call, put, takeEvery, takeLatest, select, race } from 'redux-saga/effects';
|
||||
import { delay, SagaIterator } from 'redux-saga';
|
||||
import { selectEditor } from '~/redux/editor/selectors';
|
||||
|
||||
import {
|
||||
editorHideRenderer,
|
||||
editorSetChanged,
|
||||
editorSetEditing,
|
||||
editorSetMode,
|
||||
editorSetReady,
|
||||
editorSetRenderer,
|
||||
editorSetDialog,
|
||||
editorSetDialogActive,
|
||||
editorClearAll,
|
||||
editorSetFeature,
|
||||
editorLocationChanged,
|
||||
editorKeyPressed,
|
||||
} from '~/redux/editor/actions';
|
||||
import { getUrlData, pushPath } from '~/utils/history';
|
||||
import { MODES } from '~/constants/modes';
|
||||
import { checkOSRMService } from '~/utils/api';
|
||||
import { LatLng } from 'leaflet';
|
||||
import { searchSetTab } from '../user/actions';
|
||||
import { TABS } from '~/constants/dialogs';
|
||||
import { EDITOR_ACTIONS } from './constants';
|
||||
import { getGPXString, downloadGPXTrack } from '~/utils/gpx';
|
||||
import {
|
||||
getTilePlacement,
|
||||
getPolyPlacement,
|
||||
getStickersPlacement,
|
||||
fetchImages,
|
||||
composeArrows,
|
||||
composeDistMark,
|
||||
composeImages,
|
||||
composePoly,
|
||||
composeStickers,
|
||||
imageFetcher,
|
||||
downloadCanvas,
|
||||
} from '~/utils/renderer';
|
||||
import { selectMap } from '../map/selectors';
|
||||
import { selectUser } from '../user/selectors';
|
||||
import { LOGOS } from '~/constants/logos';
|
||||
import { loadMapSaga, replaceAddressIfItsBusy } from '../map/sagas';
|
||||
import { mapSetAddressOrigin } from '../map/actions';
|
||||
|
||||
const hideLoader = () => {
|
||||
document.getElementById('loader').style.opacity = String(0);
|
||||
document.getElementById('loader').style.pointerEvents = 'none';
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
function* stopEditingSaga() {
|
||||
const { changed, editing, mode }: ReturnType<typeof selectEditor> = yield select(selectEditor);
|
||||
const { address_origin }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
const { path } = getUrlData();
|
||||
|
||||
if (!editing) return;
|
||||
if (changed && mode !== MODES.CONFIRM_CANCEL) {
|
||||
yield put(editorSetMode(MODES.CONFIRM_CANCEL));
|
||||
return;
|
||||
}
|
||||
|
||||
yield put(editorSetMode(MODES.NONE));
|
||||
yield put(editorSetChanged(false));
|
||||
|
||||
yield pushPath(`/${address_origin || path}/`);
|
||||
}
|
||||
|
||||
function* checkOSRMServiceSaga() {
|
||||
const routing = yield call(checkOSRMService, [new LatLng(1, 1), new LatLng(2, 2)]);
|
||||
|
||||
yield put(editorSetFeature({ routing }));
|
||||
}
|
||||
|
||||
export function* setReadySaga() {
|
||||
yield put(editorSetReady(true));
|
||||
hideLoader();
|
||||
|
||||
yield call(checkOSRMServiceSaga);
|
||||
yield put(searchSetTab(TABS.MY));
|
||||
}
|
||||
|
||||
function* getRenderData() {
|
||||
yield put(editorSetRenderer({ info: 'Загрузка тайлов', progress: 0.1 }));
|
||||
|
||||
const { route, stickers, provider }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
|
||||
const canvas = <HTMLCanvasElement>document.getElementById('renderer');
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
const geometry = getTilePlacement();
|
||||
const points = getPolyPlacement(route);
|
||||
const sticker_points = getStickersPlacement(stickers);
|
||||
// TODO: get distance:
|
||||
const distance = 0;
|
||||
// const distance = editor.poly.poly.distance;
|
||||
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const images = yield fetchImages(ctx, geometry, provider);
|
||||
|
||||
yield put(editorSetRenderer({ info: 'Отрисовка', progress: 0.5 }));
|
||||
|
||||
yield composeImages({ geometry, images, ctx });
|
||||
yield composePoly({ points, ctx });
|
||||
yield composeArrows({ points, ctx });
|
||||
yield composeDistMark({ ctx, points, distance });
|
||||
yield composeStickers({ stickers: sticker_points, ctx });
|
||||
|
||||
yield put(editorSetRenderer({ info: 'Готово', progress: 1 }));
|
||||
|
||||
return yield canvas.toDataURL('image/jpeg');
|
||||
}
|
||||
|
||||
function* takeAShotSaga() {
|
||||
const worker = call(getRenderData);
|
||||
|
||||
const { result, timeout } = yield race({
|
||||
result: worker,
|
||||
timeout: delay(500),
|
||||
});
|
||||
|
||||
if (timeout) yield put(editorSetMode(MODES.SHOT_PREFETCH));
|
||||
|
||||
const data = yield result || worker;
|
||||
|
||||
yield put(editorSetMode(MODES.NONE));
|
||||
yield put(
|
||||
editorSetRenderer({
|
||||
data,
|
||||
renderer_active: true,
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function* getCropData({ x, y, width, height }) {
|
||||
const { logo }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
const {
|
||||
renderer: { data },
|
||||
}: ReturnType<typeof selectEditor> = yield select(selectEditor);
|
||||
|
||||
const canvas = <HTMLCanvasElement>document.getElementById('renderer');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
const image = yield imageFetcher(data);
|
||||
|
||||
ctx.drawImage(image, -x, -y);
|
||||
|
||||
if (logo && LOGOS[logo][1]) {
|
||||
const logoImage = yield imageFetcher(LOGOS[logo][1]);
|
||||
ctx.drawImage(logoImage, width - logoImage.width, height - logoImage.height);
|
||||
}
|
||||
|
||||
return yield canvas.toDataURL('image/jpeg');
|
||||
}
|
||||
|
||||
function* cropAShotSaga(params) {
|
||||
const { title, address }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
|
||||
yield call(getCropData, params);
|
||||
const canvas = document.getElementById('renderer') as HTMLCanvasElement;
|
||||
|
||||
downloadCanvas(canvas, (title || address).replace(/\./gi, ' '));
|
||||
|
||||
return yield put(editorHideRenderer());
|
||||
}
|
||||
|
||||
function* locationChangeSaga({ location }: ReturnType<typeof editorLocationChanged>) {
|
||||
const {
|
||||
user: { id, random_url },
|
||||
}: ReturnType<typeof selectUser> = yield select(selectUser);
|
||||
|
||||
const { ready }: ReturnType<typeof selectEditor> = yield select(selectEditor);
|
||||
|
||||
const { owner, address }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
|
||||
if (!ready) return;
|
||||
|
||||
const { path, mode } = getUrlData(location);
|
||||
|
||||
if (address !== path) {
|
||||
const map = yield call(loadMapSaga, path);
|
||||
|
||||
if (map && map.route && map.route.owner && mode === 'edit' && map.route.owner !== id) {
|
||||
return yield call(replaceAddressIfItsBusy, map.random_url, map.address);
|
||||
}
|
||||
} else if (mode === 'edit' && owner.id !== id) {
|
||||
return yield call(replaceAddressIfItsBusy, random_url, address);
|
||||
} else {
|
||||
yield put(mapSetAddressOrigin(''));
|
||||
}
|
||||
|
||||
if (mode !== 'edit') {
|
||||
yield put(editorSetEditing(false));
|
||||
// editor.stopEditing();
|
||||
} else {
|
||||
yield put(editorSetEditing(true));
|
||||
// editor.startEditing();
|
||||
}
|
||||
}
|
||||
|
||||
function* keyPressedSaga({ key, target }: ReturnType<typeof editorKeyPressed>): any {
|
||||
if (target === 'INPUT' || target === 'TEXTAREA') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (key === 'Escape') {
|
||||
const {
|
||||
dialog_active,
|
||||
mode,
|
||||
renderer: { renderer_active },
|
||||
}: ReturnType<typeof selectEditor> = yield select(selectEditor);
|
||||
|
||||
if (renderer_active) return yield put(editorHideRenderer());
|
||||
if (dialog_active) return yield put(editorSetDialogActive(false));
|
||||
if (mode !== MODES.NONE) return yield put(editorSetMode(MODES.NONE));
|
||||
} else if (key === 'Delete') {
|
||||
const { editing } = yield select(selectEditor);
|
||||
|
||||
if (!editing) return;
|
||||
|
||||
const { mode } = yield select(selectUser);
|
||||
|
||||
if (mode === MODES.TRASH) {
|
||||
yield put(editorClearAll());
|
||||
} else {
|
||||
yield put(editorSetMode(MODES.TRASH));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function* getGPXTrackSaga(): SagaIterator {
|
||||
const { route, stickers, title, address }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
// const { title, address }: = yield select(selectUser);
|
||||
|
||||
if (!route || route.length <= 0) return;
|
||||
|
||||
const track = getGPXString({ route, stickers, title: title || address });
|
||||
|
||||
return downloadGPXTrack({ track, title });
|
||||
}
|
||||
|
||||
export function* editorSaga() {
|
||||
yield takeEvery(EDITOR_ACTIONS.STOP_EDITING, stopEditingSaga);
|
||||
yield takeLatest(EDITOR_ACTIONS.TAKE_A_SHOT, takeAShotSaga);
|
||||
yield takeLatest(EDITOR_ACTIONS.CROP_A_SHOT, cropAShotSaga);
|
||||
yield takeLatest(EDITOR_ACTIONS.LOCATION_CHANGED, locationChangeSaga);
|
||||
yield takeLatest(EDITOR_ACTIONS.KEY_PRESSED, keyPressedSaga);
|
||||
yield takeLatest(EDITOR_ACTIONS.GET_GPX_TRACK, getGPXTrackSaga);
|
||||
}
|
7
src/redux/editor/selectors.ts
Normal file
7
src/redux/editor/selectors.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { IState } from "../store";
|
||||
|
||||
export const selectEditor = (state: IState) => state.editor;
|
||||
export const selectEditorEditing = (state: IState) => state.editor.editing;
|
||||
export const selectEditorMode = (state: IState) => state.editor.mode;
|
||||
export const selectEditorActiveSticker = (state: IState) => state.editor.activeSticker;
|
||||
export const selectEditorRenderer = (state: IState) => state.editor.renderer;
|
|
@ -68,3 +68,8 @@ export const mapSetLogo = (logo: IMapReducer['logo']) => ({
|
|||
type: MAP_ACTIONS.SET_LOGO,
|
||||
logo,
|
||||
});
|
||||
|
||||
export const mapSetAddressOrigin = (address_origin: IMapReducer['address_origin']) => ({
|
||||
type: MAP_ACTIONS.SET_ADDRESS_ORIGIN,
|
||||
address_origin,
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@ export const MAP_ACTIONS = {
|
|||
SET_TITLE: `${P}-SET_TILE`,
|
||||
SET_DESCRIPTION: `${P}-SETDESCRIPTION`,
|
||||
SET_ADDRESS: `${P}-SET_ADDRESS`,
|
||||
SET_ADDRESS_ORIGIN: `${P}-SET_ADDRESS_ORIGIN`,
|
||||
SET_OWNER: `${P}-SET_OWNER`,
|
||||
SET_PUBLIC: `${P}-SET_PUBLIC`,
|
||||
SET_LOGO: `${P}-SET_LOGO`,
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
mapSetOwner,
|
||||
mapSetPublic,
|
||||
mapSetLogo,
|
||||
mapSetAddressOrigin,
|
||||
} from './actions';
|
||||
|
||||
const setMap = (state: IMapReducer, { map }: ReturnType<typeof mapSet>): IMapReducer => ({
|
||||
|
@ -86,6 +87,11 @@ const setLogo = (state: IMapReducer, { logo }: ReturnType<typeof mapSetLogo>): I
|
|||
logo,
|
||||
});
|
||||
|
||||
const setAddressOrigin = (state, { address_origin }: ReturnType<typeof mapSetAddressOrigin>): IMapReducer => ({
|
||||
...state,
|
||||
address_origin
|
||||
});
|
||||
|
||||
export const MAP_HANDLERS = {
|
||||
[MAP_ACTIONS.SET_MAP]: setMap,
|
||||
[MAP_ACTIONS.SET_PROVIDER]: setProvider,
|
||||
|
@ -99,4 +105,5 @@ export const MAP_HANDLERS = {
|
|||
[MAP_ACTIONS.SET_OWNER]: setOwner,
|
||||
[MAP_ACTIONS.SET_PUBLIC]: setPublic,
|
||||
[MAP_ACTIONS.SET_LOGO]: setLogo,
|
||||
[MAP_ACTIONS.SET_ADDRESS_ORIGIN]: setAddressOrigin,
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@ export interface IMapReducer {
|
|||
title: string;
|
||||
logo: string;
|
||||
address: string;
|
||||
address_origin: string;
|
||||
description: string;
|
||||
owner: { id: string };
|
||||
is_public: boolean;
|
||||
|
@ -24,6 +25,7 @@ export const MAP_INITIAL_STATE: IMapReducer = {
|
|||
stickers: [],
|
||||
title: '',
|
||||
address: '',
|
||||
address_origin: '',
|
||||
description: '',
|
||||
owner: { id: null },
|
||||
is_public: false,
|
||||
|
|
|
@ -1,39 +1,58 @@
|
|||
import { takeEvery, select, put, call, TakeEffect, race, take, takeLatest } from 'redux-saga/effects';
|
||||
import {
|
||||
takeEvery,
|
||||
select,
|
||||
put,
|
||||
call,
|
||||
TakeEffect,
|
||||
race,
|
||||
take,
|
||||
takeLatest,
|
||||
} from 'redux-saga/effects';
|
||||
import { MAP_ACTIONS } from './constants';
|
||||
import { mapClicked, mapAddSticker, mapSetProvider, mapSet, mapSetTitle, mapSetAddress, mapSetDescription, mapSetOwner, mapSetPublic } from './actions';
|
||||
import { selectUserMode, selectUserActiveSticker, selectUser, selectUserUser } from '~/redux/user/selectors';
|
||||
import {
|
||||
mapClicked,
|
||||
mapAddSticker,
|
||||
mapSetProvider,
|
||||
mapSet,
|
||||
mapSetTitle,
|
||||
mapSetAddressOrigin,
|
||||
} from './actions';
|
||||
import { selectUser, selectUserUser } from '~/redux/user/selectors';
|
||||
import { MODES } from '~/constants/modes';
|
||||
import {
|
||||
setMode,
|
||||
setChanged,
|
||||
setAddressOrigin,
|
||||
setEditing,
|
||||
setReady,
|
||||
setActiveSticker,
|
||||
setSaveError,
|
||||
setSaveLoading,
|
||||
sendSaveRequest,
|
||||
setSaveSuccess,
|
||||
setSaveOverwrite,
|
||||
} from '~/redux/user/actions';
|
||||
editorSetMode,
|
||||
editorSetChanged,
|
||||
editorSetEditing,
|
||||
editorSetReady,
|
||||
editorSetActiveSticker,
|
||||
editorSetSaveError,
|
||||
editorSetSaveLoading,
|
||||
editorSendSaveRequest,
|
||||
editorSetSaveSuccess,
|
||||
editorSetSaveOverwrite,
|
||||
} from '~/redux/editor/actions';
|
||||
import { pushLoaderState, getUrlData, pushPath, replacePath } from '~/utils/history';
|
||||
import { setReadySaga, searchSetSagaWorker } from '~/redux/user/sagas';
|
||||
import { searchSetSagaWorker } from '~/redux/user/sagas';
|
||||
import { getStoredMap, postMap } from '~/utils/api';
|
||||
import { Unwrap } from '~/utils/middleware';
|
||||
import { DEFAULT_PROVIDER } from '~/constants/providers';
|
||||
import { USER_ACTIONS } from '~/redux/user/constants';
|
||||
import { selectMap } from './selectors';
|
||||
import { selectMap, selectMapProvider } from './selectors';
|
||||
import { TIPS } from '~/constants/tips';
|
||||
import { delay } from 'redux-saga';
|
||||
import { setReadySaga } from '../editor/sagas';
|
||||
import { selectEditor } from '../editor/selectors';
|
||||
import { EDITOR_ACTIONS } from '../editor/constants';
|
||||
|
||||
function* onMapClick({ latlng }: ReturnType<typeof mapClicked>) {
|
||||
const mode = yield select(selectUserMode);
|
||||
const { set, sticker } = yield select(selectUserActiveSticker);
|
||||
const {
|
||||
mode,
|
||||
activeSticker: { set, sticker },
|
||||
}: ReturnType<typeof selectEditor> = yield select(selectEditor);
|
||||
|
||||
switch (mode) {
|
||||
case MODES.STICKERS:
|
||||
yield put(mapAddSticker({ latlng, set, sticker, text: '', angle: 0 }));
|
||||
yield put(setMode(MODES.NONE));
|
||||
yield put(editorSetMode(MODES.NONE));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -64,7 +83,7 @@ function* onMapClick({ latlng }: ReturnType<typeof mapClicked>) {
|
|||
|
||||
export function* replaceAddressIfItsBusy(destination, original) {
|
||||
if (original) {
|
||||
yield put(setAddressOrigin(original));
|
||||
yield put(mapSetAddressOrigin(original));
|
||||
}
|
||||
|
||||
pushPath(`/${destination}/edit`);
|
||||
|
@ -97,14 +116,15 @@ export function* loadMapSaga(path) {
|
|||
function* startEmptyEditorSaga() {
|
||||
const {
|
||||
user: { id, random_url },
|
||||
provider = DEFAULT_PROVIDER,
|
||||
} = yield select(selectUser);
|
||||
}: ReturnType<typeof selectUser> = yield select(selectUser);
|
||||
|
||||
const provider: ReturnType<typeof selectMapProvider> = yield select(selectMapProvider);
|
||||
|
||||
// TODO: set owner { id }
|
||||
pushPath(`/${random_url}/edit`);
|
||||
|
||||
yield put(setChanged(false));
|
||||
yield put(setEditing(true));
|
||||
yield put(editorSetChanged(false));
|
||||
yield put(editorSetEditing(true));
|
||||
|
||||
return yield call(setReadySaga);
|
||||
}
|
||||
|
@ -114,9 +134,9 @@ export function* mapInitSaga() {
|
|||
|
||||
const { path, mode, hash } = getUrlData();
|
||||
const {
|
||||
provider,
|
||||
user: { id },
|
||||
} = yield select(selectUser);
|
||||
}: ReturnType<typeof selectUser> = yield select(selectUser);
|
||||
const provider: ReturnType<typeof selectMapProvider> = yield select(selectMapProvider);
|
||||
|
||||
yield put(mapSetProvider(provider));
|
||||
|
||||
|
@ -139,14 +159,12 @@ export function* mapInitSaga() {
|
|||
yield call(setReadySaga);
|
||||
yield call(replaceAddressIfItsBusy, map.random_url, map.address);
|
||||
} else {
|
||||
yield put(setAddressOrigin(''));
|
||||
yield put(mapSetAddressOrigin(''));
|
||||
}
|
||||
|
||||
yield put(setEditing(true));
|
||||
// TODO: start editing
|
||||
yield put(editorSetEditing(true));
|
||||
} else {
|
||||
yield put(setEditing(false));
|
||||
// TODO: stop editing
|
||||
yield put(editorSetEditing(false));
|
||||
}
|
||||
|
||||
yield call(setReadySaga);
|
||||
|
@ -155,7 +173,7 @@ export function* mapInitSaga() {
|
|||
}
|
||||
|
||||
yield call(startEmptyEditorSaga);
|
||||
yield put(setReady(true));
|
||||
yield put(editorSetReady(true));
|
||||
|
||||
pushLoaderState(100);
|
||||
|
||||
|
@ -163,7 +181,7 @@ export function* mapInitSaga() {
|
|||
}
|
||||
|
||||
function* setActiveStickerSaga() {
|
||||
yield put(setMode(MODES.STICKERS));
|
||||
yield put(editorSetMode(MODES.STICKERS));
|
||||
}
|
||||
|
||||
function* setTitleSaga({ title }: ReturnType<typeof mapSetTitle>) {
|
||||
|
@ -172,10 +190,14 @@ function* setTitleSaga({ title }: ReturnType<typeof mapSetTitle>) {
|
|||
}
|
||||
}
|
||||
|
||||
function* startEditingSaga() {
|
||||
const { path } = getUrlData();
|
||||
yield pushPath(`/${path}/edit`);
|
||||
}
|
||||
|
||||
function* clearSaga({ type }) {
|
||||
switch (type) {
|
||||
case USER_ACTIONS.CLEAR_POLY:
|
||||
// TODO: clear router waypoints
|
||||
case EDITOR_ACTIONS.CLEAR_POLY:
|
||||
yield put(
|
||||
mapSet({
|
||||
route: [],
|
||||
|
@ -183,7 +205,7 @@ function* clearSaga({ type }) {
|
|||
);
|
||||
break;
|
||||
|
||||
case USER_ACTIONS.CLEAR_STICKERS:
|
||||
case EDITOR_ACTIONS.CLEAR_STICKERS:
|
||||
yield put(
|
||||
mapSet({
|
||||
stickers: [],
|
||||
|
@ -191,8 +213,8 @@ function* clearSaga({ type }) {
|
|||
);
|
||||
break;
|
||||
|
||||
case USER_ACTIONS.CLEAR_ALL:
|
||||
yield put(setChanged(false));
|
||||
case EDITOR_ACTIONS.CLEAR_ALL:
|
||||
yield put(editorSetChanged(false));
|
||||
yield put(
|
||||
mapSet({
|
||||
route: [],
|
||||
|
@ -205,8 +227,8 @@ function* clearSaga({ type }) {
|
|||
break;
|
||||
}
|
||||
|
||||
yield put(setActiveSticker(null)); // TODO: move to maps
|
||||
yield put(setMode(MODES.NONE));
|
||||
yield put(editorSetActiveSticker(null));
|
||||
yield put(editorSetMode(MODES.NONE));
|
||||
}
|
||||
|
||||
function* sendSaveRequestSaga({
|
||||
|
@ -215,17 +237,18 @@ function* sendSaveRequestSaga({
|
|||
force,
|
||||
is_public,
|
||||
description,
|
||||
}: ReturnType<typeof sendSaveRequest>) {
|
||||
const { route, stickers, provider } = yield select(selectMap);
|
||||
}: ReturnType<typeof editorSendSaveRequest>) {
|
||||
const { route, stickers, provider }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
|
||||
if (!route.length && !stickers.length) {
|
||||
return yield put(setSaveError(TIPS.SAVE_EMPTY)); // TODO: move setSaveError to editor
|
||||
return yield put(editorSetSaveError(TIPS.SAVE_EMPTY));
|
||||
}
|
||||
|
||||
const { logo, distance } = yield select(selectUser);
|
||||
const { token } = yield select(selectUserUser);
|
||||
const { logo }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
const { distance }: ReturnType<typeof selectEditor> = yield select(selectEditor);
|
||||
const { token }: ReturnType<typeof selectUserUser> = yield select(selectUserUser);
|
||||
|
||||
yield put(setSaveLoading(true)); // TODO: move setSaveLoading to maps
|
||||
yield put(editorSetSaveLoading(true));
|
||||
|
||||
const {
|
||||
result,
|
||||
|
@ -250,20 +273,21 @@ function* sendSaveRequestSaga({
|
|||
description,
|
||||
}),
|
||||
timeout: delay(10000),
|
||||
cancel: take(USER_ACTIONS.RESET_SAVE_DIALOG),
|
||||
cancel: take(EDITOR_ACTIONS.RESET_SAVE_DIALOG),
|
||||
});
|
||||
|
||||
yield put(setSaveLoading(false));
|
||||
yield put(editorSetSaveLoading(false));
|
||||
|
||||
if (cancel) return yield put(setMode(MODES.NONE));
|
||||
if (cancel) return yield put(editorSetMode(MODES.NONE));
|
||||
|
||||
if (result && result.data.code === 'already_exist') return yield put(setSaveOverwrite()); // TODO: move setSaveOverwrite to editor
|
||||
if (result && result.data.code === 'conflict') return yield put(setSaveError(TIPS.SAVE_EXISTS));
|
||||
if (result && result.data.code === 'already_exist') return yield put(editorSetSaveOverwrite());
|
||||
if (result && result.data.code === 'conflict')
|
||||
return yield put(editorSetSaveError(TIPS.SAVE_EXISTS));
|
||||
if (timeout || !result || !result.data.route || !result.data.route.address)
|
||||
return yield put(setSaveError(TIPS.SAVE_TIMED_OUT));
|
||||
return yield put(editorSetSaveError(TIPS.SAVE_TIMED_OUT));
|
||||
|
||||
return yield put( // TODO: move setSaveSuccess to editor
|
||||
setSaveSuccess({
|
||||
return yield put(
|
||||
editorSetSaveSuccess({
|
||||
address: result.data.route.address,
|
||||
title: result.data.route.title,
|
||||
is_public: result.data.route.is_public,
|
||||
|
@ -279,18 +303,23 @@ function* setSaveSuccessSaga({
|
|||
title,
|
||||
is_public,
|
||||
description,
|
||||
}: ReturnType<typeof setSaveSuccess>) {
|
||||
const { id } = yield select(selectUser);
|
||||
const { dialog_active } = yield select(selectUser);
|
||||
}: ReturnType<typeof editorSetSaveSuccess>) {
|
||||
const { id }: ReturnType<typeof selectUserUser> = yield select(selectUserUser);
|
||||
const { dialog_active }: ReturnType<typeof selectEditor> = yield select(selectEditor);
|
||||
|
||||
replacePath(`/${address}/edit`);
|
||||
|
||||
yield put(mapSetTitle(title));
|
||||
yield put(mapSetAddress(address));
|
||||
yield put(mapSetPublic(is_public));
|
||||
yield put(mapSetDescription(description));
|
||||
yield put(setChanged(false));
|
||||
yield put(mapSetOwner({ id }));
|
||||
yield put(
|
||||
mapSet({
|
||||
title,
|
||||
address,
|
||||
is_public,
|
||||
description,
|
||||
owner: { id },
|
||||
})
|
||||
);
|
||||
|
||||
yield put(editorSetChanged(false));
|
||||
|
||||
if (dialog_active) {
|
||||
yield call(searchSetSagaWorker);
|
||||
|
@ -298,27 +327,25 @@ function* setSaveSuccessSaga({
|
|||
|
||||
// yield editor.setInitialData();
|
||||
// TODO: set initial data here
|
||||
|
||||
return
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
export function* mapSaga() {
|
||||
// TODO: setChanged on set route, logo, provider, stickers
|
||||
|
||||
yield takeEvery(USER_ACTIONS.SET_ACTIVE_STICKER, setActiveStickerSaga); // TODO: move active sticker to maps
|
||||
yield takeEvery(EDITOR_ACTIONS.START_EDITING, startEditingSaga);
|
||||
yield takeEvery(EDITOR_ACTIONS.SET_ACTIVE_STICKER, setActiveStickerSaga);
|
||||
yield takeEvery(MAP_ACTIONS.MAP_CLICKED, onMapClick);
|
||||
yield takeEvery(MAP_ACTIONS.SET_TITLE, setTitleSaga);
|
||||
// yield takeEvery(USER_ACTIONS.SET_LOGO, setLogoSaga);
|
||||
yield takeLatest(USER_ACTIONS.SEND_SAVE_REQUEST, sendSaveRequestSaga);
|
||||
yield takeLatest(USER_ACTIONS.SET_SAVE_SUCCESS, setSaveSuccessSaga);
|
||||
yield takeLatest(EDITOR_ACTIONS.SEND_SAVE_REQUEST, sendSaveRequestSaga);
|
||||
yield takeLatest(EDITOR_ACTIONS.SET_SAVE_SUCCESS, setSaveSuccessSaga);
|
||||
|
||||
yield takeEvery(
|
||||
// TODO: move all actions to MAP
|
||||
[
|
||||
USER_ACTIONS.CLEAR_POLY,
|
||||
USER_ACTIONS.CLEAR_STICKERS,
|
||||
USER_ACTIONS.CLEAR_ALL,
|
||||
USER_ACTIONS.CLEAR_CANCEL,
|
||||
EDITOR_ACTIONS.CLEAR_POLY,
|
||||
EDITOR_ACTIONS.CLEAR_STICKERS,
|
||||
EDITOR_ACTIONS.CLEAR_ALL,
|
||||
EDITOR_ACTIONS.CLEAR_CANCEL,
|
||||
],
|
||||
clearSaga
|
||||
);
|
||||
|
|
|
@ -4,13 +4,20 @@ import { persistStore, persistReducer } from 'redux-persist';
|
|||
import storage from 'redux-persist/lib/storage';
|
||||
import createSagaMiddleware from 'redux-saga';
|
||||
|
||||
|
||||
import { createBrowserHistory } from 'history';
|
||||
import { editorLocationChanged } from '~/redux/editor/actions';
|
||||
import { PersistConfig, Persistor } from "redux-persist/es/types";
|
||||
|
||||
|
||||
import { userReducer, IRootReducer } from '~/redux/user';
|
||||
import { userSaga } from '~/redux/user/sagas';
|
||||
import { mapSaga } from '~/redux/map/sagas';
|
||||
import { createBrowserHistory } from 'history';
|
||||
import { locationChanged } from '~/redux/user/actions';
|
||||
import { PersistConfig, Persistor } from "redux-persist/es/types";
|
||||
|
||||
import { editor, IEditorState } from '~/redux/editor';
|
||||
import { editorSaga } from '~/redux/editor/sagas';
|
||||
|
||||
import { map, IMapReducer } from '~/redux/map';
|
||||
import { mapSaga } from '~/redux/map/sagas';
|
||||
|
||||
const userPersistConfig: PersistConfig = {
|
||||
key: 'user',
|
||||
|
@ -21,6 +28,7 @@ const userPersistConfig: PersistConfig = {
|
|||
export interface IState {
|
||||
user: IRootReducer
|
||||
map: IMapReducer,
|
||||
editor: IEditorState,
|
||||
}
|
||||
// create the saga middleware
|
||||
export const sagaMiddleware = createSagaMiddleware();
|
||||
|
@ -36,14 +44,15 @@ export const store = createStore(
|
|||
combineReducers({
|
||||
user: persistReducer(userPersistConfig, userReducer),
|
||||
map,
|
||||
// routing: routerReducer
|
||||
editor,
|
||||
}),
|
||||
composeEnhancers(applyMiddleware(/* routerMiddleware(history), */ sagaMiddleware))
|
||||
composeEnhancers(applyMiddleware(sagaMiddleware))
|
||||
);
|
||||
|
||||
export function configureStore(): { store: Store<any>, persistor: Persistor } {
|
||||
sagaMiddleware.run(userSaga);
|
||||
sagaMiddleware.run(mapSaga);
|
||||
sagaMiddleware.run(editorSaga);
|
||||
|
||||
const persistor = persistStore(store);
|
||||
|
||||
|
@ -54,5 +63,5 @@ export const history = createBrowserHistory();
|
|||
|
||||
history.listen((location, action) => {
|
||||
if (action === 'REPLACE') return;
|
||||
store.dispatch(locationChanged(location.pathname));
|
||||
store.dispatch(editorLocationChanged(location.pathname));
|
||||
});
|
||||
|
|
|
@ -1,81 +1,81 @@
|
|||
import { USER_ACTIONS } from '~/redux/user/constants';
|
||||
import { IUser } from "~/constants/auth";
|
||||
import { IRootState } from "~/redux/user";
|
||||
import { IRoute } from '~/redux/map/types';
|
||||
// import { IRootState } from "~/redux/user";
|
||||
// import { IRoute } from '~/redux/map/types';
|
||||
|
||||
export const setUser = (user: IUser) => ({ type: USER_ACTIONS.SET_USER, user });
|
||||
export const userLogout = () => ({ type: USER_ACTIONS.USER_LOGOUT });
|
||||
|
||||
export const setEditing = (editing: IRootState['editing']) => ({ type: USER_ACTIONS.SET_EDITING, editing });
|
||||
export const setMode = (mode: IRootState['mode']) => ({ type: USER_ACTIONS.SET_MODE, mode });
|
||||
export const setDistance = (distance: IRootState['distance']) => ({ type: USER_ACTIONS.SET_DISTANCE, distance });
|
||||
export const setChanged = (changed: IRootState['changed']) => ({ type: USER_ACTIONS.SET_CHANGED, changed });
|
||||
export const setRouterPoints = routerPoints => ({ type: USER_ACTIONS.SET_ROUTER_POINTS, routerPoints });
|
||||
export const setActiveSticker = activeSticker => ({ type: USER_ACTIONS.SET_ACTIVE_STICKER, activeSticker });
|
||||
// export const setEditing = (editing: IRootState['editing']) => ({ type: USER_ACTIONS.SET_EDITING, editing });
|
||||
// export const setMode = (mode: IRootState['mode']) => ({ type: USER_ACTIONS.SET_MODE, mode });
|
||||
// export const setDistance = (distance: IRootState['distance']) => ({ type: USER_ACTIONS.SET_DISTANCE, distance });
|
||||
// export const setChanged = (changed: IRootState['changed']) => ({ type: USER_ACTIONS.SET_CHANGED, changed });
|
||||
// export const setRouterPoints = routerPoints => ({ type: USER_ACTIONS.SET_ROUTER_POINTS, routerPoints });
|
||||
// export const setActiveSticker = activeSticker => ({ type: USER_ACTIONS.SET_ACTIVE_STICKER, activeSticker });
|
||||
// export const setLogo = logo => ({ type: USER_ACTIONS.SET_LOGO, logo });
|
||||
// export const setTitle = title => ({ type: USER_ACTIONS.SET_TITLE, title });
|
||||
// export const setDescription = description => ({ type: USER_ACTIONS.SET_DESCRIPTION, description });
|
||||
// export const setAddress = address => ({ type: USER_ACTIONS.SET_ADDRESS, address });
|
||||
export const setAddressOrigin = address_origin => ({ type: USER_ACTIONS.SET_ADDRESS_ORIGIN, address_origin });
|
||||
// export const setAddressOrigin = address_origin => ({ type: USER_ACTIONS.SET_ADDRESS_ORIGIN, address_origin });
|
||||
// export const setPublic = is_public => ({ type: USER_ACTIONS.SET_PUBLIC, is_public });
|
||||
export const setStarred = is_published => ({ type: USER_ACTIONS.SET_STARRED, is_published });
|
||||
export const setSpeed = speed => ({ type: USER_ACTIONS.SET_SPEED, speed });
|
||||
// export const setSpeed = speed => ({ type: USER_ACTIONS.SET_SPEED, speed });
|
||||
|
||||
export const startEditing = () => ({ type: USER_ACTIONS.START_EDITING });
|
||||
export const stopEditing = () => ({ type: USER_ACTIONS.STOP_EDITING });
|
||||
// export const startEditing = () => ({ type: USER_ACTIONS.START_EDITING });
|
||||
// export const stopEditing = () => ({ type: USER_ACTIONS.STOP_EDITING });
|
||||
|
||||
export const routerCancel = () => ({ type: USER_ACTIONS.ROUTER_CANCEL });
|
||||
export const routerSubmit = () => ({ type: USER_ACTIONS.ROUTER_SUBMIT });
|
||||
// export const routerCancel = () => ({ type: USER_ACTIONS.ROUTER_CANCEL });
|
||||
// export const routerSubmit = () => ({ type: USER_ACTIONS.ROUTER_SUBMIT });
|
||||
|
||||
export const clearPoly = () => ({ type: USER_ACTIONS.CLEAR_POLY });
|
||||
export const clearStickers = () => ({ type: USER_ACTIONS.CLEAR_STICKERS });
|
||||
export const clearAll = () => ({ type: USER_ACTIONS.CLEAR_ALL });
|
||||
export const clearCancel = () => ({ type: USER_ACTIONS.CLEAR_CANCEL });
|
||||
// export const clearPoly = () => ({ type: USER_ACTIONS.CLEAR_POLY });
|
||||
// export const clearStickers = () => ({ type: USER_ACTIONS.CLEAR_STICKERS });
|
||||
// export const clearAll = () => ({ type: USER_ACTIONS.CLEAR_ALL });
|
||||
// export const clearCancel = () => ({ type: USER_ACTIONS.CLEAR_CANCEL });
|
||||
|
||||
export const sendSaveRequest = (payload: {
|
||||
title: IRoute['title'],
|
||||
address: IRoute['address'],
|
||||
is_public: IRoute['is_public'],
|
||||
description: IRoute['description'],
|
||||
force: boolean,
|
||||
}) => ({
|
||||
type: USER_ACTIONS.SEND_SAVE_REQUEST,
|
||||
...payload,
|
||||
});
|
||||
// export const sendSaveRequest = (payload: {
|
||||
// title: IRoute['title'],
|
||||
// address: IRoute['address'],
|
||||
// is_public: IRoute['is_public'],
|
||||
// description: IRoute['description'],
|
||||
// force: boolean,
|
||||
// }) => ({
|
||||
// type: USER_ACTIONS.SEND_SAVE_REQUEST,
|
||||
// ...payload,
|
||||
// });
|
||||
|
||||
export const resetSaveDialog = () => ({ type: USER_ACTIONS.RESET_SAVE_DIALOG });
|
||||
// export const resetSaveDialog = () => ({ type: USER_ACTIONS.RESET_SAVE_DIALOG });
|
||||
|
||||
export const setSaveLoading = (save_loading: IRootState['save_loading']) => ({ type: USER_ACTIONS.SET_SAVE_LOADING, save_loading });
|
||||
// export const setSaveLoading = (save_loading: IRootState['save_loading']) => ({ type: USER_ACTIONS.SET_SAVE_LOADING, save_loading });
|
||||
|
||||
export const setSaveSuccess = (payload: {
|
||||
address: IRoute['address'],
|
||||
title: IRoute['address'],
|
||||
is_public: IRoute['is_public'],
|
||||
description: IRoute['description'],
|
||||
// export const setSaveSuccess = (payload: {
|
||||
// address: IRoute['address'],
|
||||
// title: IRoute['address'],
|
||||
// is_public: IRoute['is_public'],
|
||||
// description: IRoute['description'],
|
||||
|
||||
save_error: string,
|
||||
}) => ({ type: USER_ACTIONS.SET_SAVE_SUCCESS, ...payload });
|
||||
// save_error: string,
|
||||
// }) => ({ type: USER_ACTIONS.SET_SAVE_SUCCESS, ...payload });
|
||||
|
||||
export const setSaveError = (save_error: IRootState['save_error']) => ({ type: USER_ACTIONS.SET_SAVE_ERROR, save_error });
|
||||
export const setSaveOverwrite = () => ({ type: USER_ACTIONS.SET_SAVE_OVERWRITE });
|
||||
// export const setSaveError = (save_error: IRootState['save_error']) => ({ type: USER_ACTIONS.SET_SAVE_ERROR, save_error });
|
||||
// export const setSaveOverwrite = () => ({ type: USER_ACTIONS.SET_SAVE_OVERWRITE });
|
||||
|
||||
export const hideRenderer = () => ({ type: USER_ACTIONS.HIDE_RENDERER });
|
||||
export const setRenderer = payload => ({ type: USER_ACTIONS.SET_RENDERER, payload });
|
||||
export const takeAShot = () => ({ type: USER_ACTIONS.TAKE_A_SHOT });
|
||||
export const cropAShot = payload => ({ type: USER_ACTIONS.CROP_A_SHOT, ...payload });
|
||||
// export const hideRenderer = () => ({ type: USER_ACTIONS.HIDE_RENDERER });
|
||||
// export const setRenderer = payload => ({ type: USER_ACTIONS.SET_RENDERER, payload });
|
||||
// export const takeAShot = () => ({ type: USER_ACTIONS.TAKE_A_SHOT });
|
||||
// export const cropAShot = payload => ({ type: USER_ACTIONS.CROP_A_SHOT, ...payload });
|
||||
|
||||
// export const setProvider = provider => ({ type: USER_ACTIONS.SET_PROVIDER, provider });
|
||||
// export const changeProvider = provider => ({ type: USER_ACTIONS.CHANGE_PROVIDER, provider });
|
||||
|
||||
export const setDialog = dialog => ({ type: USER_ACTIONS.SET_DIALOG, dialog });
|
||||
export const setDialogActive = dialog_active => ({ type: USER_ACTIONS.SET_DIALOG_ACTIVE, dialog_active });
|
||||
// export const setDialog = dialog => ({ type: USER_ACTIONS.SET_DIALOG, dialog });
|
||||
// export const setDialogActive = dialog_active => ({ type: USER_ACTIONS.SET_DIALOG_ACTIVE, dialog_active });
|
||||
export const openMapDialog = tab => ({ type: USER_ACTIONS.OPEN_MAP_DIALOG, tab });
|
||||
|
||||
export const locationChanged = location => ({ type: USER_ACTIONS.LOCATION_CHANGED, location });
|
||||
export const setReady = ready => ({ type: USER_ACTIONS.SET_READY, ready });
|
||||
// export const locationChanged = location => ({ type: USER_ACTIONS.LOCATION_CHANGED, location });
|
||||
// export const setReady = ready => ({ type: USER_ACTIONS.SET_READY, ready });
|
||||
|
||||
export const gotVkUser = user => ({ type: USER_ACTIONS.GOT_VK_USER, user });
|
||||
export const keyPressed = ({ key, target: { tagName } }) => ({ type: USER_ACTIONS.KEY_PRESSED, key, target: tagName });
|
||||
// export const keyPressed = ({ key, target: { tagName } }) => ({ type: USER_ACTIONS.KEY_PRESSED, key, target: tagName });
|
||||
|
||||
export const searchSetTitle = title => ({ type: USER_ACTIONS.SEARCH_SET_TITLE, title });
|
||||
export const searchSetDistance = distance => ({ type: USER_ACTIONS.SEARCH_SET_DISTANCE, distance });
|
||||
|
@ -85,15 +85,15 @@ export const searchSetLoading = loading => ({ type: USER_ACTIONS.SEARCH_SET_LOAD
|
|||
|
||||
export const searchPutRoutes = payload => ({ type: USER_ACTIONS.SEARCH_PUT_ROUTES, ...payload });
|
||||
|
||||
export const setMarkersShown = markers_shown => ({ type: USER_ACTIONS.SET_MARKERS_SHOWN, markers_shown });
|
||||
export const getGPXTrack = () => ({ type: USER_ACTIONS.GET_GPX_TRACK });
|
||||
export const setIsEmpty = is_empty => ({ type: USER_ACTIONS.SET_IS_EMPTY, is_empty });
|
||||
// export const getGPXTrack = () => ({ type: USER_ACTIONS.GET_GPX_TRACK });
|
||||
// export const setMarkersShown = markers_shown => ({ type: USER_ACTIONS.SET_MARKERS_SHOWN, markers_shown });
|
||||
// export const setIsEmpty = is_empty => ({ type: USER_ACTIONS.SET_IS_EMPTY, is_empty });
|
||||
|
||||
export const mapsLoadMore = () => ({ type: USER_ACTIONS.MAPS_LOAD_MORE });
|
||||
export const mapsSetShift = (shift: number) => ({ type: USER_ACTIONS.MAPS_SET_SHIFT, shift });
|
||||
|
||||
export const setFeature = (features: { [x: string]: boolean }) => ({ type: USER_ACTIONS.SET_FEATURE, features });
|
||||
export const setIsRouting = (is_routing: boolean) => ({ type: USER_ACTIONS.SET_IS_ROUTING, is_routing });
|
||||
// export const setFeature = (features: { [x: string]: boolean }) => ({ type: USER_ACTIONS.SET_FEATURE, features });
|
||||
// export const setIsRouting = (is_routing: boolean) => ({ type: USER_ACTIONS.SET_IS_ROUTING, is_routing });
|
||||
|
||||
export const dropRoute = (address: string) => ({ type: USER_ACTIONS.DROP_ROUTE, address });
|
||||
export const modifyRoute = (address: string, { title, is_public }: { title: string, is_public: boolean }) => ({
|
||||
|
|
|
@ -1,61 +1,7 @@
|
|||
export interface IActions {
|
||||
[x: string]: string,
|
||||
}
|
||||
|
||||
export const USER_ACTIONS: IActions = {
|
||||
export const USER_ACTIONS = {
|
||||
SET_USER: 'SET_USER',
|
||||
USER_LOGOUT: 'USER_LOGOUT',
|
||||
|
||||
SET_EDITING: 'SET_EDITING',
|
||||
SET_MODE: 'SET_MODE',
|
||||
SET_DISTANCE: 'SET_DISTANCE',
|
||||
SET_CHANGED: 'SET_CHANGED',
|
||||
SET_ROUTER_POINTS: 'SET_ROUTER_POINTS',
|
||||
SET_ACTIVE_STICKER: 'SET_ACTIVE_STICKER',
|
||||
SET_LOGO: 'SET_LOGO',
|
||||
SET_TITLE: 'SET_TITLE',
|
||||
SET_ADDRESS: 'SET_ADDRESS',
|
||||
SET_ADDRESS_ORIGIN: 'SET_ADDRESS_ORIGIN',
|
||||
SET_PUBLIC: 'SET_PUBLIC',
|
||||
SET_STARRED: 'SET_STARRED',
|
||||
SET_DESCRIPTION: 'SET_DESCRIPTION',
|
||||
|
||||
START_EDITING: 'START_EDITING',
|
||||
STOP_EDITING: 'STOP_EDITING',
|
||||
|
||||
ROUTER_CANCEL: 'ROUTER_CANCEL',
|
||||
ROUTER_SUBMIT: 'ROUTER_SUBMIT',
|
||||
|
||||
CLEAR_POLY: 'CLEAR_POLY',
|
||||
CLEAR_STICKERS: 'CLEAR_STICKERS',
|
||||
CLEAR_ALL: 'CLEAR_ALL',
|
||||
CLEAR_CANCEL: 'CLEAR_CANCEL',
|
||||
|
||||
SEND_SAVE_REQUEST: 'SEND_SAVE_REQUEST',
|
||||
SET_SAVE_LOADING: 'SET_SAVE_LOADING',
|
||||
CANCEL_SAVE_REQUEST: 'CANCEL_SAVE_REQUEST',
|
||||
RESET_SAVE_DIALOG: 'RESET_SAVE_DIALOG',
|
||||
|
||||
SET_SAVE_SUCCESS: 'SET_SAVE_SUCCESS',
|
||||
SET_SAVE_ERROR: 'SET_SAVE_ERROR',
|
||||
SET_SAVE_OVERWRITE: 'SET_SAVE_OVERWRITE',
|
||||
|
||||
SHOW_RENDERER: 'SHOW_RENDERER',
|
||||
HIDE_RENDERER: 'HIDE_RENDERER',
|
||||
SET_RENDERER: 'SET_RENDERER',
|
||||
TAKE_A_SHOT: 'TAKE_A_SHOT',
|
||||
CROP_A_SHOT: 'CROP_A_SHOT',
|
||||
|
||||
SET_PROVIDER: 'SET_PROVIDER',
|
||||
CHANGE_PROVIDER: 'CHANGE_PROVIDER',
|
||||
|
||||
SET_DIALOG: 'SET_DIALOG',
|
||||
SET_DIALOG_ACTIVE: 'SET_DIALOG_ACTIVE',
|
||||
LOCATION_CHANGED: 'LOCATION_CHANGED',
|
||||
SET_READY: 'SET_READY',
|
||||
|
||||
GOT_VK_USER: 'GOT_VK_USER',
|
||||
KEY_PRESSED: 'KEY_PRESSED',
|
||||
|
||||
IFRAME_LOGIN_VK: 'IFRAME_LOGIN_VK',
|
||||
|
||||
|
@ -68,21 +14,13 @@ export const USER_ACTIONS: IActions = {
|
|||
SEARCH_SET_LOADING: 'SEARCH_SET_LOADING',
|
||||
|
||||
OPEN_MAP_DIALOG: 'OPEN_MAP_DIALOG',
|
||||
SET_SPEED: 'SET_SPEED',
|
||||
|
||||
SET_MARKERS_SHOWN: 'SET_MARKERS_SHOWN',
|
||||
|
||||
GET_GPX_TRACK: 'GET_GPX_TRACK',
|
||||
SET_IS_EMPTY: 'SET_IS_EMPTY',
|
||||
|
||||
MAPS_LOAD_MORE: 'MAPS_LOAD_MORE',
|
||||
MAPS_SET_SHIFT: 'MAPS_SET_SHIFT',
|
||||
|
||||
SET_FEATURE: 'SET_FEATURE',
|
||||
SET_IS_ROUTING: 'SET_IS_ROUTING',
|
||||
|
||||
DROP_ROUTE: 'DROP_ROUTE',
|
||||
SET_STARRED: 'SET_STARRED',
|
||||
MODIFY_ROUTE: 'MODIFY_ROUTE',
|
||||
|
||||
SET_ROUTE_STARRED: 'SET_ROUTE_STARRED',
|
||||
TOGGLE_ROUTE_STARRED: 'TOGGLE_ROUTE_STARRED',
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { IRootState } from ".";
|
||||
import * as ActionCreators from './actions'
|
||||
import { TIPS } from "~/constants/tips";
|
||||
import { TABS } from "~/constants/dialogs";
|
||||
import { USER_ACTIONS } from "./constants";
|
||||
|
||||
|
@ -10,11 +9,6 @@ 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: {
|
||||
|
@ -23,121 +17,6 @@ const setUser: ActionHandler<typeof ActionCreators.setUser> = (state, { 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 setDescription: ActionHandler<typeof ActionCreators.setDescription> = (state, { description }) => ({
|
||||
// ...state,
|
||||
// description
|
||||
// });
|
||||
|
||||
// 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 setSaveLoading: ActionHandler<typeof ActionCreators.setSaveLoading> = (state, { save_loading }) => ({
|
||||
...state, save_loading
|
||||
});
|
||||
|
||||
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 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: {
|
||||
|
@ -199,17 +78,8 @@ const searchSetLoading: ActionHandler<typeof ActionCreators.searchSetLoading> =
|
|||
}
|
||||
});
|
||||
|
||||
// const setPublic: ActionHandler<typeof ActionCreators.setPublic> = (state, { is_public = false }) => ({ ...state, is_public });
|
||||
const setStarred: ActionHandler<typeof ActionCreators.setStarred> = (state, { is_published = false }) => ({ ...state, is_published });
|
||||
|
||||
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 setIsEmpty: ActionHandler<typeof ActionCreators.setIsEmpty> = (state, { is_empty = true }) => ({ ...state, is_empty });
|
||||
const mapsSetShift: ActionHandler<typeof ActionCreators.mapsSetShift> = (state, { shift = 0 }) => ({
|
||||
...state,
|
||||
routes: {
|
||||
|
@ -218,19 +88,6 @@ const mapsSetShift: ActionHandler<typeof ActionCreators.mapsSetShift> = (state,
|
|||
}
|
||||
});
|
||||
|
||||
const setFeature: ActionHandler<typeof ActionCreators.setFeature> = (state, { features }) => ({
|
||||
...state,
|
||||
features: {
|
||||
...state.features,
|
||||
...features,
|
||||
}
|
||||
});
|
||||
|
||||
const setIsRouting: ActionHandler<typeof ActionCreators.setIsRouting> = (state, { is_routing }) => ({
|
||||
...state,
|
||||
is_routing,
|
||||
});
|
||||
|
||||
const setRouteStarred: ActionHandler<typeof ActionCreators.setRouteStarred> = (state, { address, is_published }) => ({
|
||||
...state,
|
||||
routes: {
|
||||
|
@ -248,33 +105,6 @@ const setRouteStarred: ActionHandler<typeof ActionCreators.setRouteStarred> = (s
|
|||
|
||||
export const USER_HANDLERS = ({
|
||||
[USER_ACTIONS.SET_USER]: setUser,
|
||||
[USER_ACTIONS.SET_EDITING]: setEditing,
|
||||
[USER_ACTIONS.SET_CHANGED]: setChanged,
|
||||
[USER_ACTIONS.SET_MODE]: setMode,
|
||||
[USER_ACTIONS.SET_DISTANCE]: setDistance,
|
||||
[USER_ACTIONS.SET_ROUTER_POINTS]: setRouterPoints,
|
||||
[USER_ACTIONS.SET_ACTIVE_STICKER]: setActiveSticker,
|
||||
// [USER_ACTIONS.SET_LOGO]: setLogo,
|
||||
// [USER_ACTIONS.SET_TITLE]: setTitle,
|
||||
// [USER_ACTIONS.SET_DESCRIPTION]: setDescription,
|
||||
// [USER_ACTIONS.SET_ADDRESS]: setAddress,
|
||||
[USER_ACTIONS.SET_ADDRESS_ORIGIN]: setAddressOrigin,
|
||||
|
||||
[USER_ACTIONS.SET_SAVE_ERROR]: setSaveError,
|
||||
[USER_ACTIONS.SET_SAVE_LOADING]: setSaveLoading,
|
||||
[USER_ACTIONS.SET_SAVE_OVERWRITE]: setSaveOverwrite,
|
||||
[USER_ACTIONS.SET_SAVE_SUCCESS]: setSaveSuccess,
|
||||
[USER_ACTIONS.SEND_SAVE_REQUEST]: sendSaveRequest,
|
||||
[USER_ACTIONS.RESET_SAVE_DIALOG]: resetSaveDialog,
|
||||
|
||||
[USER_ACTIONS.HIDE_RENDERER]: hideRenderer,
|
||||
[USER_ACTIONS.SET_RENDERER]: setRenderer,
|
||||
|
||||
// [USER_ACTIONS.SET_PROVIDER]: setProvider,
|
||||
|
||||
[USER_ACTIONS.SET_DIALOG]: setDialog,
|
||||
[USER_ACTIONS.SET_DIALOG_ACTIVE]: setDialogActive,
|
||||
[USER_ACTIONS.SET_READY]: setReady,
|
||||
|
||||
[USER_ACTIONS.SEARCH_SET_TITLE]: searchSetTitle,
|
||||
[USER_ACTIONS.SEARCH_SET_DISTANCE]: searchSetDistance,
|
||||
|
@ -282,16 +112,10 @@ export const USER_HANDLERS = ({
|
|||
[USER_ACTIONS.SEARCH_SET_TAB]: searchSetTab,
|
||||
[USER_ACTIONS.SEARCH_PUT_ROUTES]: searchPutRoutes,
|
||||
[USER_ACTIONS.SEARCH_SET_LOADING]: searchSetLoading,
|
||||
// [USER_ACTIONS.SET_PUBLIC]: setPublic,
|
||||
[USER_ACTIONS.SET_STARRED]: setStarred,
|
||||
[USER_ACTIONS.SET_SPEED]: setSpeed,
|
||||
|
||||
[USER_ACTIONS.SET_MARKERS_SHOWN]: setMarkersShown,
|
||||
[USER_ACTIONS.SET_IS_EMPTY]: setIsEmpty,
|
||||
[USER_ACTIONS.MAPS_SET_SHIFT]: mapsSetShift,
|
||||
|
||||
[USER_ACTIONS.SET_FEATURE]: setFeature,
|
||||
[USER_ACTIONS.SET_IS_ROUTING]: setIsRouting,
|
||||
[USER_ACTIONS.SET_STARRED]: setStarred,
|
||||
|
||||
[USER_ACTIONS.SET_ROUTE_STARRED]: setRouteStarred,
|
||||
});
|
|
@ -1,8 +1,5 @@
|
|||
import { createReducer } from 'reduxsauce';
|
||||
import { DEFAULT_USER, IUser } from '~/constants/auth';
|
||||
import { MODES } from '~/constants/modes';
|
||||
import { DIALOGS, IDialogs } from '~/constants/dialogs';
|
||||
import { IStickers } from "~/constants/stickers";
|
||||
import { USER_HANDLERS } from './handlers';
|
||||
|
||||
export interface IRouteListItem {
|
||||
|
@ -15,50 +12,8 @@ export interface IRouteListItem {
|
|||
}
|
||||
|
||||
export interface IRootReducer {
|
||||
ready: boolean,
|
||||
// ready: boolean,
|
||||
user: IUser,
|
||||
editing: boolean,
|
||||
mode: typeof MODES[keyof typeof MODES],
|
||||
// logo: keyof typeof LOGOS,
|
||||
routerPoints: number,
|
||||
distance: number,
|
||||
// description: string,
|
||||
estimated: number,
|
||||
speed: number,
|
||||
activeSticker: { set?: keyof IStickers, sticker?: string },
|
||||
// title: string,
|
||||
// address: string,
|
||||
// address_origin: string,
|
||||
changed: boolean,
|
||||
// provider: keyof typeof PROVIDERS,
|
||||
markers_shown: boolean,
|
||||
|
||||
is_published: boolean,
|
||||
// is_public: boolean,
|
||||
is_empty: boolean,
|
||||
is_routing: boolean,
|
||||
|
||||
save_error: string,
|
||||
save_finished: boolean,
|
||||
save_overwriting: boolean,
|
||||
save_processing: boolean,
|
||||
save_loading: boolean,
|
||||
|
||||
dialog: IDialogs[keyof IDialogs],
|
||||
dialog_active: boolean,
|
||||
|
||||
features: {
|
||||
routing: boolean,
|
||||
},
|
||||
|
||||
renderer: {
|
||||
data: string,
|
||||
width: number,
|
||||
height: number
|
||||
renderer_active: boolean,
|
||||
info: string,
|
||||
progress: number,
|
||||
},
|
||||
|
||||
routes: {
|
||||
limit: 0,
|
||||
|
@ -81,53 +36,8 @@ export interface IRootReducer {
|
|||
export type IRootState = Readonly<IRootReducer>;
|
||||
|
||||
export const INITIAL_STATE: IRootReducer = {
|
||||
ready: false,
|
||||
user: { ...DEFAULT_USER },
|
||||
|
||||
mode: MODES.NONE,
|
||||
// logo: DEFAULT_LOGO,
|
||||
routerPoints: 0,
|
||||
distance: 0,
|
||||
// description: '',
|
||||
estimated: 0,
|
||||
speed: 15,
|
||||
activeSticker: { set: null, sticker: null },
|
||||
// title: '',
|
||||
// address: '',
|
||||
// address_origin: '',
|
||||
// provider: DEFAULT_PROVIDER,
|
||||
|
||||
markers_shown: true,
|
||||
changed: false,
|
||||
editing: false,
|
||||
|
||||
is_published: false,
|
||||
// is_public: false,
|
||||
is_empty: true,
|
||||
is_routing: false,
|
||||
|
||||
save_error: '',
|
||||
save_finished: false,
|
||||
save_overwriting: false,
|
||||
save_processing: false,
|
||||
save_loading: false,
|
||||
|
||||
dialog: DIALOGS.NONE,
|
||||
dialog_active: false,
|
||||
|
||||
features: {
|
||||
routing: false,
|
||||
},
|
||||
|
||||
renderer: {
|
||||
data: '',
|
||||
width: 0,
|
||||
height: 0,
|
||||
renderer_active: false,
|
||||
info: '',
|
||||
progress: 0,
|
||||
},
|
||||
|
||||
routes: {
|
||||
limit: 0,
|
||||
loading: false, // <-- maybe delete this
|
||||
|
|
|
@ -19,23 +19,23 @@ import {
|
|||
sendRouteStarred,
|
||||
} from '~/utils/api';
|
||||
import {
|
||||
hideRenderer,
|
||||
searchPutRoutes,
|
||||
searchSetLoading,
|
||||
setChanged,
|
||||
setDialogActive,
|
||||
setEditing,
|
||||
setMode,
|
||||
setReady,
|
||||
setRenderer,
|
||||
// hideRenderer,
|
||||
// setChanged,
|
||||
// setDialogActive,
|
||||
// setEditing,
|
||||
// setMode,
|
||||
// setReady,
|
||||
// setRenderer,
|
||||
// setDialog,
|
||||
// setAddressOrigin,
|
||||
// clearAll,
|
||||
// setFeature,
|
||||
searchSetTab,
|
||||
setUser,
|
||||
setDialog,
|
||||
setAddressOrigin,
|
||||
mapsSetShift,
|
||||
searchChangeDistance,
|
||||
clearAll,
|
||||
setFeature,
|
||||
searchPutRoutes,
|
||||
searchSetLoading,
|
||||
searchSetTitle,
|
||||
setRouteStarred,
|
||||
} from '~/redux/user/actions';
|
||||
|
@ -48,43 +48,22 @@ import {
|
|||
pushPath,
|
||||
} from '~/utils/history';
|
||||
import { USER_ACTIONS } from '~/redux/user/constants';
|
||||
import { MODES } from '~/constants/modes';
|
||||
import { DEFAULT_USER } from '~/constants/auth';
|
||||
import {
|
||||
composeArrows,
|
||||
composeDistMark,
|
||||
composeImages,
|
||||
composePoly,
|
||||
composeStickers,
|
||||
downloadCanvas,
|
||||
fetchImages,
|
||||
getPolyPlacement,
|
||||
getStickersPlacement,
|
||||
getTilePlacement,
|
||||
imageFetcher,
|
||||
} from '~/utils/renderer';
|
||||
import { LOGOS } from '~/constants/logos';
|
||||
|
||||
import { DIALOGS, TABS } from '~/constants/dialogs';
|
||||
|
||||
import * as ActionCreators from '~/redux/user/actions';
|
||||
import { downloadGPXTrack, getGPXString } from '~/utils/gpx';
|
||||
import { Unwrap } from '~/utils/middleware';
|
||||
import { IState } from '~/redux/store';
|
||||
import { selectUser, selectUserUser } from './selectors';
|
||||
import { mapInitSaga, loadMapSaga, replaceAddressIfItsBusy } from '~/redux/map/sagas';
|
||||
import { LatLng } from 'leaflet';
|
||||
import { selectMap } from '~/redux/map/selectors';
|
||||
import { editorSetDialog, editorSetDialogActive } from '../editor/actions';
|
||||
import { selectEditor } from '../editor/selectors';
|
||||
import { EDITOR_ACTIONS } from '../editor/constants';
|
||||
|
||||
// const getUser = (state: IState) => state.user.user;
|
||||
// const selectUser = (state: IState) => state.user;
|
||||
|
||||
const hideLoader = () => {
|
||||
document.getElementById('loader').style.opacity = String(0);
|
||||
document.getElementById('loader').style.pointerEvents = 'none';
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
function* generateGuestSaga() {
|
||||
const {
|
||||
data: { user, random_url },
|
||||
|
@ -95,52 +74,43 @@ function* generateGuestSaga() {
|
|||
return { ...user, random_url };
|
||||
}
|
||||
|
||||
function* startEditingSaga() {
|
||||
const { path } = getUrlData();
|
||||
yield pushPath(`/${path}/edit`);
|
||||
}
|
||||
// function* stopEditingSaga() {
|
||||
// const { changed, editing, mode, address_origin } = yield select(selectUser);
|
||||
// const { path } = getUrlData();
|
||||
|
||||
function* stopEditingSaga() {
|
||||
const { changed, editing, mode, address_origin } = yield select(selectUser);
|
||||
const { path } = getUrlData();
|
||||
// if (!editing) return;
|
||||
// if (changed && mode !== MODES.CONFIRM_CANCEL) {
|
||||
// yield put(setMode(MODES.CONFIRM_CANCEL));
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!editing) return;
|
||||
if (changed && mode !== MODES.CONFIRM_CANCEL) {
|
||||
yield put(setMode(MODES.CONFIRM_CANCEL));
|
||||
return;
|
||||
}
|
||||
// yield put(setMode(MODES.NONE));
|
||||
// yield put(setChanged(false));
|
||||
|
||||
// TODO: cancel editing?
|
||||
// yield editor.cancelEditing();
|
||||
yield put(setMode(MODES.NONE));
|
||||
yield put(setChanged(false));
|
||||
// TODO: dont close editor if theres no initial data
|
||||
// yield put(setEditing(editor.hasEmptyHistory)); // don't close editor if no previous map
|
||||
// yield pushPath(`/${address_origin || path}/`);
|
||||
// }
|
||||
|
||||
yield pushPath(`/${address_origin || path}/`);
|
||||
}
|
||||
// function* checkOSRMServiceSaga() {
|
||||
// const routing = yield call(checkOSRMService, [new LatLng(1,1), new LatLng(2,2)]);
|
||||
|
||||
function* checkOSRMServiceSaga() {
|
||||
const routing = yield call(checkOSRMService, [new LatLng(1,1), new LatLng(2,2)]);
|
||||
// yield put(setFeature({ routing }));
|
||||
// }
|
||||
|
||||
yield put(setFeature({ routing }));
|
||||
}
|
||||
// export function* setReadySaga() {
|
||||
// yield put(setReady(true));
|
||||
// hideLoader();
|
||||
|
||||
export function* setReadySaga() {
|
||||
yield put(setReady(true));
|
||||
hideLoader();
|
||||
|
||||
yield call(checkOSRMServiceSaga);
|
||||
yield put(searchSetTab(TABS.MY));
|
||||
}
|
||||
// yield call(checkOSRMServiceSaga);
|
||||
// yield put(searchSetTab(TABS.MY));
|
||||
// }
|
||||
|
||||
function* authCheckSaga({ key }: RehydrateAction) {
|
||||
if (key !== 'user') return;
|
||||
|
||||
pushLoaderState(70);
|
||||
|
||||
const { id, token } = yield select(selectUserUser);
|
||||
const { ready } = yield select(selectUser);
|
||||
const { id, token }: ReturnType<typeof selectUserUser> = yield select(selectUserUser);
|
||||
const { ready }: ReturnType<typeof selectEditor> = yield select(selectEditor);
|
||||
|
||||
if (window.location.search || true) {
|
||||
const { viewer_id, auth_key } = yield parseQuery(window.location.search);
|
||||
|
@ -215,128 +185,127 @@ function* authCheckSaga({ key }: RehydrateAction) {
|
|||
// return true;
|
||||
// }
|
||||
|
||||
// function* getRenderData() {
|
||||
// yield put(setRenderer({ info: 'Загрузка тайлов', progress: 0.1 }));
|
||||
|
||||
function* getRenderData() {
|
||||
yield put(setRenderer({ info: 'Загрузка тайлов', progress: 0.1 }));
|
||||
// const { route, stickers, provider }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
|
||||
const { route, stickers, provider }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
// const canvas = <HTMLCanvasElement>document.getElementById('renderer');
|
||||
// canvas.width = window.innerWidth;
|
||||
// canvas.height = window.innerHeight;
|
||||
// const ctx = canvas.getContext('2d');
|
||||
|
||||
const canvas = <HTMLCanvasElement>document.getElementById('renderer');
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
const ctx = canvas.getContext('2d');
|
||||
// const geometry = getTilePlacement();
|
||||
// const points = getPolyPlacement(route);
|
||||
// const sticker_points = getStickersPlacement(stickers);
|
||||
// // TODO: get distance:
|
||||
// const distance = 0;
|
||||
// // const distance = editor.poly.poly.distance;
|
||||
|
||||
const geometry = getTilePlacement();
|
||||
const points = getPolyPlacement(route);
|
||||
const sticker_points = getStickersPlacement(stickers);
|
||||
// TODO: get distance:
|
||||
const distance = 0;
|
||||
// const distance = editor.poly.poly.distance;
|
||||
// ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
// const images = yield fetchImages(ctx, geometry, provider);
|
||||
|
||||
const images = yield fetchImages(ctx, geometry, provider);
|
||||
// yield put(setRenderer({ info: 'Отрисовка', progress: 0.5 }));
|
||||
|
||||
yield put(setRenderer({ info: 'Отрисовка', progress: 0.5 }));
|
||||
// yield composeImages({ geometry, images, ctx });
|
||||
// yield composePoly({ points, ctx });
|
||||
// yield composeArrows({ points, ctx });
|
||||
// yield composeDistMark({ ctx, points, distance });
|
||||
// yield composeStickers({ stickers: sticker_points, ctx });
|
||||
|
||||
yield composeImages({ geometry, images, ctx });
|
||||
yield composePoly({ points, ctx });
|
||||
yield composeArrows({ points, ctx });
|
||||
yield composeDistMark({ ctx, points, distance });
|
||||
yield composeStickers({ stickers: sticker_points, ctx });
|
||||
// yield put(setRenderer({ info: 'Готово', progress: 1 }));
|
||||
|
||||
yield put(setRenderer({ info: 'Готово', progress: 1 }));
|
||||
// return yield canvas.toDataURL('image/jpeg');
|
||||
// }
|
||||
|
||||
return yield canvas.toDataURL('image/jpeg');
|
||||
}
|
||||
// function* takeAShotSaga() {
|
||||
// const worker = call(getRenderData);
|
||||
|
||||
function* takeAShotSaga() {
|
||||
const worker = call(getRenderData);
|
||||
// const { result, timeout } = yield race({
|
||||
// result: worker,
|
||||
// timeout: delay(500),
|
||||
// });
|
||||
|
||||
const { result, timeout } = yield race({
|
||||
result: worker,
|
||||
timeout: delay(500),
|
||||
});
|
||||
// if (timeout) yield put(setMode(MODES.SHOT_PREFETCH));
|
||||
|
||||
if (timeout) yield put(setMode(MODES.SHOT_PREFETCH));
|
||||
// const data = yield result || worker;
|
||||
|
||||
const data = yield result || worker;
|
||||
// yield put(setMode(MODES.NONE));
|
||||
// yield put(
|
||||
// setRenderer({
|
||||
// data,
|
||||
// renderer_active: true,
|
||||
// width: window.innerWidth,
|
||||
// height: window.innerHeight,
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
|
||||
yield put(setMode(MODES.NONE));
|
||||
yield put(
|
||||
setRenderer({
|
||||
data,
|
||||
renderer_active: true,
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
})
|
||||
);
|
||||
}
|
||||
// function* getCropData({ x, y, width, height }) {
|
||||
// const {
|
||||
// logo,
|
||||
// renderer: { data },
|
||||
// } = yield select(selectUser);
|
||||
// const canvas = <HTMLCanvasElement>document.getElementById('renderer');
|
||||
// canvas.width = width;
|
||||
// canvas.height = height;
|
||||
// const ctx = canvas.getContext('2d');
|
||||
// const image = yield imageFetcher(data);
|
||||
|
||||
function* getCropData({ x, y, width, height }) {
|
||||
const {
|
||||
logo,
|
||||
renderer: { data },
|
||||
} = yield select(selectUser);
|
||||
const canvas = <HTMLCanvasElement>document.getElementById('renderer');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
const image = yield imageFetcher(data);
|
||||
// ctx.drawImage(image, -x, -y);
|
||||
|
||||
ctx.drawImage(image, -x, -y);
|
||||
// if (logo && LOGOS[logo][1]) {
|
||||
// const logoImage = yield imageFetcher(LOGOS[logo][1]);
|
||||
// ctx.drawImage(logoImage, width - logoImage.width, height - logoImage.height);
|
||||
// }
|
||||
|
||||
if (logo && LOGOS[logo][1]) {
|
||||
const logoImage = yield imageFetcher(LOGOS[logo][1]);
|
||||
ctx.drawImage(logoImage, width - logoImage.width, height - logoImage.height);
|
||||
}
|
||||
// return yield canvas.toDataURL('image/jpeg');
|
||||
// }
|
||||
|
||||
return yield canvas.toDataURL('image/jpeg');
|
||||
}
|
||||
// function* cropAShotSaga(params) {
|
||||
// const { title, address } = yield select(selectUser);
|
||||
// yield call(getCropData, params);
|
||||
// const canvas = document.getElementById('renderer') as HTMLCanvasElement;
|
||||
|
||||
function* cropAShotSaga(params) {
|
||||
const { title, address } = yield select(selectUser);
|
||||
yield call(getCropData, params);
|
||||
const canvas = document.getElementById('renderer') as HTMLCanvasElement;
|
||||
// downloadCanvas(canvas, (title || address).replace(/\./gi, ' '));
|
||||
|
||||
downloadCanvas(canvas, (title || address).replace(/\./gi, ' '));
|
||||
// return yield put(hideRenderer());
|
||||
// }
|
||||
|
||||
return yield put(hideRenderer());
|
||||
}
|
||||
// function* locationChangeSaga({ location }: ReturnType<typeof ActionCreators.locationChanged>) {
|
||||
// const {
|
||||
// address,
|
||||
// ready,
|
||||
// user: { id, random_url },
|
||||
// } = yield select(selectUser);
|
||||
|
||||
function* locationChangeSaga({ location }: ReturnType<typeof ActionCreators.locationChanged>) {
|
||||
const {
|
||||
address,
|
||||
ready,
|
||||
user: { id, random_url },
|
||||
} = yield select(selectUser);
|
||||
// const { owner }: ReturnType<typeof selectMap> = yield select(selectMap)
|
||||
|
||||
const { owner }: ReturnType<typeof selectMap> = yield select(selectMap)
|
||||
// if (!ready) return;
|
||||
|
||||
if (!ready) return;
|
||||
// const { path, mode } = getUrlData(location);
|
||||
|
||||
const { path, mode } = getUrlData(location);
|
||||
// if (address !== path) {
|
||||
// const map = yield call(loadMapSaga, path);
|
||||
|
||||
if (address !== path) {
|
||||
const map = yield call(loadMapSaga, path);
|
||||
// if (map && map.route && map.route.owner && mode === 'edit' && map.route.owner !== id) {
|
||||
// return yield call(replaceAddressIfItsBusy, map.random_url, map.address);
|
||||
// }
|
||||
// } else if (mode === 'edit' && owner.id !== id) {
|
||||
// return yield call(replaceAddressIfItsBusy, random_url, address);
|
||||
// } else {
|
||||
// yield put(setAddressOrigin(''));
|
||||
// }
|
||||
|
||||
if (map && map.route && map.route.owner && mode === 'edit' && map.route.owner !== id) {
|
||||
return yield call(replaceAddressIfItsBusy, map.random_url, map.address);
|
||||
}
|
||||
} else if (mode === 'edit' && owner.id !== id) {
|
||||
return yield call(replaceAddressIfItsBusy, random_url, address);
|
||||
} else {
|
||||
yield put(setAddressOrigin(''));
|
||||
}
|
||||
|
||||
if (mode !== 'edit') {
|
||||
yield put(setEditing(false));
|
||||
// editor.stopEditing();
|
||||
} else {
|
||||
yield put(setEditing(true));
|
||||
// editor.startEditing();
|
||||
}
|
||||
}
|
||||
// if (mode !== 'edit') {
|
||||
// yield put(setEditing(false));
|
||||
// // editor.stopEditing();
|
||||
// } else {
|
||||
// yield put(setEditing(true));
|
||||
// // editor.startEditing();
|
||||
// }
|
||||
// }
|
||||
|
||||
function* gotVkUserSaga({ user: u }: ReturnType<typeof ActionCreators.gotVkUser>) {
|
||||
const {
|
||||
|
@ -346,40 +315,40 @@ function* gotVkUserSaga({ user: u }: ReturnType<typeof ActionCreators.gotVkUser>
|
|||
yield put(setUser({ ...user, random_url }));
|
||||
}
|
||||
|
||||
function* keyPressedSaga({ key, target }: ReturnType<typeof ActionCreators.keyPressed>): any {
|
||||
if (target === 'INPUT' || target === 'TEXTAREA') {
|
||||
return;
|
||||
}
|
||||
// function* keyPressedSaga({ key, target }: ReturnType<typeof ActionCreators.keyPressed>): any {
|
||||
// if (target === 'INPUT' || target === 'TEXTAREA') {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (key === 'Escape') {
|
||||
const {
|
||||
dialog_active,
|
||||
mode,
|
||||
renderer: { renderer_active },
|
||||
} = yield select(selectUser);
|
||||
// if (key === 'Escape') {
|
||||
// const {
|
||||
// dialog_active,
|
||||
// mode,
|
||||
// renderer: { renderer_active },
|
||||
// } = yield select(selectUser);
|
||||
|
||||
if (renderer_active) return yield put(hideRenderer());
|
||||
if (dialog_active) return yield put(setDialogActive(false));
|
||||
if (mode !== MODES.NONE) return yield put(setMode(MODES.NONE));
|
||||
} else if (key === 'Delete') {
|
||||
const {
|
||||
user: { editing },
|
||||
} = yield select();
|
||||
// if (renderer_active) return yield put(hideRenderer());
|
||||
// if (dialog_active) return yield put(setDialogActive(false));
|
||||
// if (mode !== MODES.NONE) return yield put(setMode(MODES.NONE));
|
||||
// } else if (key === 'Delete') {
|
||||
// const {
|
||||
// user: { editing },
|
||||
// } = yield select();
|
||||
|
||||
if (!editing) return;
|
||||
// if (!editing) return;
|
||||
|
||||
const { mode } = yield select(selectUser);
|
||||
// const { mode } = yield select(selectUser);
|
||||
|
||||
if (mode === MODES.TRASH) {
|
||||
yield put(clearAll());
|
||||
} else {
|
||||
yield put(setMode(MODES.TRASH));
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (mode === MODES.TRASH) {
|
||||
// yield put(clearAll());
|
||||
// } else {
|
||||
// yield put(setMode(MODES.TRASH));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
function* searchGetRoutes() {
|
||||
const { token } = yield select(selectUserUser);
|
||||
const { token }: ReturnType<typeof selectUserUser> = yield select(selectUserUser);
|
||||
|
||||
const {
|
||||
routes: {
|
||||
|
@ -387,7 +356,7 @@ function* searchGetRoutes() {
|
|||
shift,
|
||||
filter: { title, distance, tab },
|
||||
},
|
||||
} = yield select(selectUser);
|
||||
}: ReturnType<typeof selectUser> = yield select(selectUser);
|
||||
|
||||
const result: Unwrap<typeof getRouteList> = yield getRouteList({
|
||||
token,
|
||||
|
@ -442,14 +411,17 @@ function* searchSetSaga() {
|
|||
|
||||
function* openMapDialogSaga({ tab }: ReturnType<typeof ActionCreators.openMapDialog>) {
|
||||
const {
|
||||
dialog_active,
|
||||
routes: {
|
||||
filter: { tab: current },
|
||||
},
|
||||
} = yield select(selectUser);
|
||||
}: ReturnType<typeof selectUser> = yield select(selectUser);
|
||||
|
||||
const {
|
||||
dialog_active,
|
||||
}: ReturnType<typeof selectEditor> = yield select(selectEditor);
|
||||
|
||||
if (dialog_active && tab === current) {
|
||||
return yield put(setDialogActive(false));
|
||||
return yield put(editorSetDialogActive(false));
|
||||
}
|
||||
|
||||
if (tab !== current) {
|
||||
|
@ -457,8 +429,8 @@ function* openMapDialogSaga({ tab }: ReturnType<typeof ActionCreators.openMapDia
|
|||
yield put(searchSetTab(tab));
|
||||
}
|
||||
|
||||
yield put(setDialog(DIALOGS.MAP_LIST));
|
||||
yield put(setDialogActive(true));
|
||||
yield put(editorSetDialog(DIALOGS.MAP_LIST));
|
||||
yield put(editorSetDialogActive(true));
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
@ -476,28 +448,28 @@ function* userLogoutSaga(): SagaIterator {
|
|||
}
|
||||
|
||||
function* setUserSaga() {
|
||||
const { dialog_active } = yield select(selectUser);
|
||||
const { dialog_active }: ReturnType<typeof selectEditor> = yield select(selectEditor);
|
||||
|
||||
if (dialog_active) yield call(searchSetSagaWorker);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function* getGPXTrackSaga(): SagaIterator {
|
||||
const { route, stickers }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
const { title, address } = yield select(selectUser);
|
||||
// function* getGPXTrackSaga(): SagaIterator {
|
||||
// const { route, stickers }: ReturnType<typeof selectMap> = yield select(selectMap);
|
||||
// const { title, address } = yield select(selectUser);
|
||||
|
||||
if (!route || route.length <= 0) return;
|
||||
// if (!route || route.length <= 0) return;
|
||||
|
||||
const track = getGPXString({ route, stickers, title: title || address });
|
||||
// const track = getGPXString({ route, stickers, title: title || address });
|
||||
|
||||
return downloadGPXTrack({ track, title });
|
||||
}
|
||||
// return downloadGPXTrack({ track, title });
|
||||
// }
|
||||
|
||||
function* mapsLoadMoreSaga() {
|
||||
const {
|
||||
routes: { limit, list, shift, step, loading, filter },
|
||||
} = yield select(selectUser);
|
||||
}: ReturnType<typeof selectUser> = yield select(selectUser);
|
||||
|
||||
if (loading || list.length >= limit || limit === 0) return;
|
||||
|
||||
|
@ -540,7 +512,7 @@ function* mapsLoadMoreSaga() {
|
|||
}
|
||||
|
||||
function* dropRouteSaga({ address }: ReturnType<typeof ActionCreators.dropRoute>): SagaIterator {
|
||||
const { token } = yield select(selectUserUser);
|
||||
const { token }: ReturnType<typeof selectUserUser> = yield select(selectUserUser);
|
||||
const {
|
||||
routes: {
|
||||
list,
|
||||
|
@ -549,7 +521,7 @@ function* dropRouteSaga({ address }: ReturnType<typeof ActionCreators.dropRoute>
|
|||
limit,
|
||||
filter: { min, max },
|
||||
},
|
||||
} = yield select(selectUser);
|
||||
}: ReturnType<typeof selectUser> = yield select(selectUser);
|
||||
|
||||
const index = list.findIndex(el => el.address === address);
|
||||
|
||||
|
@ -574,7 +546,7 @@ function* modifyRouteSaga({
|
|||
title,
|
||||
is_public,
|
||||
}: ReturnType<typeof ActionCreators.modifyRoute>): SagaIterator {
|
||||
const { token } = yield select(selectUserUser);
|
||||
const { token }: ReturnType<typeof selectUserUser> = yield select(selectUserUser);
|
||||
const {
|
||||
routes: {
|
||||
list,
|
||||
|
@ -606,12 +578,12 @@ function* modifyRouteSaga({
|
|||
function* toggleRouteStarredSaga({
|
||||
address,
|
||||
}: ReturnType<typeof ActionCreators.toggleRouteStarred>) {
|
||||
const { token }: ReturnType<typeof selectUserUser> = yield select(selectUserUser);
|
||||
const {
|
||||
routes: { list },
|
||||
}: IState['user'] = yield select(selectUser);
|
||||
}: ReturnType<typeof selectUser> = yield select(selectUser);
|
||||
|
||||
const route = list.find(el => el.address === address);
|
||||
const { token } = yield select(selectUserUser);
|
||||
|
||||
yield put(setRouteStarred(address, !route.is_published));
|
||||
const result = yield sendRouteStarred({
|
||||
|
@ -624,24 +596,24 @@ function* toggleRouteStarredSaga({
|
|||
}
|
||||
|
||||
export function* userSaga() {
|
||||
// yield takeEvery(USER_ACTIONS.STOP_EDITING, stopEditingSaga);
|
||||
// yield takeLatest(USER_ACTIONS.TAKE_A_SHOT, takeAShotSaga);
|
||||
// yield takeLatest(USER_ACTIONS.CROP_A_SHOT, cropAShotSaga);
|
||||
// yield takeLatest(USER_ACTIONS.LOCATION_CHANGED, locationChangeSaga);
|
||||
// yield takeLatest(USER_ACTIONS.KEY_PRESSED, keyPressedSaga);
|
||||
// yield takeLatest(USER_ACTIONS.GET_GPX_TRACK, getGPXTrackSaga);
|
||||
|
||||
yield takeLatest(REHYDRATE, authCheckSaga);
|
||||
|
||||
yield takeEvery(USER_ACTIONS.START_EDITING, startEditingSaga);
|
||||
yield takeEvery(USER_ACTIONS.STOP_EDITING, stopEditingSaga);
|
||||
|
||||
yield takeEvery(USER_ACTIONS.USER_LOGOUT, userLogoutSaga);
|
||||
|
||||
// yield takeEvery(USER_ACTIONS.ROUTER_CANCEL, routerCancelSaga);
|
||||
// yield takeEvery(USER_ACTIONS.ROUTER_SUBMIT, routerSubmitSaga);
|
||||
|
||||
yield takeLatest(USER_ACTIONS.TAKE_A_SHOT, takeAShotSaga);
|
||||
yield takeLatest(USER_ACTIONS.CROP_A_SHOT, cropAShotSaga);
|
||||
|
||||
// yield takeEvery(USER_ACTIONS.CHANGE_PROVIDER, changeProviderSaga);
|
||||
yield takeLatest(USER_ACTIONS.LOCATION_CHANGED, locationChangeSaga);
|
||||
|
||||
yield takeLatest(USER_ACTIONS.GOT_VK_USER, gotVkUserSaga);
|
||||
yield takeLatest(USER_ACTIONS.KEY_PRESSED, keyPressedSaga);
|
||||
|
||||
// yield takeLatest(USER_ACTIONS.SET_TITLE, setTitleSaga);
|
||||
|
||||
|
@ -654,7 +626,6 @@ export function* userSaga() {
|
|||
yield takeLatest(USER_ACTIONS.SEARCH_SET_TAB, searchSetTabSaga);
|
||||
yield takeLatest(USER_ACTIONS.SET_USER, setUserSaga);
|
||||
|
||||
yield takeLatest(USER_ACTIONS.GET_GPX_TRACK, getGPXTrackSaga);
|
||||
yield takeLatest(USER_ACTIONS.MAPS_LOAD_MORE, mapsLoadMoreSaga);
|
||||
|
||||
yield takeLatest(USER_ACTIONS.DROP_ROUTE, dropRouteSaga);
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import { IState } from '~/redux/store'
|
||||
|
||||
export const selectUser = (state: IState) => state.user;
|
||||
export const selectUserUser = (state: IState) => state.user.user;
|
||||
export const selectUserEditing = (state: IState) => state.user.editing;
|
||||
export const selectUserMode = (state: IState) => state.user.mode;
|
||||
export const selectUserActiveSticker = (state: IState) => state.user.activeSticker;
|
||||
export const selectUserRenderer = (state: IState) => state.user.renderer;
|
||||
export const selectUserUser = (state: IState) => state.user.user;
|
Loading…
Add table
Add a link
Reference in a new issue