import React from 'react'
import dynamic from 'next/dynamic'
import Dropdown from '../Dropdown'
import { managePopout } from '../Popout'
import ThemeIcon from '../svg/Theme'
import RemoveIcon from '../svg/Remove'
import { THEMES, COLORS, DEFAULT_THEME } from '../../lib/constants'
import { getThemes, saveThemes, stringifyRGBA, generateId } from '../../lib/util'
const ThemeCreate = dynamic(() => import('./ThemeCreate'), {
loading: () => null
})
const ThemeItem = ({ children, item, isSelected, onClick }) => (
{children}
{item.custom && !isSelected && (
)}
)
const themeIcon =
const getCustomName = themes =>
`Custom Theme ${themes.filter(({ name }) => name.startsWith('Custom Theme')).length + 1}`
class Themes extends React.PureComponent {
selectedTheme = DEFAULT_THEME
state = {
themes: THEMES,
preset: this.props.theme,
input: 'Custom Theme',
selected: null
}
dropdown = React.createRef()
componentDidMount() {
const { update, theme, highlights } = this.props
const storedThemes = getThemes(localStorage) || []
this.setState(({ themes }) => {
const newThemes = [...storedThemes, ...themes]
this.selectedTheme = newThemes.find(({ id }) => id === theme) || DEFAULT_THEME
if (Object.keys(highlights).length === 0) {
update({ highlights: this.selectedTheme.highlights })
}
return {
themes: newThemes,
input: getCustomName(newThemes)
}
})
}
componentDidUpdate(prevProps) {
const { isVisible, theme, update } = this.props
const { themes } = this.state
if (prevProps.isVisible && !isVisible) {
this.setState({ input: getCustomName(themes) })
update({ highlights: themes.find(({ id }) => id === theme).highlights })
}
}
applyPreset = preset => {
this.setState(({ themes }) => {
this.props.update({ highlights: themes.find(({ id }) => id === preset).highlights })
return {
preset
}
})
}
handleChange = ({ id }) => {
const { toggleVisibility, update } = this.props
const { themes } = this.state
if (id === 'create') {
toggleVisibility()
this.dropdown.current.closeMenu()
} else {
update({ theme: id, highlights: themes.find(theme => theme.id === id).highlights })
}
}
updateInput = ({ target: { value: input } }) => this.setState({ input })
selectHighlight = highlight => () =>
this.setState(({ selected }) => ({
selected: selected === highlight ? null : highlight
}))
updateHighlight = ({ rgb }) =>
this.props.update({
highlights: {
...this.props.highlights,
[this.state.selected]: stringifyRGBA(rgb)
}
})
removeTheme = id => event => {
const { themes } = this.state
const { theme, update } = this.props
event.stopPropagation()
const newThemes = themes.filter(t => t.id !== id)
saveThemes(localStorage, newThemes.filter(({ custom }) => custom))
if (theme === id) {
update({ theme: DEFAULT_THEME.id, highlights: DEFAULT_THEME.highlights })
} else {
this.setState({ themes: newThemes })
}
}
createTheme = () => {
const { highlights, update } = this.props
const { themes, input: name } = this.state
const id = `theme:${generateId()}`
const newTheme = {
id,
name,
highlights,
custom: true
}
const customThemes = [newTheme, ...themes.filter(({ custom }) => custom)]
saveThemes(localStorage, customThemes)
update({ theme: id })
}
itemWrapper = props =>
render() {
const { theme, isVisible, toggleVisibility, highlights } = this.props
const { input, themes, selected, preset } = this.state
const dropdownValue = isVisible ? { name: input } : { id: theme, name: this.selectedTheme.name }
const dropdownList = [
{
id: 'create',
name: 'Create +'
},
...themes
]
return (
{isVisible && (
)}
)
}
}
export default managePopout(Themes)