summaryrefslogtreecommitdiffstats
path: root/browser/components/newtab/content-src/aboutwelcome/aboutwelcome.jsx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--browser/components/newtab/content-src/aboutwelcome/aboutwelcome.jsx188
1 files changed, 188 insertions, 0 deletions
diff --git a/browser/components/newtab/content-src/aboutwelcome/aboutwelcome.jsx b/browser/components/newtab/content-src/aboutwelcome/aboutwelcome.jsx
new file mode 100644
index 0000000000..d9503584b9
--- /dev/null
+++ b/browser/components/newtab/content-src/aboutwelcome/aboutwelcome.jsx
@@ -0,0 +1,188 @@
+/* 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/. */
+
+import React from "react";
+import ReactDOM from "react-dom";
+import { MultiStageAboutWelcome } from "./components/MultiStageAboutWelcome";
+import { SimpleAboutWelcome } from "./components/SimpleAboutWelcome";
+import { ReturnToAMO } from "./components/ReturnToAMO";
+
+import {
+ AboutWelcomeUtils,
+ DEFAULT_WELCOME_CONTENT,
+} from "../lib/aboutwelcome-utils";
+
+class AboutWelcome extends React.PureComponent {
+ constructor(props) {
+ super(props);
+ this.state = { metricsFlowUri: null };
+ this.fetchFxAFlowUri = this.fetchFxAFlowUri.bind(this);
+ this.handleStartBtnClick = this.handleStartBtnClick.bind(this);
+ }
+
+ async fetchFxAFlowUri() {
+ this.setState({ metricsFlowUri: await window.AWGetFxAMetricsFlowURI() });
+ }
+
+ componentDidMount() {
+ this.fetchFxAFlowUri();
+
+ // Record impression with performance data after allowing the page to load
+ const recordImpression = domState => {
+ const { domComplete, domInteractive } = performance
+ .getEntriesByType("navigation")
+ .pop();
+ window.AWSendEventTelemetry({
+ event: "IMPRESSION",
+ event_context: {
+ domComplete,
+ domInteractive,
+ mountStart: performance.getEntriesByName("mount").pop().startTime,
+ domState,
+ source: this.props.UTMTerm,
+ page: "about:welcome",
+ },
+ message_id: this.props.messageId,
+ });
+ };
+ if (document.readyState === "complete") {
+ // Page might have already triggered a load event because it waited for async data,
+ // e.g., attribution, so the dom load timing could be of a empty content
+ // with domState in telemetry captured as 'complete'
+ recordImpression(document.readyState);
+ } else {
+ window.addEventListener("load", () => recordImpression("load"), {
+ once: true,
+ });
+ }
+
+ // Captures user has seen about:welcome by setting
+ // firstrun.didSeeAboutWelcome pref to true and capturing welcome UI unique messageId
+ window.AWSendToParent("SET_WELCOME_MESSAGE_SEEN", this.props.messageId);
+ }
+
+ handleStartBtnClick() {
+ AboutWelcomeUtils.handleUserAction(this.props.startButton.action);
+ const ping = {
+ event: "CLICK_BUTTON",
+ event_context: {
+ source: this.props.startButton.message_id,
+ page: "about:welcome",
+ },
+ message_id: this.props.messageId,
+ id: "ABOUT_WELCOME",
+ };
+ window.AWSendEventTelemetry(ping);
+ }
+
+ render() {
+ const { props } = this;
+ if (props.template === "simplified") {
+ return (
+ <SimpleAboutWelcome
+ metricsFlowUri={this.state.metricsFlowUri}
+ message_id={props.messageId}
+ utm_term={props.UTMTerm}
+ title={props.title}
+ subtitle={props.subtitle}
+ cards={props.cards}
+ startButton={props.startButton}
+ handleStartBtnClick={this.handleStartBtnClick}
+ />
+ );
+ } else if (props.template === "return_to_amo") {
+ return (
+ <ReturnToAMO
+ message_id={props.messageId}
+ name={props.name}
+ url={props.url}
+ iconURL={props.iconURL}
+ />
+ );
+ }
+
+ return (
+ <MultiStageAboutWelcome
+ screens={props.screens}
+ metricsFlowUri={this.state.metricsFlowUri}
+ message_id={props.messageId}
+ utm_term={props.UTMTerm}
+ />
+ );
+ }
+}
+
+AboutWelcome.defaultProps = DEFAULT_WELCOME_CONTENT;
+
+// Computes messageId and UTMTerm info used in telemetry
+function ComputeTelemetryInfo(welcomeContent, experimentId, branchId) {
+ let messageId =
+ welcomeContent.template === "return_to_amo"
+ ? "RTAMO_DEFAULT_WELCOME"
+ : "DEFAULT_ABOUTWELCOME";
+ let UTMTerm = "default";
+
+ if (welcomeContent.id) {
+ messageId = welcomeContent.id.toUpperCase();
+ }
+
+ if (experimentId && branchId) {
+ UTMTerm = `${experimentId}-${branchId}`.toLowerCase();
+ }
+ return {
+ messageId,
+ UTMTerm,
+ };
+}
+
+async function retrieveRenderContent() {
+ // Check for override content in pref browser.aboutwelcome.overrideContent
+ let aboutWelcomeProps = await window.AWGetWelcomeOverrideContent();
+ if (aboutWelcomeProps?.template) {
+ let { messageId, UTMTerm } = ComputeTelemetryInfo(aboutWelcomeProps);
+ return { aboutWelcomeProps, messageId, UTMTerm };
+ }
+
+ // Check for experiment and retrieve content
+ const { slug, branch } = await window.AWGetExperimentData();
+ aboutWelcomeProps = branch?.feature ? branch.feature.value : {};
+
+ // Check if there is any attribution data, this could take a while to await in series
+ // especially when there is an add-on that requires remote lookup
+ // Moving RTAMO as part of another screen of multistage is one option to fix the delay
+ // as it will allow the initial page to be fast while we fetch attribution data in parallel for a later screen.
+ const attribution = await window.AWGetAttributionData();
+ if (attribution?.template) {
+ aboutWelcomeProps = {
+ ...aboutWelcomeProps,
+ // If part of an experiment, render experiment template
+ template: aboutWelcomeProps?.template
+ ? aboutWelcomeProps.template
+ : attribution.template,
+ ...attribution.extraProps,
+ };
+ }
+
+ let { messageId, UTMTerm } = ComputeTelemetryInfo(
+ aboutWelcomeProps,
+ slug,
+ branch && branch.slug
+ );
+ return { aboutWelcomeProps, messageId, UTMTerm };
+}
+
+async function mount() {
+ let { aboutWelcomeProps, messageId, UTMTerm } = await retrieveRenderContent();
+ ReactDOM.render(
+ <AboutWelcome
+ messageId={messageId}
+ UTMTerm={UTMTerm}
+ {...aboutWelcomeProps}
+ />,
+ document.getElementById("root")
+ );
+}
+
+performance.mark("mount");
+mount();