mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-27 10:05:24 +01:00
Load icons explicit and implement save
This commit is contained in:
parent
ab79c632b0
commit
d132c09afc
5 changed files with 47 additions and 10 deletions
|
@ -45,6 +45,12 @@ export default class App extends React.Component {
|
||||||
this.setState({ currentStyle: savedStyle })
|
this.setState({ currentStyle: savedStyle })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onStyleSave() {
|
||||||
|
const snapshotStyle = this.state.currentStyle.set('modified', new Date().toJSON())
|
||||||
|
const savedStyle = this.styleStore.save(snapshotStyle)
|
||||||
|
this.setState({ currentStyle: savedStyle })
|
||||||
|
}
|
||||||
|
|
||||||
onStyleChanged(newStyle) {
|
onStyleChanged(newStyle) {
|
||||||
this.setState({ currentStyle: newStyle })
|
this.setState({ currentStyle: newStyle })
|
||||||
}
|
}
|
||||||
|
@ -60,6 +66,7 @@ export default class App extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return <div style={{ fontFamily: theme.fontFamily, color: theme.color, fontWeight: 300 }}>
|
return <div style={{ fontFamily: theme.fontFamily, color: theme.color, fontWeight: 300 }}>
|
||||||
<Toolbar
|
<Toolbar
|
||||||
|
onStyleSave={this.onStyleSave.bind(this)}
|
||||||
onStyleUpload={this.onStyleUpload.bind(this)}
|
onStyleUpload={this.onStyleUpload.bind(this)}
|
||||||
onStyleDownload={this.onStyleDownload.bind(this)}
|
onStyleDownload={this.onStyleDownload.bind(this)}
|
||||||
onOpenSettings={this.onOpenSettings.bind(this)}
|
onOpenSettings={this.onOpenSettings.bind(this)}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Toolbar, NavItem, Space} from 'rebass'
|
import { Toolbar, NavItem, Space} from 'rebass'
|
||||||
import { MdVisibility, MdDelete, MdVisibilityOff } from 'react-icons/lib/md';
|
|
||||||
import Collapse from 'react-collapse'
|
import Collapse from 'react-collapse'
|
||||||
import theme from '../theme.js'
|
import theme from '../theme.js'
|
||||||
import FillLayer from './fill.jsx'
|
import FillLayer from './fill.jsx'
|
||||||
|
@ -8,6 +7,10 @@ import LineLayer from './line.jsx'
|
||||||
import SymbolLayer from './line.jsx'
|
import SymbolLayer from './line.jsx'
|
||||||
import BackgroundLayer from './background.jsx'
|
import BackgroundLayer from './background.jsx'
|
||||||
|
|
||||||
|
import MdVisibility from 'react-icons/lib/md/visibility'
|
||||||
|
import MdVisibilityOff from 'react-icons/lib/md/visibility-off'
|
||||||
|
import MdDelete from 'react-icons/lib/md/delete'
|
||||||
|
|
||||||
class UnsupportedLayer extends React.Component {
|
class UnsupportedLayer extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return <div></div>
|
return <div></div>
|
||||||
|
|
23
src/map.jsx
23
src/map.jsx
|
@ -2,18 +2,31 @@ import React from 'react'
|
||||||
import MapboxGl from 'mapbox-gl';
|
import MapboxGl from 'mapbox-gl';
|
||||||
import diffStyles from 'mapbox-gl-style-spec/lib/diff'
|
import diffStyles from 'mapbox-gl-style-spec/lib/diff'
|
||||||
import theme from './theme.js'
|
import theme from './theme.js'
|
||||||
|
import Immutable from 'immutable'
|
||||||
|
|
||||||
export class Map extends React.Component {
|
export class Map extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
mapStyle: React.PropTypes.object.isRequired
|
mapStyle: React.PropTypes.instanceOf(Immutable.Map).isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
const map = this.state.map
|
// If the id has changed a new style has been uplaoded and
|
||||||
if(map) {
|
// it is safer to do a full new render
|
||||||
|
const mapIdChanged = this.props.mapStyle.get('id') !== nextProps.mapStyle.get('id')
|
||||||
|
if(mapIdChanged) {
|
||||||
|
this.state.map.setStyle(nextProps.mapStyle.toJS())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: If there is no map yet we need to apply the changes later?
|
||||||
|
// How to deal with that?
|
||||||
|
if(this.state.map) {
|
||||||
|
//TODO: Write own diff algo that operates on immutable collections
|
||||||
|
// Should be able to improve performance since we can only compare
|
||||||
|
// by reference
|
||||||
const changes = diffStyles(this.props.mapStyle.toJS(), nextProps.mapStyle.toJS())
|
const changes = diffStyles(this.props.mapStyle.toJS(), nextProps.mapStyle.toJS())
|
||||||
changes.forEach(change => {
|
changes.forEach(change => {
|
||||||
map[change.command].apply(map, change.args);
|
this.state.map[change.command].apply(this.state.map, change.args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +36,9 @@ export class Map extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
//TODO: Read MapboxGL token from settings
|
||||||
MapboxGl.accessToken = "pk.eyJ1IjoibW9yZ2Vua2FmZmVlIiwiYSI6IjIzcmN0NlkifQ.0LRTNgCc-envt9d5MzR75w";
|
MapboxGl.accessToken = "pk.eyJ1IjoibW9yZ2Vua2FmZmVlIiwiYSI6IjIzcmN0NlkifQ.0LRTNgCc-envt9d5MzR75w";
|
||||||
|
|
||||||
const map = new MapboxGl.Map({
|
const map = new MapboxGl.Map({
|
||||||
container: this.container,
|
container: this.container,
|
||||||
style: this.props.mapStyle.toJS(),
|
style: this.props.mapStyle.toJS(),
|
||||||
|
|
|
@ -69,7 +69,7 @@ export class StyleStore {
|
||||||
// Find the last edited style
|
// Find the last edited style
|
||||||
latestStyle() {
|
latestStyle() {
|
||||||
if(this.mapStyles.length == 0) {
|
if(this.mapStyles.length == 0) {
|
||||||
return Immutable.fromJS(emptyStyle)
|
return ensureOptionalStyleProps(Immutable.fromJS(emptyStyle))
|
||||||
}
|
}
|
||||||
const styleId = window.localStorage.getItem(storage.keys.latest)
|
const styleId = window.localStorage.getItem(storage.keys.latest)
|
||||||
const styleItem = window.localStorage.getItem(styleKey(styleId))
|
const styleItem = window.localStorage.getItem(styleKey(styleId))
|
||||||
|
|
|
@ -3,7 +3,12 @@ import FileReaderInput from 'react-file-reader-input';
|
||||||
|
|
||||||
import { Button, Text } from 'rebass';
|
import { Button, Text } from 'rebass';
|
||||||
import { Menu, NavItem, Tooltip, Container, Block, Fixed } from 'rebass'
|
import { Menu, NavItem, Tooltip, Container, Block, Fixed } from 'rebass'
|
||||||
import { MdFileDownload, MdFileUpload, MdSettings, MdPalette, MdLayers, MdSave, MdFolderOpen} from 'react-icons/lib/md';
|
|
||||||
|
import MdFileDownload from 'react-icons/lib/md/file-download'
|
||||||
|
import MdFileUpload from 'react-icons/lib/md/file-upload'
|
||||||
|
import MdSettings from 'react-icons/lib/md/settings'
|
||||||
|
import MdLayers from 'react-icons/lib/md/layers'
|
||||||
|
import MdSave from 'react-icons/lib/md/save'
|
||||||
|
|
||||||
import theme from './theme.js';
|
import theme from './theme.js';
|
||||||
|
|
||||||
|
@ -11,13 +16,13 @@ export class Toolbar extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onStyleUpload: React.PropTypes.func.isRequired,
|
onStyleUpload: React.PropTypes.func.isRequired,
|
||||||
onStyleDownload: React.PropTypes.func.isRequired,
|
onStyleDownload: React.PropTypes.func.isRequired,
|
||||||
|
onStyleSave: React.PropTypes.func,
|
||||||
onOpenSettings: React.PropTypes.func,
|
onOpenSettings: React.PropTypes.func,
|
||||||
onOpenLayers: React.PropTypes.func,
|
onOpenLayers: React.PropTypes.func,
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.onUpload = this.onUpload.bind(this);
|
|
||||||
this.state = {
|
this.state = {
|
||||||
styleUploaded: false
|
styleUploaded: false
|
||||||
}
|
}
|
||||||
|
@ -39,7 +44,7 @@ export class Toolbar extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let downloadButton = null
|
let downloadButton = null
|
||||||
if(this.state.styleUploaded) {
|
if(this.props.styleUploaded) {
|
||||||
downloadButton = <Block>
|
downloadButton = <Block>
|
||||||
<Button onClick={this.props.onStyleDownload} big={true}>
|
<Button onClick={this.props.onStyleDownload} big={true}>
|
||||||
<Tooltip inverted rounded title="Download style">
|
<Tooltip inverted rounded title="Download style">
|
||||||
|
@ -59,7 +64,7 @@ export class Toolbar extends React.Component {
|
||||||
backgroundColor: theme.colors.black }
|
backgroundColor: theme.colors.black }
|
||||||
}>
|
}>
|
||||||
<Block>
|
<Block>
|
||||||
<FileReaderInput onChange={this.onUpload}>
|
<FileReaderInput onChange={this.onUpload.bind(this)}>
|
||||||
<Button big={true} theme={this.state.styleUploaded ? "default" : "success"}>
|
<Button big={true} theme={this.state.styleUploaded ? "default" : "success"}>
|
||||||
<Tooltip inverted rounded title="Upload style">
|
<Tooltip inverted rounded title="Upload style">
|
||||||
<MdFileUpload />
|
<MdFileUpload />
|
||||||
|
@ -68,6 +73,13 @@ export class Toolbar extends React.Component {
|
||||||
</FileReaderInput>
|
</FileReaderInput>
|
||||||
</Block>
|
</Block>
|
||||||
{downloadButton}
|
{downloadButton}
|
||||||
|
<Block>
|
||||||
|
<Button onClick={this.props.onStyleSave} big={true}>
|
||||||
|
<Tooltip inverted rounded title="Save style">
|
||||||
|
<MdSave />
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
|
</Block>
|
||||||
<Block>
|
<Block>
|
||||||
<Button big={true} onClick={this.props.onOpenLayers}>
|
<Button big={true} onClick={this.props.onOpenLayers}>
|
||||||
<Tooltip inverted rounded title="Layers">
|
<Tooltip inverted rounded title="Layers">
|
||||||
|
|
Loading…
Reference in a new issue