mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-28 17:31:14 +01:00
Add open modal
This commit is contained in:
parent
57ab4be42c
commit
fbdc87f2f1
6 changed files with 214 additions and 19 deletions
29
src/components/Button.jsx
Normal file
29
src/components/Button.jsx
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import React from 'react'
|
||||||
|
import colors from '../config/colors'
|
||||||
|
import { margins, fontSizes } from '../config/scales'
|
||||||
|
|
||||||
|
class Button extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
onClick: React.PropTypes.func.isRequired,
|
||||||
|
style: React.PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <a
|
||||||
|
onClick={this.props.onClick}
|
||||||
|
style={{
|
||||||
|
cursor: 'pointer',
|
||||||
|
backgroundColor: colors.midgray,
|
||||||
|
color: colors.lowgray,
|
||||||
|
fontSize: fontSizes[4],
|
||||||
|
padding: margins[1],
|
||||||
|
userSelect: 'none',
|
||||||
|
borderRadius: 2,
|
||||||
|
...this.props.style,
|
||||||
|
}}>
|
||||||
|
{this.props.children}
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Button
|
13
src/components/Paragraph.jsx
Normal file
13
src/components/Paragraph.jsx
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import React from 'react'
|
||||||
|
import colors from '../config/colors'
|
||||||
|
import { margins, fontSizes } from '../config/scales'
|
||||||
|
|
||||||
|
const Paragraph = (props) => <p style={{
|
||||||
|
color: colors.lowgray,
|
||||||
|
fontSize: fontSizes[5],
|
||||||
|
...props.style
|
||||||
|
}}>
|
||||||
|
{props.children}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
export default Paragraph
|
|
@ -17,6 +17,7 @@ import MdFindInPage from 'react-icons/lib/md/find-in-page'
|
||||||
|
|
||||||
import SettingsModal from './modals/SettingsModal'
|
import SettingsModal from './modals/SettingsModal'
|
||||||
import SourcesModal from './modals/SourcesModal'
|
import SourcesModal from './modals/SourcesModal'
|
||||||
|
import OpenModal from './modals/OpenModal'
|
||||||
|
|
||||||
import style from '../libs/style'
|
import style from '../libs/style'
|
||||||
import colors from '../config/colors'
|
import colors from '../config/colors'
|
||||||
|
@ -37,6 +38,7 @@ const ToolbarAction = props => <a onClick={props.onClick}
|
||||||
{props.children}
|
{props.children}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
export default class Toolbar extends React.Component {
|
export default class Toolbar extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
mapStyle: React.PropTypes.object.isRequired,
|
mapStyle: React.PropTypes.object.isRequired,
|
||||||
|
@ -54,21 +56,10 @@ export default class Toolbar extends React.Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
openSettingsModal: false,
|
openSettingsModal: false,
|
||||||
openSourcesModal: false,
|
openSourcesModal: false,
|
||||||
|
openOpenModal: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpload(_, files) {
|
|
||||||
const [e, file] = files[0];
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.readAsText(file, "UTF-8");
|
|
||||||
reader.onload = e => {
|
|
||||||
let mapStyle = JSON.parse(e.target.result)
|
|
||||||
mapStyle = style.ensureMetadataExists(mapStyle)
|
|
||||||
this.props.onStyleUpload(mapStyle);
|
|
||||||
}
|
|
||||||
reader.onerror = e => console.log(e.target);
|
|
||||||
}
|
|
||||||
|
|
||||||
saveButton() {
|
saveButton() {
|
||||||
if(this.props.mapStyle.layers.length > 0) {
|
if(this.props.mapStyle.layers.length > 0) {
|
||||||
return <ToolbarAction onClick={this.props.onStyleSave} big={true}>
|
return <ToolbarAction onClick={this.props.onStyleSave} big={true}>
|
||||||
|
@ -94,6 +85,10 @@ export default class Toolbar extends React.Component {
|
||||||
this.setState({openSourcesModal: !this.state.openSourcesModal})
|
this.setState({openSourcesModal: !this.state.openSourcesModal})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleOpen() {
|
||||||
|
this.setState({openOpenModal: !this.state.openOpenModal})
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <div style={{
|
return <div style={{
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
|
@ -110,6 +105,10 @@ export default class Toolbar extends React.Component {
|
||||||
isOpen={this.state.openSettingsModal}
|
isOpen={this.state.openSettingsModal}
|
||||||
toggle={() => this.toggleSettings.bind(this)}
|
toggle={() => this.toggleSettings.bind(this)}
|
||||||
/>
|
/>
|
||||||
|
<OpenModal
|
||||||
|
isOpen={this.state.openOpenModal}
|
||||||
|
toggle={() => this.toggleOpen.bind(this)}
|
||||||
|
/>
|
||||||
<SourcesModal
|
<SourcesModal
|
||||||
mapStyle={this.props.mapStyle}
|
mapStyle={this.props.mapStyle}
|
||||||
onStyleChanged={this.props.onStyleChanged}
|
onStyleChanged={this.props.onStyleChanged}
|
||||||
|
@ -124,11 +123,9 @@ export default class Toolbar extends React.Component {
|
||||||
<img src="https://github.com/maputnik/editor/raw/master/media/maputnik.png" alt="Maputnik" style={{width: 30, height: 30, paddingRight: 5, verticalAlign: 'middle'}}/>
|
<img src="https://github.com/maputnik/editor/raw/master/media/maputnik.png" alt="Maputnik" style={{width: 30, height: 30, paddingRight: 5, verticalAlign: 'middle'}}/>
|
||||||
<span style={{fontSize: 20, verticalAlign: 'middle' }}>Maputnik</span>
|
<span style={{fontSize: 20, verticalAlign: 'middle' }}>Maputnik</span>
|
||||||
</ToolbarAction>
|
</ToolbarAction>
|
||||||
<ToolbarAction>
|
<ToolbarAction onClick={this.toggleOpen.bind(this)}>
|
||||||
<FileReaderInput onChange={this.onUpload.bind(this)}>
|
|
||||||
<MdOpenInBrowser />
|
<MdOpenInBrowser />
|
||||||
<IconText>Open</IconText>
|
<IconText>Open</IconText>
|
||||||
</FileReaderInput>
|
|
||||||
</ToolbarAction>
|
</ToolbarAction>
|
||||||
{this.downloadButton()}
|
{this.downloadButton()}
|
||||||
{this.saveButton()}
|
{this.saveButton()}
|
||||||
|
|
115
src/components/modals/OpenModal.jsx
Normal file
115
src/components/modals/OpenModal.jsx
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
import React from 'react'
|
||||||
|
import Modal from './Modal'
|
||||||
|
import Heading from '../Heading'
|
||||||
|
import Button from '../Button'
|
||||||
|
import Paragraph from '../Paragraph'
|
||||||
|
import FileReaderInput from 'react-file-reader-input'
|
||||||
|
|
||||||
|
import FileUploadIcon from 'react-icons/lib/md/file-upload'
|
||||||
|
import AddIcon from 'react-icons/lib/md/add-circle-outline'
|
||||||
|
|
||||||
|
import colors from '../../config/colors'
|
||||||
|
import { margins, fontSizes } from '../../config/scales'
|
||||||
|
import publicStyles from '../../config/styles.json'
|
||||||
|
|
||||||
|
class PublicStyle extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
url: React.PropTypes.string.isRequired,
|
||||||
|
thumbnailUrl: React.PropTypes.string.isRequired,
|
||||||
|
title: React.PropTypes.string.isRequired,
|
||||||
|
onSelect: React.PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <div style={{
|
||||||
|
verticalAlign: 'top',
|
||||||
|
marginTop: margins[2],
|
||||||
|
marginRight: margins[2],
|
||||||
|
backgroundColor: colors.gray,
|
||||||
|
display: 'inline-block',
|
||||||
|
width: 180,
|
||||||
|
fontSize: fontSizes[4],
|
||||||
|
color: colors.lowgray,
|
||||||
|
}}>
|
||||||
|
<Button style={{
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
padding: margins[2],
|
||||||
|
display: 'block',
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
}}>
|
||||||
|
<span style={{fontWeight: 700}}>{this.props.title}</span>
|
||||||
|
<span style={{flexGrow: 1}} />
|
||||||
|
<AddIcon />
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
style={{
|
||||||
|
display: 'block',
|
||||||
|
marginTop: margins[1],
|
||||||
|
maxWidth: '100%',
|
||||||
|
}}
|
||||||
|
src={this.props.thumbnailUrl}
|
||||||
|
alt={this.props.title}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OpenModal extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
isOpen: React.PropTypes.bool.isRequired,
|
||||||
|
toggle: React.PropTypes.func.isRequired,
|
||||||
|
onStyleOpen: React.PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpload(_, files) {
|
||||||
|
const [e, file] = files[0];
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsText(file, "UTF-8");
|
||||||
|
reader.onload = e => {
|
||||||
|
let mapStyle = JSON.parse(e.target.result)
|
||||||
|
mapStyle = style.ensureMetadataExists(mapStyle)
|
||||||
|
this.props.onStyleOpen(mapStyle);
|
||||||
|
}
|
||||||
|
reader.onerror = e => console.log(e.target);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const styleOptions = publicStyles.map(style => {
|
||||||
|
return <PublicStyle
|
||||||
|
key={style.key}
|
||||||
|
url={style.url}
|
||||||
|
title={style.title}
|
||||||
|
thumbnailUrl={style.thumbnail}
|
||||||
|
/>
|
||||||
|
})
|
||||||
|
|
||||||
|
return <Modal
|
||||||
|
isOpen={this.props.isOpen}
|
||||||
|
toggleOpen={this.props.toggle}
|
||||||
|
title={'Open Style'}
|
||||||
|
>
|
||||||
|
<Heading level={4}>Upload Style</Heading>
|
||||||
|
<Paragraph>
|
||||||
|
Upload a JSON style from your computer.
|
||||||
|
</Paragraph>
|
||||||
|
<FileReaderInput onChange={this.onUpload.bind(this)}>
|
||||||
|
<Button>
|
||||||
|
<FileUploadIcon />
|
||||||
|
Upload
|
||||||
|
</Button>
|
||||||
|
</FileReaderInput>
|
||||||
|
|
||||||
|
<Heading level={4}>Gallery Styles</Heading>
|
||||||
|
<Paragraph>
|
||||||
|
Open one of the publicly available styles to start from.
|
||||||
|
</Paragraph>
|
||||||
|
{styleOptions}
|
||||||
|
</Modal>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OpenModal
|
|
@ -2,6 +2,7 @@ import React from 'react'
|
||||||
import Modal from './Modal'
|
import Modal from './Modal'
|
||||||
import Heading from '../Heading'
|
import Heading from '../Heading'
|
||||||
import Button from '../Button'
|
import Button from '../Button'
|
||||||
|
import Paragraph from '../Paragraph'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import InputBlock from '../inputs/InputBlock'
|
||||||
import StringInput from '../inputs/StringInput'
|
import StringInput from '../inputs/StringInput'
|
||||||
import SelectInput from '../inputs/SelectInput'
|
import SelectInput from '../inputs/SelectInput'
|
||||||
|
@ -187,11 +188,13 @@ class SourcesModal extends React.Component {
|
||||||
<Heading level={4}>Add New Source</Heading>
|
<Heading level={4}>Add New Source</Heading>
|
||||||
<div style={{maxWidth: 300}}>
|
<div style={{maxWidth: 300}}>
|
||||||
<p style={{color: colors.lowgray, fontSize: fontSizes[5]}}>Add a new source to your style. You can only choose the source type and id at creation time!</p>
|
<p style={{color: colors.lowgray, fontSize: fontSizes[5]}}>Add a new source to your style. You can only choose the source type and id at creation time!</p>
|
||||||
<AddSource onSourceAdd={} />
|
<AddSource />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Heading level={4}>Choose Public Source</Heading>
|
<Heading level={4}>Choose Public Source</Heading>
|
||||||
<p style={{color: colors.lowgray, fontSize: fontSizes[5]}}>Add one of the publicly availble sources to your style.</p>
|
<Paragraph>
|
||||||
|
Add one of the publicly availble sources to your style.
|
||||||
|
</Paragraph>
|
||||||
<div style={{maxwidth: 500}}>
|
<div style={{maxwidth: 500}}>
|
||||||
{tilesetOptions}
|
{tilesetOptions}
|
||||||
</div>
|
</div>
|
||||||
|
|
38
src/config/styles.json
Normal file
38
src/config/styles.json
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "dark-matter",
|
||||||
|
"title": "Dark Matter",
|
||||||
|
"url": "https://openmaptiles.github.io/dark-matter-gl-style/style-cdn.json",
|
||||||
|
"thumbnail": "https://camo.githubusercontent.com/b73c515d633d2be7368e8e29e3c23e14117fd21b/68747470733a2f2f6170692e6d6170626f782e636f6d2f7374796c65732f76312f6d6f7267656e6b61666665652f6369757878356e37683031396c326870626e396c6970726d6e2f7374617469632f382e3631393138342c34372e3333363230332c392e30372c302e30302c302e30302f363030783430303f6163636573735f746f6b656e3d706b2e65794a31496a6f69625739795a3256756132466d5a6d566c4969776959534936496a497a636d4e304e6c6b6966512e304c52544e6743632d656e76743964354d7a52373577"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "positron",
|
||||||
|
"title": "Positron",
|
||||||
|
"url": "https://openmaptiles.github.io/positron-gl-style/style-cdn.json",
|
||||||
|
"thumbnail": "https://camo.githubusercontent.com/0dd866e3fa7b21ada87da69082eac6801e16ec99/68747470733a2f2f6170692e6d6170626f782e636f6d2f7374796c65732f76312f6d6f7267656e6b61666665652f63697578756e37736530313976326a6c387162326a743374662f7374617469632f382e3631393138342c34372e3333363230332c392e30372c302e30302c302e30302f363030783430303f6163636573735f746f6b656e3d706b2e65794a31496a6f69625739795a3256756132466d5a6d566c4969776959534936496a497a636d4e304e6c6b6966512e304c52544e6743632d656e76743964354d7a52373577"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "osm-bright",
|
||||||
|
"title": "OSM Bright",
|
||||||
|
"url": "https://openmaptiles.github.io/osm-bright-gl-style/style-cdn.json",
|
||||||
|
"thumbnail": "https://camo.githubusercontent.com/a15e23ab59202c56502e57cde963cb7772ed3bb1/68747470733a2f2f6170692e6d6170626f782e636f6d2f7374796c65732f76312f6f70656e6d617074696c65732f63697736637a7a326e30303234326b6d673668773230626f782f7374617469632f382e3534303538372c34372e3337303535352c31342e30382c302e30302c302e30302f363030783430303f6163636573735f746f6b656e3d706b2e65794a31496a6f696233426c626d3168634852706247567a4969776959534936496d4e70646e593365544a785a7a41774d474d796233427064574a6d616a63784e7a636966512e685031427863786c644968616b4d6350534a4c513151"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "klokantech-basic",
|
||||||
|
"title": "Klokantech Basic",
|
||||||
|
"url": "https://openmaptiles.github.io/klokantech-basic-gl-style/style-cdn.json",
|
||||||
|
"thumbnail": "https://camo.githubusercontent.com/5cf548fdb9fc606f4a452d14fd2a7a959155fd40/68747470733a2f2f6170692e6d6170626f782e636f6d2f7374796c65732f76312f6d6f7267656e6b61666665652f63697578757465726630316135326971716f366b6f6c776b312f7374617469632f382e3534303538372c34372e3337303535352c31342e30382c302e30302c302e30302f363030783430303f6163636573735f746f6b656e3d706b2e65794a31496a6f69625739795a3256756132466d5a6d566c4969776959534936496a497a636d4e304e6c6b6966512e304c52544e6743632d656e76743964354d7a52373577"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fiord-color",
|
||||||
|
"title": "Fiord Color",
|
||||||
|
"url": "https://openmaptiles.github.io/fiord-color-gl-style/style-cdn.json",
|
||||||
|
"thumbnail": "https://camo.githubusercontent.com/605f2edc30e413b37d16a6ca1d500f265725d76d/68747470733a2f2f6170692e6d6170626f782e636f6d2f7374796c65732f76312f6f70656e6d617074696c65732f6369776775693378353030317732706e7668633063327767302f7374617469632f31302e3938373235382c34362e3435333135302c332e30322c302e30302c302e30302f363030783430303f6163636573735f746f6b656e3d706b2e65794a31496a6f696233426c626d3168634852706247567a4969776959534936496d4e70646e593365544a785a7a41774d474d796233427064574a6d616a63784e7a636966512e685031427863786c644968616b4d6350534a4c513151"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "toner",
|
||||||
|
"title": "Toner",
|
||||||
|
"url": "https://openmaptiles.github.io/toner-gl-style/style-cdn.json",
|
||||||
|
"thumbnail": "https://cloud.githubusercontent.com/assets/1288339/21422755/86ebe96e-c839-11e6-8337-42742dfe34a2.png"
|
||||||
|
}
|
||||||
|
]
|
Loading…
Reference in a new issue