import React from 'react'
import omitBy from 'lodash.omitby'
import { useKeyboardListener } from 'actionsack'
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 MenuButton from './MenuButton'
import { COLORS, DEFAULT_PRESETS } from '../lib/constants'
import { toggle, getPresets, savePresets, generateId, fileToJSON } from '../lib/util'
import SettingsIcon from './svg/Settings'
function KeyboardShortcut({ trigger, handle }) {
useKeyboardListener(trigger, handle)
return null
}
function WindowSettings({
onChange,
windowTheme,
paddingHorizontal,
paddingVertical,
dropShadow,
dropShadowBlurRadius,
dropShadowOffsetY,
windowControls,
lineNumbers,
firstLineNumber,
hiddenCharacters,
widthAdjustment,
watermark,
onWidthChanging,
onWidthChanged
}) {
return (
{dropShadow && (
)}
{lineNumbers && (
onChange('firstLineNumber', Number(e.target.value))}
width="50%"
/>
)}
)
}
function TypeSettings({
onChange,
onUpload,
font,
size,
lineHeight,
onWidthChanging,
onWidthChanged
}) {
return (
)
}
const resetButtonStyle = { borderTop: `1px solid ${COLORS.SECONDARY}` }
function MiscSettings({ 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 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()
menuRef = 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)
this.setState({ previousSettings })
}
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 (
{
toggleVisibility()
if (!isVisible) {
this.menuRef.current.focus()
}
}}
/>
)
}
}
export default managePopout(Settings)