import React from 'react'; import PropTypes from 'proptypes'; import _ from 'lodash'; import { Tabs, Tab } from 'material-ui/Tabs'; import MenuItem from 'material-ui/MenuItem'; import injectSheet from 'react-jss'; import { SelectField, TextField, NumberField, Checkbox } from './FormComponents.js'; import { grey800, red500 } from 'material-ui/styles/colors'; import Divider from 'material-ui/Divider'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import { LOCAL_STORAGE_KEY } from '../constants.js'; import shortid from 'shortid'; import defaultSettings from '../settings/default.yml'; import printerSettings from '../settings/printer.yml'; import materialSettings from '../settings/material.yml'; import qualitySettings from '../settings/quality.yml'; import update from 'react-addons-update'; import SettingsIcon from 'material-ui-icons/Settings'; const styles = { textFieldRow: { display: 'flex', alignItems: 'center' }, container: { width: '100%', flexGrow: 1, overflowY: 'auto', '& p, h3': { fontWeight: 'bold', margin: '30px 0 0 0' } }, error: { color: red500 } }; const getLocalStorage = () => { let localStorage = window.localStorage.getItem(LOCAL_STORAGE_KEY); if (!localStorage) { localStorage = { printers: {}, active: null }; updateLocalStorage(localStorage); } else { localStorage = JSON.parse(localStorage); } return localStorage; }; const updateLocalStorage = (localStorage) => { window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(localStorage)); }; class Settings extends React.Component { static propTypes = { classes: PropTypes.objectOf(PropTypes.string), onChange: PropTypes.func, disabled: PropTypes.bool.isRequired }; static defaultProps: { disabled: false }; static childContextTypes = { settings: PropTypes.object.isRequired, onChange: PropTypes.func.isRequired, disabled: PropTypes.bool.isRequired, addPrinter: PropTypes.object.isRequired, managePrinter: PropTypes.object.isRequired, activePrinter: PropTypes.string, advancedFields: PropTypes.array.isRequired }; state = { localStorage: getLocalStorage(), addPrinter: { open: false, name: '', printer: '', error: null }, managePrinter: { open: false } }; componentDidMount() { const { onChange } = this.props; const { localStorage } = this.state; if (localStorage.active) { if (onChange) onChange(this.constructSettings(localStorage)); } else { this.openAddPrinterDialog(); } } changeSettings = (fieldName, value) => { const { onChange } = this.props; const { localStorage } = this.state; let state = _.cloneDeep(this.state); const removeAddPrinterError = () => { state = update(state, { addPrinter: { error: { $set: null } } }); }; switch (fieldName) { case 'managePrinter.printer': case 'managePrinter.name': state = _.set(state, fieldName, value); break; case 'addPrinter.printer': state = update(state, { addPrinter: { printer: { $set: value } } }); state = update(state, { addPrinter: { name: { $set: printerSettings[value].title } } }); removeAddPrinterError(); break; case 'addPrinter.name': state = update(state, { addPrinter: { name: { $set: value } } }); removeAddPrinterError(); break; case 'activePrinter': if (value !== 'add_printer') state = update(state, { localStorage: { active: { $set: value } } }); break; case 'settings.quality': case 'settings.material': if (!localStorage.active) return this.openAddPrinterDialog(); state = _.set(state, `localStorage.printers[${localStorage.active}].${fieldName}`, value); break; case 'settings.layerHeight': case 'settings.dimensions.x': case 'settings.dimensions.y': case 'settings.dimensions.z': case 'settings.nozzleDiameter': case 'settings.bedTemperature': case 'settings.heatedBed': case 'settings.filamentThickness': case 'settings.temperature': case 'settings.thickness.top': case 'settings.thickness.bottom': case 'settings.thickness.shell': case 'settings.retraction.enabled': case 'settings.retraction.amount': case 'settings.retraction.speed': case 'settings.retraction.minDistance': case 'settings.travel.speed': case 'settings.combing': case 'settings.innerShell.speed': case 'settings.innerShell.flowRate': case 'settings.outerShell.speed': case 'settings.outerShell.flowRate': case 'settings.innerInfill.precentage': case 'settings.innerInfill.speed': case 'settings.innerInfill.flowRate': case 'settings.outerInfill.speed': case 'settings.outerInfill.flowRate': case 'settings.brim.size': case 'settings.brim.speed': case 'settings.brim.flowRate': case 'settings.firstLayer.speed': case 'settings.firstLayer.flowRate': if (!localStorage.active) return this.openAddPrinterDialog(); if (value === null) { const advanced = { ...state.localStorage.printers[localStorage.active].settings.advanced }; delete advanced[fieldName]; state = update(state, { localStorage: { printers: { [localStorage.active]: { settings: { advanced: { $set: advanced } } } } } }); } else { state = _.set(state, `localStorage.printers[${localStorage.active}].settings.advanced[${JSON.stringify(fieldName)}]`, value); } break; default: break; } this.setState(state); if (localStorage.active) { if (onChange) onChange(this.constructSettings(state.localStorage)); updateLocalStorage(state.localStorage); } } getChildContext() { const { localStorage, addPrinter, managePrinter } = this.state; return { addPrinter, managePrinter, activePrinter: localStorage.active, advancedFields: localStorage.active ? Object.keys(localStorage.printers[localStorage.active].settings.advanced) : [], settings: this.constructSettings(localStorage), onChange: this.changeSettings, disabled: this.props.disabled }; } constructSettings(localStorage) { if (!localStorage.active) return defaultSettings; const { printer, material, quality, advanced } = localStorage.printers[localStorage.active].settings; let settings = { ...defaultSettings, printer, material, quality }; settings = _.merge({}, settings, printerSettings[printer]); settings = _.merge({}, settings, qualitySettings[quality]); settings = _.merge({}, settings, materialSettings[material]); for (const key in advanced) { const value = advanced[key]; settings = _.set(_.cloneDeep(settings), key.replace('settings.', ''), value); } return settings; } addPrinter = () => { const { name, printer } = this.state.addPrinter; if (!name || !printer) { this.setState({ addPrinter: { ...this.state.addPrinter, error: 'Please enter a name and printer' } }); return; } const id = shortid.generate(); const localStorage = { active: id, printers: { ...this.state.localStorage.printers, [id]: { name, settings: { printer, material: 'pla', quality: 'medium', advanced: {} } } } }; this.setState({ localStorage }); updateLocalStorage(localStorage); this.closeAddPrinterDialog(); const { onChange } = this.props; if (onChange) onChange(this.constructSettings(localStorage)); }; editPrinter = () => { const { localStorage: { active, printers }, managePrinter: { printer, name } } = this.state; const localStorage = update(this.state.localStorage, { printers: { [active]: { name: { $set: name }, settings: { printer: { $set: printer } } } } }); this.closeManagePrinterDialog(); this.setState({ localStorage }); updateLocalStorage(localStorage); const { onChange } = this.props; if (onChange) onChange(this.constructSettings(localStorage)); }; removeActivePrinter = () => { let { localStorage: { active, printers } } = this.state; if (!active) return; printers = { ...printers }; delete printers[active]; active = Object.keys(printers)[0] || null; const localStorage = { active, printers }; this.closeManagePrinterDialog(); this.setState({ localStorage }); updateLocalStorage(localStorage); const { onChange } = this.props; if (onChange) onChange(this.constructSettings(localStorage)); }; closeAddPrinterDialog = () => this.setAddPrinterDialog(false); openAddPrinterDialog = () => this.setAddPrinterDialog(true); setAddPrinterDialog = (open) => this.setState({ addPrinter: { name: '', printer: '', error: null, open } }); closeManagePrinterDialog = () => this.setManagePrinterDialog(false); openManagePrinterDialog = () => this.setManagePrinterDialog(true); setManagePrinterDialog = (open) => { const { localStorage: { active, printers } } = this.state; if (!active) return this.setState({ managePrinter: { open: false } }); this.setState({ managePrinter: { open, name: printers[active].name, printer: printers[active].settings.printer } }); } render() { const { addPrinter, managePrinter, localStorage } = this.state; const { classes, disabled } = this.props; return (
Layer
Thickness
Material
Bed
Brim
First layer
Inner shell
Outer shell
Inner infill
Outer infill
Travel
Retraction
Printer dimensions
Nozzle
{addPrinter.error}
} ,