Added application shortcuts and shortcut modal.

Also moved modals into App.jsx to move the business logic to one place.
This commit is contained in:
orangemug 2018-05-29 17:06:00 +01:00
parent 6200edea25
commit 35353d75f5
4 changed files with 199 additions and 68 deletions

View file

@ -12,6 +12,12 @@ import Toolbar from './Toolbar'
import AppLayout from './AppLayout'
import MessagePanel from './MessagePanel'
import SettingsModal from './modals/SettingsModal'
import ExportModal from './modals/ExportModal'
import SourcesModal from './modals/SourcesModal'
import OpenModal from './modals/OpenModal'
import ShortcutsModal from './modals/ShortcutsModal'
import { downloadGlyphsMetadata, downloadSpriteMetadata } from '../libs/metadata'
import * as styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import style from '../libs/style.js'
@ -50,39 +56,75 @@ export default class App extends React.Component {
onLocalStyleChange: mapStyle => this.onStyleChanged(mapStyle, false)
})
const keyCodes = {
"esc": 27,
"?": 191,
"o": 79,
"e": 69,
"s": 83,
"p": 80,
"i": 73,
"m": 77,
}
const shortcuts = [
{
keyCode: keyCodes["?"],
handler: () => {
this.toggleModal("shortcuts");
}
},
{
keyCode: keyCodes["o"],
handler: () => {
this.toggleModal("open");
}
},
{
keyCode: keyCodes["e"],
handler: () => {
this.toggleModal("export");
}
},
{
keyCode: keyCodes["s"],
handler: () => {
this.toggleModal("sources");
}
},
{
keyCode: keyCodes["p"],
handler: () => {
this.toggleModal("settings");
}
},
{
keyCode: keyCodes["i"],
handler: () => {
this.changeInspectMode();
}
},
{
keyCode: keyCodes["m"],
handler: () => {
document.querySelector(".mapboxgl-canvas").focus();
}
},
]
document.body.addEventListener("keyup", (e) => {
if(e.keyCode === 27) {
if(e.keyCode === keyCodes["esc"]) {
e.target.blur();
document.body.focus();
}
else if(document.activeElement === document.body) {
console.log(">>> e", e.keyCode);
if(e.keyCode === 191) {
console.log("TODO: SHORTCUTS");
}
else if(e.keyCode === 79) {
console.log("TODO: OPEN");
}
else if(e.keyCode === 69) {
console.log("TODO: EXPORT");
}
else if(e.keyCode === 83) {
console.log("TODO: SOURCES");
}
else if(e.keyCode === 80) {
console.log("TODO: METADATA");
}
else if(e.keyCode === 73) {
console.log("TODO: INSPECT");
}
else if(e.keyCode === 76) {
console.log("TODO: LAYER LIST");
}
else if(e.keyCode === 67) {
console.log("TODO: CURRENT LAYER");
}
else if(e.keyCode === 77) {
console.log("TODO: MAP");
const shortcut = shortcuts.find((shortcut) => {
return (shortcut.keyCode === e.keyCode)
})
if(shortcut) {
shortcut.handler(e);
}
}
})
@ -120,6 +162,13 @@ export default class App extends React.Component {
vectorLayers: {},
inspectModeEnabled: false,
spec: styleSpec.latest,
isOpen: {
settings: false,
sources: false,
open: false,
shortcuts: false,
export: false,
}
}
this.layerWatcher = new LayerWatcher({
@ -374,6 +423,15 @@ export default class App extends React.Component {
this.setState({ selectedLayerIndex: idx })
}
toggleModal(modalName) {
this.setState({
isOpen: {
...this.state.isOpen,
[modalName]: !this.state.isOpen[modalName]
}
})
}
render() {
const layers = this.state.mapStyle.layers || []
const selectedLayer = layers.length > 0 ? layers[this.state.selectedLayerIndex] : null
@ -386,6 +444,7 @@ export default class App extends React.Component {
onStyleChanged={this.onStyleChanged.bind(this)}
onStyleOpen={this.onStyleChanged.bind(this)}
onInspectModeToggle={this.changeInspectMode.bind(this)}
onToggleModal={this.toggleModal.bind(this)}
/>
const layerList = <LayerList
@ -421,12 +480,44 @@ export default class App extends React.Component {
infos={this.state.infos}
/> : null
const modals = <div>
<ShortcutsModal
isOpen={this.state.isOpen.shortcuts}
onOpenToggle={this.toggleModal.bind(this, 'shortcuts')}
/>
<SettingsModal
mapStyle={this.state.mapStyle}
onStyleChanged={this.onStyleChanged}
isOpen={this.state.isOpen.settings}
onOpenToggle={this.toggleModal.bind(this, 'settings')}
/>
<ExportModal
mapStyle={this.state.mapStyle}
onStyleChanged={this.onStyleChanged}
isOpen={this.state.isOpen.export}
onOpenToggle={this.toggleModal.bind(this, 'export')}
/>
<OpenModal
isOpen={this.state.isOpen.open}
onStyleOpen={this.onStyleChanged.bind(this)}
onOpenToggle={this.toggleModal.bind(this, 'open')}
/>
<SourcesModal
mapStyle={this.state.mapStyle}
onStyleChanged={this.onStyleChanged}
isOpen={this.state.isOpen.sources}
onOpenToggle={this.toggleModal.bind(this, 'sources')}
/>
</div>
return <AppLayout
toolbar={toolbar}
layerList={layerList}
layerEditor={layerEditor}
map={this.mapRenderer()}
bottom={bottomPanel}
modals={modals}
/>
}
}

View file

@ -39,6 +39,7 @@ class AppLayout extends React.Component {
{this.props.bottom}
</div>
}
{this.props.modals}
</div>
}
}

View file

@ -18,10 +18,6 @@ import HelpIcon from 'react-icons/lib/md/help-outline'
import InspectionIcon from 'react-icons/lib/md/find-in-page'
import logoImage from 'maputnik-design/logos/logo-color.svg'
import SettingsModal from './modals/SettingsModal'
import ExportModal from './modals/ExportModal'
import SourcesModal from './modals/SourcesModal'
import OpenModal from './modals/OpenModal'
import pkgJson from '../../package.json'
import style from '../libs/style'
@ -99,40 +95,8 @@ export default class Toolbar extends React.Component {
}
}
toggleModal(modalName) {
this.setState({
isOpen: {
...this.state.isOpen,
[modalName]: !this.state.isOpen[modalName]
}
})
}
render() {
return <div className='maputnik-toolbar'>
<SettingsModal
mapStyle={this.props.mapStyle}
onStyleChanged={this.props.onStyleChanged}
isOpen={this.state.isOpen.settings}
onOpenToggle={this.toggleModal.bind(this, 'settings')}
/>
<ExportModal
mapStyle={this.props.mapStyle}
onStyleChanged={this.props.onStyleChanged}
isOpen={this.state.isOpen.export}
onOpenToggle={this.toggleModal.bind(this, 'export')}
/>
<OpenModal
isOpen={this.state.isOpen.open}
onStyleOpen={this.props.onStyleOpen}
onOpenToggle={this.toggleModal.bind(this, 'open')}
/>
<SourcesModal
mapStyle={this.props.mapStyle}
onStyleChanged={this.props.onStyleChanged}
isOpen={this.state.isOpen.sources}
onOpenToggle={this.toggleModal.bind(this, 'sources')}
/>
<div className="maputnik-toolbar__inner">
<ToolbarLink
href={"https://github.com/maputnik/editor"}
@ -144,19 +108,19 @@ export default class Toolbar extends React.Component {
</h1>
</ToolbarLink>
<div className="maputnik-toolbar__actions">
<ToolbarAction wdKey="nav:open" onClick={this.toggleModal.bind(this, 'open')}>
<ToolbarAction wdKey="nav:open" onClick={this.props.onToggleModal.bind(this, 'open')}>
<OpenIcon />
<IconText>Open</IconText>
</ToolbarAction>
<ToolbarAction wdKey="nav:export" onClick={this.toggleModal.bind(this, 'export')}>
<ToolbarAction wdKey="nav:export" onClick={this.props.onToggleModal.bind(this, 'export')}>
<MdFileDownload />
<IconText>Export</IconText>
</ToolbarAction>
<ToolbarAction wdKey="nav:sources" onClick={this.toggleModal.bind(this, 'sources')}>
<ToolbarAction wdKey="nav:sources" onClick={this.props.onToggleModal.bind(this, 'sources')}>
<SourcesIcon />
<IconText>Sources</IconText>
</ToolbarAction>
<ToolbarAction wdKey="nav:settings" onClick={this.toggleModal.bind(this, 'settings')}>
<ToolbarAction wdKey="nav:settings" onClick={this.props.onToggleModal.bind(this, 'settings')}>
<SettingsIcon />
<IconText>Style Settings</IconText>
</ToolbarAction>

View file

@ -0,0 +1,75 @@
import React from 'react'
import PropTypes from 'prop-types'
import Button from '../Button'
import Modal from './Modal'
class ShortcutsModal extends React.Component {
static propTypes = {
isOpen: PropTypes.bool.isRequired,
onOpenToggle: PropTypes.func.isRequired,
}
constructor(props) {
super(props);
}
render() {
const help = [
{
key: "?",
text: "Show shortcuts menu"
},
{
key: "o",
text: "Open modal"
},
{
key: "e",
text: "Export modal"
},
{
key: "s",
text: "Sources modal"
},
{
key: "p",
text: "Source settings modal"
},
{
key: "i",
text: "Toggle map"
},
{
key: "m",
text: "Focus map"
},
]
return <Modal
data-wd-key="shortcuts-modal"
isOpen={this.props.isOpen}
onOpenToggle={this.props.onOpenToggle}
title={'Shortcuts'}
>
<div className="maputnik-modal-section">
<ul>
{help.map((item) => {
return <li>
<code>{item.key}</code> {item.text}
</li>
})}
</ul>
<p>
<Button onClick={() => this.props.onOpenToggle()}>
Close
</Button>
</p>
</div>
</Modal>
}
}
export default ShortcutsModal