diff --git a/package.json b/package.json index 95de154..75631f6 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "react-icons": "^2.2.1", "react-motion": "^0.4.7", "react-sortable-hoc": "^0.4.5", + "reconnecting-websocket": "^3.0.3", "request": "^2.79.0" }, "babel": { diff --git a/src/components/App.jsx b/src/components/App.jsx index 662aada..0d7da24 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -24,8 +24,10 @@ import LayerWatcher from '../libs/layerwatcher' export default class App extends React.Component { constructor(props) { super(props) - this.styleStore = new ApiStyleStore() this.revisionStore = new RevisionStore() + this.styleStore = new ApiStyleStore({ + onLocalStyleChange: mapStyle => this.onStyleChanged(mapStyle, false) + }) this.styleStore.supported(isSupported => { if(!isSupported) { @@ -76,11 +78,11 @@ export default class App extends React.Component { this.styleStore.save(snapshotStyle) } - onStyleChanged(newStyle) { + onStyleChanged(newStyle, save=true) { const errors = validateStyleMin(newStyle, GlSpec) if(errors.length === 0) { this.revisionStore.addRevision(newStyle) - this.saveStyle(newStyle) + if(save) this.saveStyle(newStyle) this.setState({ mapStyle: newStyle, errors: [], diff --git a/src/components/map/MapboxGlMap.jsx b/src/components/map/MapboxGlMap.jsx index 788a655..4de0f06 100644 --- a/src/components/map/MapboxGlMap.jsx +++ b/src/components/map/MapboxGlMap.jsx @@ -28,6 +28,7 @@ export default class MapboxGlMap extends React.Component { constructor(props) { super(props) + MapboxGl.accessToken = props.accessToken this.state = { map: null, isPopupOpen: false, @@ -37,6 +38,8 @@ export default class MapboxGlMap extends React.Component { } componentWillReceiveProps(nextProps) { + MapboxGl.accessToken = nextProps.accessToken + if(!this.state.map) return //Mapbox GL now does diffing natively so we don't need to calculate @@ -45,8 +48,6 @@ export default class MapboxGlMap extends React.Component { } componentDidMount() { - MapboxGl.accessToken = this.props.accessToken - const map = new MapboxGl.Map({ container: this.container, style: this.props.mapStyle, diff --git a/src/libs/apistore.js b/src/libs/apistore.js index 6b7c372..4f20114 100644 --- a/src/libs/apistore.js +++ b/src/libs/apistore.js @@ -1,25 +1,49 @@ import request from 'request' import style from './style.js' +import ReconnectingWebSocket from 'reconnecting-websocket' + +const host = 'localhost' +const port = '8000' +const localUrl = `http://${host}:${port}` +const websocketUrl = `ws://${host}:${port}/ws` + +console.log(localUrl, websocketUrl) export class ApiStyleStore { + constructor(opts) { + if(opts.onLocalStyleChange) { + const connection = new ReconnectingWebSocket(websocketUrl) + connection.onmessage = function(e) { + if(!e.data) return + try { + console.log('Received style update from API') + const updatedStyle = style.ensureStyleValidity(JSON.parse(e.data)) + opts.onLocalStyleChange(updatedStyle) + } catch(err) { + console.error('Cannot parse local file ' + e.data) + } + } + } + } + supported(cb) { - request('http://localhost:8000/styles', (error, response, body) => { - cb(error === undefined) + request(localUrl + '/styles', (error, response, body) => { + cb(error === null) }) } latestStyle(cb) { if(this.latestStyleId) { - request('http://localhost:8000/styles/' + this.latestStyleId, (error, response, body) => { + request(localUrl + '/styles/' + this.latestStyleId, (error, response, body) => { cb(JSON.parse(body)) }) } else { - request('http://localhost:8000/styles', (error, response, body) => { + request(localUrl + '/styles', (error, response, body) => { if (!error && response.statusCode == 200) { const styleIds = JSON.parse(body); this.latestStyleId = styleIds[0]; - request('http://localhost:8000/styles/' + this.latestStyleId, (error, response, body) => { - cb(style.fromJSON(JSON.parse(body))) + request(localUrl + '/styles/' + this.latestStyleId, (error, response, body) => { + cb(style.ensureStyleValidity(JSON.parse(body))) }) } }) @@ -28,11 +52,11 @@ export class ApiStyleStore { // Save current style replacing previous version save(mapStyle) { - const id = mapStyle.get('id') + const id = mapStyle.id request.put({ - url: 'http://localhost:8000/styles/' + id, + url: localUrl + '/styles/' + id, json: true, - body: style.toJSON(mapStyle) + body: mapStyle }, (error, response, body) => { console.log('Saved style'); })