From a76e08aee7d1a5ad0ed789fdcb5e94fbace5d4f7 Mon Sep 17 00:00:00 2001 From: orangemug Date: Wed, 8 Nov 2017 11:11:36 +0000 Subject: [PATCH 1/4] Fixed source layer autocomplete to fetch from the sources json definition --- src/components/App.jsx | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/components/App.jsx b/src/components/App.jsx index 2fb38d27..bb7d524d 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -67,9 +67,9 @@ export default class App extends React.Component { } this.layerWatcher = new LayerWatcher({ - onSourcesChange: v => this.setState({ sources: v }), onVectorLayersChange: v => this.setState({ vectorLayers: v }) }) + this.fetchSources(); } componentDidMount() { @@ -126,6 +126,8 @@ export default class App extends React.Component { errors: errors.map(err => err.message) }) } + + this.fetchSources(); } onUndo() { @@ -182,11 +184,49 @@ export default class App extends React.Component { }) } + fetchSources() { + const sourceList = {...this.state.sources}; + + for(let [key, val] of Object.entries(this.state.mapStyle.sources)) { + sourceList[key] = sourceList[key] || []; + + if(val.type === "vector") { + const url = val.url; + fetch(url) + .then((response) => { + return response.json(); + }) + .then((json) => { + const sourceList = {...this.state.sources}; + sourceList[key] = []; + + for(let layer of json.vector_layers) { + sourceList[key].push(layer.id) + } + + this.setState({ + sources: sourceList + }); + }) + .catch((err) => { + console.error("Failed to process sources for '%s'", url, err); + }) + } + } + + // Note: Each source will be missing layers initially until the fetch is complete + this.setState({ + sources: sourceList + }) + + } + mapRenderer() { const mapProps = { mapStyle: style.replaceAccessToken(this.state.mapStyle), onDataChange: (e) => { this.layerWatcher.analyzeMap(e.map) + this.fetchSources(); }, } From 63ac70741545a8fd892634ad23254b89abdb404d Mon Sep 17 00:00:00 2001 From: orangemug Date: Fri, 17 Nov 2017 10:53:46 +0000 Subject: [PATCH 2/4] Call fetchSources after component mount. --- src/components/App.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/App.jsx b/src/components/App.jsx index bb7d524d..7ca7f2bc 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -69,10 +69,10 @@ export default class App extends React.Component { this.layerWatcher = new LayerWatcher({ onVectorLayersChange: v => this.setState({ vectorLayers: v }) }) - this.fetchSources(); } componentDidMount() { + this.fetchSources(); Mousetrap.bind(['ctrl+z'], this.onUndo.bind(this)); Mousetrap.bind(['ctrl+y'], this.onRedo.bind(this)); } @@ -185,7 +185,7 @@ export default class App extends React.Component { } fetchSources() { - const sourceList = {...this.state.sources}; + const sourceList = {}; for(let [key, val] of Object.entries(this.state.mapStyle.sources)) { sourceList[key] = sourceList[key] || []; @@ -197,6 +197,7 @@ export default class App extends React.Component { return response.json(); }) .then((json) => { + // Create new objects before setState const sourceList = {...this.state.sources}; sourceList[key] = []; From a4fbe55012118014b360c40bf1fdb8ed653b058b Mon Sep 17 00:00:00 2001 From: orangemug Date: Fri, 17 Nov 2017 11:43:56 +0000 Subject: [PATCH 3/4] Added type to sources list and now filtering in modal autocomplete. --- src/components/App.jsx | 9 ++++-- src/components/modals/AddModal.jsx | 52 +++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/components/App.jsx b/src/components/App.jsx index 7ca7f2bc..279f66dd 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -188,7 +188,10 @@ export default class App extends React.Component { const sourceList = {}; for(let [key, val] of Object.entries(this.state.mapStyle.sources)) { - sourceList[key] = sourceList[key] || []; + sourceList[key] = { + type: val.type, + layers: [] + }; if(val.type === "vector") { const url = val.url; @@ -199,10 +202,10 @@ export default class App extends React.Component { .then((json) => { // Create new objects before setState const sourceList = {...this.state.sources}; - sourceList[key] = []; + sourceList[key] = {...sourceList[key]}; for(let layer of json.vector_layers) { - sourceList[key].push(layer.id) + sourceList[key].layers.push(layer.id) } this.setState({ diff --git a/src/components/modals/AddModal.jsx b/src/components/modals/AddModal.jsx index 24a4638d..ab4a6de6 100644 --- a/src/components/modals/AddModal.jsx +++ b/src/components/modals/AddModal.jsx @@ -56,18 +56,54 @@ class AddModal extends React.Component { } } - componentWillReceiveProps(nextProps) { - const sourceIds = Object.keys(nextProps.sources) - if(!this.state.source && sourceIds.length > 0) { + componentWillUpdate(nextProps, nextState) { + // Check if source is valid for new type + const availableSources = this.getSources(nextState.type); + if( + this.state.source !== "" + && availableSources.indexOf(this.state.source) < 0 + ) { this.setState({ - source: sourceIds[0], - 'source-layer': this.state['source-layer'] || (nextProps.sources[sourceIds[0]] || [])[0] - }) + source: "" + }); } } + getLayersForSource(source) { + const sourceObj = this.props.sources[source] || {}; + return sourceObj.layers || []; + } + + getSources(type) { + const sources = []; + + const types = { + vector: [ + "fill", + "line", + "symbol", + "circle", + "fill-extrusion" + ], + raster: [ + "raster" + ] + } + + for(let [key, val] of Object.entries(this.props.sources)) { + if(types[val.type].indexOf(type) > -1) { + sources.push(key); + } + } + + return sources; + } + render() { + const sources = this.getSources(this.state.type); + const layers = this.getLayersForSource(this.state.source); + return {this.state.type !== 'background' && this.setState({ source: v })} /> } {this.state.type !== 'background' && this.state.type !== 'raster' && this.setState({ 'source-layer': v })} /> From 002e9c4647f5bda5edbb832956d282cce2a48bce Mon Sep 17 00:00:00 2001 From: orangemug Date: Fri, 17 Nov 2017 13:06:26 +0000 Subject: [PATCH 4/4] Fix for new sources definition. --- src/components/layers/LayerEditor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/layers/LayerEditor.jsx b/src/components/layers/LayerEditor.jsx index 2184388e..1d43bffe 100644 --- a/src/components/layers/LayerEditor.jsx +++ b/src/components/layers/LayerEditor.jsx @@ -134,7 +134,7 @@ export default class LayerEditor extends React.Component { /> } {this.props.layer.type !== 'raster' && this.props.layer.type !== 'background' && this.changeProperty(null, 'source-layer', v)} />