From ad676d5fde7682b1b3ef71da3157bb653174f3d2 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 22 Jan 2020 15:16:34 +0700 Subject: [PATCH] forwards and backwards drawing --- src/components/dialogs/PolylineDialog.tsx | 38 ++++++++++++++++++++++- src/components/dialogs/RouterDialog.tsx | 11 +++---- src/map/Route/index.tsx | 17 +++++++--- src/redux/editor/actions.ts | 5 +++ src/redux/editor/constants.ts | 7 +++++ src/redux/editor/handlers.ts | 10 ++++++ src/redux/editor/index.ts | 12 +++++-- src/redux/editor/selectors.ts | 1 + src/sprites/icon.svg | 18 +++++++++-- src/styles/panel.less | 6 ++++ src/utils/map/InteractivePoly.ts | 15 +++++++-- 11 files changed, 119 insertions(+), 21 deletions(-) diff --git a/src/components/dialogs/PolylineDialog.tsx b/src/components/dialogs/PolylineDialog.tsx index dc8eb0d..4f27150 100644 --- a/src/components/dialogs/PolylineDialog.tsx +++ b/src/components/dialogs/PolylineDialog.tsx @@ -5,18 +5,28 @@ import * as MAP_ACTIONS from '~/redux/map/actions'; import { IState } from '~/redux/store'; import { selectMapRoute } from '~/redux/map/selectors'; import classNames from 'classnames'; +import { selectEditorDirection } from '~/redux/editor/selectors'; +import * as EDITOR_ACTIONS from '~/redux/editor/actions'; +import { DRAWING_DIRECTIONS } from '~/redux/editor/constants'; const mapStateToProps = (state: IState) => ({ route: selectMapRoute(state), + direction: selectEditorDirection(state), }); const mapDispatchToProps = { mapSetRoute: MAP_ACTIONS.mapSetRoute, + editorSetDirection: EDITOR_ACTIONS.editorSetDirection, }; type Props = ReturnType & typeof mapDispatchToProps & {}; -const PolylineDialogUnconnected: FC = ({ route, mapSetRoute }) => { +const PolylineDialogUnconnected: FC = ({ + route, + direction, + editorSetDirection, + mapSetRoute, +}) => { const reverseRoute = useCallback(() => { if (route.length < 2) return; mapSetRoute([...route].reverse()); @@ -34,6 +44,14 @@ const PolylineDialogUnconnected: FC = ({ route, mapSetRoute }) => { mapSetRoute(route.slice(0, route.length - 1)); }, [mapSetRoute, route]); + const continueBackward = useCallback(() => { + editorSetDirection(DRAWING_DIRECTIONS.BACKWARDS); + }, [editorSetDirection]); + + const continueForward = useCallback(() => { + editorSetDirection(DRAWING_DIRECTIONS.FORWARDS); + }, [editorSetDirection]); + return (
@@ -59,6 +77,24 @@ const PolylineDialogUnconnected: FC = ({ route, mapSetRoute }) => { + + + +
Ручной режим
diff --git a/src/components/dialogs/RouterDialog.tsx b/src/components/dialogs/RouterDialog.tsx index 827f0cc..f353697 100644 --- a/src/components/dialogs/RouterDialog.tsx +++ b/src/components/dialogs/RouterDialog.tsx @@ -3,8 +3,9 @@ import { Icon } from '~/components/panels/Icon'; import * as EDITOR_ACTIONS from '~/redux/editor/actions'; import classnames from 'classnames'; import { connect } from 'react-redux'; -import { selectEditor } from '~/redux/editor/selectors'; +import { selectEditor, selectEditorRouter, selectEditorDirection } from '~/redux/editor/selectors'; import pick from 'ramda/es/pick'; +import { IState } from '~/redux/store'; const noPoints = ({ editorRouterCancel, @@ -84,8 +85,8 @@ const draggablePoints = ({ ); -const mapStateToProps = state => ({ - editor: pick(['router'], selectEditor(state)), +const mapStateToProps = (state: IState) => ({ + router: selectEditorRouter(state), }); const mapDispatchToProps = { @@ -96,9 +97,7 @@ const mapDispatchToProps = { type Props = ReturnType & typeof mapDispatchToProps & {}; const RouterDialogUnconnected: FC = ({ - editor: { - router: { waypoints }, - }, + router: { waypoints }, editorRouterCancel, editorRouterSubmit, }) => ( diff --git a/src/map/Route/index.tsx b/src/map/Route/index.tsx index 1501f0a..9d769b2 100644 --- a/src/map/Route/index.tsx +++ b/src/map/Route/index.tsx @@ -2,19 +2,20 @@ import React, { FC, useEffect, memo, useState, useCallback } from 'react'; import { InteractivePoly } from '~/utils/map/InteractivePoly'; import { isMobile } from '~/utils/window'; import { LatLng } from 'leaflet'; -import { selectEditor, selectEditorMode, selectEditorEditing } from '~/redux/editor/selectors'; -import pick from 'ramda/es/pick'; +import { selectEditorMode, selectEditorEditing, selectEditorDirection } from '~/redux/editor/selectors'; import * as MAP_ACTIONS from '~/redux/map/actions'; import { connect } from 'react-redux'; -import { selectMap, selectMapRoute } from '~/redux/map/selectors'; +import { selectMapRoute } from '~/redux/map/selectors'; import { MainMap } from '~/constants/map'; import { MODES } from '~/constants/modes'; import * as EDITOR_ACTIONS from '~/redux/editor/actions'; +import { IState } from '~/redux/store'; -const mapStateToProps = state => ({ +const mapStateToProps = (state: IState) => ({ mode: selectEditorMode(state), editing: selectEditorEditing(state), route: selectMapRoute(state), + drawing_direction: selectEditorDirection(state), }); const mapDispatchToProps = { @@ -26,7 +27,7 @@ const mapDispatchToProps = { type Props = ReturnType & typeof mapDispatchToProps & {}; const RouteUnconnected: FC = memo( - ({ route, editing, mode, mapSetRoute, editorSetDistance, editorSetMarkersShown }) => { + ({ route, editing, mode, drawing_direction, mapSetRoute, editorSetDistance, editorSetMarkersShown }) => { const [layer, setLayer] = useState(null); const onDistanceChange = useCallback(({ distance }) => editorSetDistance(distance), [ @@ -103,6 +104,12 @@ const RouteUnconnected: FC = memo( } }, [mode, layer]); + useEffect(() => { + if (!layer) return; + + layer.setDirection(drawing_direction); + }, [drawing_direction, layer]); + return null; } ); diff --git a/src/redux/editor/actions.ts b/src/redux/editor/actions.ts index 8d580b0..6432b54 100644 --- a/src/redux/editor/actions.ts +++ b/src/redux/editor/actions.ts @@ -146,3 +146,8 @@ export const editorRedo = () => ({ export const editorCaptureHistory = () => ({ type: EDITOR_ACTIONS.CAPTURE_HIPSTORY, }); + +export const editorSetDirection = (drawing_direction: IEditorState['drawing_direction']) => ({ + type: EDITOR_ACTIONS.SET_DIRECTION, + drawing_direction, +}); diff --git a/src/redux/editor/constants.ts b/src/redux/editor/constants.ts index 412efcc..68cc83b 100644 --- a/src/redux/editor/constants.ts +++ b/src/redux/editor/constants.ts @@ -1,5 +1,10 @@ const P = 'EDITOR'; +export const DRAWING_DIRECTIONS: Record<'FORWARDS' | 'BACKWARDS', 'forward' | 'backward'> = { + FORWARDS: 'forward', + BACKWARDS: 'backward', +}; + export const EDITOR_HISTORY_LENGTH = 100; export const EDITOR_ACTIONS = { @@ -54,4 +59,6 @@ export const EDITOR_ACTIONS = { UNDO: `${P}-UNDO`, REDO: `${P}-REDO`, CAPTURE_HIPSTORY: `${P}-CAPTURE_HIPSTORY`, + + SET_DIRECTION: `${P}-SET_DIRECTION`, }; diff --git a/src/redux/editor/handlers.ts b/src/redux/editor/handlers.ts index b039b3a..71684b7 100644 --- a/src/redux/editor/handlers.ts +++ b/src/redux/editor/handlers.ts @@ -179,6 +179,14 @@ const setHistory = ( }, }); +const setDirection = ( + state, + { drawing_direction }: ReturnType +): IEditorState => ({ + ...state, + drawing_direction, +}); + export const EDITOR_HANDLERS = { [EDITOR_ACTIONS.SET_EDITING]: setEditing, [EDITOR_ACTIONS.SET_CHANGED]: setChanged, @@ -209,4 +217,6 @@ export const EDITOR_HANDLERS = { [EDITOR_ACTIONS.SET_NOMINATIM]: setNominatim, [EDITOR_ACTIONS.SET_HISTORY]: setHistory, + + [EDITOR_ACTIONS.SET_DIRECTION]: setDirection, }; diff --git a/src/redux/editor/index.ts b/src/redux/editor/index.ts index 0a1c3c3..5b42a4a 100644 --- a/src/redux/editor/index.ts +++ b/src/redux/editor/index.ts @@ -5,6 +5,7 @@ import { EDITOR_HANDLERS } from './handlers'; import { ILatLng } from '../map/types'; import { INominatimResult } from '~/redux/types'; import { IMapReducer } from '../map'; +import { DRAWING_DIRECTIONS } from './constants'; export interface IEditorHistoryItem { route: IMapReducer['route']; @@ -35,6 +36,7 @@ export interface IEditorState { is_empty: boolean; is_published: boolean; is_routing: boolean; + drawing_direction: typeof DRAWING_DIRECTIONS[keyof typeof DRAWING_DIRECTIONS]; features: { routing: boolean; @@ -63,6 +65,7 @@ export interface IEditorState { processing: boolean; loading: boolean; }; + history: { records: IEditorHistoryItem[]; position: number; @@ -84,13 +87,16 @@ export const EDITOR_INITIAL_STATE = { estimated: 0, speed: 15, activeSticker: { set: null, sticker: null }, + drawing_direction: DRAWING_DIRECTIONS.FORWARDS, + + is_published: false, + is_empty: true, + is_routing: false, + router: { waypoints: [], points: [], }, - is_published: false, - is_empty: true, - is_routing: false, features: { routing: false, diff --git a/src/redux/editor/selectors.ts b/src/redux/editor/selectors.ts index c4ce029..4c6ab6d 100644 --- a/src/redux/editor/selectors.ts +++ b/src/redux/editor/selectors.ts @@ -9,3 +9,4 @@ export const selectEditorRenderer = (state: IState) => state.editor.renderer; export const selectEditorRouter = (state: IState) => state.editor.router; export const selectEditorDistance = (state: IState) => state.editor.distance; export const selectEditorNominatim = (state: IState) => state.editor.nominatim; +export const selectEditorDirection = (state: IState) => state.editor.drawing_direction; diff --git a/src/sprites/icon.svg b/src/sprites/icon.svg index e8170d3..21ac47e 100644 --- a/src/sprites/icon.svg +++ b/src/sprites/icon.svg @@ -372,7 +372,7 @@ - + @@ -382,12 +382,24 @@ - + - + + + + + + + + + + + + + diff --git a/src/styles/panel.less b/src/styles/panel.less index 21b2126..e88b8ee 100644 --- a/src/styles/panel.less +++ b/src/styles/panel.less @@ -430,6 +430,12 @@ &.inactive { opacity: 0.5; } + + &.active { + svg { + fill: url(#activeButtonGradient); + } + } } .helper__buttons { diff --git a/src/utils/map/InteractivePoly.ts b/src/utils/map/InteractivePoly.ts index d71be9c..9e83fbb 100644 --- a/src/utils/map/InteractivePoly.ts +++ b/src/utils/map/InteractivePoly.ts @@ -45,9 +45,7 @@ class InteractivePoly extends Polyline { this.startDragHinting(); } - setLatLngs = (latlngs: LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][]) => { - super.setLatLngs(latlngs); - + updateConstraintsToLatLngs = (latlngs: LatLngExpression[]) => { if (this.is_drawing) { // update mouse hinter on latlngs change const constraints = this.constrLine.getLatLngs() as LatLng[]; @@ -63,6 +61,12 @@ class InteractivePoly extends Polyline { this.setConstraints([constraints[0], source as LatLng]); } + } + + setLatLngs = (latlngs: LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][]) => { + super.setLatLngs(latlngs); + + this.updateConstraintsToLatLngs(latlngs as LatLngExpression[]); return this; }; @@ -492,6 +496,11 @@ class InteractivePoly extends Polyline { this.constrLine.setLatLngs(coords); }; + setDirection = (direction: 'forward' | 'backward') => { + this.drawing_direction = direction; + this.updateConstraintsToLatLngs(this.getLatLngs() as LatLngExpression[]); + } + dropMarker = ({ target }: LeafletMouseEvent): void => { const index = this.markers.indexOf(target); const latlngs = this.getLatLngs();