moved editor to separate reducer

This commit is contained in:
Fedor Katurov 2020-01-09 10:59:26 +07:00
parent e950d98b73
commit 87670770b0
38 changed files with 1425 additions and 1069 deletions

View file

@ -1,20 +1,25 @@
// flow
import React from 'react';
import { toHours } from '~/utils/format';
import { Icon } from '~/components/panels/Icon';
import { connect } from 'react-redux';
// import Slider from 'rc-slider';
import Slider from 'rc-slider/lib/Slider';
import { bindActionCreators } from 'redux';
import { setSpeed } from '~/redux/user/actions';
import { IRootState } from "~/redux/user";
import { editorSetSpeed } from '~/redux/editor/actions';
import { Tooltip } from "~/components/panels/Tooltip";
import { isMobile } from "~/utils/window";
import { IState } from '~/redux/store';
interface Props extends IRootState {
setSpeed: typeof setSpeed,
function mapStateToProps(state) {
const {
editor: { distance, estimated, speed },
}: IState = state;
return { distance, estimated, speed };
}
const mapDispatchToProps = { editorSetSpeed };
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
interface State {
dialogOpened: boolean,
}
@ -68,7 +73,7 @@ class Component extends React.PureComponent<Props, State> {
min={min}
max={max}
step={step}
onChange={this.props.setSpeed}
onChange={this.props.editorSetSpeed}
defaultValue={15}
value={speed}
marks={marks}
@ -81,18 +86,6 @@ class Component extends React.PureComponent<Props, State> {
}
}
function mapStateToProps(state) {
const {
user: { distance, estimated, speed },
} = state;
return { distance, estimated, speed };
}
const mapDispatchToProps = dispatch => bindActionCreators({
setSpeed,
}, dispatch);
export const DistanceBar = connect(
mapStateToProps,
mapDispatchToProps

View file

@ -12,29 +12,13 @@ import { connect } from 'react-redux';
import { ProviderDialog } from '~/components/dialogs/ProviderDialog';
import { ShotPrefetchDialog } from '~/components/dialogs/ShotPrefetchDialog';
import { selectUserMode } from '~/redux/user/selectors';
import { selectEditorMode } from '~/redux/editor/selectors';
const mapStateToProps = state => ({ mode: selectUserMode(state) });
// const mapDispatchToProps = dispatch => bindActionCreators({
// routerCancel: USER_ACTIONS.routerCancel,
// routerSubmit: USER_ACTIONS.routerSubmit,
// setActiveSticker: USER_ACTIONS.setActiveSticker,
// clearStickers: USER_ACTIONS.clearStickers,
// clearPoly: USER_ACTIONS.clearPoly,
// clearAll: USER_ACTIONS.clearAll,
// clearCancel: USER_ACTIONS.clearCancel,
// stopEditing: USER_ACTIONS.stopEditing,
// setEditing: USER_ACTIONS.setEditing,
// setMode: USER_ACTIONS.setMode,
// sendSaveRequest: USER_ACTIONS.sendSaveRequest,
// changeProvider: USER_ACTIONS.changeProvider,
// mapSetLogo: MAP_ACTIONS.mapSetLogo,
// }, dispatch);
const mapStateToProps = state => ({ mode: selectEditorMode(state) });
type Props = ReturnType<typeof mapStateToProps> & {
width: number;
};
width: number;
};
const DIALOG_CONTENTS: { [x: string]: any } = {
[MODES.ROUTER]: RouterDialog,
@ -47,12 +31,9 @@ const DIALOG_CONTENTS: { [x: string]: any } = {
[MODES.SHOT_PREFETCH]: ShotPrefetchDialog,
};
export const Component = (props: Props) =>
props.mode && DIALOG_CONTENTS[props.mode]
? createElement(DIALOG_CONTENTS[props.mode])
: null;
const EditorDialogUnconnected = (props: Props) =>
props.mode && DIALOG_CONTENTS[props.mode] ? createElement(DIALOG_CONTENTS[props.mode]) : null;
export const EditorDialog = connect(
mapStateToProps
// mapDispatchToProps
)(Component);
const EditorDialog = connect(mapStateToProps)(EditorDialogUnconnected);
export { EditorDialog };

View file

@ -1,4 +1,4 @@
import React from 'react';
import React, { PureComponent } from 'react';
import { MODES } from '~/constants/modes';
import classnames from 'classnames';
@ -6,21 +6,34 @@ import { Icon } from '~/components/panels/Icon';
import { EditorDialog } from '~/components/panels/EditorDialog';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { setMode, startEditing, stopEditing, takeAShot, keyPressed } from '~/redux/user/actions';
import { IRootState } from "~/redux/user";
import { Tooltip } from "~/components/panels/Tooltip";
import {
editorSetMode,
editorStartEditing,
editorStopEditing,
editorTakeAShot,
editorKeyPressed,
} from '~/redux/editor/actions';
import { Tooltip } from '~/components/panels/Tooltip';
import { IState } from '~/redux/store';
import { selectEditor } from '~/redux/editor/selectors';
interface Props extends IRootState {
routing: IRootState['features']['routing'],
setMode: typeof setMode,
startEditing: typeof startEditing,
stopEditing: typeof stopEditing,
keyPressed: EventListenerOrEventListenerObject,
}
const mapStateToProps = (state: IState) => ({
editor: selectEditor(state),
});
class Component extends React.PureComponent<Props, void> {
const mapDispatchToProps = {
editorSetMode,
editorStartEditing,
editorStopEditing,
editorTakeAShot,
editorKeyPressed,
};
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
class EditorPanelUnconnected extends PureComponent<Props, void> {
componentDidMount() {
window.addEventListener('keydown', this.props.keyPressed);
window.addEventListener('keydown', this.props.editorKeyPressed as any);
const obj = document.getElementById('control-dialog');
const { width } = this.panel.getBoundingClientRect();
@ -33,29 +46,38 @@ class Component extends React.PureComponent<Props, void> {
panel: HTMLElement = null;
componentWillUnmount() {
window.removeEventListener('keydown', this.props.keyPressed);
window.removeEventListener('keydown', this.props.editorKeyPressed as any);
}
startPolyMode = () => this.props.setMode(MODES.POLY);
startStickerMode = () => this.props.setMode(MODES.STICKERS_SELECT);
startRouterMode = () => this.props.setMode(MODES.ROUTER);
startTrashMode = () => this.props.setMode(MODES.TRASH);
startPolyMode = () => this.props.editorSetMode(MODES.POLY);
startStickerMode = () => this.props.editorSetMode(MODES.STICKERS_SELECT);
startRouterMode = () => this.props.editorSetMode(MODES.ROUTER);
startTrashMode = () => this.props.editorSetMode(MODES.TRASH);
startSaveMode = () => {
// if (!this.props.changed) return;
this.props.setMode(MODES.SAVE);
this.props.editorSetMode(MODES.SAVE);
};
render() {
const {
mode, changed, editing, routing,
editor: {
mode,
changed,
editing,
features: { routing },
},
} = this.props;
return (
<div>
<div className={classnames('panel right', { active: editing })} ref={el => { this.panel = el; }}>
<div
className={classnames('panel right', { active: editing })}
ref={el => {
this.panel = el;
}}
>
<div className="control-bar control-bar-padded">
{
routing &&
{routing && (
<button
className={classnames({ active: mode === MODES.ROUTER })}
onClick={this.startRouterMode}
@ -63,8 +85,7 @@ class Component extends React.PureComponent<Props, void> {
<Tooltip>Автоматический маршрут</Tooltip>
<Icon icon="icon-route-2" />
</button>
}
)}
<button
className={classnames({ active: mode === MODES.POLY })}
@ -75,13 +96,14 @@ class Component extends React.PureComponent<Props, void> {
</button>
<button
className={classnames({ active: (mode === MODES.STICKERS || mode === MODES.STICKERS_SELECT) })}
className={classnames({
active: mode === MODES.STICKERS || mode === MODES.STICKERS_SELECT,
})}
onClick={this.startStickerMode}
>
<Tooltip>Точки маршрута</Tooltip>
<Icon icon="icon-sticker-3" />
</button>
</div>
<div className="control-sep" />
@ -99,10 +121,7 @@ class Component extends React.PureComponent<Props, void> {
<div className="control-sep" />
<div className="control-bar">
<button
className="highlighted cancel"
onClick={this.props.stopEditing}
>
<button className="highlighted cancel" onClick={this.props.editorStopEditing}>
<Icon icon="icon-cancel-1" />
</button>
@ -114,59 +133,21 @@ class Component extends React.PureComponent<Props, void> {
<Icon icon="icon-check-1" />
</button>
</div>
</div>
<div className={classnames('panel right', { active: !editing })}>
<div className="control-bar">
<button className="primary single" onClick={this.props.startEditing}>
<button className="primary single" onClick={this.props.editorStartEditing}>
<Icon icon="icon-route-2" />
<span>
РЕДАКТИРОВАТЬ
</span>
<span>РЕДАКТИРОВАТЬ</span>
</button>
</div>
</div>
<EditorDialog
width={((this.panel && this.panel.getBoundingClientRect().width) || 0)}
/>
<EditorDialog width={(this.panel && this.panel.getBoundingClientRect().width) || 0} />
</div>
);
}
}
function mapStateToProps(state) {
const {
user: {
editing,
mode,
changed,
features: {
routing,
}
},
} = state;
return {
editing,
mode,
changed,
routing,
};
}
const mapDispatchToProps = dispatch => bindActionCreators({
setMode,
// setLogo,
startEditing,
stopEditing,
takeAShot,
keyPressed,
}, dispatch);
export const EditorPanel = connect(
mapStateToProps,
mapDispatchToProps
)(Component);
export const EditorPanel = connect(mapStateToProps, mapDispatchToProps)(EditorPanelUnconnected);

View file

@ -1,36 +1,34 @@
// flow
import React, { useCallback } from 'react';
import { Icon } from '~/components/panels/Icon';
import { PROVIDERS } from '~/constants/providers';
import { LOGOS } from '~/constants/logos';
import * as USER_ACTIONS from '~/redux/user/actions';
import * as EDITOR_ACTIONS from '~/redux/editor/actions';
import { connect } from 'react-redux';
import { MODES } from '~/constants/modes';
import { IRootState } from '~/redux/user';
import { Tooltip } from '~/components/panels/Tooltip';
import { selectMap } from '~/redux/map/selectors';
import { selectUser } from '~/redux/user/selectors';
import { selectEditor } from '~/redux/editor/selectors';
const mapStateToProps = state => ({
map: selectMap(state),
user: selectUser(state),
editor: selectEditor(state),
});
const mapDispatchToProps = {
setMode: USER_ACTIONS.setMode,
editorSetMode: EDITOR_ACTIONS.editorSetMode,
};
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
const TopRightPanelUnconnected = ({
map: { provider, logo },
user: { markers_shown, editing },
setMode,
editor: { markers_shown, editing },
editorSetMode,
}: Props) => {
const startProviderMode = useCallback(() => setMode(MODES.PROVIDER), [setMode]);
const startLogoMode = useCallback(() => setMode(MODES.LOGO), [setMode]);
const clearMode = useCallback(() => setMode(MODES.NONE), [setMode]);
const startProviderMode = useCallback(() => editorSetMode(MODES.PROVIDER), [editorSetMode]);
const startLogoMode = useCallback(() => editorSetMode(MODES.LOGO), [editorSetMode]);
const clearMode = useCallback(() => editorSetMode(MODES.NONE), [editorSetMode]);
return (
<div className="status-panel top right">

View file

@ -4,35 +4,41 @@ import { GuestButton } from '~/components/user/GuestButton';
import { DEFAULT_USER, ROLES } from '~/constants/auth';
import { UserButton } from '~/components/user/UserButton';
import { UserMenu } from '~/components/user/UserMenu';
import { setUser, userLogout, gotVkUser, openMapDialog } from '~/redux/user/actions';
import {
setUser,
userLogout,
takeAShot,
setDialog,
gotVkUser,
setDialogActive,
openMapDialog,
getGPXTrack,
} from '~/redux/user/actions';
editorTakeAShot,
editorSetDialog,
editorSetDialogActive,
editorGetGPXTrack,
} from '~/redux/editor/actions';
import { connect } from 'react-redux';
import { Icon } from '~/components/panels/Icon';
import classnames from 'classnames';
import { CLIENT } from '~/config/frontend';
import { DIALOGS, TABS } from '~/constants/dialogs';
import { IRootState } from '~/redux/user';
import { Tooltip } from '~/components/panels/Tooltip';
import { TitleDialog } from '~/components/dialogs/TitleDialog';
interface Props extends IRootState {
userLogout: typeof userLogout;
setDialog: typeof setDialog;
setDialogActive: typeof setDialogActive;
gotVkUser: typeof gotVkUser;
takeAShot: typeof takeAShot;
openMapDialog: typeof openMapDialog;
getGPXTrack: typeof getGPXTrack;
}
const mapStateToProps = ({ user: { user }, editor: { dialog, dialog_active, is_empty } }) => ({
dialog,
dialog_active,
user,
is_empty,
});
const mapDispatchToProps = {
setUser,
userLogout,
editorTakeAShot,
editorSetDialog,
gotVkUser,
editorSetDialogActive,
openMapDialog,
editorGetGPXTrack,
};
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
interface State {
menuOpened: boolean;
@ -84,8 +90,8 @@ export class UserPanelUnconnected extends PureComponent<Props, State> {
openAppInfoDialog = () => {
this.setMenuOpened();
this.props.setDialog(DIALOGS.APP_INFO);
this.props.setDialogActive(this.props.dialog !== DIALOGS.APP_INFO);
this.props.editorSetDialog(DIALOGS.APP_INFO);
this.props.editorSetDialogActive(this.props.dialog !== DIALOGS.APP_INFO);
};
openOauthFrame = () => {
@ -143,7 +149,7 @@ export class UserPanelUnconnected extends PureComponent<Props, State> {
<div className="control-sep" />
<div className="control-bar">
<button className={classnames({ active: false })} onClick={this.props.takeAShot}>
<button className={classnames({ active: false })} onClick={this.props.editorTakeAShot}>
<Tooltip>Снимок карты</Tooltip>
<Icon icon="icon-shot-4" />
</button>
@ -153,7 +159,10 @@ export class UserPanelUnconnected extends PureComponent<Props, State> {
<div className="control-sep" />
<div className="control-bar">
<button className={classnames({ active: false })} onClick={this.props.getGPXTrack}>
<button
className={classnames({ active: false })}
onClick={this.props.editorGetGPXTrack}
>
<Tooltip>Экспорт GPX</Tooltip>
<Icon icon="icon-gpx-1" />
</button>
@ -166,24 +175,6 @@ export class UserPanelUnconnected extends PureComponent<Props, State> {
}
}
const mapStateToProps = ({ user: { dialog, dialog_active, user, is_empty } }) => ({
dialog,
dialog_active,
user,
is_empty,
});
const mapDispatchToProps = {
setUser,
userLogout,
takeAShot,
setDialog,
gotVkUser,
setDialogActive,
openMapDialog,
getGPXTrack,
};
const UserPanel = connect(mapStateToProps, mapDispatchToProps)(UserPanelUnconnected);
export { UserPanel };