Refactor index.js (#310)

* Move Editor to components

* Separate index and editor a little

* Revert dynamic import of hljs b/c it's critical

* Move query param update to index.js

* Clean up editor further
main
Michael Fix 7 years ago committed by GitHub
parent d6a31941d5
commit 5691236934
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,4 +1,5 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import * as hljs from 'highlight.js'
import Spinner from 'react-spinner' import Spinner from 'react-spinner'
import ResizeObserver from 'resize-observer-polyfill' import ResizeObserver from 'resize-observer-polyfill'
import debounce from 'lodash.debounce' import debounce from 'lodash.debounce'
@ -50,20 +51,13 @@ class Carbon extends PureComponent {
this.props.updateTitleBar(newTitle) this.props.updateTitleBar(newTitle)
} }
async getHighlightLang(code = '') {
if (!this.hljs) {
this.hljs = await import('highlight.js')
}
return this.hljs.highlightAuto(code).language
}
handleLanguageChange = debounce( handleLanguageChange = debounce(
async (newCode, config) => { (newCode, config) => {
const props = (config && config.customProps) || this.props const props = (config && config.customProps) || this.props
if (props.config.language === 'auto') { if (props.config.language === 'auto') {
// try to set the language // try to set the language
const detectedLanguage = await this.getHighlightLang(newCode) const detectedLanguage = hljs.highlightAuto(newCode).language
const languageMode = const languageMode =
LANGUAGE_MODE_HASH[detectedLanguage] || LANGUAGE_NAME_HASH[detectedLanguage] LANGUAGE_MODE_HASH[detectedLanguage] || LANGUAGE_NAME_HASH[detectedLanguage]

@ -6,14 +6,13 @@ import domtoimage from 'dom-to-image'
import ReadFileDropContainer, { DATA_URL, TEXT } from 'dropperx' import ReadFileDropContainer, { DATA_URL, TEXT } from 'dropperx'
// Ours // Ours
import Page from '../components/Page' import Button from './Button'
import Button from '../components/Button' import Dropdown from './Dropdown'
import Dropdown from '../components/Dropdown' import BackgroundSelect from './BackgroundSelect'
import BackgroundSelect from '../components/BackgroundSelect' import Settings from './Settings'
import Settings from '../components/Settings' import Toolbar from './Toolbar'
import Toolbar from '../components/Toolbar' import Overlay from './Overlay'
import Overlay from '../components/Overlay' import Carbon from './Carbon'
import Carbon from '../components/Carbon'
import api from '../lib/api' import api from '../lib/api'
import { import {
THEMES, THEMES,
@ -29,8 +28,8 @@ import {
DEFAULT_CODE, DEFAULT_CODE,
DEFAULT_SETTINGS DEFAULT_SETTINGS
} from '../lib/constants' } from '../lib/constants'
import { getQueryStringState, updateQueryString, serializeState } from '../lib/routing' import { serializeState } from '../lib/routing'
import { getState, saveState } from '../lib/util' import { getState } from '../lib/util'
const saveButtonOptions = { const saveButtonOptions = {
button: true, button: true,
@ -40,30 +39,13 @@ const saveButtonOptions = {
} }
class Editor extends React.Component { class Editor extends React.Component {
static async getInitialProps({ asPath, query }) {
const path = removeQueryString(asPath.split('/').pop())
const queryParams = getQueryStringState(query)
const initialState = Object.keys(queryParams).length ? queryParams : null
try {
// TODO fix this hack
if (path.length >= 19 && path.indexOf('.') === -1) {
const content = await api.getGist(path)
return { content, initialState }
}
} catch (e) {
console.log(e)
}
return { initialState }
}
constructor(props) { constructor(props) {
super(props) super(props)
this.state = Object.assign( this.state = Object.assign(
{ {
...DEFAULT_SETTINGS, ...DEFAULT_SETTINGS,
uploading: false, uploading: false,
code: props.content, code: props.content
_initialState: this.props.initialState
}, },
this.props.initialState this.props.initialState
) )
@ -84,7 +66,7 @@ class Editor extends React.Component {
componentDidMount() { componentDidMount() {
// Load from localStorage instead of query params // Load from localStorage instead of query params
if (!this.state._initialState) { if (!this.props.initialState) {
const state = getState(localStorage) const state = getState(localStorage)
if (state) { if (state) {
this.setState(state) this.setState(state)
@ -93,12 +75,7 @@ class Editor extends React.Component {
} }
componentDidUpdate() { componentDidUpdate() {
updateQueryString(this.state) this.props.onUpdate(this.state)
const s = { ...this.state }
delete s.code
delete s.backgroundImage
delete s.backgroundImageSelection
saveState(localStorage, s)
} }
getCarbonImage({ format, type } = { format: 'png' }) { getCarbonImage({ format, type } = { format: 'png' }) {
@ -204,7 +181,7 @@ class Editor extends React.Component {
render() { render() {
return ( return (
<Page enableHeroText={true}> <React.Fragment>
<div id="editor"> <div id="editor">
<Toolbar> <Toolbar>
<Dropdown <Dropdown
@ -279,19 +256,11 @@ class Editor extends React.Component {
} }
`} `}
</style> </style>
</Page> </React.Fragment>
) )
} }
} }
function removeQueryString(str) {
const qI = str.indexOf('?')
return (qI >= 0 ? str.substr(0, qI) : str)
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\//g, '&#x2F;')
}
function isImage(file) { function isImage(file) {
return file.type.split('/')[0] === 'image' return file.type.split('/')[0] === 'image'
} }
@ -303,4 +272,8 @@ function readAs(file) {
return TEXT return TEXT
} }
Editor.defaultProps = {
onUpdate: () => {}
}
export default DragDropContext(HTML5Backend)(Editor) export default DragDropContext(HTML5Backend)(Editor)

@ -1,3 +1,54 @@
import Editor from './editor' // Theirs
import React from 'react'
export default Editor // Ours
import Editor from '../components/Editor'
import Page from '../components/Page'
import api from '../lib/api'
import { getQueryStringState, updateQueryString } from '../lib/routing'
import { saveState } from '../lib/util'
class Index extends React.Component {
static async getInitialProps({ asPath, query }) {
const path = removeQueryString(asPath.split('/').pop())
const queryParams = getQueryStringState(query)
const initialState = Object.keys(queryParams).length ? queryParams : null
try {
// TODO fix this hack
if (path.length >= 19 && path.indexOf('.') === -1) {
const content = await api.getGist(path)
return { content, initialState }
}
} catch (e) {
console.log(e)
}
return { initialState }
}
render() {
return (
<Page enableHeroText={true}>
<Editor {...this.props} onUpdate={onEditorUpdate} />
</Page>
)
}
}
function onEditorUpdate(state) {
updateQueryString(state)
const s = { ...state }
delete s.code
delete s.backgroundImage
delete s.backgroundImageSelection
saveState(localStorage, s)
}
function removeQueryString(str) {
const qI = str.indexOf('?')
return (qI >= 0 ? str.substr(0, qI) : str)
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\//g, '&#x2F;')
}
export default Index

Loading…
Cancel
Save