simplify theme state logic

main
Mike Fix 6 years ago committed by Michael Fix
parent 132c0f6d5a
commit 0db4a89e72

@ -76,7 +76,7 @@ class Carbon extends React.PureComponent {
const options = {
lineNumbers: config.lineNumbers,
mode: languageMode || 'plaintext',
theme: config.theme.id,
theme: config.theme,
scrollBarStyle: null,
viewportMargin: Infinity,
lineWrapping: true,

@ -46,7 +46,6 @@ class Editor extends React.Component {
super(props)
this.state = {
...DEFAULT_SETTINGS,
themes: THEMES,
preset: DEFAULT_PRESET_ID,
loading: true
}
@ -83,27 +82,12 @@ class Editor extends React.Component {
loading: false
}
const storedThemes = getThemes(localStorage) || []
newState.themes = [...storedThemes, ...this.state.themes]
if (newState.theme) {
newState.theme = newState.themes.find(t => t.id === newState.theme) || DEFAULT_THEME
}
if (newState.highlights) {
newState.theme = {
...newState.theme,
highlights: newState.highlights
}
}
// Makes sure the slash in 'application/X' is decoded
if (newState.language) {
newState.language = unescapeHtml(newState.language)
}
this.updateState(omit(newState, ['highlights']))
this.updateState(newState)
this.isSafari =
window.navigator &&
@ -116,10 +100,7 @@ class Editor extends React.Component {
updateState = updates => {
this.setState(updates, () => {
if (!this.gist) {
this.props.onUpdate({
...this.state,
theme: this.state.theme.id
})
this.props.onUpdate(this.state)
}
})
}
@ -137,14 +118,7 @@ class Editor extends React.Component {
// if safari, get image from api
const isPNG = format !== 'svg'
if (this.context.image && this.isSafari && isPNG) {
const state = {
...this.state,
theme: this.state.theme.id,
highlights: this.state.theme.highlights
}
const encodedState = serializeState(omit(state, ['themes']))
const encodedState = serializeState(this.state)
return this.context.image(encodedState)
}
@ -289,32 +263,17 @@ class Editor extends React.Component {
updateTheme = theme => this.updateState({ theme })
createTheme = theme =>
this.setState(({ themes }) => {
const newThemes = [theme, ...themes]
saveThemes(localStorage, newThemes.filter(({ custom }) => custom))
return {
theme,
themes: newThemes
}
})
removeTheme = id =>
this.setState(({ themes, theme }) => {
const newState = {
themes: themes.filter(t => t.id !== id)
}
saveThemes(localStorage, newState.themes.filter(({ custom }) => custom))
if (theme.id === id) {
newState.theme = DEFAULT_THEME
}
createTheme = theme => {
this.props.updateThemes(themes => [theme, ...themes])
this.updateTheme(theme.id)
}
return newState
})
removeTheme = id => {
this.props.updateThemes(themes => themes.filter(t => t.id !== id))
if (this.state.theme.id === id) {
this.updateTheme(DEFAULT_THEME.id)
}
}
format = () =>
formatCode(this.state.code)
@ -326,7 +285,6 @@ class Editor extends React.Component {
render() {
const {
theme,
themes,
language,
backgroundColor,
backgroundImage,
@ -345,7 +303,8 @@ class Editor extends React.Component {
remove={this.removeTheme}
create={this.createTheme}
theme={theme}
themes={themes}
themes={this.props.themes}
router={this.props.router}
/>
<Dropdown
icon={languageIcon}
@ -432,4 +391,21 @@ Editor.defaultProps = {
onReset: () => {}
}
export default Editor
function ThemesContainer(props) {
const [themes, updateThemes] = React.useState(THEMES)
React.useEffect(() => {
const storedThemes = getThemes(localStorage) || []
if (storedThemes) {
updateThemes(currentThemes => [...storedThemes, ...currentThemes])
}
}, [])
React.useEffect(() => {
saveThemes(localStorage, themes.filter(({ custom }) => custom))
}, [themes])
return <Editor {...props} themes={themes} updateThemes={updateThemes} />
}
export default ThemesContainer

@ -53,6 +53,8 @@ const getCustomName = themes =>
const ThemeCreate = ({ theme, themes, highlights, create, updateHighlights }) => {
const [preset, updatePreset] = React.useState(theme.id)
const [highlight, selectHighlight] = React.useState()
// TODO consider using an uncontrolled input
const [name, updateName] = React.useState(getCustomName(themes))
return (

@ -5,7 +5,8 @@ import Dropdown from '../Dropdown'
import { managePopout } from '../Popout'
import ThemeIcon from '../svg/Theme'
import RemoveIcon from '../svg/Remove'
import { COLORS } from '../../lib/constants'
import { COLORS, DEFAULT_THEME } from '../../lib/constants'
import { getRouteState } from '../../lib/routing'
const ThemeCreate = dynamic(() => import('./ThemeCreate'), {
loading: () => null
@ -52,12 +53,24 @@ class Themes extends React.PureComponent {
highlights: {}
}
componentDidMount() {
// TODO consider just using withRouter directly
const { queryState } = getRouteState(this.props.router)
if (queryState.highlights) {
this.updateHighlights(queryState.highlights)
}
}
dropdown = React.createRef()
static getDerivedStateFromProps(props) {
if (!props.isVisible) {
// TODO use shared function for this next line
const themeConfig =
(props.themes && props.themes.find(t => t.id === props.theme)) || DEFAULT_THEME
return {
highlights: {}
highlights: themeConfig.highlights
}
}
return null
@ -69,7 +82,7 @@ class Themes extends React.PureComponent {
toggleVisibility()
this.dropdown.current.closeMenu()
} else {
update(theme)
update(theme.id)
}
}
@ -90,10 +103,11 @@ class Themes extends React.PureComponent {
render() {
const { themes, theme, isVisible, toggleVisibility } = this.props
const { highlights } = this.state
const highlights = { ...theme.highlights, ...this.state.highlights }
const themeConfig = themes.find(t => t.id === theme) || DEFAULT_THEME
const dropdownValue = isVisible ? { name: '' } : { id: theme.id, name: theme.name }
const dropdownValue = isVisible ? { name: '' } : { id: themeConfig.id, name: themeConfig.name }
const dropdownList = [
{
@ -118,7 +132,7 @@ class Themes extends React.PureComponent {
/>
{isVisible && (
<ThemeCreate
theme={theme}
theme={themeConfig}
themes={themes}
highlights={highlights}
create={this.create}

@ -26,7 +26,7 @@ class Index extends React.Component {
updateRouteState(this.props.router, state)
saveSettings(
localStorage,
omit(state, ['code', 'backgroundImage', 'backgroundImageSelection', 'themes'])
omit(state, ['code', 'backgroundImage', 'backgroundImageSelection', 'themes', 'highlights'])
)
},
750,

Loading…
Cancel
Save