import React from 'react' import enhanceWithClickOutside from 'react-click-outside' import omitBy from 'lodash.omitby' import ThemeSelect from './ThemeSelect' import FontSelect from './FontSelect' import Slider from './Slider' import Toggle from './Toggle' import WindowPointer from './WindowPointer' import { COLORS, DEFAULT_PRESETS } from '../lib/constants' import { getPresets, savePresets } from '../lib/util' import { toggle } from '../lib/util' import SettingsIcon from './svg/Settings' import * as Arrows from './svg/Arrows' import Remove from './svg/Remove' const WindowSettings = React.memo( ({ onChange, windowTheme, paddingHorizontal, paddingVertical, dropShadow, dropShadowBlurRadius, dropShadowOffsetY, windowControls, lineNumbers, widthAdjustment, watermark, onWidthChanging, onWidthChanged }) => { return (
{dropShadow && (
)}
) } ) const TypeSettings = React.memo( ({ onChange, font, size, lineHeight, onWidthChanging, onWidthChanged }) => { return (
) } ) const MiscSettings = React.memo(({ format, reset }) => { return (
) }) const MenuButton = React.memo(({ name, select, selected }) => { return ( ) }) const Preset = React.memo(({ remove, apply, selected, preset }) => (
) : null}
)) const Presets = React.memo( ({ show, create, toggle, undo, presets, selected, remove, apply, applied, contentRef }) => { const customPresetsLength = presets.length - DEFAULT_PRESETS.length const disabledCreate = selected != null return (
Presets {show && ( )}
{show ? (
{presets.filter(p => p.custom).map(preset => ( ))} {customPresetsLength > 0 ?
: null} {presets.filter(p => !p.custom).map(preset => ( ))}
) : null} {show && applied ? (
Preset applied!
) : null}
) } ) class Settings extends React.PureComponent { state = { presets: DEFAULT_PRESETS, isVisible: false, selectedMenu: 'Window', showPresets: false, previousSettings: null, widthChanging: false } settingsRef = React.createRef() presetContentRef = React.createRef() componentDidMount() { const storedPresets = getPresets(localStorage) || [] this.setState(({ presets }) => ({ presets: [...storedPresets, ...presets] })) } toggleVisible = () => this.setState(toggle('isVisible')) togglePresets = () => this.setState(toggle('showPresets')) handleClickOutside = () => this.setState({ isVisible: false }) selectMenu = selectedMenu => () => this.setState({ selectedMenu }) handleWidthChanging = () => { const rect = this.settingsRef.current.getBoundingClientRect() this.settingPosition = { top: rect.bottom + 12, left: rect.left } this.setState({ widthChanging: true }) } handleWidthChanged = () => this.setState({ widthChanging: false }) handleChange = (key, value) => { this.props.onChange(key, value) this.setState({ previousSettings: null }) } handleReset = () => { this.props.resetDefaultSettings() this.setState({ previousSettings: null }) } getSettingsFromProps = () => omitBy(this.props, (v, k) => typeof v === 'function' || k === 'preset') applyPreset = preset => { const previousSettings = this.getSettingsFromProps() this.props.applyPreset(preset) // TODO: this is a hack to prevent the scrollLeft position from changing when preset is applied const { scrollLeft: previousScrollLeft } = this.presetContentRef.current this.setState({ previousSettings }, () => { this.presetContentRef.current.scrollLeft = previousScrollLeft }) } undoPreset = () => { this.props.applyPreset({ ...this.state.previousSettings, id: null }) this.setState({ previousSettings: null }) } removePreset = id => { if (this.props.preset === id) { this.props.onChange('preset', null) this.setState({ previousSettings: null }) } this.setState( ({ presets }) => ({ presets: presets.filter(p => p.id !== id) }), this.savePresets ) } createPreset = async () => { const newPreset = this.getSettingsFromProps() newPreset.id = `preset:${Math.random() .toString(36) .slice(2)}` newPreset.custom = true newPreset.icon = await this.props.getCarbonImage({ format: 'png', squared: true, exportSize: 1 }) this.props.onChange('preset', newPreset.id) this.setState( ({ presets }) => ({ previousSettings: null, presets: [newPreset, ...presets] }), this.savePresets ) } savePresets = () => savePresets(localStorage, this.state.presets.filter(p => p.custom)) renderContent = () => { switch (this.state.selectedMenu) { case 'Window': return ( ) case 'Type': return ( ) case 'Misc': return default: return null } } render() { const { isVisible, selectedMenu, showPresets, presets, previousSettings, widthChanging } = this.state const { preset } = this.props return (
{this.renderContent()}
) } } export default enhanceWithClickOutside(Settings)