import React from 'react' import omitBy from 'lodash.omitby' import ThemeSelect from './ThemeSelect' import FontSelect from './FontSelect' import Slider from './Slider' import Toggle from './Toggle' import Popout, { managePopout } from './Popout' import Button from './Button' import Presets from './Presets' import { COLORS, DEFAULT_PRESETS } from '../lib/constants' import { toggle, getPresets, savePresets } from '../lib/util' import SettingsIcon from './svg/Settings' import * as Arrows from './svg/Arrows' 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 resetButtonStyle = { borderTop: `1px solid ${COLORS.SECONDARY}` } const MiscSettings = React.memo(({ format, reset }) => { return (
) }) const MenuButton = React.memo(({ name, select, selected }) => { return (
) }) const settingButtonStyle = { width: '40px', height: '100%' } class Settings extends React.PureComponent { state = { presets: DEFAULT_PRESETS, selectedMenu: 'Window', showPresets: true, previousSettings: null, widthChanging: false } settingsRef = React.createRef() presetContentRef = React.createRef() componentDidMount() { const storedPresets = getPresets(localStorage) || [] this.setState(({ presets }) => ({ presets: [...storedPresets, ...presets] })) } togglePresets = () => this.setState(toggle('showPresets')) selectMenu = selectedMenu => () => this.setState({ selectedMenu }) handleWidthChanging = () => { const rect = this.settingsRef.current.getBoundingClientRect() this.settingPosition = { top: rect.bottom, 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 { selectedMenu, showPresets, presets, previousSettings, widthChanging } = this.state const { preset, isVisible, toggleVisibility } = this.props return (
) } } export default managePopout(Settings)