diff --git a/front_end/entrypoints/rn_fusebox/rn_fusebox.ts b/front_end/entrypoints/rn_fusebox/rn_fusebox.ts index a0c718ea7dd..76561ed07ce 100644 --- a/front_end/entrypoints/rn_fusebox/rn_fusebox.ts +++ b/front_end/entrypoints/rn_fusebox/rn_fusebox.ts @@ -48,6 +48,14 @@ const UIStrings = { *@description Label of the FB-only 'send feedback' action button in the toolbar */ sendFeedback: '[FB-only] Send feedback', + /** + *@description Tooltip of the connection status toolbar button while disconnected + */ + connectionStatusDisconnectedTooltip: 'Debugging connection was closed', + /** + *@description Button label of the connection status toolbar button while disconnected + */ + connectionStatusDisconnectedLabel: 'Reconnect DevTools', }; const str_ = i18n.i18n.registerUIStrings('entrypoints/rn_fusebox/rn_fusebox.ts', UIStrings); const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_); @@ -171,4 +179,47 @@ if (globalThis.FB_ONLY__reactNativeFeedbackLink) { }); } +class ConnectionStatusToolbarItemProvider extends SDK.TargetManager.Observer implements UI.Toolbar.Provider { + #button = new UI.Toolbar.ToolbarButton(''); + + constructor() { + super(); + this.#button.setVisible(false); + this.#button.element.classList.add('fusebox-connection-status'); + this.#button.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this.onClick.bind(this)); + + SDK.TargetManager.TargetManager.instance().observeTargets(this, {scoped: true}); + } + + override targetAdded(_target: SDK.Target.Target): void { + this.#updateRootTarget(); + } + override targetRemoved(_target: SDK.Target.Target): void { + this.#updateRootTarget(); + } + + #updateRootTarget(): void { + const rootTarget = SDK.TargetManager.TargetManager.instance().rootTarget(); + this.#button.setTitle(i18nLazyString(UIStrings.connectionStatusDisconnectedTooltip)()); + this.#button.setText(i18nLazyString(UIStrings.connectionStatusDisconnectedLabel)()); + this.#button.setVisible(!rootTarget); + } + + onClick(): void { + window.location.reload(); + } + + item(): UI.Toolbar.ToolbarItem { + return this.#button; + } +} + +const connectionStatusToolbarItemProvider = new ConnectionStatusToolbarItemProvider(); +UI.Toolbar.registerToolbarItem({ + location: UI.Toolbar.ToolbarItemLocation.MAIN_TOOLBAR_RIGHT, + loadItem: async () => { + return connectionStatusToolbarItemProvider; + }, +}); + Host.rnPerfMetrics.entryPointLoadingFinished('rn_fusebox'); diff --git a/front_end/ui/legacy/toolbar.css b/front_end/ui/legacy/toolbar.css index 8b1ca62bcc1..6186eaee637 100644 --- a/front_end/ui/legacy/toolbar.css +++ b/front_end/ui/legacy/toolbar.css @@ -581,3 +581,22 @@ devtools-icon.leading-issue-icon { [aria-label="[FB-only] Send feedback"] .toolbar-glyph { color: white !important; } + +/* [RN] Customise styling for Fusebox's connection status button */ + +.fusebox-connection-status { + margin: 4px; + height: 20px; + padding: 0 4px; + border-radius: 4px; + background: color-mix(in srgb, var(--color-red) 80%, transparent); +} + +.fusebox-connection-status:hover { + background: color-mix(in srgb, var(--color-red) 90%, transparent); +} + +.fusebox-connection-status .toolbar-text, +.fusebox-connection-status .toolbar-glyph { + color: white !important; +}