diff --git a/src/components/App.jsx b/src/components/App.jsx index bd8f31f..ba10485 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -1,5 +1,4 @@ import React from 'react' -import { saveAs } from 'file-saver' import Mousetrap from 'mousetrap' import MapboxGlMap from './map/MapboxGlMap' @@ -21,6 +20,7 @@ import { loadDefaultStyle, StyleStore } from '../libs/stylestore' import { ApiStyleStore } from '../libs/apistore' import { RevisionStore } from '../libs/revisions' import LayerWatcher from '../libs/layerwatcher' +import tokens from '../config/tokens.json' function updateRootSpec(spec, fieldName, newValues) { return { @@ -89,18 +89,14 @@ export default class App extends React.Component { loadDefaultStyle(mapStyle => this.onStyleOpen(mapStyle)) } - onStyleDownload() { - const mapStyle = this.state.mapStyle - const blob = new Blob([formatStyle(mapStyle)], {type: "application/json;charset=utf-8"}); - saveAs(blob, mapStyle.id + ".json"); - } - saveStyle(snapshotStyle) { this.styleStore.save(snapshotStyle) } updateFonts(urlTemplate) { - downloadGlyphsMetadata(urlTemplate, fonts => { + const metadata = this.state.mapStyle.metadata || {} + const accessToken = metadata['maputnik:openmaptiles_access_token'] || tokens.openmaptiles + downloadGlyphsMetadata(urlTemplate.replace('{key}', accessToken), fonts => { this.setState({ spec: updateRootSpec(this.state.spec, 'glyphs', fonts)}) }) } @@ -189,20 +185,14 @@ export default class App extends React.Component { } mapRenderer() { - const metadata = this.state.mapStyle.metadata || {} const mapProps = { - mapStyle: this.state.mapStyle, - accessToken: metadata['maputnik:access_token'], + mapStyle: style.replaceAccessToken(this.state.mapStyle), onDataChange: (e) => { this.layerWatcher.analyzeMap(e.map) }, - //TODO: This would actually belong to the layout component - style:{ - top: 40, - //left: 500, - } } + const metadata = this.state.mapStyle.metadata || {} const renderer = metadata['maputnik:renderer'] || 'mbgljs' // Check if OL3 code has been loaded? @@ -231,7 +221,6 @@ export default class App extends React.Component { sources={this.state.sources} onStyleChanged={this.onStyleChanged.bind(this)} onStyleOpen={this.onStyleChanged.bind(this)} - onStyleDownload={this.onStyleDownload.bind(this)} onInspectModeToggle={this.changeInspectMode.bind(this)} /> diff --git a/src/components/Toolbar.jsx b/src/components/Toolbar.jsx index fc14638..46ae067 100644 --- a/src/components/Toolbar.jsx +++ b/src/components/Toolbar.jsx @@ -54,8 +54,6 @@ export default class Toolbar extends React.Component { onStyleChanged: React.PropTypes.func.isRequired, // A new style has been uploaded onStyleOpen: React.PropTypes.func.isRequired, - // Current style is requested for download - onStyleDownload: React.PropTypes.func.isRequired, // A dict of source id's and the available source layers sources: React.PropTypes.object.isRequired, onInspectModeToggle: React.PropTypes.func.isRequired @@ -74,13 +72,6 @@ export default class Toolbar extends React.Component { } } - downloadButton() { - return - - Download - - } - toggleModal(modalName) { this.setState({ isOpen: { @@ -100,7 +91,6 @@ export default class Toolbar extends React.Component { /> diff --git a/src/components/map/MapboxGlMap.jsx b/src/components/map/MapboxGlMap.jsx index 717cad4..11593b6 100644 --- a/src/components/map/MapboxGlMap.jsx +++ b/src/components/map/MapboxGlMap.jsx @@ -6,6 +6,7 @@ import FeatureLayerPopup from './FeatureLayerPopup' import FeaturePropertyPopup from './FeaturePropertyPopup' import validateColor from 'mapbox-gl-style-spec/lib/validate/validate_color' import style from '../../libs/style.js' +import tokens from '../../config/tokens.json' import { colorHighlightedLayer } from '../../libs/highlight' import 'mapbox-gl/dist/mapbox-gl.css' import '../../mapboxgl.css' @@ -56,8 +57,6 @@ export default class MapboxGlMap extends React.Component { static propTypes = { onDataChange: React.PropTypes.func, mapStyle: React.PropTypes.object.isRequired, - accessToken: React.PropTypes.string, - style: React.PropTypes.object, inspectModeEnabled: React.PropTypes.bool.isRequired, highlightedLayer: React.PropTypes.object, } @@ -65,11 +64,12 @@ export default class MapboxGlMap extends React.Component { static defaultProps = { onMapLoaded: () => {}, onDataChange: () => {}, + mapboxAccessToken: tokens.mapbox, } constructor(props) { super(props) - MapboxGl.accessToken = props.accessToken + MapboxGl.accessToken = tokens.mapbox this.state = { map: null, inspect: null, @@ -80,8 +80,9 @@ export default class MapboxGlMap extends React.Component { } componentWillReceiveProps(nextProps) { - MapboxGl.accessToken = nextProps.accessToken if(!this.state.map) return + const metadata = nextProps.mapStyle.metadata || {} + MapboxGl.accessToken = metadata['maputnik:mapbox_access_token'] || tokens.mapbox if(!nextProps.inspectModeEnabled) { //Mapbox GL now does diffing natively so we don't need to calculate diff --git a/src/components/modals/ExportModal.jsx b/src/components/modals/ExportModal.jsx index 89547c2..17dec43 100644 --- a/src/components/modals/ExportModal.jsx +++ b/src/components/modals/ExportModal.jsx @@ -1,4 +1,5 @@ import React from 'react' +import { saveAs } from 'file-saver' import GlSpec from 'mapbox-gl-style-spec/reference/latest.js' import InputBlock from '../inputs/InputBlock' @@ -103,24 +104,30 @@ class Gist extends React.Component { } } - +function stripAccessTokens(mapStyle) { + const changedMetadata = { ...mapStyle.metadata } + delete changedMetadata['maputnik:mapbox_access_token'] + delete changedMetadata['maputnik:openmaptiles_access_token'] + return { + ...mapStyle, + metadata: changedMetadata + } +} class ExportModal extends React.Component { static propTypes = { mapStyle: React.PropTypes.object.isRequired, isOpen: React.PropTypes.bool.isRequired, onOpenToggle: React.PropTypes.func.isRequired, - // Current style is requested for download - onStyleDownload: React.PropTypes.func.isRequired, } constructor(props) { super(props); } - onStyleDownload() { - const blob = new Blob([formatStyle(mapStyle)], {type: "application/json;charset=utf-8"}); - saveAs(blob, mapStyle.id + ".json"); + downloadStyle() { + const blob = new Blob([formatStyle(stripAccessTokens(this.props.mapStyle))], {type: "application/json;charset=utf-8"}); + saveAs(blob, this.props.mapStyle.id + ".json"); } render() { @@ -135,7 +142,7 @@ class ExportModal extends React.Component {

Download a JSON style to your computer.

- diff --git a/src/components/modals/SettingsModal.jsx b/src/components/modals/SettingsModal.jsx index dc4fbf3..66967c2 100644 --- a/src/components/modals/SettingsModal.jsx +++ b/src/components/modals/SettingsModal.jsx @@ -45,6 +45,7 @@ class SettingsModal extends React.Component { onOpenToggle={this.props.onOpenToggle} title={'Style Settings'} > +
- + + + + + @@ -88,6 +96,7 @@ class SettingsModal extends React.Component { onChange={this.changeMetadataProperty.bind(this, 'maputnik:renderer')} /> +
} } diff --git a/src/config/tokens.json b/src/config/tokens.json new file mode 100644 index 0000000..9676c74 --- /dev/null +++ b/src/config/tokens.json @@ -0,0 +1,4 @@ +{ + "mapbox": "pk.eyJ1IjoibW9yZ2Vua2FmZmVlIiwiYSI6ImNpeHJmNXNmZTAwNHIycXBid2NqdTJibjMifQ.Dv1-GDpTWi0NP6xW9Fct1w", + "openmaptiles": "Og58UhhtiiTaLVlPtPgs" +} diff --git a/src/libs/style.js b/src/libs/style.js index 5e2404f..3f012d2 100644 --- a/src/libs/style.js +++ b/src/libs/style.js @@ -1,6 +1,7 @@ import React from 'react'; import spec from 'mapbox-gl-style-spec/reference/latest.min.js' import derefLayers from 'mapbox-gl-style-spec/lib/deref' +import tokens from '../config/tokens.json' // Empty style is always used if no style could be restored or fetched const emptyStyle = ensureStyleValidity({ @@ -19,6 +20,20 @@ function ensureHasId(style) { return style } +function ensureHasNoInteractive(style) { + const changedLayers = style.layers.map(layer => { + const changedLayer = { ...layer } + delete changedLayer.interactive + return changedLayer + }) + + const nonInteractiveStyle = { + ...style, + layers: changedLayers + } + return nonInteractiveStyle +} + function ensureHasNoRefs(style) { const derefedStyle = { ...style, @@ -28,7 +43,7 @@ function ensureHasNoRefs(style) { } function ensureStyleValidity(style) { - return ensureHasNoRefs(ensureHasId(style)) + return ensureHasNoInteractive(ensureHasNoRefs(ensureHasId(style))) } function indexOfLayer(layers, layerId) { @@ -40,9 +55,32 @@ function indexOfLayer(layers, layerId) { return null } +function replaceAccessToken(mapStyle) { + const omtSource = mapStyle.sources.openmaptiles + if(!omtSource) return mapStyle + + const metadata = mapStyle.metadata || {} + const accessToken = metadata['maputnik:openmaptiles_access_token'] || tokens.openmaptiles + const changedSources = { + ...mapStyle.sources, + openmaptiles: { + ...omtSource, + url: omtSource.url.replace('{key}', accessToken) + } + } + const changedStyle = { + ...mapStyle, + glyphs: mapStyle.glyphs.replace('{key}', accessToken), + sources: changedSources + } + + return changedStyle +} + export default { ensureStyleValidity, emptyStyle, indexOfLayer, generateId, + replaceAccessToken, }