Load icons explicit and implement save

This commit is contained in:
lukasmartinelli 2016-09-10 14:47:06 +02:00
parent ab79c632b0
commit d132c09afc
5 changed files with 47 additions and 10 deletions

View file

@ -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)}

View file

@ -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>

View file

@ -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(),

View file

@ -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))

View file

@ -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">