Sidebar.js (7740B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const { 8 createFactory, 9 PureComponent, 10 } = require("resource://devtools/client/shared/vendor/react.mjs"); 11 const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js"); 12 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs"); 13 14 const FluentReact = require("resource://devtools/client/shared/vendor/fluent-react.js"); 15 const Localized = createFactory(FluentReact.Localized); 16 17 const { 18 ICON_LABEL_LEVEL, 19 PAGE_TYPES, 20 RUNTIMES, 21 } = require("resource://devtools/client/aboutdebugging/src/constants.js"); 22 const Types = require("resource://devtools/client/aboutdebugging/src/types/index.js"); 23 loader.lazyRequireGetter( 24 this, 25 "ADB_ADDON_STATES", 26 "resource://devtools/client/shared/remote-debugging/adb/adb-addon.js", 27 true 28 ); 29 30 const IconLabel = createFactory( 31 require("resource://devtools/client/aboutdebugging/src/components/shared/IconLabel.js") 32 ); 33 const SidebarItem = createFactory( 34 require("resource://devtools/client/aboutdebugging/src/components/sidebar/SidebarItem.js") 35 ); 36 const SidebarFixedItem = createFactory( 37 require("resource://devtools/client/aboutdebugging/src/components/sidebar/SidebarFixedItem.js") 38 ); 39 const SidebarRuntimeItem = createFactory( 40 require("resource://devtools/client/aboutdebugging/src/components/sidebar/SidebarRuntimeItem.js") 41 ); 42 const RefreshDevicesButton = createFactory( 43 require("resource://devtools/client/aboutdebugging/src/components/sidebar/RefreshDevicesButton.js") 44 ); 45 const FIREFOX_ICON = 46 "chrome://devtools/skin/images/aboutdebugging-firefox-logo.svg"; 47 const CONNECT_ICON = "chrome://devtools/skin/images/settings.svg"; 48 const GLOBE_ICON = 49 "chrome://devtools/skin/images/aboutdebugging-globe-icon.svg"; 50 const USB_ICON = 51 "chrome://devtools/skin/images/aboutdebugging-connect-icon.svg"; 52 53 class Sidebar extends PureComponent { 54 static get propTypes() { 55 return { 56 adbAddonStatus: Types.adbAddonStatus, 57 className: PropTypes.string, 58 dispatch: PropTypes.func.isRequired, 59 isAdbReady: PropTypes.bool.isRequired, 60 isScanningUsb: PropTypes.bool.isRequired, 61 networkRuntimes: PropTypes.arrayOf(Types.runtime).isRequired, 62 selectedPage: Types.page, 63 selectedRuntimeId: PropTypes.string, 64 usbRuntimes: PropTypes.arrayOf(Types.runtime).isRequired, 65 }; 66 } 67 68 renderAdbStatus() { 69 const isUsbEnabled = 70 this.props.isAdbReady && 71 this.props.adbAddonStatus === ADB_ADDON_STATES.INSTALLED; 72 const localizationId = isUsbEnabled 73 ? "about-debugging-sidebar-usb-enabled" 74 : "about-debugging-sidebar-usb-disabled"; 75 return IconLabel( 76 { 77 level: isUsbEnabled ? ICON_LABEL_LEVEL.OK : ICON_LABEL_LEVEL.INFO, 78 }, 79 Localized( 80 { 81 id: localizationId, 82 }, 83 dom.span( 84 { 85 className: "qa-sidebar-usb-status", 86 }, 87 localizationId 88 ) 89 ) 90 ); 91 } 92 93 renderDevicesEmpty() { 94 return SidebarItem( 95 {}, 96 Localized( 97 { 98 id: "about-debugging-sidebar-no-devices", 99 }, 100 dom.aside( 101 { 102 className: "sidebar__label qa-sidebar-no-devices", 103 }, 104 "No devices discovered" 105 ) 106 ) 107 ); 108 } 109 110 renderDevices() { 111 const { networkRuntimes, usbRuntimes } = this.props; 112 113 // render a "no devices" messages when the lists are empty 114 if (!networkRuntimes.length && !usbRuntimes.length) { 115 return this.renderDevicesEmpty(); 116 } 117 // render all devices otherwise 118 return [ 119 ...this.renderRuntimeItems(GLOBE_ICON, networkRuntimes), 120 ...this.renderRuntimeItems(USB_ICON, usbRuntimes), 121 ]; 122 } 123 124 renderRuntimeItems(icon, runtimes) { 125 const { dispatch, selectedPage, selectedRuntimeId } = this.props; 126 127 return runtimes.map(runtime => { 128 const keyId = `${runtime.type}-${runtime.id}`; 129 const runtimeHasDetails = !!runtime.runtimeDetails; 130 const isSelected = 131 selectedPage === PAGE_TYPES.RUNTIME && runtime.id === selectedRuntimeId; 132 133 let name = runtime.name; 134 if (runtime.type === RUNTIMES.USB && runtimeHasDetails) { 135 // Update the name to be same to the runtime page. 136 name = runtime.runtimeDetails.info.name; 137 } 138 139 return SidebarRuntimeItem({ 140 deviceName: runtime.extra.deviceName, 141 dispatch, 142 icon, 143 key: keyId, 144 isConnected: runtimeHasDetails, 145 isConnecting: runtime.isConnecting, 146 isConnectionFailed: runtime.isConnectionFailed, 147 isConnectionNotResponding: runtime.isConnectionNotResponding, 148 isConnectionTimeout: runtime.isConnectionTimeout, 149 isSelected, 150 isUnavailable: runtime.isUnavailable, 151 isUnplugged: runtime.isUnplugged, 152 name, 153 runtimeId: runtime.id, 154 }); 155 }); 156 } 157 158 renderFooter() { 159 const HELP_ICON_SRC = "chrome://global/skin/icons/help.svg"; 160 const SUPPORT_URL = 161 "https://firefox-source-docs.mozilla.org/devtools-user/about_colon_debugging/"; 162 163 return dom.footer( 164 { 165 className: "sidebar__footer", 166 }, 167 dom.ul( 168 {}, 169 SidebarItem( 170 { 171 className: "sidebar-item--condensed", 172 to: SUPPORT_URL, 173 }, 174 dom.span( 175 { 176 className: "sidebar__footer__support-help", 177 }, 178 Localized( 179 { 180 id: "about-debugging-sidebar-support-icon", 181 attrs: { 182 alt: true, 183 }, 184 }, 185 dom.img({ 186 className: "sidebar__footer__icon", 187 src: HELP_ICON_SRC, 188 }) 189 ), 190 Localized( 191 { 192 id: "about-debugging-sidebar-support", 193 }, 194 dom.span({}, "about-debugging-sidebar-support") 195 ) 196 ) 197 ) 198 ) 199 ); 200 } 201 202 render() { 203 const { dispatch, selectedPage, selectedRuntimeId, isScanningUsb } = 204 this.props; 205 206 return dom.aside( 207 { 208 className: `sidebar ${this.props.className || ""}`, 209 }, 210 dom.ul( 211 {}, 212 Localized( 213 { id: "about-debugging-sidebar-setup", attrs: { name: true } }, 214 SidebarFixedItem({ 215 dispatch, 216 icon: CONNECT_ICON, 217 isSelected: PAGE_TYPES.CONNECT === selectedPage, 218 key: PAGE_TYPES.CONNECT, 219 name: "Setup", 220 to: "/setup", 221 }) 222 ), 223 Localized( 224 { id: "about-debugging-sidebar-this-firefox", attrs: { name: true } }, 225 SidebarFixedItem({ 226 icon: FIREFOX_ICON, 227 isSelected: 228 PAGE_TYPES.RUNTIME === selectedPage && 229 selectedRuntimeId === RUNTIMES.THIS_FIREFOX, 230 key: RUNTIMES.THIS_FIREFOX, 231 name: "This Firefox", 232 to: `/runtime/${RUNTIMES.THIS_FIREFOX}`, 233 }) 234 ), 235 SidebarItem( 236 { 237 className: "sidebar__adb-status", 238 }, 239 dom.hr({ className: "separator separator--breathe" }), 240 this.renderAdbStatus() 241 ), 242 this.renderDevices(), 243 SidebarItem( 244 { 245 className: "sidebar-item--breathe sidebar__refresh-usb", 246 key: "refresh-devices", 247 }, 248 RefreshDevicesButton({ 249 dispatch, 250 isScanning: isScanningUsb, 251 }) 252 ) 253 ), 254 this.renderFooter() 255 ); 256 } 257 } 258 259 module.exports = Sidebar;