|
|
@ -1,12 +1,10 @@
|
|
|
|
// Theirs
|
|
|
|
// Theirs
|
|
|
|
import url from 'url'
|
|
|
|
import url from 'url'
|
|
|
|
import React from 'react'
|
|
|
|
import React from 'react'
|
|
|
|
import HTML5Backend from 'react-dnd-html5-backend'
|
|
|
|
|
|
|
|
import { DragDropContext } from 'react-dnd'
|
|
|
|
|
|
|
|
import domtoimage from 'dom-to-image'
|
|
|
|
import domtoimage from 'dom-to-image'
|
|
|
|
import ReadFileDropContainer, { DATA_URL, TEXT } from 'dropperx'
|
|
|
|
|
|
|
|
import Spinner from 'react-spinner'
|
|
|
|
import Spinner from 'react-spinner'
|
|
|
|
import dynamic from 'next/dynamic'
|
|
|
|
import dynamic from 'next/dynamic'
|
|
|
|
|
|
|
|
import Dropzone from 'react-dropzone'
|
|
|
|
|
|
|
|
|
|
|
|
// Ours
|
|
|
|
// Ours
|
|
|
|
import Button from './Button'
|
|
|
|
import Button from './Button'
|
|
|
@ -245,15 +243,30 @@ class Editor extends React.Component {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
onDrop([file]) {
|
|
|
|
onDrop([file]) {
|
|
|
|
|
|
|
|
if (!file) return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const reader = new FileReader()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO abstract this into Dropperx
|
|
|
|
|
|
|
|
reader.onload = event => {
|
|
|
|
|
|
|
|
file.content = event.target.result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isImage(file)) {
|
|
|
|
|
|
|
|
this.updateState({
|
|
|
|
|
|
|
|
backgroundImage: file.content,
|
|
|
|
|
|
|
|
backgroundImageSelection: null,
|
|
|
|
|
|
|
|
backgroundMode: 'image',
|
|
|
|
|
|
|
|
preset: null
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
this.updateState({ code: file.content, language: 'auto' })
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isImage(file)) {
|
|
|
|
if (isImage(file)) {
|
|
|
|
this.updateState({
|
|
|
|
reader.readAsDataURL(file)
|
|
|
|
backgroundImage: file.content,
|
|
|
|
|
|
|
|
backgroundImageSelection: null,
|
|
|
|
|
|
|
|
backgroundMode: 'image',
|
|
|
|
|
|
|
|
preset: null
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
this.updateState({ code: file.content, language: 'auto' })
|
|
|
|
reader.readAsText(file, 'UTF-8')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -325,82 +338,86 @@ class Editor extends React.Component {
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<React.Fragment>
|
|
|
|
<React.Fragment>
|
|
|
|
<div className="editor">
|
|
|
|
<Dropzone accept="image/*, text/*, application/*" onDrop={this.onDrop}>
|
|
|
|
<Toolbar>
|
|
|
|
{({ getRootProps, isDragAccept }) => {
|
|
|
|
<Themes key={theme} updateTheme={this.updateTheme} theme={theme} />
|
|
|
|
const root = getRootProps()
|
|
|
|
<Dropdown
|
|
|
|
return (
|
|
|
|
icon={languageIcon}
|
|
|
|
<div className="editor" {...root}>
|
|
|
|
selected={
|
|
|
|
<Toolbar>
|
|
|
|
LANGUAGE_NAME_HASH[language] ||
|
|
|
|
<Themes key={theme} updateTheme={this.updateTheme} theme={theme} />
|
|
|
|
LANGUAGE_MIME_HASH[language] ||
|
|
|
|
<Dropdown
|
|
|
|
LANGUAGE_MODE_HASH[language] ||
|
|
|
|
icon={languageIcon}
|
|
|
|
LANGUAGE_MODE_HASH[DEFAULT_LANGUAGE]
|
|
|
|
selected={
|
|
|
|
}
|
|
|
|
LANGUAGE_NAME_HASH[language] ||
|
|
|
|
list={LANGUAGES}
|
|
|
|
LANGUAGE_MIME_HASH[language] ||
|
|
|
|
onChange={this.updateLanguage}
|
|
|
|
LANGUAGE_MODE_HASH[language] ||
|
|
|
|
/>
|
|
|
|
LANGUAGE_MODE_HASH[DEFAULT_LANGUAGE]
|
|
|
|
<BackgroundSelect
|
|
|
|
}
|
|
|
|
onChange={this.updateBackground}
|
|
|
|
list={LANGUAGES}
|
|
|
|
mode={backgroundMode}
|
|
|
|
onChange={this.updateLanguage}
|
|
|
|
color={backgroundColor}
|
|
|
|
/>
|
|
|
|
image={backgroundImage}
|
|
|
|
<BackgroundSelect
|
|
|
|
aspectRatio={aspectRatio}
|
|
|
|
onChange={this.updateBackground}
|
|
|
|
/>
|
|
|
|
mode={backgroundMode}
|
|
|
|
<Settings
|
|
|
|
color={backgroundColor}
|
|
|
|
{...config}
|
|
|
|
image={backgroundImage}
|
|
|
|
onChange={this.updateSetting}
|
|
|
|
aspectRatio={aspectRatio}
|
|
|
|
resetDefaultSettings={this.resetDefaultSettings}
|
|
|
|
/>
|
|
|
|
format={this.format}
|
|
|
|
<Settings
|
|
|
|
applyPreset={this.applyPreset}
|
|
|
|
{...config}
|
|
|
|
getCarbonImage={this.getCarbonImage}
|
|
|
|
onChange={this.updateSetting}
|
|
|
|
/>
|
|
|
|
resetDefaultSettings={this.resetDefaultSettings}
|
|
|
|
<div className="buttons">
|
|
|
|
format={this.format}
|
|
|
|
{this.props.api.tweet && online && (
|
|
|
|
applyPreset={this.applyPreset}
|
|
|
|
<Button
|
|
|
|
getCarbonImage={this.getCarbonImage}
|
|
|
|
border
|
|
|
|
/>
|
|
|
|
large
|
|
|
|
<div className="buttons">
|
|
|
|
padding="0 16px"
|
|
|
|
{this.props.api.tweet && online && (
|
|
|
|
margin="0 8px 0 0"
|
|
|
|
<Button
|
|
|
|
onClick={this.upload}
|
|
|
|
border
|
|
|
|
color="#57b5f9"
|
|
|
|
large
|
|
|
|
|
|
|
|
padding="0 16px"
|
|
|
|
|
|
|
|
margin="0 8px 0 0"
|
|
|
|
|
|
|
|
onClick={this.upload}
|
|
|
|
|
|
|
|
color="#57b5f9"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{uploading ? 'Loading...' : 'Tweet'}
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
<ExportMenu
|
|
|
|
|
|
|
|
onChange={this.updateSetting}
|
|
|
|
|
|
|
|
export={this.export}
|
|
|
|
|
|
|
|
exportSize={exportSize}
|
|
|
|
|
|
|
|
disablePNG={this.disablePNG}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</Toolbar>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<Overlay
|
|
|
|
|
|
|
|
isOver={isDragAccept}
|
|
|
|
|
|
|
|
title={`Drop your file here to import ${isDragAccept ? '✋' : '✊'}`}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{uploading ? 'Loading...' : 'Tweet'}
|
|
|
|
{/*key ensures Carbon's internal language state is updated when it's changed by Dropdown*/}
|
|
|
|
</Button>
|
|
|
|
<Carbon
|
|
|
|
)}
|
|
|
|
key={language}
|
|
|
|
<ExportMenu
|
|
|
|
config={this.state}
|
|
|
|
onChange={this.updateSetting}
|
|
|
|
updateCode={this.updateCode}
|
|
|
|
export={this.export}
|
|
|
|
onAspectRatioChange={this.updateAspectRatio}
|
|
|
|
exportSize={exportSize}
|
|
|
|
titleBar={titleBar}
|
|
|
|
disablePNG={this.disablePNG}
|
|
|
|
updateTitleBar={this.updateTitleBar}
|
|
|
|
/>
|
|
|
|
innerRef={this.innerRef}
|
|
|
|
</div>
|
|
|
|
>
|
|
|
|
</Toolbar>
|
|
|
|
{code != null ? code : DEFAULT_CODE}
|
|
|
|
|
|
|
|
</Carbon>
|
|
|
|
<ReadFileDropContainer readAs={readAs} onDrop={this.onDrop}>
|
|
|
|
</Overlay>
|
|
|
|
{({ isOver, canDrop }) => (
|
|
|
|
</div>
|
|
|
|
<Overlay
|
|
|
|
)
|
|
|
|
isOver={isOver || canDrop}
|
|
|
|
}}
|
|
|
|
title={`Drop your file here to import ${isOver ? '✋' : '✊'}`}
|
|
|
|
</Dropzone>
|
|
|
|
>
|
|
|
|
|
|
|
|
{/*key ensures Carbon's internal language state is updated when it's changed by Dropdown*/}
|
|
|
|
|
|
|
|
<Carbon
|
|
|
|
|
|
|
|
key={language}
|
|
|
|
|
|
|
|
config={this.state}
|
|
|
|
|
|
|
|
updateCode={this.updateCode}
|
|
|
|
|
|
|
|
onAspectRatioChange={this.updateAspectRatio}
|
|
|
|
|
|
|
|
titleBar={titleBar}
|
|
|
|
|
|
|
|
updateTitleBar={this.updateTitleBar}
|
|
|
|
|
|
|
|
innerRef={this.innerRef}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{code != null ? code : DEFAULT_CODE}
|
|
|
|
|
|
|
|
</Carbon>
|
|
|
|
|
|
|
|
</Overlay>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</ReadFileDropContainer>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<style jsx>
|
|
|
|
<style jsx>
|
|
|
|
{`
|
|
|
|
{`
|
|
|
|
.editor {
|
|
|
|
.editor {
|
|
|
|
|
|
|
|
outline: none;
|
|
|
|
background: ${COLORS.BLACK};
|
|
|
|
background: ${COLORS.BLACK};
|
|
|
|
border: 3px solid ${COLORS.SECONDARY};
|
|
|
|
border: 3px solid ${COLORS.SECONDARY};
|
|
|
|
border-radius: 8px;
|
|
|
|
border-radius: 8px;
|
|
|
@ -429,17 +446,10 @@ function isImage(file) {
|
|
|
|
return file.type.split('/')[0] === 'image'
|
|
|
|
return file.type.split('/')[0] === 'image'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function readAs(file) {
|
|
|
|
|
|
|
|
if (isImage(file)) {
|
|
|
|
|
|
|
|
return DATA_URL
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return TEXT
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Editor.defaultProps = {
|
|
|
|
Editor.defaultProps = {
|
|
|
|
api: {},
|
|
|
|
api: {},
|
|
|
|
onUpdate: () => {},
|
|
|
|
onUpdate: () => {},
|
|
|
|
onReset: () => {}
|
|
|
|
onReset: () => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default DragDropContext(HTML5Backend)(Editor)
|
|
|
|
export default Editor
|
|
|
|