import React from 'react' import omitBy from 'lodash.omitby' import ThemeSelect from './ThemeSelect' import FontSelect from './FontSelect' import Slider from './Slider' import Input from './Input' 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, generateId, fileToJSON } 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, firstLineNumber, widthAdjustment, watermark, onWidthChanging, onWidthChanged }) => { return (
{dropShadow && (
)} {lineNumbers && (
onChange('firstLineNumber', Number(e.target.value))} width="50%" />
)}
) } ) const TypeSettings = React.memo( ({ onChange, onUpload, font, size, lineHeight, onWidthChanging, onWidthChanged }) => { return (
) } ) const resetButtonStyle = { borderTop: `1px solid ${COLORS.SECONDARY}` } const MiscSettings = React.memo(({ format, reset, applyPreset, settings }) => { const input = React.useRef(null) let download try { download = `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(settings))}` } catch (error) { // pass } return (
{ const json = await fileToJSON(e.target.files[0]) if (json) { applyPreset(json) } }} />
) }) 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 }) } handleFontUpload = (id, url) => { this.props.onChange('fontFamily', id) this.props.onChange('fontUrl', url) this.props.toggleVisibility() } 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:${generateId()}` 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(this.state.presets.filter(p => p.custom)) renderContent = () => { switch (this.state.selectedMenu) { case 'Window': return ( ) case 'Type': return ( ) case 'Misc': { const settings = this.getSettingsFromProps() return ( ) } default: return null } } render() { const { selectedMenu, showPresets, presets, previousSettings, widthChanging } = this.state const { preset, isVisible, toggleVisibility } = this.props return (
) } } export default managePopout(Settings)