Support setting access token

This commit is contained in:
lukasmartinelli 2016-09-10 16:26:39 +02:00
parent 8582496811
commit 2cc4055416
5 changed files with 52 additions and 15 deletions

View file

@ -5,7 +5,7 @@ import { Drawer, Container, Block, Fixed } from 'rebass'
import {Map} from './map.jsx' import {Map} from './map.jsx'
import {Toolbar} from './toolbar.jsx' import {Toolbar} from './toolbar.jsx'
import { StyleManager } from './style.js' import { StyleManager } from './style.js'
import { StyleStore } from './stylestore.js' import { SettingsStore, StyleStore } from './stylestore.js'
import { WorkspaceDrawer } from './workspace.jsx' import { WorkspaceDrawer } from './workspace.jsx'
import theme from './theme.js' import theme from './theme.js'
@ -19,7 +19,9 @@ export default class App extends React.Component {
constructor(props) { constructor(props) {
super(props) super(props)
this.styleStore = new StyleStore() this.styleStore = new StyleStore()
this.settingsStore = new SettingsStore()
this.state = { this.state = {
accessToken: this.settingsStore.accessToken,
workContext: "layers", workContext: "layers",
currentStyle: this.styleStore.latestStyle(), currentStyle: this.styleStore.latestStyle(),
} }
@ -62,6 +64,11 @@ export default class App extends React.Component {
this.setState({ workContext: "layers", }) this.setState({ workContext: "layers", })
} }
onAccessTokenChanged(newToken) {
this.settingsStore.accessToken = newToken
this.setState({ accessToken: newToken })
}
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
@ -76,8 +83,13 @@ export default class App extends React.Component {
onStyleChanged={this.onStyleChanged.bind(this)} onStyleChanged={this.onStyleChanged.bind(this)}
workContext={this.state.workContext} workContext={this.state.workContext}
mapStyle={this.state.currentStyle} mapStyle={this.state.currentStyle}
accessToken={this.state.accessToken}
onAccessTokenChanged={this.onAccessTokenChanged.bind(this)}
/>
<Map
mapStyle={this.state.currentStyle}
accessToken={this.state.accessToken}
/> />
<Map mapStyle={this.state.currentStyle} />
</div> </div>
} }
} }

View file

