import React from 'react' import PropTypes from 'prop-types' import { saveAs } from 'file-saver' import styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec' import InputBlock from '../inputs/InputBlock' import StringInput from '../inputs/StringInput' import SelectInput from '../inputs/SelectInput' import CheckboxInput from '../inputs/CheckboxInput' import Button from '../Button' import Modal from './Modal' import MdFileDownload from 'react-icons/lib/md/file-download' import TiClipboard from 'react-icons/lib/ti/clipboard' import style from '../../libs/style.js' import GitHub from 'github-api' import { CopyToClipboard } from 'react-copy-to-clipboard' class Gist extends React.Component { static propTypes = { mapStyle: PropTypes.object.isRequired, onStyleChanged: PropTypes.func.isRequired, } constructor(props) { super(props); this.state = { preview: false, public: false, saving: false, latestGist: null, } } componentWillReceiveProps(nextProps) { this.setState({ ...this.state, preview: !!(nextProps.mapStyle.metadata || {})['maputnik:openmaptiles_access_token'] }) } onSave() { this.setState({ ...this.state, saving: true }); const preview = this.state.preview; const mapboxToken = (this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token']; const mapStyleStr = preview ? styleSpec.format(stripAccessTokens(style.replaceAccessToken(this.props.mapStyle))) : styleSpec.format(stripAccessTokens(this.props.mapStyle)); const styleTitle = this.props.mapStyle.name || 'Style'; const htmlStr = ` `+styleTitle+` Preview
` const files = { "style.json": { content: mapStyleStr } } if(preview) { files["index.html"] = { content: htmlStr } } const gh = new GitHub(); let gist = gh.getGist(); // not a gist yet gist.create({ public: this.state.public, description: styleTitle, files: files }).then(function({data}) { return gist.read(); }).then(function({data}) { this.setState({ ...this.state, latestGist: data, saving: false, }); }.bind(this)); } onPreviewChange(value) { this.setState({ ...this.state, preview: value }) } onPublicChange(value) { this.setState({ ...this.state, public: value }) } changeMetadataProperty(property, value) { const changedStyle = { ...this.props.mapStyle, metadata: { ...this.props.mapStyle.metadata, [property]: value } } this.props.onStyleChanged(changedStyle) } renderPreviewLink() { const gist = this.state.latestGist; const user = gist.user || 'anonymous'; const preview = !!gist.files['index.html']; if(preview) { return Preview,{' '} } return null; } renderLatestGist() { const gist = this.state.latestGist; const saving = this.state.saving; if(saving) { return

Saving...

} else if(gist) { const user = gist.user || 'anonymous'; const rawGistLink = "https://gist.githubusercontent.com/" + user + "/" + gist.id + "/raw/" + gist.history[0].version + "/style.json" const maputnikStyleLink = "https://maputnik.github.io/editor/?style=" + rawGistLink return

Latest saved gist:{' '} {this.renderPreviewLink(this)} Source

Share this style:

} } render() { return
Public gist
Include preview
{this.state.preview ?
Get your free access token
: null} {this.renderLatestGist()}
} } 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: PropTypes.object.isRequired, onStyleChanged: PropTypes.func.isRequired, isOpen: PropTypes.bool.isRequired, onOpenToggle: PropTypes.func.isRequired, } constructor(props) { super(props); } downloadStyle() { const blob = new Blob([styleSpec.format(stripAccessTokens(this.props.mapStyle))], {type: "application/json;charset=utf-8"}); saveAs(blob, this.props.mapStyle.id + ".json"); } render() { return

Download Style

Download a JSON style to your computer.

Save style

} } export default ExportModal