diff --git a/src/components/dialogs/CancelDialog.jsx b/src/components/dialogs/CancelDialog.jsx index b152e75..b1736ed 100644 --- a/src/components/dialogs/CancelDialog.jsx +++ b/src/components/dialogs/CancelDialog.jsx @@ -1,13 +1,12 @@ import React from 'react'; import { MODES } from '$constants/modes'; -import { editor } from '$modules/Editor'; import { Icon } from '$components/panels/Icon'; type Props = { stopEditing: Function, setMode: Function, - setEditing: Function, + width: Number, }; export class CancelDialog extends React.Component<Props, void> { @@ -23,19 +22,23 @@ export class CancelDialog extends React.Component<Props, void> { }; render() { - return ( - <div className="helper cancel-helper"> - <div className="helper__text danger"> - <Icon icon="icon-cancel-1" /> - <div className="big upper">Закрыть редактор?</div> - </div> - <div className="helper__buttons"> - <div className="button router-helper__button" onClick={this.cancel}> - Удалить измения - </div> + const { width } = this.props; - <div className="button primary router-helper__button" onClick={this.proceed}> - Вернуться + return ( + <div className="control-dialog" style={{ width }}> + <div className="helper cancel-helper"> + <div className="helper__text danger"> + <Icon icon="icon-cancel-1" /> + <div className="big upper">Закрыть редактор?</div> + </div> + <div className="helper__buttons"> + <div className="button router-helper__button" onClick={this.cancel}> + Удалить измения + </div> + + <div className="button primary router-helper__button" onClick={this.proceed}> + Вернуться + </div> </div> </div> </div> diff --git a/src/components/dialogs/LogoDialog.jsx b/src/components/dialogs/LogoDialog.jsx index 177a0a1..34409ef 100644 --- a/src/components/dialogs/LogoDialog.jsx +++ b/src/components/dialogs/LogoDialog.jsx @@ -9,20 +9,22 @@ type Props = { } export const LogoDialog = ({ logo, setLogo }: Props) => ( - <div className="helper logo-helper"> - <div className="helper-back"> - <Icon icon="icon-logo" size={200} /> + <div className="control-dialog top"> + <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> - { - 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/dialogs/ProviderDialog.jsx b/src/components/dialogs/ProviderDialog.jsx index 1019dcc..2018718 100644 --- a/src/components/dialogs/ProviderDialog.jsx +++ b/src/components/dialogs/ProviderDialog.jsx @@ -17,7 +17,7 @@ export class ProviderDialog extends React.Component<Props, void> { const { provider, setProvider } = this.props; return ( - <React.Fragment> + <div className="control-dialog top right control-dialog-provider"> <div className="helper provider-helper"> { Object.keys(PROVIDERS).map(item => ( @@ -39,16 +39,7 @@ export class ProviderDialog extends React.Component<Props, void> { )) } </div> - <div className="helper"> - <div className="helper__text"> - <Icon icon="icon-map-1" /> - <div className="big upper">ВЫБЕРИТЕ СТИЛЬ КАРТЫ</div> - </div> - <div className="helper__buttons button-group" onClick={this.closeDialog}> - <Icon icon="icon-cancel-1" /> - </div> - </div> - </React.Fragment> + </div> ); } } diff --git a/src/components/dialogs/RouterDialog.jsx b/src/components/dialogs/RouterDialog.jsx index 7e33cee..2c67886 100644 --- a/src/components/dialogs/RouterDialog.jsx +++ b/src/components/dialogs/RouterDialog.jsx @@ -5,6 +5,7 @@ type Props = { routerCancel: Function, routerSubmit: Function, routerPoints: Number, + width: Number, } const noPoints = ({ routerCancel }: Props) => ( @@ -54,8 +55,8 @@ const draggablePoints = ({ routerCancel, routerSubmit }: Props) => ( </div> ); -export const RouterDialog = ({ routerPoints, routerCancel, routerSubmit }: Props) => ( - <div> +export const RouterDialog = ({ routerPoints, routerCancel, routerSubmit, width }: Props) => ( + <div className="control-dialog" style={{ width }}> {!routerPoints && noPoints({ routerCancel })} {routerPoints === 1 && firstPoint({ routerCancel })} {routerPoints >= 2 && draggablePoints({ routerCancel, routerSubmit })} diff --git a/src/components/dialogs/SaveDialog.jsx b/src/components/dialogs/SaveDialog.jsx index 0687b4f..113b166 100644 --- a/src/components/dialogs/SaveDialog.jsx +++ b/src/components/dialogs/SaveDialog.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { getUrlData, pushPath } from '$utils/history'; +import { getUrlData } from '$utils/history'; import { toTranslit } from '$utils/format'; import { TIPS } from '$constants/tips'; import { MODES } from '$constants/modes'; @@ -11,7 +11,8 @@ type Props = { save_error: String, save_finished: Boolean, save_overwriting: Boolean, - save_processing: Boolean, + + width: Number, setMode: Function, sendSaveRequest: Function, @@ -59,50 +60,50 @@ export class SaveDialog extends React.Component<Props, State> { render() { const { title } = this.state; - const { save_error, save_finished, save_overwriting } = this.props; + const { save_error, save_finished, save_overwriting, width } = this.props; const { host } = getUrlData(); return ( - <div className="helper save-helper"> - <div className="save-title"> - <div className="save-title-input"> - <div className="save-title-label">Название</div> - <input type="text" value={title} onChange={this.setTitle} autoFocus readOnly={save_finished} /> - </div> - </div> - - <div className="save-description"> - <div className="save-address-input"> - <label className="save-address-label">http://{host}/</label> - <input type="text" value={this.getAddress().substr(0, 32)} onChange={this.setAddress} readOnly={save_finished} /> + <div className="control-dialog" style={{ width }}> + <div className="helper save-helper"> + <div className="save-title"> + <div className="save-title-input"> + <div className="save-title-label">Название</div> + <input type="text" value={title} onChange={this.setTitle} autoFocus readOnly={save_finished} /> + </div> </div> - <div className="save-text"> - { save_error || TIPS.SAVE_INFO } - </div> + <div className="save-description"> + <div className="save-address-input"> + <label className="save-address-label">http://{host}/</label> + <input type="text" value={this.getAddress().substr(0, 32)} onChange={this.setAddress} readOnly={save_finished} /> + </div> - <div className="save-buttons"> - <div className="save-buttons-text" /> - <div> - { !save_finished && - <div className="button" onClick={this.cancelSaving}>Отмена</div> - } - { - !save_finished && !save_overwriting && - <div className="button primary" onClick={this.sendSaveRequest}>Сохранить</div> - } - { - save_overwriting && - <div className="button danger" onClick={this.forceSaveRequest}>Перезаписать</div> - } - { save_finished && - <div className="button success" onClick={this.cancelSaving}>Отлично, спасибо!</div> - } + <div className="save-text"> + { save_error || TIPS.SAVE_INFO } + </div> + + <div className="save-buttons"> + <div className="save-buttons-text" /> + <div> + { !save_finished && + <div className="button" onClick={this.cancelSaving}>Отмена</div> + } + { + !save_finished && !save_overwriting && + <div className="button primary" onClick={this.sendSaveRequest}>Сохранить</div> + } + { + save_overwriting && + <div className="button danger" onClick={this.forceSaveRequest}>Перезаписать</div> + } + { save_finished && + <div className="button success" onClick={this.cancelSaving}>Отлично, спасибо!</div> + } + </div> </div> </div> </div> - - </div> ); } diff --git a/src/components/dialogs/StickersDialog.jsx b/src/components/dialogs/StickersDialog.jsx index 6819443..6937ff3 100644 --- a/src/components/dialogs/StickersDialog.jsx +++ b/src/components/dialogs/StickersDialog.jsx @@ -4,32 +4,35 @@ import React from 'react'; import { STICKERS } from '$constants/stickers'; type Props = { - setActiveSticker: Function + setActiveSticker: Function, + width: Number, }; -export const StickersDialog = ({ setActiveSticker }: Props) => ( - <div className="helper stickers-helper"> - { - Object.keys(STICKERS).map(set => ( - <div key={set}> - <div className="stickers-set-title">{STICKERS[set].title || null}</div> - <div className="stickers-grid"> - { - Object.keys(STICKERS[set].layers).map(sticker => ( - <div - style={{ - backgroundImage: `url(${STICKERS[set].url})`, - backgroundPosition: `${-STICKERS[set].layers[sticker].off * 48}px 50%`, - }} - className="sticker-preview" - key={`${set}-${sticker}`} - onClick={() => setActiveSticker({ set, sticker })} - /> - )) - } +export const StickersDialog = ({ setActiveSticker, width }: Props) => ( + <div className="control-dialog" style={{ width }}> + <div className="helper stickers-helper"> + { + Object.keys(STICKERS).map(set => ( + <div key={set}> + <div className="stickers-set-title">{STICKERS[set].title || null}</div> + <div className="stickers-grid"> + { + Object.keys(STICKERS[set].layers).map(sticker => ( + <div + style={{ + backgroundImage: `url(${STICKERS[set].url})`, + backgroundPosition: `${-STICKERS[set].layers[sticker].off * 48}px 50%`, + }} + className="sticker-preview" + key={`${set}-${sticker}`} + onClick={() => setActiveSticker({ set, sticker })} + /> + )) + } + </div> </div> - </div> - )) - } + )) + } + </div> </div> ); diff --git a/src/components/dialogs/TrashDialog.jsx b/src/components/dialogs/TrashDialog.jsx index 638e0a8..986b1a6 100644 --- a/src/components/dialogs/TrashDialog.jsx +++ b/src/components/dialogs/TrashDialog.jsx @@ -6,30 +6,34 @@ type Props = { clearStickers: Function, clearAll: Function, clearCancel: Function, + + width: Number, } export const TrashDialog = ({ - clearPoly, clearStickers, clearAll, clearCancel + clearPoly, clearStickers, clearAll, clearCancel, width, }: Props) => ( - <div className="helper trash-helper"> - <div className="helper__text danger"> - <Icon icon="icon-trash-4" /> - <div className="big upper">Удалить:</div> - </div> - <div className="helper__buttons"> - <div className="button-group"> - <div className="button router-helper__button" onClick={clearPoly}> - Маршрут - </div> - <div className="button router-helper__button" onClick={clearStickers}> - Стикеры - </div> - <div className="button router-helper__button" onClick={clearAll}> - Удалить все - </div> + <div className="control-dialog" style={{ width }}> + <div className="helper trash-helper"> + <div className="helper__text danger"> + <Icon icon="icon-trash-4" /> + <div className="big upper">Удалить:</div> </div> - <div className="button primary router-helper__button" onClick={clearCancel}> - Отмена + <div className="helper__buttons"> + <div className="button-group"> + <div className="button router-helper__button" onClick={clearPoly}> + Маршрут + </div> + <div className="button router-helper__button" onClick={clearStickers}> + Стикеры + </div> + <div className="button router-helper__button" onClick={clearAll}> + Удалить все + </div> + </div> + <div className="button primary router-helper__button" onClick={clearCancel}> + Отмена + </div> </div> </div> </div> diff --git a/src/components/panels/EditorDialog.jsx b/src/components/panels/EditorDialog.jsx index 07d94ac..4cad345 100644 --- a/src/components/panels/EditorDialog.jsx +++ b/src/components/panels/EditorDialog.jsx @@ -34,42 +34,24 @@ type Props = { width: Number, } +const DIALOG_CONTENTS = { + [MODES.ROUTER]: RouterDialog, + [MODES.STICKERS]: StickersDialog, + [MODES.TRASH]: TrashDialog, + [MODES.LOGO]: LogoDialog, + [MODES.SAVE]: SaveDialog, + [MODES.CONFIRM_CANCEL]: CancelDialog, + [MODES.PROVIDER]: ProviderDialog, +}; + export const Component = (props: Props) => { const { - mode, activeSticker, width + mode } = props; - const showDialog = ( - mode === MODES.ROUTER - || (mode === MODES.STICKERS && !activeSticker.set) - || mode === MODES.TRASH - || mode === MODES.LOGO - || mode === MODES.SAVE - || mode === MODES.CONFIRM_CANCEL - || mode === MODES.PROVIDER - ); - - const dialogIsSmall = ( - mode === MODES.LOGO - ); - return ( - showDialog && - <div - id="control-dialog" - style={{ - width: dialogIsSmall ? 201 : width, - right: dialogIsSmall ? 217 : 10, - }} - > - { mode === MODES.ROUTER && <RouterDialog {...props} /> } - { mode === MODES.STICKERS && <StickersDialog {...props} /> } - { mode === MODES.TRASH && <TrashDialog {...props} /> } - { mode === MODES.LOGO && <LogoDialog {...props} /> } - { mode === MODES.SAVE && <SaveDialog {...props} /> } - { mode === MODES.CONFIRM_CANCEL && <CancelDialog {...props} /> } - { mode === MODES.PROVIDER && <ProviderDialog {...props} /> } - </div> + (mode && DIALOG_CONTENTS[mode] && React.createElement(DIALOG_CONTENTS[mode], { ...props })) + || <div>null</div> ); }; diff --git a/src/components/panels/EditorPanel.jsx b/src/components/panels/EditorPanel.jsx index 6b25007..2b2e625 100644 --- a/src/components/panels/EditorPanel.jsx +++ b/src/components/panels/EditorPanel.jsx @@ -75,16 +75,16 @@ class Component extends React.PureComponent<Props, void> { </div> <div className="status-panel top right"> - <div className="status-bar pointer top-control padded"> + <div className="status-bar pointer top-control padded" onClick={this.startProviderMode}> <Icon icon="icon-map-1" size={24} /> <div className="status-bar-sep" /> - {(provider && PROVIDERS[provider] && PROVIDERS[provider].name) || '...'} + <span>{(provider && PROVIDERS[provider] && PROVIDERS[provider].name) || '...'}</span> </div> - <div className="status-bar pointer top-control padded"> + <div className="status-bar pointer top-control padded" onClick={this.startLogoMode}> <Icon icon="icon-logo-3" size={24} /> <div className="status-bar-sep" /> - {(logo && LOGOS[logo] && LOGOS[logo][0]) || '...'} + <span>{(logo && LOGOS[logo] && LOGOS[logo][0]) || '...'}</span> </div> </div> @@ -122,24 +122,10 @@ class Component extends React.PureComponent<Props, void> { </button> <button - className={classnames({ active: mode === MODES.TRASH })} + className={classnames({ active: false })} onClick={this.props.takeAShot} > - <Icon icon="icon-shot-3" /> - </button> - - <button - className={classnames({ active: mode === MODES.PROVIDER })} - onClick={this.startProviderMode} - > - <Icon icon="icon-map-1" /> - </button> - - <button - className={classnames({ active: mode === MODES.LOGO })} - onClick={this.startLogoMode} - > - <Icon icon="icon-logo-3" /> + <Icon icon="icon-shot-2" /> </button> </div> @@ -157,7 +143,6 @@ class Component extends React.PureComponent<Props, void> { className={classnames({ primary: changed, disabled: !changed })} onClick={this.startSaveMode} > - <span>СХОРОНИТЬ</span> <Icon icon="icon-check-1" /> </button> </div> diff --git a/src/constants/logos.js b/src/constants/logos.js index 2e3a66b..349112e 100644 --- a/src/constants/logos.js +++ b/src/constants/logos.js @@ -1,5 +1,5 @@ export const LOGOS = { - default: ['Без логотипа', null, 'bottom-right'], + default: ['Без лого', null, 'bottom-right'], nvs: ['НВС', 'http://map.vault48.org/misc/lgo.png', 'bottom-right'], pinmix: ['Пин-Микс', 'http://map.vault48.org/misc/pin-mix.png', 'top-right'], jolly: ['Пин-Микс + JW', 'http://map.vault48.org/misc/jw.png', 'top-right'], diff --git a/src/index.js b/src/index.js index d8a6635..68b231d 100644 --- a/src/index.js +++ b/src/index.js @@ -11,10 +11,10 @@ todo map search todo map lazy loading - todo map preview on save todo tooltips todo better poly editor https://github.com/SupriyaSudhindra/leaflet-editable-polyline + todo network operations notify todo delayed notify (delay(2000).then(showLoadingMsg)) todo network error notifications @@ -24,6 +24,7 @@ todo better loader screen todo network errors handling on startup + todo map preview on save */ import React from 'react'; import ReactDOM from 'react-dom'; diff --git a/src/modules/Editor.js b/src/modules/Editor.js index a7a8680..7b50233 100644 --- a/src/modules/Editor.js +++ b/src/modules/Editor.js @@ -263,7 +263,7 @@ export class Editor { setInitialData = () => { const { path } = getUrlData(); const { id } = this.getUser(); - const { route, stickers } = this.dumpData(); + const { route, stickers, provider } = this.dumpData(); this.initialData = { version: 2, @@ -273,6 +273,7 @@ export class Editor { path, route, stickers, + provider, }; }; @@ -321,6 +322,7 @@ export class Editor { dumpData = () => ({ route: this.poly.dumpData(), stickers: this.stickers.dumpData(), + provider: this.provider, }); setProvider = provider => { diff --git a/src/styles/panel.less b/src/styles/panel.less index dd4a4b5..48d9279 100644 --- a/src/styles/panel.less +++ b/src/styles/panel.less @@ -153,7 +153,7 @@ background: #222222; } -#control-dialog { +.control-dialog { background: rgba(30, 30, 30, 0.95); position: absolute; right: 10px; @@ -164,6 +164,15 @@ box-sizing: border-box; // padding-bottom: 48px; box-shadow: inset rgba(255, 255, 255, 0.05) 1px 1px; + + &.top { + bottom: auto; + top: 52px; + } +} + +.control-dialog-provider { + width: 500px; } .helper { @@ -284,7 +293,6 @@ grid-template-columns: 1fr 1fr 1fr 1fr; grid-column-gap: 10px; grid-row-gap: 10px; - padding-bottom: 0; .provider-helper-thumb { height: 100px; @@ -351,6 +359,15 @@ justify-content: center; box-shadow: @bar_shadow; + span { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex: 1; + text-transform: uppercase; + font-size: 0.9em; + } + &.square { width: 32px; } @@ -360,11 +377,8 @@ } &.top-control { - width: 120px; + width: 150px; justify-content: flex-start; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; } svg {