redux: editor-panel: login-logout

This commit is contained in:
muerwre 2018-11-26 15:11:51 +07:00
parent e56e49acf4
commit 185fe80fc5
15 changed files with 314 additions and 260 deletions

View file

@ -3,29 +3,26 @@ import { LOGOS } from '$constants/logos';
import { Icon } from '$components/panels/Icon'; import { Icon } from '$components/panels/Icon';
import classnames from 'classnames'; import classnames from 'classnames';
export class LogoDialog extends React.Component { type Props = {
changeLogo = logo => { logo: String,
this.props.editor.changeLogo(logo); setLogo: Function,
}; }
render() { export const LogoDialog = ({ logo, setLogo }: Props) => (
return (
<div className="helper logo-helper"> <div className="helper logo-helper">
<div className="helper-back"> <div className="helper-back">
<Icon icon="icon-logo" size={200} /> <Icon icon="icon-logo" size={200} />
</div> </div>
{ {
Object.keys(LOGOS).map(logo => ( Object.keys(LOGOS).map(item => (
<div <div
className={classnames('helper-menu-item', { active: (logo === this.props.logo) })} className={classnames('helper-menu-item', { active: (item === logo) })}
onClick={() => this.changeLogo(logo)} onClick={() => setLogo(item)}
key={logo} key={item}
> >
{LOGOS[logo][0]} {LOGOS[item][0]}
</div> </div>
)) ))
} }
</div> </div>
); );
}
}

View file

