You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
carbon/pages/editor.js

170 lines
4.5 KiB
JavaScript

// Theirs
7 years ago
import React from 'react';
import HTML5Backend from 'react-dnd-html5-backend';
import { DragDropContext } from 'react-dnd';
import domtoimage from 'dom-to-image';
import ReadFileDropContainer from 'dropperx';
// Ours
7 years ago
import Page from '../components/Page';
import Button from '../components/Button';
import Dropdown from '../components/Dropdown';
import ColorPicker from '../components/ColorPicker';
import Settings from '../components/Settings';
import Toolbar from '../components/Toolbar';
import Overlay from '../components/Overlay';
import Carbon from '../components/Carbon';
import api from '../lib/api';
import {
7 years ago
THEMES_ARRAY,
THEMES,
LANGUAGES,
DEFAULT_LANGUAGE,
COLORS,
DEFAULT_CODE
7 years ago
} from '../lib/constants';
class Editor extends React.Component {
/* pathname, asPath, err, req, res */
7 years ago
static async getInitialProps({ asPath }) {
try {
// TODO fix this hack
if (asPath.length > 30) {
7 years ago
const content = await api.getGist(asPath);
return { content };
}
} catch (e) {
7 years ago
console.log(e);
}
7 years ago
return {};
}
7 years ago
constructor(props) {
super(props);
this.state = {
7 years ago
background: '#ABB8C3',
7 years ago
theme: THEMES.seti.id,
language: DEFAULT_LANGUAGE,
7 years ago
dropShadow: true,
windowControls: true,
paddingVertical: '48px',
paddingHorizontal: '32px',
7 years ago
uploading: false,
code: props.content || DEFAULT_CODE
7 years ago
};
7 years ago
this.save = this.save.bind(this);
this.upload = this.upload.bind(this);
this.updateCode = this.updateCode.bind(this);
}
7 years ago
getCarbonImage() {
const node = document.getElementById('section');
const config = {
style: {
transform: 'scale(2)',
'transform-origin': 'center'
},
width: node.offsetWidth * 2,
height: node.offsetHeight * 2
7 years ago
};
7 years ago
return domtoimage.toPng(node, config);
}
7 years ago
updateCode(code) {
this.setState({ code });
7 years ago
}
7 years ago
save() {
this.getCarbonImage().then(dataUrl => {
const link = document.createElement('a');
link.download = 'carbon.png';
link.href = dataUrl;
document.body.appendChild(link);
link.click();
link.remove();
});
}
7 years ago
upload() {
this.setState({ uploading: true });
this.getCarbonImage()
7 years ago
.then(api.tweet)
.then(() => this.setState({ uploading: false }))
.catch(err => {
console.error(err);
this.setState({ uploading: false });
});
}
7 years ago
render() {
return (
7 years ago
<Page enableHeroText>
<div id="editor">
<Toolbar>
<Dropdown
selected={THEMES[this.state.theme]}
list={THEMES_ARRAY}
onChange={theme => this.setState({ theme: theme.id })}
/>
<Dropdown
list={LANGUAGES}
onChange={language => this.setState({ language: language.module })}
/>
<ColorPicker
onChange={color => this.setState({ background: color })}
bg={this.state.background}
/>
<Settings
onChange={(key, value) => this.setState({ [key]: value })}
enabled={this.state}
/>
<div className="buttons">
<Button
className="tweetButton"
onClick={this.upload}
title={this.state.uploading ? 'Loading...' : 'Tweet Image'}
color="#57b5f9"
style={{ marginRight: '8px' }}
/>
7 years ago
<Button onClick={this.save} title="Save Image" color="#c198fb" />
</div>
</Toolbar>
7 years ago
<ReadFileDropContainer onDrop={([file]) => this.setState({ code: file.content })}>
{({ isOver, canDrop }) => (
<Overlay
isOver={isOver || canDrop}
title={`Drop your file here to import ${isOver ? '✋' : '✊'}`}
>
<Carbon config={this.state} updateCode={this.updateCode}>
{this.state.code}
</Carbon>
</Overlay>
)}
</ReadFileDropContainer>
</div>
<style jsx>
{`
#editor {
background: ${COLORS.BLACK};
border: 3px solid ${COLORS.SECONDARY};
border-radius: 8px;
padding: 16px;
}
.buttons {
display: flex;
margin-left: auto;
}
`}
7 years ago
</style>
</Page>
);
}
}
7 years ago
export default DragDropContext(HTML5Backend)(Editor);