mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-29 13:10:28 +01:00
Merge pull request #81 from maputnik/default-access-token
Default access token
This commit is contained in:
commit
24dc71344e
7 changed files with 80 additions and 42 deletions
|
@ -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)}
|
||||
/>
|
||||
|
||||
|
|
|
@ -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 <ToolbarAction onClick={this.props.onStyleDownload}>
|
||||
<MdFileDownload />
|
||||
<IconText>Download</IconText>
|
||||
</ToolbarAction>
|
||||
}
|
||||
|
||||
toggleModal(modalName) {
|
||||
this.setState({
|
||||
isOpen: {
|
||||
|
@ -100,7 +91,6 @@ export default class Toolbar extends React.Component {
|
|||
/>
|
||||
<ExportModal
|
||||
mapStyle={this.props.mapStyle}
|
||||
onStyleDownload={this.props.onStyleDownload}
|
||||
isOpen={this.state.isOpen.export}
|
||||
onOpenToggle={this.toggleModal.bind(this, 'export')}
|
||||
/>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
|||
<p>
|
||||
Download a JSON style to your computer.
|
||||
</p>
|
||||
<Button onClick={this.props.onStyleDownload}>
|
||||
<Button onClick={this.downloadStyle.bind(this)}>
|
||||
<MdFileDownload />
|
||||
Download
|
||||
</Button>
|
||||
|
|
|
@ -45,6 +45,7 @@ class SettingsModal extends React.Component {
|
|||
onOpenToggle={this.props.onOpenToggle}
|
||||
title={'Style Settings'}
|
||||
>
|
||||
<div style={{minWidth: 350}}>
|
||||
<InputBlock label={"Name"} doc={GlSpec.$root.name.doc}>
|
||||
<StringInput {...inputProps}
|
||||
value={this.props.mapStyle.name}
|
||||
|
@ -71,10 +72,17 @@ class SettingsModal extends React.Component {
|
|||
/>
|
||||
</InputBlock>
|
||||
|
||||
<InputBlock label={"Access Token"} doc={"Public access token for Mapbox GL."}>
|
||||
<InputBlock label={"Mapbox Access Token"} doc={"Public access token for Mapbox services."}>
|
||||
<StringInput {...inputProps}
|
||||
value={metadata['maputnik:access_token']}
|
||||
onChange={this.changeMetadataProperty.bind(this, "maputnik:access_token")}
|
||||
value={metadata['maputnik:mapbox_access_token']}
|
||||
onChange={this.changeMetadataProperty.bind(this, "maputnik:mapbox_access_token")}
|
||||
/>
|
||||
</InputBlock>
|
||||
|
||||
<InputBlock label={"OpenMapTiles Access Token"} doc={"Public access token for the OpenMapTiles CDN."}>
|
||||
<StringInput {...inputProps}
|
||||
value={metadata['maputnik:openmaptiles_access_token']}
|
||||
onChange={this.changeMetadataProperty.bind(this, "maputnik:openmaptiles_access_token")}
|
||||
/>
|
||||
</InputBlock>
|
||||
|
||||
|
@ -88,6 +96,7 @@ class SettingsModal extends React.Component {
|
|||
onChange={this.changeMetadataProperty.bind(this, 'maputnik:renderer')}
|
||||
/>
|
||||
</InputBlock>
|
||||
</div>
|
||||
</Modal>
|
||||
}
|
||||
}
|
||||
|
|
4
src/config/tokens.json
Normal file
4
src/config/tokens.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"mapbox": "pk.eyJ1IjoibW9yZ2Vua2FmZmVlIiwiYSI6ImNpeHJmNXNmZTAwNHIycXBid2NqdTJibjMifQ.Dv1-GDpTWi0NP6xW9Fct1w",
|
||||
"openmaptiles": "Og58UhhtiiTaLVlPtPgs"
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue