/* 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/. */ "use strict"; const { createFactory, PureComponent, } = require("resource://devtools/client/shared/vendor/react.js"); const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js"); const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.js"); const FluentReact = require("resource://devtools/client/shared/vendor/fluent-react.js"); const Localized = createFactory(FluentReact.Localized); const { ICON_LABEL_LEVEL, PAGE_TYPES, RUNTIMES, } = require("resource://devtools/client/aboutdebugging/src/constants.js"); const Types = require("resource://devtools/client/aboutdebugging/src/types/index.js"); loader.lazyRequireGetter( this, "ADB_ADDON_STATES", "resource://devtools/client/shared/remote-debugging/adb/adb-addon.js", true ); const IconLabel = createFactory( require("resource://devtools/client/aboutdebugging/src/components/shared/IconLabel.js") ); const SidebarItem = createFactory( require("resource://devtools/client/aboutdebugging/src/components/sidebar/SidebarItem.js") ); const SidebarFixedItem = createFactory( require("resource://devtools/client/aboutdebugging/src/components/sidebar/SidebarFixedItem.js") ); const SidebarRuntimeItem = createFactory( require("resource://devtools/client/aboutdebugging/src/components/sidebar/SidebarRuntimeItem.js") ); const RefreshDevicesButton = createFactory( require("resource://devtools/client/aboutdebugging/src/components/sidebar/RefreshDevicesButton.js") ); const FIREFOX_ICON = "chrome://devtools/skin/images/aboutdebugging-firefox-logo.svg"; const CONNECT_ICON = "chrome://devtools/skin/images/settings.svg"; const GLOBE_ICON = "chrome://devtools/skin/images/aboutdebugging-globe-icon.svg"; const USB_ICON = "chrome://devtools/skin/images/aboutdebugging-connect-icon.svg"; class Sidebar extends PureComponent { static get propTypes() { return { adbAddonStatus: Types.adbAddonStatus, className: PropTypes.string, dispatch: PropTypes.func.isRequired, isAdbReady: PropTypes.bool.isRequired, isScanningUsb: PropTypes.bool.isRequired, networkRuntimes: PropTypes.arrayOf(Types.runtime).isRequired, selectedPage: Types.page, selectedRuntimeId: PropTypes.string, usbRuntimes: PropTypes.arrayOf(Types.runtime).isRequired, }; } renderAdbStatus() { const isUsbEnabled = this.props.isAdbReady && this.props.adbAddonStatus === ADB_ADDON_STATES.INSTALLED; const localizationId = isUsbEnabled ? "about-debugging-sidebar-usb-enabled" : "about-debugging-sidebar-usb-disabled"; return IconLabel( { level: isUsbEnabled ? ICON_LABEL_LEVEL.OK : ICON_LABEL_LEVEL.INFO, }, Localized( { id: localizationId, }, dom.span( { className: "qa-sidebar-usb-status", }, localizationId ) ) ); } renderDevicesEmpty() { return SidebarItem( {}, Localized( { id: "about-debugging-sidebar-no-devices", }, dom.aside( { className: "sidebar__label qa-sidebar-no-devices", }, "No devices discovered" ) ) ); } renderDevices() { const { networkRuntimes, usbRuntimes } = this.props; // render a "no devices" messages when the lists are empty if (!networkRuntimes.length && !usbRuntimes.length) { return this.renderDevicesEmpty(); } // render all devices otherwise return [ ...this.renderRuntimeItems(GLOBE_ICON, networkRuntimes), ...this.renderRuntimeItems(USB_ICON, usbRuntimes), ]; } renderRuntimeItems(icon, runtimes) { const { dispatch, selectedPage, selectedRuntimeId } = this.props; return runtimes.map(runtime => { const keyId = `${runtime.type}-${runtime.id}`; const runtimeHasDetails = !!runtime.runtimeDetails; const isSelected = selectedPage === PAGE_TYPES.RUNTIME && runtime.id === selectedRuntimeId; let name = runtime.name; if (runtime.type === RUNTIMES.USB && runtimeHasDetails) { // Update the name to be same to the runtime page. name = runtime.runtimeDetails.info.name; } return SidebarRuntimeItem({ deviceName: runtime.extra.deviceName, dispatch, icon, key: keyId, isConnected: runtimeHasDetails, isConnecting: runtime.isConnecting, isConnectionFailed: runtime.isConnectionFailed, isConnectionNotResponding: runtime.isConnectionNotResponding, isConnectionTimeout: runtime.isConnectionTimeout, isSelected, isUnavailable: runtime.isUnavailable, isUnplugged: runtime.isUnplugged, name, runtimeId: runtime.id, }); }); } renderFooter() { const HELP_ICON_SRC = "chrome://global/skin/icons/help.svg"; const SUPPORT_URL = "https://firefox-source-docs.mozilla.org/devtools-user/about_colon_debugging/"; return dom.footer( { className: "sidebar__footer", }, dom.ul( {}, SidebarItem( { className: "sidebar-item--condensed", to: SUPPORT_URL, }, dom.span( { className: "sidebar__footer__support-help", }, Localized( { id: "about-debugging-sidebar-support-icon", attrs: { alt: true, }, }, dom.img({ className: "sidebar__footer__icon", src: HELP_ICON_SRC, }) ), Localized( { id: "about-debugging-sidebar-support", }, dom.span({}, "about-debugging-sidebar-support") ) ) ) ) ); } render() { const { dispatch, selectedPage, selectedRuntimeId, isScanningUsb } = this.props; return dom.aside( { className: `sidebar ${this.props.className || ""}`, }, dom.ul( {}, Localized( { id: "about-debugging-sidebar-setup", attrs: { name: true } }, SidebarFixedItem({ dispatch, icon: CONNECT_ICON, isSelected: PAGE_TYPES.CONNECT === selectedPage, key: PAGE_TYPES.CONNECT, name: "Setup", to: "/setup", }) ), Localized( { id: "about-debugging-sidebar-this-firefox", attrs: { name: true } }, SidebarFixedItem({ icon: FIREFOX_ICON, isSelected: PAGE_TYPES.RUNTIME === selectedPage && selectedRuntimeId === RUNTIMES.THIS_FIREFOX, key: RUNTIMES.THIS_FIREFOX, name: "This Firefox", to: `/runtime/${RUNTIMES.THIS_FIREFOX}`, }) ), SidebarItem( { className: "sidebar__adb-status", }, dom.hr({ className: "separator separator--breathe" }), this.renderAdbStatus() ), this.renderDevices(), SidebarItem( { className: "sidebar-item--breathe sidebar__refresh-usb", key: "refresh-devices", }, RefreshDevicesButton({ dispatch, isScanning: isScanningUsb, }) ) ), this.renderFooter() ); } } module.exports = Sidebar;