diff --git a/config/gni/devtools_grd_files.gni b/config/gni/devtools_grd_files.gni index 9be8248b0fb..c94b512f407 100644 --- a/config/gni/devtools_grd_files.gni +++ b/config/gni/devtools_grd_files.gni @@ -177,6 +177,7 @@ grd_files_release_sources = [ "front_end/Images/popup.svg", "front_end/Images/preview_feature_video_thumbnail.svg", "front_end/Images/profile.svg", + "front_end/Images/react_native/welcomeIcon.png", "front_end/Images/record-start.svg", "front_end/Images/record-stop.svg", "front_end/Images/redo.svg", @@ -537,6 +538,10 @@ 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/rn_welcome-meta.js", + "front_end/panels/rn_welcome/RNWelcome.js", + "front_end/panels/rn_welcome/rn_welcome.js", + "front_end/panels/rn_welcome/rnWelcome.css.js", "front_end/panels/screencast/screencast-meta.js", "front_end/panels/screencast/screencast.js", "front_end/panels/search/search-legacy.js", diff --git a/config/gni/devtools_image_files.gni b/config/gni/devtools_image_files.gni index f530c096a6f..19f3186ac48 100644 --- a/config/gni/devtools_image_files.gni +++ b/config/gni/devtools_image_files.gni @@ -15,6 +15,7 @@ devtools_image_files = [ "navigationControls.png", "nodeIcon.avif", "popoverArrows.png", + "react_native/welcomeIcon.png", "toolbarResizerVertical.png", "touchCursor_2x.png", "touchCursor.png", diff --git a/front_end/Images/react_native/welcomeIcon.png b/front_end/Images/react_native/welcomeIcon.png new file mode 100644 index 00000000000..72466742079 Binary files /dev/null and b/front_end/Images/react_native/welcomeIcon.png differ diff --git a/front_end/core/root/Runtime.ts b/front_end/core/root/Runtime.ts index d1a0f4b6ab4..99b7cb67f06 100644 --- a/front_end/core/root/Runtime.ts +++ b/front_end/core/root/Runtime.ts @@ -314,6 +314,7 @@ export enum ExperimentName { HIGHLIGHT_ERRORS_ELEMENTS_PANEL = 'highlightErrorsElementsPanel', SET_ALL_BREAKPOINTS_EAGERLY = 'setAllBreakpointsEagerly', SELF_XSS_WARNING = 'selfXssWarning', + REACT_NATIVE_SPECIFIC_UI = 'reactNativeSpecificUI', } // TODO(crbug.com/1167717): Make this a const enum again diff --git a/front_end/entrypoints/rn_inspector/BUILD.gn b/front_end/entrypoints/rn_inspector/BUILD.gn index feacd8bde3d..0e439d25f33 100644 --- a/front_end/entrypoints/rn_inspector/BUILD.gn +++ b/front_end/entrypoints/rn_inspector/BUILD.gn @@ -26,6 +26,7 @@ devtools_entrypoint("entrypoint") { "../../panels/network:meta", "../../panels/performance_monitor:meta", "../../panels/recorder:meta", + "../../panels/rn_welcome:meta", "../../panels/security:meta", "../../panels/sensors:meta", "../../panels/timeline:meta", diff --git a/front_end/entrypoints/rn_inspector/rn_inspector.ts b/front_end/entrypoints/rn_inspector/rn_inspector.ts index a6b1ba40c30..777b7b787bc 100644 --- a/front_end/entrypoints/rn_inspector/rn_inspector.ts +++ b/front_end/entrypoints/rn_inspector/rn_inspector.ts @@ -10,10 +10,21 @@ import '../inspector_main/inspector_main-meta.js'; import '../../panels/issues/issues-meta.js'; import '../../panels/mobile_throttling/mobile_throttling-meta.js'; import '../../panels/timeline/timeline-meta.js'; +import '../../panels/rn_welcome/rn_welcome-meta.js'; import * as Root from '../../core/root/root.js'; import * as Main from '../main/main.js'; +Root.Runtime.experiments.register( + Root.Runtime.ExperimentName.REACT_NATIVE_SPECIFIC_UI, + 'Show React Native-specific UI', + /* unstable */ false, +); + +Root.Runtime.experiments.enableExperimentsByDefault( + [Root.Runtime.ExperimentName.REACT_NATIVE_SPECIFIC_UI], +); + // @ts-ignore Exposed for legacy layout tests self.runtime = Root.Runtime.Runtime.instance({forceNew: true}); new Main.MainImpl.MainImpl(); diff --git a/front_end/panels/rn_welcome/BUILD.gn b/front_end/panels/rn_welcome/BUILD.gn new file mode 100644 index 00000000000..aac17b8c749 --- /dev/null +++ b/front_end/panels/rn_welcome/BUILD.gn @@ -0,0 +1,54 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("../../../scripts/build/ninja/devtools_entrypoint.gni") +import("../../../scripts/build/ninja/devtools_module.gni") +import("../../../scripts/build/ninja/generate_css.gni") +import("../visibility.gni") + +generate_css("css_files") { + sources = [ "rnWelcome.css" ] +} + +devtools_module("rn_welcome") { + sources = [ "RNWelcome.ts" ] + + deps = [ + "../../core/host:bundle", + "../../core/i18n:bundle", + "../../core/protocol_client:bundle", + "../../core/sdk:bundle", + "../../models/text_utils:bundle", + "../../ui/components/data_grid:bundle", + "../../ui/components/icon_button:bundle", + "../../ui/legacy:bundle", + "../../ui/lit-html:bundle", + ] +} + +devtools_entrypoint("bundle") { + entrypoint = "rn_welcome.ts" + + deps = [ + ":css_files", + ":rn_welcome", + ] + + visibility = [ + ":*", + "../../../test/unittests/front_end/entrypoints/missing_entrypoints/*", + # "../../../test/unittests/front_end/panels/rn_welcome/*", + "../../entrypoints/*", + ] + + visibility += devtools_panels_visibility +} + +devtools_entrypoint("meta") { + entrypoint = "rn_welcome-meta.ts" + + deps = [ ":bundle" ] + + visibility = [ "../../entrypoints/*" ] +} diff --git a/front_end/panels/rn_welcome/RNWelcome.ts b/front_end/panels/rn_welcome/RNWelcome.ts new file mode 100644 index 00000000000..e3a17a4e42c --- /dev/null +++ b/front_end/panels/rn_welcome/RNWelcome.ts @@ -0,0 +1,71 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import * as UI from '../../ui/legacy/legacy.js'; +import * as i18n from '../../core/i18n/i18n.js'; + +import rnWelcomeStyles from './rnWelcome.css.js'; +import * as LitHtml from '../../ui/lit-html/lit-html.js'; + +const UIStrings = { + /** @description The name of the debugging product */ + debuggerBrandName: 'React Native JS Inspector', + /** @description Welcome text */ + welcomeMessage: 'Welcome to debugging in React Native', + /** @description "Debugging docs" link */ + docsLabel: 'Debugging docs', + /** @description "What's new" link */ + whatsNewLabel: "What's new", +}; +const {render, html} = LitHtml; + +const str_ = i18n.i18n.registerUIStrings('panels/rn_welcome/RNWelcome.ts', UIStrings); +const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); + +let rnWelcomeImplInstance: RNWelcomeImpl; + +export class RNWelcomeImpl extends UI.Widget.VBox { + static instance(opts: {forceNew: null|boolean} = {forceNew: null}): RNWelcomeImpl { + const {forceNew} = opts; + if (!rnWelcomeImplInstance || forceNew) { + rnWelcomeImplInstance = new RNWelcomeImpl(); + } + return rnWelcomeImplInstance; + } + + private constructor() { + super(true, true); + } + + override wasShown(): void { + super.wasShown(); + this.registerCSSFiles([rnWelcomeStyles]); + this.render(); + UI.InspectorView.InspectorView.instance().showDrawer(true); + } + + render(): void { + render(html` +
+
+ +
+ ${i18nString(UIStrings.debuggerBrandName)} +
+
+
+ ${i18nString(UIStrings.welcomeMessage)} +
+ +
+ `, this.contentElement, {host: this}); + } +} diff --git a/front_end/panels/rn_welcome/rnWelcome.css b/front_end/panels/rn_welcome/rnWelcome.css new file mode 100644 index 00000000000..872f4053b27 --- /dev/null +++ b/front_end/panels/rn_welcome/rnWelcome.css @@ -0,0 +1,61 @@ +/* + * Copyright 2021 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +.rn-welcome-panel { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + padding: 16px; + text-align: center; + font-size: 1rem; + background-color: var(--color-background-elevation-0); +} + +.rn-welcome-header { + display: flex; + align-items: center; + margin-bottom: 16px; +} + +.rn-welcome-icon { + width: 30px; + height: 30px; + border-radius: 4px; + margin-right: 12px; +} + +.rn-welcome-title { + font-size: 20px; + color: var(--color-text-primary); +} + +.rn-welcome-tagline { + margin-bottom: 24px; + font-size: 1rem; + line-height: 1.3; + color: var(--color-text-secondary); +} + +.rn-welcome-links { + display: flex; + align-items: center; +} + +.rn-welcome-links > .devtools-link { + position: relative; + margin: 0 16px; + font-size: 14px; +} + +.rn-welcome-links > .devtools-link:not(:last-child)::after { + content: ""; + position: absolute; + right: -16px; + height: 16px; + border-right: 1px solid var(--color-details-hairline); +} diff --git a/front_end/panels/rn_welcome/rn_welcome-meta.ts b/front_end/panels/rn_welcome/rn_welcome-meta.ts new file mode 100644 index 00000000000..aaf2144e19b --- /dev/null +++ b/front_end/panels/rn_welcome/rn_welcome-meta.ts @@ -0,0 +1,46 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import * as i18n from '../../core/i18n/i18n.js'; +import * as Root from '../../core/root/root.js'; +import * as UI from '../../ui/legacy/legacy.js'; + +import type * as RNWelcome from './rn_welcome.js'; + +const UIStrings = { + /** + * @description Title of the Welcome panel, plus an emoji symbolizing React Native + */ + rnWelcome: '⚛️ Welcome', + + /** + * @description Command for showing the Welcome panel + */ + showRnWelcome: 'Show React Native Welcome panel', +}; +const str_ = i18n.i18n.registerUIStrings('panels/rn_welcome/rn_welcome-meta.ts', UIStrings); +const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_); + +let loadedRNWelcomeModule: (typeof RNWelcome|undefined); + +async function loadRNWelcomeModule(): Promise { + if (!loadedRNWelcomeModule) { + loadedRNWelcomeModule = await import('./rn_welcome.js'); + } + return loadedRNWelcomeModule; +} + +UI.ViewManager.registerViewExtension({ + location: UI.ViewManager.ViewLocationValues.PANEL, + id: 'rn-welcome', + title: i18nLazyString(UIStrings.rnWelcome), + commandPrompt: i18nLazyString(UIStrings.showRnWelcome), + order: -10, + persistence: UI.ViewManager.ViewPersistence.PERMANENT, + async loadView() { + const RNWelcome = await loadRNWelcomeModule(); + return RNWelcome.RNWelcome.RNWelcomeImpl.instance(); + }, + experiment: Root.Runtime.ExperimentName.REACT_NATIVE_SPECIFIC_UI, +}); diff --git a/front_end/panels/rn_welcome/rn_welcome.ts b/front_end/panels/rn_welcome/rn_welcome.ts new file mode 100644 index 00000000000..8f89f6dbf7b --- /dev/null +++ b/front_end/panels/rn_welcome/rn_welcome.ts @@ -0,0 +1,11 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import './RNWelcome.js'; + +import * as RNWelcome from './RNWelcome.js'; + +export { + RNWelcome, +};