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)