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 (
)
}
)
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 }) => (
))
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 && (
create +
)}
{show ? : }
{show ? (
{presets.filter(p => p.custom).map(preset => (
))}
{customPresetsLength > 0 ?
: null}
{presets.filter(p => !p.custom).map(preset => (
))}
) : null}
{show && applied ? (
Preset applied!
undo ↩
) : 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 (
)
}
}
export default enhanceWithClickOutside(Settings)