From 185fe80fc53060b5eae8a17e22008d3090ee49f1 Mon Sep 17 00:00:00 2001
From: muerwre <gotham48@gmail.com>
Date: Mon, 26 Nov 2018 15:11:51 +0700
Subject: [PATCH] redux: editor-panel: login-logout

---
 src/components/logo/LogoDialog.jsx     |  47 +++--
 src/components/panels/EditorDialog.jsx |  19 +-
 src/components/panels/EditorPanel.jsx  |   6 +-
 src/components/panels/UserPanel.jsx    |  33 +++-
 src/components/user/GuestButton.jsx    |   8 +-
 src/components/user/UserButton.jsx     |  22 ++-
 src/components/user/UserMenu.jsx       |  23 ++-
 src/config.js                          |   4 +
 src/containers/App.jsx                 | 260 +++++++++++--------------
 src/modules/Editor.js                  |  98 ++++------
 src/modules/Map.js                     |   4 +-
 src/redux/user/actions.js              |   3 +
 src/redux/user/constants.js            |   3 +-
 src/redux/user/sagas.js                |  33 +++-
 src/styles/user-button.less            |  11 +-
 15 files changed, 314 insertions(+), 260 deletions(-)

diff --git a/src/components/logo/LogoDialog.jsx b/src/components/logo/LogoDialog.jsx
index 4b7bdf6..d54c3f4 100644
--- a/src/components/logo/LogoDialog.jsx
+++ b/src/components/logo/LogoDialog.jsx
@@ -3,29 +3,26 @@ import { LOGOS } from '$constants/logos';
 import { Icon } from '$components/panels/Icon';
 import classnames from 'classnames';
 