@ -7,10 +7,23 @@ import { TrashDialog } from '$components/trash/TrashDialog';
import { LogoDialog } from '$components/logo/LogoDialog'; import { LogoDialog } from '$components/logo/LogoDialog';
import { SaveDialog } from '$components/save/SaveDialog'; import { SaveDialog } from '$components/save/SaveDialog';
import { CancelDialog } from '$components/save/CancelDialog'; import { CancelDialog } from '$components/save/CancelDialog';
import type { UserType } from '$constants/types';
type Props = {
mode: String,
routerPoints: Number,
editor: Object,
activeSticker: String,
logo: String,
user: UserType,
title: String,
address: String,
setLogo: Function,
}
export const EditorDialog = ({ export const EditorDialog = ({
mode, routerPoints, editor, activeSticker, logo, user, title, address, mode, routerPoints, editor, activeSticker, logo, user, title, address, setLogo
}) => { }: Props) => {
const showDialog = ( const showDialog = (
mode === MODES.ROUTER mode === MODES.ROUTER
|| (mode === MODES.STICKERS && !activeSticker) || (mode === MODES.STICKERS && !activeSticker)
@ -26,7 +39,7 @@ export const EditorDialog = ({
{ mode === MODES.ROUTER && <RouterDialog routerPoints={routerPoints} editor={editor} /> } { mode === MODES.ROUTER && <RouterDialog routerPoints={routerPoints} editor={editor} /> }
{ mode === MODES.STICKERS && <StickersDialog editor={editor} /> } { mode === MODES.STICKERS && <StickersDialog editor={editor} /> }
{ mode === MODES.TRASH && <TrashDialog editor={editor} /> } { mode === MODES.TRASH && <TrashDialog editor={editor} /> }
{ mode === MODES.LOGO && <LogoDialog editor={editor} logo={logo} /> } { mode === MODES.LOGO && <LogoDialog editor={editor} logo={logo} setLogo={setLogo} /> }
{ mode === MODES.SAVE && <SaveDialog editor={editor} user={user} title={title} address={address} /> } { mode === MODES.SAVE && <SaveDialog editor={editor} user={user} title={title} address={address} /> }
{ mode === MODES.CONFIRM_CANCEL && <CancelDialog editor={editor} /> } { mode === MODES.CONFIRM_CANCEL && <CancelDialog editor={editor} /> }
</div> </div>

View file

@ -9,7 +9,7 @@ import { EditorDialog } from '$components/panels/EditorDialog';
import { LogoPreview } from '$components/logo/LogoPreview'; import { LogoPreview } from '$components/logo/LogoPreview';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { setMode, startEditing, stopEditing } from '$redux/user/actions'; import { setMode, startEditing, stopEditing, setLogo } from '$redux/user/actions';
import type { UserType } from '$constants/types'; import type { UserType } from '$constants/types';
import { editor } from '$modules/Editor'; import { editor } from '$modules/Editor';
@ -29,7 +29,7 @@ type Props = {
setMode: Function, setMode: Function,
startEditing: Function, startEditing: Function,
stopEditing: Function, stopEditing: Function,
setLogo: Function,
} }
class Component extends React.PureComponent<Props, void> { class Component extends React.PureComponent<Props, void> {
@ -76,6 +76,7 @@ class Component extends React.PureComponent<Props, void> {
user={user} user={user}
title={title} title={title}
address={address} address={address}
setLogo={this.props.setLogo}
/> />
<LogoPreview logo={logo} /> <LogoPreview logo={logo} />
@ -209,6 +210,7 @@ function mapStateToProps(state) {
const mapDispatchToProps = dispatch => bindActionCreators({ const mapDispatchToProps = dispatch => bindActionCreators({
setMode, setMode,
setLogo,
startEditing, startEditing,
stopEditing, stopEditing,
}, dispatch); }, dispatch);

View file

@ -5,8 +5,18 @@ import { SERVER } from '$constants/api';
import { DEFAULT_USER, ROLES } from '$constants/auth'; import { DEFAULT_USER, ROLES } from '$constants/auth';
import { UserButton } from '$components/user/UserButton'; import { UserButton } from '$components/user/UserButton';
import { UserMenu } from '$components/user/UserMenu'; import { UserMenu } from '$components/user/UserMenu';
import { setUser, userLogout } from '$redux/user/actions';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import type { UserType } from '$constants/types';
export class UserPanel extends React.PureComponent { type Props = {
user: UserType,
userLogout: Function,
setUser: Function,
};
export class Component extends React.PureComponent<Props, void> {
state = { state = {
menuOpened: false, menuOpened: false,
}; };
@ -56,7 +66,7 @@ export class UserPanel extends React.PureComponent {
render() { render() {
const { const {
props: { user, userLogout, editor, editing }, props: { user },
state: { menuOpened }, state: { menuOpened },
} = this; } = this;
@ -71,7 +81,7 @@ export class UserPanel extends React.PureComponent {
} }
{ {
(user && user.role && user.role !== 'guest' && menuOpened) && (user && user.role && user.role !== 'guest' && menuOpened) &&
<UserMenu user={user} userLogout={userLogout} /> <UserMenu user={user} userLogout={this.props.userLogout} />
} }
</div> </div>
</div> </div>
@ -79,3 +89,20 @@ export class UserPanel extends React.PureComponent {
); );
} }
} }
function mapStateToProps(state) {
const { user: { user } } = state;
return { user };
}
const mapDispatchToProps = dispatch => bindActionCreators({
setUser,
userLogout,
}, dispatch);
export const UserPanel = connect(
mapStateToProps,
mapDispatchToProps
)(Component);

View file

@ -1,8 +1,14 @@
// @flow
import React from 'react'; import React from 'react';
export const GuestButton = ({ onClick }) => ( type Props = {
onClick: Function,
}
export const GuestButton = ({ onClick }: Props) => (
<div className="control-bar user-bar"> <div className="control-bar user-bar">
<button <button
className="user-bar-guest"
onClick={onClick} onClick={onClick}
> >
<span>ВОЙТИ</span> <span>ВОЙТИ</span>

View file

@ -1,23 +1,29 @@
// @flow
import React from 'react'; import React from 'react';
import { UserPicture } from '$components/user/UserPicture'; import { UserPicture } from '$components/user/UserPicture';
import type { UserType } from '$constants/types';
type Props = {
user: UserType,
setMenuOpened: Function,
};
const getUserName = name => name.split(' ')[0];
export const UserButton = ({ export const UserButton = ({
setMenuOpened, setMenuOpened,
user: { user: {
id, id,
userdata: { userdata: { name, photo }
name,
photo,
} }
} }: Props) => (
}) => (
<div className="control-bar user-bar"> <div className="control-bar user-bar">
<div className="user-button" onClick={setMenuOpened}> <div className="user-button" onClick={setMenuOpened}>
<UserPicture photo={photo} /> <UserPicture photo={photo} />
<div className="user-button-fields"> <div className="user-button-fields">
<div className="user-button-name">{(name || id || '...')}</div> <div className="user-button-name">{((name && getUserName(name)) || id || '...')}</div>
<div className="user-button-text">{(id || 'пользователь')}</div> <div className="user-button-text">{((name && id) || 'пользователь')}</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,14 +1,11 @@
import React from 'react'; import React from 'react';
export const UserMenu = ({ userLogout, user: { id, userdata: { agent, ip } } }) => ( type Props = {
userLogout: Function,
}
export const UserMenu = ({ userLogout }: Props) => (
<div className="user-panel-menu"> <div className="user-panel-menu">
<div className="user-panel-text small">
<div>Мы храним следующие данные о вас:</div>
{ id && <div><u>ID:</u> {id}</div> }
{ agent && <div><u>Браузер:</u> {agent}</div> }
{ ip && <div><u>Адрес:</u> {ip}</div> }
<div>Мы используем их для авторизации и исправления ошибок.</div>
</div>
<a className="user-panel-item gray" href="https://github.com/muerwre/orchidMap" target="_blank" rel="noopener noreferrer"> <a className="user-panel-item gray" href="https://github.com/muerwre/orchidMap" target="_blank" rel="noopener noreferrer">
Проект на github Проект на github
</a> </a>
@ -17,3 +14,13 @@ export const UserMenu = ({ userLogout, user: { id, userdata: { agent, ip } } })
</div> </div>
</div> </div>
); );
/*
<div className="user-panel-text small">
<div>Мы храним следующие данные о вас:</div>
{ id && <div><u>ID:</u> {id}</div> }
{ agent && <div><u>Браузер:</u> {agent}</div> }
{ ip && <div><u>Адрес:</u> {ip}</div> }
<div>Мы используем их для авторизации и исправления ошибок.</div>
</div>
*/

View file

@ -1,3 +1,7 @@
import { providers } from '$constants/providers';
export const CONFIG = { export const CONFIG = {
OSRM_URL: 'http://vault48.org:5000/route/v1', OSRM_URL: 'http://vault48.org:5000/route/v1',
}; };
export const PROVIDER = providers.blank;

View file

@ -4,12 +4,8 @@ import React from 'react';
import { editor } from '$modules/Editor'; import { editor } from '$modules/Editor';
import { EditorPanel } from '$components/panels/EditorPanel'; import { EditorPanel } from '$components/panels/EditorPanel';
import { Fills } from '$components/Fills'; import { Fills } from '$components/Fills';
import { DEFAULT_LOGO } from '$constants/logos';
import { UserLocation } from '$components/UserLocation'; import { UserLocation } from '$components/UserLocation';
import { DEFAULT_USER } from '$constants/auth';
import { storeData, getData } from '$utils/storage';
import { UserPanel } from '$components/panels/UserPanel'; import { UserPanel } from '$components/panels/UserPanel';
import { pushPath } from '$utils/history';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
@ -17,44 +13,26 @@ import { hot } from 'react-hot-loader';
import type { UserType } from '$constants/types'; import type { UserType } from '$constants/types';
type Props = { type Props = {
// todo: clean this!
user: UserType, user: UserType,
editing: false,
mode: String,
changed: Boolean,
distance: Number,
title: String,
address: String,
mode: String,
editing: Boolean,
logo: String,
routerPoints: Number,
estimateTime: Number,
activeSticker: String,
title: String,
address: String,
} }
type State = {
} class Component extends React.Component<Props, void> {
// state = {
class Component extends React.Component<Props, State> { // // mode: 'none',
state = { // // editing: false,
// mode: 'none', // logo: DEFAULT_LOGO,
// editing: false, // routerPoints: 0,
logo: DEFAULT_LOGO, // totalDistance: 0,
routerPoints: 0, // estimateTime: 0,
totalDistance: 0, // activeSticker: null,
estimateTime: 0, // // user: {
activeSticker: null, // // ...DEFAULT_USER,
// user: { // // },
// ...DEFAULT_USER, // // title: '',
// }, // // address: '',
// title: '', // // changed: false,
// address: '', // };
// changed: false,
};
componentDidMount() { componentDidMount() {
// this.authInit(); // this.authInit();
@ -79,76 +57,76 @@ class Component extends React.Component<Props, State> {
// this.startEmptyEditor(); // this.startEmptyEditor();
// } // }
// }; // };
startEmptyEditor = () => {
const { user } = this.state;
if (!user || !user.random_url || !user.id) return;
pushPath(`/${user.random_url}/edit`);
editor.owner = user.id;
editor.startEditing();
this.hideLoader();
this.clearChanged();
};
setTitle = title => this.setState({ title });
setAddress = address => {
this.setState({ address });
};
getTitle = () => this.state.title;
setDataOnLoad = data => {
this.clearChanged();
editor.setData(data);
this.hideLoader();
};
hideLoader = () => {
document.getElementById('loader').style.opacity = 0;
document.getElementById('loader').style.pointerEvents = 'none';
};
setMode = mode => {
this.setState({ mode });
};
setRouterPoints = routerPoints => {
this.setState({ routerPoints });
};
setTotalDist = totalDistance => {
const time = (totalDistance && (totalDistance / 15)) || 0;
const estimateTime = (time && parseFloat(time.toFixed(1)));
this.setState({ totalDistance, estimateTime });
};
setActiveSticker = activeSticker => {
this.setState({ activeSticker });
};
setLogo = logo => {
this.setState({ logo });
};
setEditing = editing => {
this.setState({ editing });
};
getUser = () => this.state.user;
// //
// triggerOnChange = () => { // startEmptyEditor = () => {
// if (!this.state.editing) return; // const { user } = this.state;
// if (!user || !user.random_url || !user.id) return;
// //
// this.setState({ changed: true }); // pushPath(`/${user.random_url}/edit`);
//
// editor.owner = user.id;
// editor.startEditing();
//
// this.hideLoader();
//
// this.clearChanged();
// };
//
// setTitle = title => this.setState({ title });
// setAddress = address => {
// this.setState({ address });
// };
//
// getTitle = () => this.state.title;
//
// setDataOnLoad = data => {
// this.clearChanged();
// editor.setData(data);
// this.hideLoader();
// };
//
// hideLoader = () => {
// document.getElementById('loader').style.opacity = 0;
// document.getElementById('loader').style.pointerEvents = 'none';
// };
//
// setMode = mode => {
// this.setState({ mode });
// };
//
// setRouterPoints = routerPoints => {
// this.setState({ routerPoints });
// };
//
// setTotalDist = totalDistance => {
// const time = (totalDistance && (totalDistance / 15)) || 0;
// const estimateTime = (time && parseFloat(time.toFixed(1)));
// this.setState({ totalDistance, estimateTime });
// };
//
// setActiveSticker = activeSticker => {
// this.setState({ activeSticker });
// };
//
// setLogo = logo => {
// this.setState({ logo });
// };
//
// setEditing = editing => {
// this.setState({ editing });
// };
//
// getUser = () => this.state.user;
// //
// // triggerOnChange = () => {
// // if (!this.state.editing) return;
// //
// // this.setState({ changed: true });
// // };
//
// clearChanged = () => {
// this.setState({ changed: false });
// }; // };
clearChanged = () => {
this.setState({ changed: false });
};
// editor = new Editor({ // editor = new Editor({
// container: 'map', // container: 'map',
@ -186,45 +164,43 @@ class Component extends React.Component<Props, State> {
// } // }
// }; // };
setUser = user => { // setUser = user => {
if (!user.token || !user.id) return; // if (!user.token || !user.id) return;
if (this.state.user.id === editor.owner) {
editor.owner = user.id;
}
this.setState({
user: {
...DEFAULT_USER,
...user,
}
});
this.storeUserData();
};
storeUserData = () => {
storeData('user', this.state.user);
};
getUserData = () => getData('user') || null;
userLogout = () => {
if (this.state.user.id === editor.owner) {
editor.owner = null;
}
// //
this.setState({ // if (this.state.user.id === editor.owner) {
user: DEFAULT_USER, // editor.owner = user.id;
}); // }
//
// this.setState({
// user: {
// ...DEFAULT_USER,
// ...user,
// }
// });
//
// this.storeUserData();
// };
setTimeout(this.storeUserData, 0); // storeUserData = () => {
}; // storeData('user', this.state.user);
// };
// getUserData = () => getData('user') || null;
//
// userLogout = () => {
// if (this.state.user.id === editor.owner) {
// editor.owner = null;
// }
// //
// this.setState({
// user: DEFAULT_USER,
// });
//
// setTimeout(this.storeUserData, 0);
// };
render() { render() {
const { const { props: { user } } = this;
props: { user }
} = this;
return ( return (
<div> <div>
@ -235,8 +211,8 @@ class Component extends React.Component<Props, State> {
<UserPanel <UserPanel
editor={editor} editor={editor}
user={user} user={user}
setUser={this.setUser} // setUser={this.setUser}
userLogout={this.userLogout} // userLogout={this.userLogout}
/> />
<EditorPanel /> <EditorPanel />

View file

@ -14,31 +14,19 @@ import {
setChanged, setChanged,
setDistance, setDistance,
setEditing, setEditing,
setLogo, setLogo, setMode,
setRouterPoints, setRouterPoints,
setTitle setTitle
} from '$redux/user/actions'; } from '$redux/user/actions';
export class Editor { export class Editor {
constructor({ constructor() {
// container,
// mode,
// setMode,
// setRouterPoints,
// setTotalDist,
// setEditing,
// triggerOnChange,
// getTitle,
// clearChanged,
// setActiveSticker,
// setLogo,
// setTitle,
// setAddress,
}) {
this.logo = DEFAULT_LOGO; this.logo = DEFAULT_LOGO;
this.owner = null; this.owner = null;
this.map = new Map({ container: 'map' }); this.map = new Map({ container: 'map' });
this.initialData = {}; this.initialData = {};
this.activeSticker = null;
this.mode = MODES.NONE;
const { const {
triggerOnChange, lockMapClicks, routerMoveStart, changeMode, pushPolyPoints, triggerOnChange, lockMapClicks, routerMoveStart, changeMode, pushPolyPoints,
@ -81,8 +69,6 @@ export class Editor {
[MODES.ROUTER]: this.router.pushWaypointOnClick, [MODES.ROUTER]: this.router.pushWaypointOnClick,
}; };
this.activeSticker = null;
this.mode = MODES.NONE;
// this.clearChanged = clearChanged; // this.clearChanged = clearChanged;
// this.setActiveSticker = setActiveSticker; // this.setActiveSticker = setActiveSticker;
// this.setLogo = setLogo; // this.setLogo = setLogo;
@ -104,6 +90,7 @@ export class Editor {
getChanged = () => store.getState().user.changed; getChanged = () => store.getState().user.changed;
setEditing = value => store.dispatch(setEditing(value)); setEditing = value => store.dispatch(setEditing(value));
setMode = value => store.dispatch(setMode(value));
setDistance = value => store.dispatch(setDistance(value)); setDistance = value => store.dispatch(setDistance(value));
setChanged = value => store.dispatch(setChanged(value)); setChanged = value => store.dispatch(setChanged(value));
setRouterPoints = value => store.dispatch(setRouterPoints(value)); setRouterPoints = value => store.dispatch(setRouterPoints(value));
@ -121,17 +108,20 @@ export class Editor {
}; };
createStickerOnClick = (e) => { createStickerOnClick = (e) => {
// todo: move to sagas?
if (!e || !e.latlng || !this.activeSticker) return; if (!e || !e.latlng || !this.activeSticker) return;
const { latlng } = e; const { latlng } = e;
this.stickers.createSticker({ latlng, sticker: this.activeSticker }); this.stickers.createSticker({ latlng, sticker: this.activeSticker });
this.setSticker(null); this.setActiveSticker(null);
}; };
changeMode = mode => { changeMode = mode => {
// todo: check if TOGGLING works (we changing MODE from the sagas now)
if (this.mode === mode) { if (this.mode === mode) {
if (this.switches[mode] && this.switches[mode].toggle) { if (this.switches[mode] && this.switches[mode].toggle) {
this.switches[mode].toggle(); // if we have special function on mode when it toggles // if we have special function on mode when it clicked again
this.switches[mode].toggle();
} else { } else {
this.disableMode(mode); this.disableMode(mode);
// this.setMode(MODES.NONE); // this.setMode(MODES.NONE);
@ -154,7 +144,7 @@ export class Editor {
}; };
onClick = e => { onClick = e => {
if (e.originalEvent.which === 3) return; // skip right click if (e.originalEvent.which === 3) return; // skip right / middle click
if (this.clickHandlers[this.mode]) this.clickHandlers[this.mode](e); if (this.clickHandlers[this.mode]) this.clickHandlers[this.mode](e);
}; };
@ -190,45 +180,47 @@ export class Editor {
this.poly.pushPoints(latlngs); this.poly.pushPoints(latlngs);
}; };
setSticker = sticker => { // setSticker = sticker => {
this.activeSticker = sticker; // this.activeSticker = sticker;
this.setActiveSticker(sticker); // this.setActiveSticker(sticker);
}; // };
clearSticker = () => { clearSticker = () => {
if (this.activeSticker) { if (this.activeSticker) {
this.setSticker(null); this.setActiveSticker(null);
} else { } else {
this.changeMode(MODES.NONE); this.setMode(MODES.NONE);
} }
}; };
clearAll = () => { clearAll = () => {
// todo: move to sagas
this.poly.clearAll(); this.poly.clearAll();
this.router.clearAll(); this.router.clearAll();
this.stickers.clearAll(); this.stickers.clearAll();
this.setSticker(null); this.setActiveSticker(null);
this.changeMode(MODES.NONE); this.setMode(MODES.NONE);
this.clearChanged(); this.clearChanged();
}; };
changeLogo = logo => { changeLogo = logo => {
// todo: move to sagas
this.logo = logo; this.logo = logo;
this.setLogo(logo); this.setLogo(logo);
this.changeMode(MODES.NONE); this.changeMode(MODES.NONE);
}; };
setData = ({ route, stickers, version = 1, owner, title, address }) => { setData = ({
route, stickers, version = 1, owner, title, address
}) => {
this.setTitle(title || ''); this.setTitle(title || '');
const { id } = this.getUser(); const { id } = this.getUser();
if (address && id && owner && id === owner) this.setAddress(address); if (address && id && owner && id === owner) this.setAddress(address);
if (route) { if (route) this.poly.setPoints(route);
this.poly.setPoints(route);
}
if (stickers) { if (stickers) {
stickers.map(sticker => this.stickers.createSticker({ stickers.map(sticker => this.stickers.createSticker({
@ -238,9 +230,7 @@ export class Editor {
})); }));
} }
if (owner) { if (owner) this.owner = owner;
this.owner = owner;
}
if (!route || route.length <= 1) return; if (!route || route.length <= 1) return;
@ -258,7 +248,7 @@ export class Editor {
version: 2, version: 2,
title: this.getTitle(), title: this.getTitle(),
owner: this.owner, owner: this.owner,
address: this.owner === id ? path : null, address: (this.owner === id ? path : null),
path, path,
route, route,
stickers, stickers,
@ -278,19 +268,19 @@ export class Editor {
if (this.poly.latlngs && this.poly.latlngs.length > 1) this.poly.poly.enableEdit(); if (this.poly.latlngs && this.poly.latlngs.length > 1) this.poly.poly.enableEdit();
this.stickers.startEditing(); this.stickers.startEditing();
// this.setEditing(true);
console.log(this.initialData); // this.setEditing(true);
// console.log(this.initialData);
}; };
stopEditing = () => { stopEditing = () => {
const { path } = getUrlData(); const { path } = getUrlData();
pushPath(`/${(this.initialData && this.initialData.path) || path}`); pushPath(`/${(this.initialData && this.initialData.path) || path}`);
this.changeMode(MODES.NONE); // this.changeMode(MODES.NONE);
this.poly.poly.disableEdit(); this.poly.poly.disableEdit();
this.stickers.stopEditing(); this.stickers.stopEditing();
this.setEditing(false); // this.setEditing(false);
}; };
cancelEditing = () => { cancelEditing = () => {
@ -313,11 +303,11 @@ export class Editor {
stickers: this.stickers.dumpData(), stickers: this.stickers.dumpData(),
}); });
isEmpty = () => { // isEmpty = () => {
const { route, stickers } = this.dumpData(); // const { route, stickers } = this.dumpData();
//
return (route.length > 1 && stickers.length > 0); // return (route.length > 1 && stickers.length > 0);
}; // };
hasEmptyHistory = () => { hasEmptyHistory = () => {
const { route, stickers } = this.initialData; const { route, stickers } = this.initialData;
@ -326,18 +316,4 @@ export class Editor {
} }
} }
export const editor = new Editor({ export const editor = new Editor({});
// setMode: this.setMode,
// setTotalDist: this.setTotalDist,
// setEditing: this.setEditing,
// getUser: this.getUser,
// triggerOnChange: this.triggerOnChange,
// getTitle: this.getTitle,
// setRouterPoints: this.setRouterPoints,
// setActiveSticker: this.setActiveSticker,
// setLogo: this.setLogo,
// setTitle: this.setTitle,
// setAddress: this.setAddress,
// clearChanged: this.clearChanged,
});

View file

@ -1,14 +1,14 @@
import { map, tileLayer } from 'leaflet'; import { map, tileLayer } from 'leaflet';
import { providers } from '$constants/providers';
import 'leaflet/dist/leaflet.css'; import 'leaflet/dist/leaflet.css';
import 'leaflet-editable'; import 'leaflet-editable';
import { PROVIDER } from '$config';
export class Map { export class Map {
constructor({ container }) { constructor({ container }) {
this.map = map(container, { editable: true }).setView([55.0153275, 82.9071235], 13); this.map = map(container, { editable: true }).setView([55.0153275, 82.9071235], 13);
this.tileLayer = tileLayer(providers.default, { this.tileLayer = tileLayer(PROVIDER, {
attribution: 'Независимое Велосообщество', attribution: 'Независимое Велосообщество',
maxNativeZoom: 18, maxNativeZoom: 18,
maxZoom: 18, maxZoom: 18,

View file

@ -1,6 +1,9 @@
import { ACTIONS } from '$redux/user/constants'; import { ACTIONS } from '$redux/user/constants';
export const setUser = user => ({ type: ACTIONS.SET_USER, user }); export const setUser = user => ({ type: ACTIONS.SET_USER, user });
export const userLogout = user => ({ type: ACTIONS.USER_LOGOUT });
export const setEditing = editing => ({ type: ACTIONS.SET_EDITING, editing }); export const setEditing = editing => ({ type: ACTIONS.SET_EDITING, editing });
export const setMode = mode => ({ type: ACTIONS.SET_MODE, mode }); export const setMode = mode => ({ type: ACTIONS.SET_MODE, mode });
export const setDistance = distance => ({ type: ACTIONS.SET_DISTANCE, distance }); export const setDistance = distance => ({ type: ACTIONS.SET_DISTANCE, distance });

View file

@ -1,7 +1,8 @@
export const ACTIONS = { export const ACTIONS = {
SET_USER: 'SET_USER', SET_USER: 'SET_USER',
SET_EDITING: 'SET_EDITING', USER_LOGOUT: 'USER_LOGOUT',
SET_EDITING: 'SET_EDITING',
SET_MODE: 'SET_MODE', SET_MODE: 'SET_MODE',
SET_DISTANCE: 'SET_DISTANCE', SET_DISTANCE: 'SET_DISTANCE',
SET_CHANGED: 'SET_CHANGED', SET_CHANGED: 'SET_CHANGED',

View file

@ -6,6 +6,7 @@ import { getUrlData, pushPath } from '$utils/history';
import { editor } from '$modules/Editor'; import { editor } from '$modules/Editor';
import { ACTIONS } from '$redux/user/constants'; import { ACTIONS } from '$redux/user/constants';
import { MODES } from '$constants/modes'; import { MODES } from '$constants/modes';
import { DEFAULT_USER } from '$constants/auth';
const getUser = state => (state.user.user); const getUser = state => (state.user.user);
const getState = state => (state.user); const getState = state => (state.user);
@ -101,12 +102,40 @@ function* stopEditingSaga() {
} }
} }
function* userLogoutSaga() {
const { id } = yield select(getUser);
if (id === editor.owner) {
editor.owner = null;
}
yield put(setUser(DEFAULT_USER));
yield call(generateGuestSaga);
}
function* setActiveStickerSaga({ activeSticker }) {
yield editor.activeSticker = activeSticker;
return true;
}
function* setLogoSaga({ logo }) {
const { mode } = yield select(getState);
editor.logo = logo;
if (mode === MODES.LOGO) {
yield put(setMode(MODES.NONE));
}
}
export function* userSaga() { export function* userSaga() {
// Login // ASYNCHRONOUS!!! :-)
// yield takeLatest(AUTH_ACTIONS.SEND_LOGIN_REQUEST, sendLoginRequestSaga);
yield takeLatest(REHYDRATE, authChechSaga); yield takeLatest(REHYDRATE, authChechSaga);
yield takeEvery(ACTIONS.SET_MODE, setModeSaga); yield takeEvery(ACTIONS.SET_MODE, setModeSaga);
yield takeEvery(ACTIONS.START_EDITING, startEditingSaga); yield takeEvery(ACTIONS.START_EDITING, startEditingSaga);
yield takeEvery(ACTIONS.STOP_EDITING, stopEditingSaga); yield takeEvery(ACTIONS.STOP_EDITING, stopEditingSaga);
yield takeEvery(ACTIONS.USER_LOGOUT, userLogoutSaga);
yield takeEvery(ACTIONS.SET_ACTIVE_STICKER, setActiveStickerSaga);
yield takeEvery(ACTIONS.SET_LOGO, setLogoSaga);
} }

View file

@ -1,13 +1,17 @@
.user-bar { .user-bar {
width: 240px; // width: 160px;
.button { .button {
width: 100%; width: 100%;
} }
} }
.user-bar-guest {
width: 168px;
}
.user-button { .user-button {
width: 100%; width: 120px;
padding-left: 48px;
height: 48px; height: 48px;
display: flex; display: flex;
@ -22,6 +26,9 @@
background-position: 50% 50%; background-position: 50% 50%;
background: rgba(0,0,0,0.3); background: rgba(0,0,0,0.3);
border-radius: 3px 0 0 3px; border-radius: 3px 0 0 3px;
position: absolute;
left: 0;
top: 0;
} }
.user-button-fields { .user-button-fields {