mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-27 09:55:23 +01:00
Export to Gist anonymously, related to maputnik/editor#3
This commit is contained in:
parent
8c2b110115
commit
69a665373f
3 changed files with 165 additions and 1 deletions
|
@ -24,6 +24,7 @@
|
||||||
"codemirror": "^5.18.2",
|
"codemirror": "^5.18.2",
|
||||||
"color": "^1.0.3",
|
"color": "^1.0.3",
|
||||||
"file-saver": "^1.3.2",
|
"file-saver": "^1.3.2",
|
||||||
|
"github-api": "^3.0.0",
|
||||||
"lodash.capitalize": "^4.2.1",
|
"lodash.capitalize": "^4.2.1",
|
||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
"lodash.isequal": "^4.4.0",
|
"lodash.isequal": "^4.4.0",
|
||||||
|
|
|
@ -18,6 +18,7 @@ import InspectionIcon from 'react-icons/lib/md/find-in-page'
|
||||||
|
|
||||||
import logoImage from '../img/maputnik.png'
|
import logoImage from '../img/maputnik.png'
|
||||||
import SettingsModal from './modals/SettingsModal'
|
import SettingsModal from './modals/SettingsModal'
|
||||||
|
import ExportModal from './modals/ExportModal'
|
||||||
import SourcesModal from './modals/SourcesModal'
|
import SourcesModal from './modals/SourcesModal'
|
||||||
import OpenModal from './modals/OpenModal'
|
import OpenModal from './modals/OpenModal'
|
||||||
|
|
||||||
|
@ -68,6 +69,7 @@ export default class Toolbar extends React.Component {
|
||||||
sources: false,
|
sources: false,
|
||||||
open: false,
|
open: false,
|
||||||
add: false,
|
add: false,
|
||||||
|
export: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,6 +98,12 @@ export default class Toolbar extends React.Component {
|
||||||
isOpen={this.state.isOpen.settings}
|
isOpen={this.state.isOpen.settings}
|
||||||
onOpenToggle={this.toggleModal.bind(this, 'settings')}
|
onOpenToggle={this.toggleModal.bind(this, 'settings')}
|
||||||
/>
|
/>
|
||||||
|
<ExportModal
|
||||||
|
mapStyle={this.props.mapStyle}
|
||||||
|
onStyleDownload={this.props.onStyleDownload}
|
||||||
|
isOpen={this.state.isOpen.export}
|
||||||
|
onOpenToggle={this.toggleModal.bind(this, 'export')}
|
||||||
|
/>
|
||||||
<OpenModal
|
<OpenModal
|
||||||
isOpen={this.state.isOpen.open}
|
isOpen={this.state.isOpen.open}
|
||||||
onStyleOpen={this.props.onStyleOpen}
|
onStyleOpen={this.props.onStyleOpen}
|
||||||
|
@ -118,7 +126,10 @@ export default class Toolbar extends React.Component {
|
||||||
<OpenIcon />
|
<OpenIcon />
|
||||||
<IconText>Open</IconText>
|
<IconText>Open</IconText>
|
||||||
</ToolbarAction>
|
</ToolbarAction>
|
||||||
{this.downloadButton()}
|
<ToolbarAction onClick={this.toggleModal.bind(this, 'export')}>
|
||||||
|
<MdFileDownload />
|
||||||
|
<IconText>Export</IconText>
|
||||||
|
</ToolbarAction>
|
||||||
<ToolbarAction onClick={this.toggleModal.bind(this, 'sources')}>
|
<ToolbarAction onClick={this.toggleModal.bind(this, 'sources')}>
|
||||||
<SourcesIcon />
|
<SourcesIcon />
|
||||||
<IconText>Sources</IconText>
|
<IconText>Sources</IconText>
|
||||||
|
|
152
src/components/modals/ExportModal.jsx
Normal file
152
src/components/modals/ExportModal.jsx
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import GlSpec from 'mapbox-gl-style-spec/reference/latest.js'
|
||||||
|
import InputBlock from '../inputs/InputBlock'
|
||||||
|
import StringInput from '../inputs/StringInput'
|
||||||
|
import SelectInput from '../inputs/SelectInput'
|
||||||
|
import Button from '../Button'
|
||||||
|
import Modal from './Modal'
|
||||||
|
import MdFileDownload from 'react-icons/lib/md/file-download'
|
||||||
|
import formatStyle from 'mapbox-gl-style-spec/lib/format'
|
||||||
|
import GitHub from 'github-api'
|
||||||
|
|
||||||
|
|
||||||
|
class Gist extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
mapStyle: React.PropTypes.object.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSave() {
|
||||||
|
this.setState({
|
||||||
|
saving: true
|
||||||
|
});
|
||||||
|
const mapStyleStr = formatStyle(this.props.mapStyle);
|
||||||
|
const styleTitle = this.props.mapStyle.name || 'Style';
|
||||||
|
const htmlStr = `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>`+styleTitle+` Preview</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://api.mapbox.com/mapbox-gl-js/v0.28.0/mapbox-gl.css" />
|
||||||
|
<script src="https://api.mapbox.com/mapbox-gl-js/v0.28.0/mapbox-gl.js"></script>
|
||||||
|
<style>
|
||||||
|
body { margin:0; padding:0; }
|
||||||
|
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='map'></div>
|
||||||
|
<script>
|
||||||
|
var map = new mapboxgl.Map({
|
||||||
|
container: 'map',
|
||||||
|
style: 'style.json',
|
||||||
|
attributionControl: true,
|
||||||
|
hash: true
|
||||||
|
});
|
||||||
|
map.addControl(new mapboxgl.NavigationControl());
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`
|
||||||
|
const gh = new GitHub();
|
||||||
|
let gist = gh.getGist(); // not a gist yet
|
||||||
|
gist.create({
|
||||||
|
public: true,
|
||||||
|
description: styleTitle + 'Preview',
|
||||||
|
files: {
|
||||||
|
"style.json": {
|
||||||
|
content: mapStyleStr
|
||||||
|
},
|
||||||
|
"index.html": {
|
||||||
|
content: htmlStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).then(function({data}) {
|
||||||
|
return gist.read();
|
||||||
|
}).then(function({data}) {
|
||||||
|
this.setState({
|
||||||
|
latestGist: data
|
||||||
|
});
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
renderLatestGist() {
|
||||||
|
const gist = this.state.latestGist;
|
||||||
|
const saving = this.state.saving;
|
||||||
|
if(gist) {
|
||||||
|
const user = gist.user || 'anonymous';
|
||||||
|
return <p>
|
||||||
|
Latest saved gist:{' '}
|
||||||
|
<a target="_blank" href={"https://bl.ocks.org/"+user+"/"+gist.id}>Preview</a>,{' '}
|
||||||
|
<a target="_blank" href={"https://gist.github.com/"+user+"/"+gist.id}>Source</a>
|
||||||
|
</p>
|
||||||
|
} else if(saving) {
|
||||||
|
return <p>Saving...</p>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <div>
|
||||||
|
<Button onClick={this.onSave.bind(this)}>
|
||||||
|
<MdFileDownload />
|
||||||
|
Save to Gist (anonymous)
|
||||||
|
</Button>
|
||||||
|
{this.renderLatestGist()}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <Modal
|
||||||
|
isOpen={this.props.isOpen}
|
||||||
|
onOpenToggle={this.props.onOpenToggle}
|
||||||
|
title={'Export Style'}
|
||||||
|
>
|
||||||
|
|
||||||
|
<div className="maputnik-modal-section">
|
||||||
|
<h4>Download Style</h4>
|
||||||
|
<p>
|
||||||
|
Download a JSON style to your computer.
|
||||||
|
</p>
|
||||||
|
<Button onClick={this.props.onStyleDownload}>
|
||||||
|
<MdFileDownload />
|
||||||
|
Download
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="maputnik-modal-section">
|
||||||
|
<h4>Save style</h4>
|
||||||
|
<Gist mapStyle={this.props.mapStyle} />
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExportModal
|
Loading…
Reference in a new issue