-export class LogoDialog extends React.Component {
-  changeLogo = logo => {
-    this.props.editor.changeLogo(logo);
-  };
-
-  render() {
-    return (
-      <div className="helper logo-helper">
-        <div className="helper-back">
-          <Icon icon="icon-logo" size={200} />
-        </div>
-        {
-          Object.keys(LOGOS).map(logo => (
-            <div
-              className={classnames('helper-menu-item', { active: (logo === this.props.logo) })}
-              onClick={() => this.changeLogo(logo)}
-              key={logo}
-            >
-              {LOGOS[logo][0]}
-            </div>
-          ))
-        }
-      </div>
-    );
-  }
+type Props = {
+  logo: String,
+  setLogo: Function,
 }
+
+export const LogoDialog = ({ logo, setLogo }: Props)  => (
+  <div className="helper logo-helper">
+    <div className="helper-back">
+      <Icon icon="icon-logo" size={200} />
+    </div>
+    {
+      Object.keys(LOGOS).map(item => (
+        <div
+          className={classnames('helper-menu-item', { active: (item === logo) })}
+          onClick={() => setLogo(item)}
+          key={item}
+        >
+          {LOGOS[item][0]}
+        </div>
+      ))
+    }
+  </div>
+);
diff --git a/src/components/panels/EditorDialog.jsx b/src/components/panels/EditorDialog.jsx
index 60a54ce..ba40897 100644
--- a/src/components/panels/EditorDialog.jsx
+++ b/src/components/panels/EditorDialog.jsx
@@ -7,10 +7,23 @@ import { TrashDialog } from '$components/trash/TrashDialog';
 import { LogoDialog } from '$components/logo/LogoDialog';
 import { SaveDialog } from '$components/save/SaveDialog';
 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 = ({
-  mode, routerPoints, editor, activeSticker, logo, user, title, address,
-}) => {
+  mode, routerPoints, editor, activeSticker, logo, user, title, address, setLogo
+}: Props) => {
   const showDialog = (
     mode === MODES.ROUTER
     || (mode === MODES.STICKERS && !activeSticker)
@@ -26,7 +39,7 @@ export const EditorDialog = ({
         { mode === MODES.ROUTER && <RouterDialog routerPoints={routerPoints} editor={editor} /> }
         { mode === MODES.STICKERS && <StickersDialog 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.CONFIRM_CANCEL && <CancelDialog editor={editor} /> }
       </div>
diff --git a/src/components/panels/EditorPanel.jsx b/src/components/panels/EditorPanel.jsx
index 8f86f73..dd3f64a 100644
--- a/src/components/panels/EditorPanel.jsx
+++ b/src/components/panels/EditorPanel.jsx
@@ -9,7 +9,7 @@ import { EditorDialog } from '$components/panels/EditorDialog';
 import { LogoPreview } from '$components/logo/LogoPreview';
 import { bindActionCreators } from '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 { editor } from '$modules/Editor';
 
@@ -29,7 +29,7 @@ type Props = {
   setMode: Function,
   startEditing: Function,
   stopEditing: Function,
-
+  setLogo: Function,
 }
 
 class Component extends React.PureComponent<Props, void> {
@@ -76,6 +76,7 @@ class Component extends React.PureComponent<Props, void> {
           user={user}
           title={title}
           address={address}
+          setLogo={this.props.setLogo}
         />
 
         <LogoPreview logo={logo} />
@@ -209,6 +210,7 @@ function mapStateToProps(state) {
 
 const mapDispatchToProps = dispatch => bindActionCreators({
   setMode,
+  setLogo,
   startEditing,
   stopEditing,
 }, dispatch);
diff --git a/src/components/panels/UserPanel.jsx b/src/components/panels/UserPanel.jsx
index 1bb564c..a3e2e92 100644
--- a/src/components/panels/UserPanel.jsx
+++ b/src/components/panels/UserPanel.jsx
@@ -5,8 +5,18 @@ import { SERVER } from '$constants/api';
 import { DEFAULT_USER, ROLES } from '$constants/auth';
 import { UserButton } from '$components/user/UserButton';
 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 = {
     menuOpened: false,
   };
@@ -56,7 +66,7 @@ export class UserPanel extends React.PureComponent {
 
   render() {
     const {
-      props: { user, userLogout, editor, editing },
+      props: { user },
       state: { menuOpened },
     } = this;
 
@@ -71,7 +81,7 @@ export class UserPanel extends React.PureComponent {
             }
             {
               (user && user.role && user.role !== 'guest' && menuOpened) &&
-              <UserMenu user={user} userLogout={userLogout} />
+              <UserMenu user={user} userLogout={this.props.userLogout} />
             }
           </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);
diff --git a/src/components/user/GuestButton.jsx b/src/components/user/GuestButton.jsx
index 51989eb..51cfd96 100644
--- a/src/components/user/GuestButton.jsx
+++ b/src/components/user/GuestButton.jsx
@@ -1,8 +1,14 @@
+// @flow
 import React from 'react';
 
-export const GuestButton = ({ onClick }) => (
+type Props = {
+  onClick: Function,
+}
+
+export const GuestButton = ({ onClick }: Props) => (
   <div className="control-bar user-bar">
     <button
+      className="user-bar-guest"
       onClick={onClick}
     >
       <span>ВОЙТИ</span>
diff --git a/src/components/user/UserButton.jsx b/src/components/user/UserButton.jsx
index 29e3b16..eddd353 100644
--- a/src/components/user/UserButton.jsx
+++ b/src/components/user/UserButton.jsx
@@ -1,23 +1,29 @@
+// @flow
 import React from 'react';
 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 = ({
   setMenuOpened,
   user: {
-   id,
-   userdata: {
-     name,
-     photo,
-   }
+    id,
+    userdata: { name, photo }
   }
-}) => (
+}: Props) => (
   <div className="control-bar user-bar">
     <div className="user-button" onClick={setMenuOpened}>
       <UserPicture photo={photo} />
 
       <div className="user-button-fields">
-        <div className="user-button-name">{(name || id || '...')}</div>
-        <div className="user-button-text">{(id || 'пользователь')}</div>
+        <div className="user-button-name">{((name && getUserName(name)) || id || '...')}</div>
+        <div className="user-button-text">{((name && id) || 'пользователь')}</div>
       </div>
     </div>
   </div>
diff --git a/src/components/user/UserMenu.jsx b/src/components/user/UserMenu.jsx
index 37819f4..655d8d5 100644
--- a/src/components/user/UserMenu.jsx
+++ b/src/components/user/UserMenu.jsx
@@ -1,14 +1,11 @@
 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-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">
       Проект на github
     </a>
@@ -17,3 +14,13 @@ export const UserMenu = ({ userLogout, user: { id, userdata: { agent, ip } } })
     </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>
+ */
diff --git a/src/config.js b/src/config.js
index e1b5973..88e2302 100644
--- a/src/config.js
+++ b/src/config.js
@@ -1,3 +1,7 @@
+import { providers } from '$constants/providers';
+
 export const CONFIG = {
   OSRM_URL: 'http://vault48.org:5000/route/v1',
 };
+
+export const PROVIDER = providers.blank;
diff --git a/src/containers/App.jsx b/src/containers/App.jsx
index 11b1c64..14fd877 100644
--- a/src/containers/App.jsx
+++ b/src/containers/App.jsx
@@ -4,12 +4,8 @@ import React from 'react';
 import { editor } from '$modules/Editor';
 import { EditorPanel } from '$components/panels/EditorPanel';
 import { Fills } from '$components/Fills';
-import { DEFAULT_LOGO } from '$constants/logos';
 import { UserLocation } from '$components/UserLocation';
-import { DEFAULT_USER } from '$constants/auth';
-import { storeData, getData } from '$utils/storage';
 import { UserPanel } from '$components/panels/UserPanel';
-import { pushPath } from '$utils/history';
 import { connect } from 'react-redux';
 import { bindActionCreators } from 'redux';
 
@@ -17,44 +13,26 @@ import { hot } from 'react-hot-loader';
 import type { UserType } from '$constants/types';
 
 type Props = {
-  // todo: clean this!
   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, State> {
-  state = {
-    // mode: 'none',
-    // editing: false,
-    logo: DEFAULT_LOGO,
-    routerPoints: 0,
-    totalDistance: 0,
-    estimateTime: 0,
-    activeSticker: null,
-    // user: {
-    //   ...DEFAULT_USER,
-    // },
-    // title: '',
-    // address: '',
-    // changed: false,
-  };
+class Component extends React.Component<Props, void> {
+  // state = {
+  //   // mode: 'none',
+  //   // editing: false,
+  //   logo: DEFAULT_LOGO,
+  //   routerPoints: 0,
+  //   totalDistance: 0,
+  //   estimateTime: 0,
+  //   activeSticker: null,
+  //   // user: {
+  //   //   ...DEFAULT_USER,
+  //   // },
+  //   // title: '',
+  //   // address: '',
+  //   // changed: false,
+  // };
 
   componentDidMount() {
     // this.authInit();
@@ -79,76 +57,76 @@ class Component extends React.Component<Props, State> {
   //     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 = () => {
-  //   if (!this.state.editing) return;
+  // startEmptyEditor = () => {
+  //   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({
   //   container: 'map',
@@ -186,45 +164,43 @@ class Component extends React.Component<Props, State> {
   //   }
   // };
 
-  setUser = user => {
-    if (!user.token || !user.id) return;
+  // setUser = user => {
+  //   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();
+  // };
 
-    if (this.state.user.id === editor.owner) {
-      editor.owner = user.id;
-    }
+  // storeUserData = () => {
+  //   storeData('user', this.state.user);
+  // };
 
-    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({
-      user: DEFAULT_USER,
-    });
-
-    setTimeout(this.storeUserData, 0);
-  };
+  // 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() {
-    const {
-      props: { user }
-    } = this;
+    const { props: { user } } = this;
 
     return (
       <div>
@@ -235,8 +211,8 @@ class Component extends React.Component<Props, State> {
         <UserPanel
           editor={editor}
           user={user}
-          setUser={this.setUser}
-          userLogout={this.userLogout}
+          // setUser={this.setUser}
+          // userLogout={this.userLogout}
         />
 
         <EditorPanel />
diff --git a/src/modules/Editor.js b/src/modules/Editor.js
index 044476f..35a58d6 100644
--- a/src/modules/Editor.js
+++ b/src/modules/Editor.js
@@ -14,31 +14,19 @@ import {
   setChanged,
   setDistance,
   setEditing,
-  setLogo,
+  setLogo, setMode,
   setRouterPoints,
   setTitle
 } from '$redux/user/actions';
 
 export class Editor {
-  constructor({
-    // container,
-    // mode,
-    // setMode,
-    // setRouterPoints,
-    // setTotalDist,
-    // setEditing,
-    // triggerOnChange,
-    // getTitle,
-    // clearChanged,
-    // setActiveSticker,
-    // setLogo,
-    // setTitle,
-    // setAddress,
-  }) {
+  constructor() {
     this.logo = DEFAULT_LOGO;
     this.owner = null;
     this.map = new Map({ container: 'map' });
     this.initialData = {};
+    this.activeSticker = null;
+    this.mode = MODES.NONE;
 
     const {
       triggerOnChange, lockMapClicks, routerMoveStart, changeMode, pushPolyPoints,
@@ -81,8 +69,6 @@ export class Editor {
       [MODES.ROUTER]: this.router.pushWaypointOnClick,
     };
 
-    this.activeSticker = null;
-    this.mode = MODES.NONE;
     // this.clearChanged = clearChanged;
     // this.setActiveSticker = setActiveSticker;
     // this.setLogo = setLogo;
@@ -104,6 +90,7 @@ export class Editor {
   getChanged = () => store.getState().user.changed;
 
   setEditing = value => store.dispatch(setEditing(value));
+  setMode = value => store.dispatch(setMode(value));
   setDistance = value => store.dispatch(setDistance(value));
   setChanged = value => store.dispatch(setChanged(value));
   setRouterPoints = value => store.dispatch(setRouterPoints(value));
@@ -121,17 +108,20 @@ export class Editor {
   };
 
   createStickerOnClick = (e) => {
+    // todo: move to sagas?
     if (!e || !e.latlng || !this.activeSticker) return;
     const { latlng } = e;
 
     this.stickers.createSticker({ latlng, sticker: this.activeSticker });
-    this.setSticker(null);
+    this.setActiveSticker(null);
   };
 
   changeMode = mode => {
+    // todo: check if TOGGLING works (we changing MODE from the sagas now)
     if (this.mode === mode) {
       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 {
         this.disableMode(mode);
         // this.setMode(MODES.NONE);
@@ -154,7 +144,7 @@ export class Editor {
   };
 
   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);
   };
 
@@ -190,45 +180,47 @@ export class Editor {
     this.poly.pushPoints(latlngs);
   };
 
-  setSticker = sticker => {
-    this.activeSticker = sticker;
-    this.setActiveSticker(sticker);
-  };
+  // setSticker = sticker => {
+  //   this.activeSticker = sticker;
+  //   this.setActiveSticker(sticker);
+  // };
 
   clearSticker = () => {
     if (this.activeSticker) {
-      this.setSticker(null);
+      this.setActiveSticker(null);
     } else {
-      this.changeMode(MODES.NONE);
+      this.setMode(MODES.NONE);
     }
   };
 
   clearAll = () => {
+    // todo: move to sagas
     this.poly.clearAll();
     this.router.clearAll();
     this.stickers.clearAll();
 
-    this.setSticker(null);
-    this.changeMode(MODES.NONE);
+    this.setActiveSticker(null);
+    this.setMode(MODES.NONE);
 
     this.clearChanged();
   };
 
   changeLogo = logo => {
+    // todo: move to sagas
     this.logo = logo;
     this.setLogo(logo);
     this.changeMode(MODES.NONE);
   };
 
-  setData = ({ route, stickers, version = 1, owner, title, address }) => {
+  setData = ({
+    route, stickers, version = 1, owner, title, address
+  }) => {
     this.setTitle(title || '');
     const { id } = this.getUser();
 
     if (address && id && owner && id === owner) this.setAddress(address);
 
-    if (route) {
-      this.poly.setPoints(route);
-    }
+    if (route) this.poly.setPoints(route);
 
     if (stickers) {
       stickers.map(sticker => this.stickers.createSticker({
@@ -238,9 +230,7 @@ export class Editor {
       }));
     }
 
-    if (owner) {
-      this.owner = owner;
-    }
+    if (owner) this.owner = owner;
 
     if (!route || route.length <= 1) return;
 
@@ -258,7 +248,7 @@ export class Editor {
       version: 2,
       title: this.getTitle(),
       owner: this.owner,
-      address: this.owner === id ? path : null,
+      address: (this.owner === id ? path : null),
       path,
       route,
       stickers,
@@ -278,19 +268,19 @@ export class Editor {
     if (this.poly.latlngs && this.poly.latlngs.length > 1) this.poly.poly.enableEdit();
 
     this.stickers.startEditing();
-    // this.setEditing(true);
 
-    console.log(this.initialData);
+    // this.setEditing(true);
+    // console.log(this.initialData);
   };
 
   stopEditing = () => {
     const { path } = getUrlData();
     pushPath(`/${(this.initialData && this.initialData.path) || path}`);
 
-    this.changeMode(MODES.NONE);
+    // this.changeMode(MODES.NONE);
     this.poly.poly.disableEdit();
     this.stickers.stopEditing();
-    this.setEditing(false);
+    // this.setEditing(false);
   };
 
   cancelEditing = () => {
@@ -313,11 +303,11 @@ export class Editor {
     stickers: this.stickers.dumpData(),
   });
 
-  isEmpty = () => {
-    const { route, stickers } = this.dumpData();
-
-    return (route.length > 1 && stickers.length > 0);
-  };
+  // isEmpty = () => {
+  //   const { route, stickers } = this.dumpData();
+  //
+  //   return (route.length > 1 && stickers.length > 0);
+  // };
 
   hasEmptyHistory = () => {
     const { route, stickers } = this.initialData;
@@ -326,18 +316,4 @@ export class 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,
-});
+export const editor = new Editor({});
diff --git a/src/modules/Map.js b/src/modules/Map.js
index ce5e935..38b5349 100644
--- a/src/modules/Map.js
+++ b/src/modules/Map.js
@@ -1,14 +1,14 @@
 import { map, tileLayer } from 'leaflet';
-import { providers } from '$constants/providers';
 
 import 'leaflet/dist/leaflet.css';
 import 'leaflet-editable';
+import { PROVIDER } from '$config';
 
 export class Map {
   constructor({ container }) {
     this.map = map(container, { editable: true }).setView([55.0153275, 82.9071235], 13);
 
-    this.tileLayer = tileLayer(providers.default, {
+    this.tileLayer = tileLayer(PROVIDER, {
       attribution: 'Независимое Велосообщество',
       maxNativeZoom: 18,
       maxZoom: 18,
diff --git a/src/redux/user/actions.js b/src/redux/user/actions.js
index 5c4d87e..6b946f1 100644
--- a/src/redux/user/actions.js
+++ b/src/redux/user/actions.js
@@ -1,6 +1,9 @@
 import { ACTIONS } from '$redux/user/constants';
 
 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 setMode = mode => ({ type: ACTIONS.SET_MODE, mode });
 export const setDistance = distance => ({ type: ACTIONS.SET_DISTANCE, distance });
diff --git a/src/redux/user/constants.js b/src/redux/user/constants.js
index e069f33..031fdc7 100644
--- a/src/redux/user/constants.js
+++ b/src/redux/user/constants.js
@@ -1,7 +1,8 @@
 export const ACTIONS = {
   SET_USER: 'SET_USER',
-  SET_EDITING: 'SET_EDITING',
+  USER_LOGOUT: 'USER_LOGOUT',
 
+  SET_EDITING: 'SET_EDITING',
   SET_MODE: 'SET_MODE',
   SET_DISTANCE: 'SET_DISTANCE',
   SET_CHANGED: 'SET_CHANGED',
diff --git a/src/redux/user/sagas.js b/src/redux/user/sagas.js
index 556dd51..dbed7f6 100644
--- a/src/redux/user/sagas.js
+++ b/src/redux/user/sagas.js
@@ -6,6 +6,7 @@ import { getUrlData, pushPath } from '$utils/history';
 import { editor } from '$modules/Editor';
 import { ACTIONS } from '$redux/user/constants';
 import { MODES } from '$constants/modes';
+import { DEFAULT_USER } from '$constants/auth';
 
 const getUser = state => (state.user.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() {
-  // Login
-  // yield takeLatest(AUTH_ACTIONS.SEND_LOGIN_REQUEST, sendLoginRequestSaga);
+  // ASYNCHRONOUS!!! :-)
+
   yield takeLatest(REHYDRATE, authChechSaga);
   yield takeEvery(ACTIONS.SET_MODE, setModeSaga);
 
   yield takeEvery(ACTIONS.START_EDITING, startEditingSaga);
   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);
 }
diff --git a/src/styles/user-button.less b/src/styles/user-button.less
index 2c4bfe5..ca74703 100644
--- a/src/styles/user-button.less
+++ b/src/styles/user-button.less
@@ -1,13 +1,17 @@
 .user-bar {
-  width: 240px;
+  // width: 160px;
 
   .button {
     width: 100%;
   }
 }
+.user-bar-guest {
+  width: 168px;
+}
 
 .user-button {
-  width: 100%;
+  width: 120px;
+  padding-left: 48px;
   height: 48px;
   display: flex;
 
@@ -22,6 +26,9 @@
   background-position: 50% 50%;
   background: rgba(0,0,0,0.3);
   border-radius: 3px 0 0 3px;
+  position: absolute;
+  left: 0;
+  top: 0;
 }
 
 .user-button-fields {