Skip to content

Commit

Permalink
Refactor model observers for window title / version label
Browse files Browse the repository at this point in the history
  • Loading branch information
huntie committed Jul 3, 2024
1 parent d4f9bec commit a8268fc
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 42 deletions.
2 changes: 1 addition & 1 deletion config/gni/devtools_grd_files.gni
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,6 @@ grd_files_release_sources = [
"front_end/panels/recorder/recorder-meta.js",
"front_end/panels/recorder/recorder.js",
"front_end/panels/recorder/util/util.js",
"front_end/panels/rn_welcome/ReactNativeApplicationModel.js",
"front_end/panels/rn_welcome/rn_welcome-legacy-meta.js",
"front_end/panels/rn_welcome/rn_welcome-meta.js",
"front_end/panels/rn_welcome/rn_welcome.js",
Expand Down Expand Up @@ -787,6 +786,7 @@ grd_files_debug_sources = [
"front_end/core/sdk/PerformanceMetricsModel.js",
"front_end/core/sdk/PreloadingModel.js",
"front_end/core/sdk/ProfileTreeModel.js",
"front_end/core/sdk/ReactNativeApplicationModel.js",
"front_end/core/sdk/RemoteObject.js",
"front_end/core/sdk/Resource.js",
"front_end/core/sdk/ResourceTreeModel.js",
Expand Down
1 change: 1 addition & 0 deletions front_end/core/sdk/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ devtools_module("sdk") {
"PreloadingModel.ts",
"ProfileTreeModel.ts",
"RemoteObject.ts",
"ReactNativeApplicationModel.ts",
"Resource.ts",
"ResourceTreeModel.ts",
"RuntimeModel.ts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,37 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import * as SDK from '../../core/sdk/sdk.js';

import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
import type * as Protocol from '../../generated/protocol.js';

export class ReactNativeApplicationModel extends SDK.SDKModel.SDKModel<EventTypes> implements ProtocolProxyApi.ReactNativeApplicationDispatcher {
private enabled: boolean;
private readonly agent: ProtocolProxyApi.ReactNativeApplicationApi;
import {Capability, type Target} from './Target.js';
import {SDKModel} from './SDKModel.js';

export class ReactNativeApplicationModel extends SDKModel<EventTypes> implements ProtocolProxyApi.ReactNativeApplicationDispatcher {
#enabled: boolean;
readonly #agent: ProtocolProxyApi.ReactNativeApplicationApi;

metadataCached: Protocol.ReactNativeApplication.MetadataUpdatedEvent | null = null;

constructor(target: SDK.Target.Target) {
constructor(target: Target) {
super(target);

this.enabled = false;
this.agent = target.reactNativeApplicationAgent();
this.#enabled = false;
this.#agent = target.reactNativeApplicationAgent();
target.registerReactNativeApplicationDispatcher(this);
}

ensureEnabled(): void {
if (this.enabled) {
if (this.#enabled) {
return;
}

void this.agent.invoke_enable();
this.enabled = true;
void this.#agent.invoke_enable();
this.#enabled = true;
}

metadataUpdated(metadata: Protocol.ReactNativeApplication.MetadataUpdatedEvent): void {
this.metadataCached = metadata;
this.dispatchEventToListeners(Events.MetadataUpdated, metadata);
}
}
Expand All @@ -42,10 +46,10 @@ export type EventTypes = {
[Events.MetadataUpdated]: Protocol.ReactNativeApplication.MetadataUpdatedEvent,
};

SDK.SDKModel.SDKModel.register(
SDKModel.register(
ReactNativeApplicationModel,
{
capabilities: SDK.Target.Capability.None,
capabilities: Capability.None,
autostart: true,
},
);
2 changes: 2 additions & 0 deletions front_end/core/sdk/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import * as PaintProfiler from './PaintProfiler.js';
import * as PerformanceMetricsModel from './PerformanceMetricsModel.js';
import * as PreloadingModel from './PreloadingModel.js';
import * as ProfileTreeModel from './ProfileTreeModel.js';
import * as ReactNativeApplicationModel from './ReactNativeApplicationModel.js';
import * as RemoteObject from './RemoteObject.js';
import * as Resource from './Resource.js';
import * as ResourceTreeModel from './ResourceTreeModel.js';
Expand Down Expand Up @@ -136,6 +137,7 @@ export {
PerformanceMetricsModel,
PreloadingModel,
ProfileTreeModel,
ReactNativeApplicationModel,
RemoteObject,
Resource,
ResourceTreeModel,
Expand Down
31 changes: 31 additions & 0 deletions front_end/entrypoints/rn_fusebox/rn_fusebox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import * as SDK from '../../core/sdk/sdk.js';
import * as UI from '../../ui/legacy/legacy.js';
import * as Main from '../main/main.js';

import type * as Common from '../../core/common/common.js';
import type * as Platform from '../../core/platform/platform.js';
import type * as Protocol from '../../generated/protocol.js';
import type * as Sources from '../../panels/sources/sources.js';
import * as RNExperiments from '../../core/rn_experiments/rn_experiments.js';

Expand Down Expand Up @@ -222,4 +224,33 @@ UI.Toolbar.registerToolbarItem({
},
});

class FuseboxReactNativeApplicationObserver implements
SDK.TargetManager.SDKModelObserver<SDK.ReactNativeApplicationModel.ReactNativeApplicationModel> {
constructor(targetManager: SDK.TargetManager.TargetManager) {
targetManager.observeModels(SDK.ReactNativeApplicationModel.ReactNativeApplicationModel, this);
}

modelAdded(model: SDK.ReactNativeApplicationModel.ReactNativeApplicationModel): void {
model.ensureEnabled();
model.addEventListener(SDK.ReactNativeApplicationModel.Events.MetadataUpdated, this.#handleMetadataUpdated, this);
}

modelRemoved(model: SDK.ReactNativeApplicationModel.ReactNativeApplicationModel): void {
model.removeEventListener(
SDK.ReactNativeApplicationModel.Events.MetadataUpdated, this.#handleMetadataUpdated, this);
}

#handleMetadataUpdated(
event: Common.EventTarget.EventTargetEvent<Protocol.ReactNativeApplication.MetadataUpdatedEvent>): void {
const {appDisplayName, deviceName} = event.data;

// Update window title
if (appDisplayName != null && deviceName != null) {
document.title = `${appDisplayName} (${deviceName}) - React Native DevTools`;
}
}
}

new FuseboxReactNativeApplicationObserver(SDK.TargetManager.TargetManager.instance());

Host.rnPerfMetrics.entryPointLoadingFinished('rn_fusebox');
1 change: 0 additions & 1 deletion front_end/panels/rn_welcome/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ generate_css("css_files") {
devtools_module("rn_welcome") {
sources = [
"RNWelcome.ts",
"ReactNativeApplicationModel.ts",
]

deps = [
Expand Down
51 changes: 24 additions & 27 deletions front_end/panels/rn_welcome/RNWelcome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import rnWelcomeStyles from './rnWelcome.css.js';
import * as LitHtml from '../../ui/lit-html/lit-html.js';
import type * as Platform from '../../core/platform/platform.js';
import type * as Protocol from '../../generated/protocol.js';
import {Events as ModelEvents, ReactNativeApplicationModel} from './ReactNativeApplicationModel.js';

const UIStrings = {
/** @description Beta label */
Expand Down Expand Up @@ -53,10 +52,11 @@ type RNWelcomeOptions = {
showDocs?: boolean
};

export class RNWelcomeImpl extends UI.Widget.VBox implements SDK.TargetManager.SDKModelObserver<ReactNativeApplicationModel> {
export class RNWelcomeImpl extends UI.Widget.VBox implements
SDK.TargetManager.SDKModelObserver<SDK.ReactNativeApplicationModel.ReactNativeApplicationModel> {
private readonly options: RNWelcomeOptions;

private reactNativeVersion: string | undefined;
#reactNativeVersion: string|undefined;

static instance(options: RNWelcomeOptions): RNWelcomeImpl {
if (!rnWelcomeImplInstance) {
Expand All @@ -70,7 +70,8 @@ export class RNWelcomeImpl extends UI.Widget.VBox implements SDK.TargetManager.S

this.options = options;

SDK.TargetManager.TargetManager.instance().observeModels(ReactNativeApplicationModel, this);
SDK.TargetManager.TargetManager.instance().observeModels(
SDK.ReactNativeApplicationModel.ReactNativeApplicationModel, this);
}

override wasShown(): void {
Expand All @@ -80,35 +81,31 @@ export class RNWelcomeImpl extends UI.Widget.VBox implements SDK.TargetManager.S
UI.InspectorView.InspectorView.instance().showDrawer({focus: true, hasTargetDrawer: false});
}

modelAdded(model: ReactNativeApplicationModel): void {
if (this.isShowing()) {
model.ensureEnabled();
model.addEventListener(ModelEvents.MetadataUpdated, this._updateReactNativeVersion, this);
}
}

modelRemoved(model: ReactNativeApplicationModel): void {
model.removeEventListener(ModelEvents.MetadataUpdated, this._updateReactNativeVersion, this);
modelAdded(model: SDK.ReactNativeApplicationModel.ReactNativeApplicationModel): void {
model.ensureEnabled();
model.addEventListener(
SDK.ReactNativeApplicationModel.Events.MetadataUpdated, this.#handleMetadataUpdated, this);
this.#reactNativeVersion = model.metadataCached?.reactNativeVersion;
}

private _handleLinkPress(url: string): void {
Host.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(
url as Platform.DevToolsPath.UrlString,
);
modelRemoved(model: SDK.ReactNativeApplicationModel.ReactNativeApplicationModel): void {
model.removeEventListener(
SDK.ReactNativeApplicationModel.Events.MetadataUpdated, this.#handleMetadataUpdated, this);
}

private _updateReactNativeVersion(event: Common.EventTarget.EventTargetEvent<Protocol.ReactNativeApplication.MetadataUpdatedEvent>): void {
const {appDisplayName, deviceName, reactNativeVersion} = event.data;
#handleMetadataUpdated(
event: Common.EventTarget.EventTargetEvent<Protocol.ReactNativeApplication.MetadataUpdatedEvent>): void {
this.#reactNativeVersion = event.data.reactNativeVersion;

if (reactNativeVersion != null) {
this.reactNativeVersion = reactNativeVersion;
if (this.isShowing()) {
this.render();
}
}

// Side-effect: Update window title
if (appDisplayName != null && deviceName != null) {
document.title = `${appDisplayName} (${deviceName}) - React Native DevTools`;
}
private _handleLinkPress(url: string): void {
Host.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(
url as Platform.DevToolsPath.UrlString,
);
}

render(): void {
Expand Down Expand Up @@ -153,8 +150,8 @@ export class RNWelcomeImpl extends UI.Widget.VBox implements SDK.TargetManager.S
${i18nString(UIStrings.whatsNewLabel)}
</x-link>
</div>
${this.reactNativeVersion != null ? html`
<p class="rn-welcome-version">React Native: <code>${this.reactNativeVersion}</code></p>
${this.#reactNativeVersion != null ? html`
<p class="rn-welcome-version">React Native: <code>${this.#reactNativeVersion}</code></p>
` : null}
</header>
${showDocs ? html`
Expand Down

0 comments on commit a8268fc

Please sign in to comment.