/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* eslint-env browser */ "use strict"; const { DOM: dom, createClass, PropTypes, addons } = require("devtools/client/shared/vendor/react"); const { getStr } = require("../utils/l10n"); const Types = require("../types"); module.exports = createClass({ displayName: "DeviceModal", propTypes: { devices: PropTypes.shape(Types.devices).isRequired, onDeviceListUpdate: PropTypes.func.isRequired, onUpdateDeviceDisplayed: PropTypes.func.isRequired, onUpdateDeviceModalOpen: PropTypes.func.isRequired, }, mixins: [ addons.PureRenderMixin ], getInitialState() { return {}; }, componentDidMount() { window.addEventListener("keydown", this.onKeyDown, true); }, componentWillReceiveProps(nextProps) { let { devices, } = nextProps; for (let type of devices.types) { for (let device of devices[type]) { this.setState({ [device.name]: device.displayed, }); } } }, componentWillUnmount() { window.removeEventListener("keydown", this.onKeyDown, true); }, onDeviceCheckboxClick({ target }) { this.setState({ [target.value]: !this.state[target.value] }); }, onDeviceModalSubmit() { let { devices, onDeviceListUpdate, onUpdateDeviceDisplayed, onUpdateDeviceModalOpen, } = this.props; let preferredDevices = { "added": new Set(), "removed": new Set(), }; for (let type of devices.types) { for (let device of devices[type]) { let newState = this.state[device.name]; if (device.featured && !newState) { preferredDevices.removed.add(device.name); } else if (!device.featured && newState) { preferredDevices.added.add(device.name); } if (this.state[device.name] != device.displayed) { onUpdateDeviceDisplayed(device, type, this.state[device.name]); } } } onDeviceListUpdate(preferredDevices); onUpdateDeviceModalOpen(false); }, onKeyDown(event) { if (!this.props.devices.isModalOpen) { return; } // Escape keycode if (event.keyCode === 27) { let { onUpdateDeviceModalOpen } = this.props; onUpdateDeviceModalOpen(false); } }, render() { let { devices, onUpdateDeviceModalOpen, } = this.props; const sortedDevices = {}; for (let type of devices.types) { sortedDevices[type] = Object.assign([], devices[type]) .sort((a, b) => a.name.localeCompare(b.name)); } return dom.div( { id: "device-modal-wrapper", className: this.props.devices.isModalOpen ? "opened" : "closed", }, dom.div( { className: "device-modal container", }, dom.button({ id: "device-close-button", className: "toolbar-button devtools-button", onClick: () => onUpdateDeviceModalOpen(false), }), dom.div( { className: "device-modal-content", }, devices.types.map(type => { return dom.div( { className: "device-type", key: type, }, dom.header( { className: "device-header", }, type ), sortedDevices[type].map(device => { return dom.label( { className: "device-label", key: device.name, }, dom.input({ className: "device-input-checkbox", type: "checkbox", value: device.name, checked: this.state[device.name], onChange: this.onDeviceCheckboxClick, }), device.name ); }) ); }) ), dom.button( { id: "device-submit-button", onClick: this.onDeviceModalSubmit, }, getStr("responsive.done") ) ), dom.div( { className: "modal-overlay", onClick: () => onUpdateDeviceModalOpen(false), } ) ); }, });