@ -7,13 +7,17 @@ import Immutable from 'immutable'
export class Map extends React.Component { export class Map extends React.Component {
static propTypes = { static propTypes = {
mapStyle: React.PropTypes.instanceOf(Immutable.Map).isRequired, mapStyle: React.PropTypes.instanceOf(Immutable.Map).isRequired,
accessToken: React.PropTypes.string,
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
const tokenChanged = nextProps.accessToken !== MapboxGl.accessToken
// If the id has changed a new style has been uplaoded and // If the id has changed a new style has been uplaoded and
// it is safer to do a full new render // it is safer to do a full new render
const mapIdChanged = this.props.mapStyle.get('id') !== nextProps.mapStyle.get('id') const mapIdChanged = this.props.mapStyle.get('id') !== nextProps.mapStyle.get('id')
if(mapIdChanged) {
if(mapIdChanged || tokenChanged) {
this.state.map.setStyle(nextProps.mapStyle.toJS()) this.state.map.setStyle(nextProps.mapStyle.toJS())
return return
} }
@ -36,8 +40,7 @@ export class Map extends React.Component {
} }
componentDidMount() { componentDidMount() {
//TODO: Read MapboxGL token from settings MapboxGl.accessToken = this.props.accessToken
MapboxGl.accessToken = "pk.eyJ1IjoibW9yZ2Vua2FmZmVlIiwiYSI6IjIzcmN0NlkifQ.0LRTNgCc-envt9d5MzR75w";
const map = new MapboxGl.Map({ const map = new MapboxGl.Map({
container: this.container, container: this.container,

View file

@ -7,7 +7,9 @@ import Immutable from 'immutable'
export class SettingsEditor extends React.Component { export class SettingsEditor extends React.Component {
static propTypes = { static propTypes = {
mapStyle: React.PropTypes.instanceOf(Immutable.Map).isRequired, mapStyle: React.PropTypes.instanceOf(Immutable.Map).isRequired,
onStyleChanged: React.PropTypes.func.isRequired onStyleChanged: React.PropTypes.func.isRequired,
accessToken: React.PropTypes.string,
onAccessTokenChanged: React.PropTypes.func
} }
onChange(property, e) { onChange(property, e) {
@ -23,6 +25,12 @@ export class SettingsEditor extends React.Component {
</NavItem> </NavItem>
</Toolbar> </Toolbar>
<Container> <Container>
<Input
name="access-token"
label="Mapbox GL access token"
value={this.props.accessToken}
onChange={e => this.props.onAccessTokenChanged(e.target.value)}
/>
<Input <Input
name="name" name="name"
label="Name" label="Name"

View file

@ -1,11 +1,10 @@
import { colorizeLayers } from './style.js' import { colorizeLayers } from './style.js'
import Immutable from 'immutable' import Immutable from 'immutable'
const storage = { const storagePrefix = "mapolo"
prefix: 'mapolo', const storageKeys = {
keys: { latest: [storagePrefix, 'latest_style'].join(''),
latest: 'mapolo:latest_style' accessToken: [storagePrefix, 'access_token'].join('')
}
} }
const emptyStyle = { const emptyStyle = {
@ -28,7 +27,7 @@ function loadStoredStyles() {
function isStyleKey(key) { function isStyleKey(key) {
const parts = key.split(":") const parts = key.split(":")
return parts.length == 2 && parts[0] === storage.prefix return parts.length == 2 && parts[0] === storagePrefix
} }
// Load style id from key // Load style id from key
@ -44,7 +43,7 @@ function fromKey(key) {
// Calculate key that identifies the style with a version // Calculate key that identifies the style with a version
function styleKey(styleId) { function styleKey(styleId) {
return [storage.prefix, styleId].join(":") return [storagePrefix, styleId].join(":")
} }
// Ensure a style has a unique id and a created date // Ensure a style has a unique id and a created date
@ -58,6 +57,17 @@ function ensureOptionalStyleProps(mapStyle) {
return mapStyle return mapStyle
} }
// Store style independent settings
export class SettingsStore {
get accessToken() {
const token = window.localStorage.getItem(storageKeys.accessToken)
return token ? token : ""
}
set accessToken(val) {
window.localStorage.setItem(storageKeys.accessToken, val)
}
}
// Manages many possible styles that are stored in the local storage // Manages many possible styles that are stored in the local storage
export class StyleStore { export class StyleStore {
// Tile store will load all items from local storage and // Tile store will load all items from local storage and
@ -71,7 +81,7 @@ export class StyleStore {
if(this.mapStyles.length == 0) { if(this.mapStyles.length == 0) {
return ensureOptionalStyleProps(Immutable.fromJS(emptyStyle)) return ensureOptionalStyleProps(Immutable.fromJS(emptyStyle))
} }
const styleId = window.localStorage.getItem(storage.keys.latest) const styleId = window.localStorage.getItem(storageKeys.latest)
const styleItem = window.localStorage.getItem(styleKey(styleId)) const styleItem = window.localStorage.getItem(styleKey(styleId))
return Immutable.fromJS(JSON.parse(styleItem)) return Immutable.fromJS(JSON.parse(styleItem))
} }
@ -84,7 +94,7 @@ export class StyleStore {
mapStyle = ensureOptionalStyleProps(mapStyle) mapStyle = ensureOptionalStyleProps(mapStyle)
const key = styleKey(mapStyle.get('id')) const key = styleKey(mapStyle.get('id'))
window.localStorage.setItem(key, JSON.stringify(mapStyle.toJS())) window.localStorage.setItem(key, JSON.stringify(mapStyle.toJS()))
window.localStorage.setItem(storage.keys.latest, mapStyle.get('id')) window.localStorage.setItem(storageKeys.latest, mapStyle.get('id'))
return mapStyle return mapStyle
} }
} }

View file

@ -10,6 +10,8 @@ export class WorkspaceDrawer extends React.Component {
mapStyle: React.PropTypes.object.isRequired, mapStyle: React.PropTypes.object.isRequired,
onStyleChanged: React.PropTypes.func.isRequired, onStyleChanged: React.PropTypes.func.isRequired,
workContext: React.PropTypes.oneOf(['layers', 'settings']).isRequired, workContext: React.PropTypes.oneOf(['layers', 'settings']).isRequired,
accessToken: React.PropTypes.string,
onAccessTokenChanged: React.PropTypes.func,
} }
onLayersChanged(changedLayers) { onLayersChanged(changedLayers) {
@ -31,6 +33,8 @@ export class WorkspaceDrawer extends React.Component {
workspaceContent = <SettingsEditor workspaceContent = <SettingsEditor
onStyleChanged={this.props.onStyleChanged} onStyleChanged={this.props.onStyleChanged}
mapStyle={this.props.mapStyle} mapStyle={this.props.mapStyle}
accessToken={this.props.accessToken}
onAccessTokenChanged={this.props.onAccessTokenChanged}
/> />
} }