aboutwelcome.jsx (4258B)
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 file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import React from "react"; 6 import ReactDOM from "react-dom"; 7 import { AboutWelcomeUtils } from "./lib/aboutwelcome-utils.mjs"; 8 import { MultiStageAboutWelcome } from "./components/MultiStageAboutWelcome"; 9 10 class AboutWelcome extends React.PureComponent { 11 constructor(props) { 12 super(props); 13 this.state = { metricsFlowUri: null }; 14 this.fetchFxAFlowUri = this.fetchFxAFlowUri.bind(this); 15 } 16 17 async fetchFxAFlowUri() { 18 this.setState({ metricsFlowUri: await window.AWGetFxAMetricsFlowURI?.() }); 19 } 20 21 componentDidMount() { 22 if (!this.props.skipFxA) { 23 this.fetchFxAFlowUri(); 24 } 25 26 if (document.location.href === "about:welcome") { 27 // Record impression with performance data after allowing the page to load 28 const recordImpression = domState => { 29 const { domComplete, domInteractive } = performance 30 .getEntriesByType("navigation") 31 .pop(); 32 AboutWelcomeUtils.sendImpressionTelemetry(this.props.messageId, { 33 domComplete, 34 domInteractive, 35 mountStart: performance.getEntriesByName("mount").pop().startTime, 36 domState, 37 source: this.props.UTMTerm, 38 }); 39 }; 40 if (document.readyState === "complete") { 41 // Page might have already triggered a load event because it waited for async data, 42 // e.g., attribution, so the dom load timing could be of a empty content 43 // with domState in telemetry captured as 'complete' 44 recordImpression(document.readyState); 45 } else { 46 window.addEventListener("load", () => recordImpression("load"), { 47 once: true, 48 }); 49 } 50 51 // Captures user has seen about:welcome by setting 52 // firstrun.didSeeAboutWelcome pref to true and capturing welcome UI unique messageId 53 window.AWSendToParent("SET_WELCOME_MESSAGE_SEEN", this.props.messageId); 54 } 55 } 56 57 render() { 58 const { props } = this; 59 return ( 60 <MultiStageAboutWelcome 61 addonId={props.addonId} 62 addonType={props.type} 63 addonName={props.name || ""} 64 addonURL={props.url} 65 addonIconURL={props.iconURL} 66 themeScreenshots={props.screenshots} 67 message_id={props.messageId} 68 defaultScreens={props.screens} 69 updateHistory={!props.disableHistoryUpdates} 70 metricsFlowUri={this.state.metricsFlowUri} 71 utm_term={props.UTMTerm} 72 transitions={props.transitions} 73 backdrop={props.backdrop} 74 startScreen={props.startScreen || 0} 75 appAndSystemLocaleInfo={props.appAndSystemLocaleInfo} 76 ariaRole={props.aria_role} 77 gateInitialPaint={true} 78 /> 79 ); 80 } 81 } 82 83 // Computes messageId and UTMTerm info used in telemetry 84 function ComputeTelemetryInfo(welcomeContent, experimentId, branchId) { 85 let messageId = 86 welcomeContent.template === "return_to_amo" 87 ? `RTAMO_DEFAULT_WELCOME_${welcomeContent.type.toUpperCase()}` 88 : "DEFAULT_ID"; 89 let UTMTerm = "aboutwelcome-default"; 90 91 if (welcomeContent.id) { 92 messageId = welcomeContent.id.toUpperCase(); 93 } 94 95 if (experimentId && branchId) { 96 UTMTerm = `aboutwelcome-${experimentId}-${branchId}`.toLowerCase(); 97 } 98 return { 99 messageId, 100 UTMTerm, 101 }; 102 } 103 104 async function retrieveRenderContent() { 105 // Feature config includes RTAMO attribution data if exists 106 // else below data in order specified 107 // user prefs 108 // experiment data 109 // defaults 110 let featureConfig = await window.AWGetFeatureConfig(); 111 112 let { messageId, UTMTerm } = ComputeTelemetryInfo( 113 featureConfig, 114 featureConfig.slug, 115 featureConfig.branch && featureConfig.branch.slug 116 ); 117 return { featureConfig, messageId, UTMTerm }; 118 } 119 120 async function mount() { 121 let { 122 featureConfig: aboutWelcomeProps, 123 messageId, 124 UTMTerm, 125 } = await retrieveRenderContent(); 126 ReactDOM.render( 127 <AboutWelcome 128 messageId={messageId} 129 UTMTerm={UTMTerm} 130 {...aboutWelcomeProps} 131 />, 132 document.getElementById("multi-stage-message-root") 133 ); 134 } 135 136 performance.mark("mount"); 137 mount();