зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1696547 - Refactor MultiStageAboutWelcome to support Proton onboarding r=Mardak,emcminn
Differential Revision: https://phabricator.services.mozilla.com/D107954
This commit is contained in:
Родитель
8ed6d71b3b
Коммит
9624bcba17
|
@ -40,6 +40,8 @@ module.exports = {
|
|||
files: [
|
||||
"content-src/aboutwelcome/components/Zap.jsx",
|
||||
"content-src/aboutwelcome/components/MultiStageAboutWelcome.jsx",
|
||||
"content-src/aboutwelcome/components/MultiStageScreen.jsx",
|
||||
"content-src/aboutwelcome/components/MultiStageProtonScreen.jsx",
|
||||
"content-src/aboutwelcome/components/ReturnToAMO.jsx",
|
||||
"content-src/asrouter/templates/OnboardingMessage/**",
|
||||
"content-src/asrouter/templates/FirstRun/**",
|
||||
|
|
|
@ -101,7 +101,7 @@ __webpack_require__.r(__webpack_exports__);
|
|||
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
|
||||
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
|
||||
/* harmony import */ var _components_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
|
||||
/* harmony import */ var _components_ReturnToAMO__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9);
|
||||
/* harmony import */ var _components_ReturnToAMO__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11);
|
||||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
|
@ -183,7 +183,8 @@ class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComp
|
|||
screens: props.screens,
|
||||
metricsFlowUri: this.state.metricsFlowUri,
|
||||
message_id: props.messageId,
|
||||
utm_term: props.UTMTerm
|
||||
utm_term: props.UTMTerm,
|
||||
design: props.design
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -260,14 +261,16 @@ module.exports = ReactDOM;
|
|||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiStageAboutWelcome", function() { return MultiStageAboutWelcome; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SecondaryCTA", function() { return SecondaryCTA; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StepsIndicator", function() { return StepsIndicator; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WelcomeScreen", function() { return WelcomeScreen; });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
|
||||
/* harmony import */ var _Zap__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
|
||||
/* harmony import */ var _HelpText__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7);
|
||||
/* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
|
||||
/* harmony import */ var _MultiStageScreen__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6);
|
||||
/* harmony import */ var _MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9);
|
||||
/* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(10);
|
||||
/* 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/. */
|
||||
|
@ -283,7 +286,7 @@ const MultiStageAboutWelcome = props => {
|
|||
// Send impression ping when respective screen first renders
|
||||
props.screens.forEach(screen => {
|
||||
if (index === screen.order) {
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].sendImpressionTelemetry(`${props.message_id}_${screen.id}`);
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].sendImpressionTelemetry(`${props.message_id}_${screen.id}`);
|
||||
}
|
||||
}); // Remember that a new screen has loaded for browser navigation
|
||||
|
||||
|
@ -310,12 +313,12 @@ const MultiStageAboutWelcome = props => {
|
|||
Object(react__WEBPACK_IMPORTED_MODULE_0__["useEffect"])(() => {
|
||||
(async () => {
|
||||
if (metricsFlowUri) {
|
||||
setFlowParams(await _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].fetchFlowParams(metricsFlowUri));
|
||||
setFlowParams(await _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].fetchFlowParams(metricsFlowUri));
|
||||
}
|
||||
})();
|
||||
}, [metricsFlowUri]); // Transition to next screen, opening about:home on last screen button CTA
|
||||
|
||||
const handleTransition = index < props.screens.length - 1 ? () => setScreenIndex(prevState => prevState + 1) : () => _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].handleUserAction({
|
||||
const handleTransition = index < props.screens.length - 1 ? () => setScreenIndex(prevState => prevState + 1) : () => _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].handleUserAction({
|
||||
type: "OPEN_ABOUT_PAGE",
|
||||
data: {
|
||||
args: "home",
|
||||
|
@ -351,7 +354,7 @@ const MultiStageAboutWelcome = props => {
|
|||
const showImportable = useImportable && importable.length >= 5;
|
||||
|
||||
if (!importTelemetrySent.current) {
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].sendImpressionTelemetry(`${props.message_id}_SITES`, {
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].sendImpressionTelemetry(`${props.message_id}_SITES`, {
|
||||
display: showImportable ? "importable" : "static",
|
||||
importable: importable.length
|
||||
});
|
||||
|
@ -368,7 +371,7 @@ const MultiStageAboutWelcome = props => {
|
|||
})();
|
||||
}, [useImportable, region]);
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: `outer-wrapper onboardingContainer`
|
||||
className: `outer-wrapper onboardingContainer ${props.design}`
|
||||
}, props.screens.map(screen => {
|
||||
return index === screen.order ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(WelcomeScreen, {
|
||||
key: screen.id,
|
||||
|
@ -383,10 +386,38 @@ const MultiStageAboutWelcome = props => {
|
|||
flowParams: flowParams,
|
||||
activeTheme: activeTheme,
|
||||
initialTheme: initialTheme,
|
||||
setActiveTheme: setActiveTheme
|
||||
setActiveTheme: setActiveTheme,
|
||||
design: props.design
|
||||
}) : null;
|
||||
})));
|
||||
};
|
||||
const SecondaryCTA = props => {
|
||||
let targetElement = props.position ? `secondary_button_${props.position}` : `secondary_button`;
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: props.position ? `secondary-cta ${props.position}` : "secondary-cta"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: props.content[targetElement].text
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: props.content[targetElement].label
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
|
||||
className: "secondary",
|
||||
value: targetElement,
|
||||
onClick: props.handleAction
|
||||
})));
|
||||
};
|
||||
const StepsIndicator = props => {
|
||||
let steps = [];
|
||||
|
||||
for (let i = 0; i < props.totalNumberOfScreens; i++) {
|
||||
let className = i === props.order ? "current" : "";
|
||||
steps.push( /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
key: i,
|
||||
className: `indicator ${className}`
|
||||
}));
|
||||
}
|
||||
|
||||
return steps;
|
||||
};
|
||||
class WelcomeScreen extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -431,7 +462,7 @@ class WelcomeScreen extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCom
|
|||
};
|
||||
}
|
||||
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].handleUserAction({
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].handleUserAction({
|
||||
type,
|
||||
data
|
||||
});
|
||||
|
@ -448,7 +479,7 @@ class WelcomeScreen extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCom
|
|||
} // Send telemetry before waiting on actions
|
||||
|
||||
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].sendActionTelemetry(props.messageId, event.currentTarget.value);
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].sendActionTelemetry(props.messageId, event.currentTarget.value);
|
||||
let {
|
||||
action
|
||||
} = targetContent;
|
||||
|
@ -456,11 +487,11 @@ class WelcomeScreen extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCom
|
|||
if (["OPEN_URL", "SHOW_FIREFOX_ACCOUNTS"].includes(action.type)) {
|
||||
this.handleOpenURL(action, props.flowParams, props.UTMTerm);
|
||||
} else if (action.type) {
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].handleUserAction(action); // Wait until migration closes to complete the action
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].handleUserAction(action); // Wait until migration closes to complete the action
|
||||
|
||||
if (action.type === "SHOW_MIGRATION_WIZARD") {
|
||||
await window.AWWaitForMigrationClose();
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].sendActionTelemetry(props.messageId, "migrate_close");
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].sendActionTelemetry(props.messageId, "migrate_close");
|
||||
}
|
||||
} // Wait until we become default browser to continue rest of action.
|
||||
|
||||
|
@ -478,7 +509,7 @@ class WelcomeScreen extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCom
|
|||
setTimeout(checkDefault, 100);
|
||||
}
|
||||
}());
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].sendActionTelemetry(props.messageId, "default_browser");
|
||||
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].sendActionTelemetry(props.messageId, "default_browser");
|
||||
} // A special tiles.action.theme value indicates we should use the event's value vs provided value.
|
||||
|
||||
|
||||
|
@ -493,171 +524,37 @@ class WelcomeScreen extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCom
|
|||
}
|
||||
}
|
||||
|
||||
renderSecondaryCTA(position) {
|
||||
let targetElement = position ? `secondary_button_${position}` : `secondary_button`;
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: position ? `secondary-cta ${position}` : "secondary-cta"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: this.props.content[targetElement].text
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: this.props.content[targetElement].label
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
|
||||
className: "secondary",
|
||||
value: targetElement,
|
||||
onClick: this.handleAction
|
||||
})));
|
||||
}
|
||||
|
||||
renderTiles() {
|
||||
switch (this.props.content.tiles.type) {
|
||||
case "topsites":
|
||||
return this.props.topSites && this.props.topSites.data ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: `tiles-container ${this.props.content.tiles.info ? "info" : ""}`
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "tiles-topsites-section",
|
||||
name: "topsites-section",
|
||||
id: "topsites-section",
|
||||
"aria-labelledby": "helptext",
|
||||
role: "region"
|
||||
}, this.props.topSites.data.slice(0, 5).map(({
|
||||
icon,
|
||||
label,
|
||||
title
|
||||
}) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "site",
|
||||
key: icon + label,
|
||||
"aria-label": title ? title : label,
|
||||
role: "img"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "icon",
|
||||
style: icon ? {
|
||||
backgroundColor: "transparent",
|
||||
backgroundImage: `url(${icon})`
|
||||
} : {}
|
||||
}, icon ? "" : label && label[0].toUpperCase()), this.props.content.tiles.showTitles && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "host"
|
||||
}, title || label))))) : null;
|
||||
|
||||
case "theme":
|
||||
return this.props.content.tiles.data ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "tiles-theme-container"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("fieldset", {
|
||||
className: "tiles-theme-section"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: this.props.content.subtitle
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("legend", {
|
||||
className: "sr-only"
|
||||
})), this.props.content.tiles.data.map(({
|
||||
theme,
|
||||
label,
|
||||
tooltip,
|
||||
description
|
||||
}) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
key: theme + label,
|
||||
text: typeof tooltip === "object" ? tooltip : {}
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("label", {
|
||||
className: `theme${theme === this.props.activeTheme ? " selected" : ""}`,
|
||||
title: theme + label
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: typeof description === "object" ? description : {}
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("input", {
|
||||
type: "radio",
|
||||
value: theme,
|
||||
name: "theme",
|
||||
checked: theme === this.props.activeTheme,
|
||||
className: "sr-only input",
|
||||
onClick: this.handleAction,
|
||||
"data-l10n-attrs": "aria-description"
|
||||
})), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: `icon ${theme}`
|
||||
}), label && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: label
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "text"
|
||||
})))))))) : null;
|
||||
|
||||
case "video":
|
||||
return this.props.content.tiles.source ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: `tiles-media-section ${this.props.content.tiles.media_type}`
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "fade"
|
||||
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("video", {
|
||||
className: "media",
|
||||
autoPlay: "true",
|
||||
loop: "true",
|
||||
muted: "true",
|
||||
src: _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].hasDarkMode() ? this.props.content.tiles.source.dark : this.props.content.tiles.source.default
|
||||
})) : null;
|
||||
|
||||
case "image":
|
||||
return this.props.content.tiles.source ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: `${this.props.content.tiles.media_type}`
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("img", {
|
||||
src: _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].hasDarkMode() && this.props.content.tiles.source.dark ? this.props.content.tiles.source.dark : this.props.content.tiles.source.default,
|
||||
role: "presentation",
|
||||
alt: ""
|
||||
})) : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
renderStepsIndicator() {
|
||||
let steps = [];
|
||||
|
||||
for (let i = 0; i < this.props.totalNumberOfScreens; i++) {
|
||||
let className = i === this.props.order ? "current" : "";
|
||||
steps.push( /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
key: i,
|
||||
className: `indicator ${className}`
|
||||
}));
|
||||
}
|
||||
|
||||
return steps;
|
||||
}
|
||||
|
||||
renderHelpText() {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_HelpText__WEBPACK_IMPORTED_MODULE_3__["HelpText"], {
|
||||
text: this.props.content.help_text.text,
|
||||
position: this.props.content.help_text.position,
|
||||
hasImg: this.props.content.help_text.img
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
// Use the provided content or switch to an alternate one.
|
||||
const {
|
||||
content,
|
||||
topSites
|
||||
} = this.props;
|
||||
let newContent = content;
|
||||
|
||||
if (content[this.state.alternateContent]) {
|
||||
Object.assign(content, content[this.state.alternateContent]);
|
||||
newContent = { ...content,
|
||||
...content[this.state.alternateContent]
|
||||
};
|
||||
}
|
||||
|
||||
const showImportableSitesDisclaimer = content.tiles && content.tiles.type === "topsites" && topSites && topSites.showImportable;
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("main", {
|
||||
className: `screen ${this.props.id}`
|
||||
}, content.secondary_button_top ? this.renderSecondaryCTA("top") : null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: `brand-logo ${content.secondary_button_top ? "cta-top" : ""}`
|
||||
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "welcome-text"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Zap__WEBPACK_IMPORTED_MODULE_2__["Zap"], {
|
||||
hasZap: content.zap,
|
||||
text: content.title
|
||||
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: content.subtitle
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h2", null))), content.tiles ? this.renderTiles() : null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: content.primary_button ? content.primary_button.label : null
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
|
||||
className: "primary",
|
||||
value: "primary_button",
|
||||
onClick: this.handleAction
|
||||
}))), content.help_text && content.help_text.position === "default" ? this.renderHelpText() : null, content.secondary_button ? this.renderSecondaryCTA() : null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("nav", {
|
||||
className: content.help_text && content.help_text.position === "footer" || showImportableSitesDisclaimer ? "steps has-helptext" : "steps",
|
||||
"data-l10n-id": "onboarding-welcome-steps-indicator",
|
||||
"data-l10n-args": `{"current": ${parseInt(this.props.order, 10) + 1}, "total": ${this.props.totalNumberOfScreens}}`
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("br", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", null), this.renderStepsIndicator()), content.help_text && content.help_text.position === "footer" || showImportableSitesDisclaimer ? this.renderHelpText() : null);
|
||||
if (this.props.design === "proton") {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_4__["MultiStageProtonScreen"], {
|
||||
content: newContent,
|
||||
id: this.props.id,
|
||||
handleAction: this.handleAction
|
||||
});
|
||||
}
|
||||
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MultiStageScreen__WEBPACK_IMPORTED_MODULE_3__["MultiStageScreen"], {
|
||||
content: newContent,
|
||||
id: this.props.id,
|
||||
order: this.props.order,
|
||||
topSites: topSites,
|
||||
activeTheme: this.props.activeTheme,
|
||||
totalNumberOfScreens: this.props.totalNumberOfScreens,
|
||||
handleAction: this.handleAction
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -729,132 +626,6 @@ const Localized = ({
|
|||
/* 5 */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Zap", function() { return Zap; });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
|
||||
/* 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/. */
|
||||
|
||||
|
||||
const MS_STRING_PROP = "string_id";
|
||||
const ZAP_SIZE_THRESHOLD = 160;
|
||||
|
||||
function calculateZapLength() {
|
||||
let span = document.querySelector(".zap");
|
||||
|
||||
if (!span) {
|
||||
return;
|
||||
}
|
||||
|
||||
let rect = span.getBoundingClientRect();
|
||||
|
||||
if (rect && rect.width > ZAP_SIZE_THRESHOLD) {
|
||||
span.classList.add("long");
|
||||
} else {
|
||||
span.classList.add("short");
|
||||
}
|
||||
}
|
||||
|
||||
const Zap = props => {
|
||||
Object(react__WEBPACK_IMPORTED_MODULE_0__["useEffect"])(() => {
|
||||
requestAnimationFrame(() => calculateZapLength());
|
||||
});
|
||||
|
||||
if (!props.text) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (props.hasZap) {
|
||||
if (typeof props.text === "object" && props.text[MS_STRING_PROP]) {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: props.text
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", {
|
||||
className: "welcomeZap"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", {
|
||||
"data-l10n-name": "zap",
|
||||
className: "zap"
|
||||
})));
|
||||
} else if (typeof props.text === "string") {
|
||||
// Parse string to zap style last word of the props.text
|
||||
let titleArray = props.text.split(" ");
|
||||
let lastWord = `${titleArray.pop()}`;
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", {
|
||||
className: "welcomeZap"
|
||||
}, titleArray.join(" ").concat(" "), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", {
|
||||
className: "zap"
|
||||
}, lastWord));
|
||||
}
|
||||
} else {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: props.text
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", null));
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/***/ }),
|
||||
/* 6 */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HelpText", function() { return HelpText; });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
|
||||
/* 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/. */
|
||||
|
||||
|
||||
const MS_STRING_PROP = "string_id";
|
||||
const HelpText = props => {
|
||||
if (!props.text) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (props.hasImg) {
|
||||
if (typeof props.text === "object" && props.text[MS_STRING_PROP]) {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: props.text
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", {
|
||||
className: `helptext ${props.position}`
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("img", {
|
||||
"data-l10n-name": "help-img",
|
||||
className: `helptext-img ${props.position}`,
|
||||
src: props.hasImg.src,
|
||||
alt: ""
|
||||
})));
|
||||
} else if (typeof props.text === "string") {
|
||||
// Add the img at the end of the props.text
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", {
|
||||
className: `helptext ${props.position}`
|
||||
}, props.text, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("img", {
|
||||
className: `helptext-img ${props.position} end`,
|
||||
src: props.hasImg.src,
|
||||
alt: ""
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: props.text
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", {
|
||||
className: `helptext ${props.position}`
|
||||
}));
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/***/ }),
|
||||
/* 7 */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AboutWelcomeUtils", function() { return AboutWelcomeUtils; });
|
||||
|
@ -964,10 +735,343 @@ const DEFAULT_RTAMO_CONTENT = {
|
|||
}
|
||||
};
|
||||
|
||||
/***/ }),
|
||||
/* 6 */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiStageScreen", function() { return MultiStageScreen; });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
|
||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
|
||||
/* harmony import */ var _Zap__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7);
|
||||
/* harmony import */ var _HelpText__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8);
|
||||
/* harmony import */ var _MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(3);
|
||||
/* 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/. */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class MultiStageScreen extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
|
||||
renderTiles() {
|
||||
switch (this.props.content.tiles.type) {
|
||||
case "topsites":
|
||||
return this.props.topSites && this.props.topSites.data ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: `tiles-container ${this.props.content.tiles.info ? "info" : ""}`
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "tiles-topsites-section",
|
||||
name: "topsites-section",
|
||||
id: "topsites-section",
|
||||
"aria-labelledby": "helptext",
|
||||
role: "region"
|
||||
}, this.props.topSites.data.slice(0, 5).map(({
|
||||
icon,
|
||||
label,
|
||||
title
|
||||
}) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "site",
|
||||
key: icon + label,
|
||||
"aria-label": title ? title : label,
|
||||
role: "img"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "icon",
|
||||
style: icon ? {
|
||||
backgroundColor: "transparent",
|
||||
backgroundImage: `url(${icon})`
|
||||
} : {}
|
||||
}, icon ? "" : label && label[0].toUpperCase()), this.props.content.tiles.showTitles && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "host"
|
||||
}, title || label))))) : null;
|
||||
|
||||
case "theme":
|
||||
return this.props.content.tiles.data ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "tiles-theme-container"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("fieldset", {
|
||||
className: "tiles-theme-section"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_2__["Localized"], {
|
||||
text: this.props.content.subtitle
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("legend", {
|
||||
className: "sr-only"
|
||||
})), this.props.content.tiles.data.map(({
|
||||
theme,
|
||||
label,
|
||||
tooltip,
|
||||
description
|
||||
}) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_2__["Localized"], {
|
||||
key: theme + label,
|
||||
text: typeof tooltip === "object" ? tooltip : {}
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("label", {
|
||||
className: `theme${theme === this.props.activeTheme ? " selected" : ""}`,
|
||||
title: theme + label
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_2__["Localized"], {
|
||||
text: typeof description === "object" ? description : {}
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("input", {
|
||||
type: "radio",
|
||||
value: theme,
|
||||
name: "theme",
|
||||
checked: theme === this.props.activeTheme,
|
||||
className: "sr-only input",
|
||||
onClick: this.props.handleAction,
|
||||
"data-l10n-attrs": "aria-description"
|
||||
})), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: `icon ${theme}`
|
||||
}), label && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_2__["Localized"], {
|
||||
text: label
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "text"
|
||||
})))))))) : null;
|
||||
|
||||
case "video":
|
||||
return this.props.content.tiles.source ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: `tiles-media-section ${this.props.content.tiles.media_type}`
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "fade"
|
||||
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("video", {
|
||||
className: "media",
|
||||
autoPlay: "true",
|
||||
loop: "true",
|
||||
muted: "true",
|
||||
src: _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__["AboutWelcomeUtils"].hasDarkMode() ? this.props.content.tiles.source.dark : this.props.content.tiles.source.default
|
||||
})) : null;
|
||||
|
||||
case "image":
|
||||
return this.props.content.tiles.source ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: `${this.props.content.tiles.media_type}`
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("img", {
|
||||
src: _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__["AboutWelcomeUtils"].hasDarkMode() && this.props.content.tiles.source.dark ? this.props.content.tiles.source.dark : this.props.content.tiles.source.default,
|
||||
role: "presentation",
|
||||
alt: ""
|
||||
})) : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
content,
|
||||
topSites
|
||||
} = this.props;
|
||||
const showImportableSitesDisclaimer = content.tiles && content.tiles.type === "topsites" && topSites && topSites.showImportable;
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("main", {
|
||||
className: `screen ${this.props.id}`
|
||||
}, content.secondary_button_top ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_5__["SecondaryCTA"], {
|
||||
content: content,
|
||||
handleAction: this.props.handleAction,
|
||||
position: "top"
|
||||
}) : null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: `brand-logo ${content.secondary_button_top ? "cta-top" : ""}`
|
||||
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "welcome-text"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Zap__WEBPACK_IMPORTED_MODULE_3__["Zap"], {
|
||||
hasZap: content.zap,
|
||||
text: content.title
|
||||
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_2__["Localized"], {
|
||||
text: content.subtitle
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h2", null))), content.tiles ? this.renderTiles() : null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_2__["Localized"], {
|
||||
text: content.primary_button ? content.primary_button.label : null
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
|
||||
className: "primary",
|
||||
value: "primary_button",
|
||||
onClick: this.props.handleAction
|
||||
}))), content.help_text && content.help_text.position === "default" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_HelpText__WEBPACK_IMPORTED_MODULE_4__["HelpText"], {
|
||||
text: content.help_text.text,
|
||||
position: content.help_text.position,
|
||||
hasImg: content.help_text.img
|
||||
}) : null, content.secondary_button ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_5__["SecondaryCTA"], {
|
||||
content: content,
|
||||
handleAction: this.props.handleAction
|
||||
}) : null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("nav", {
|
||||
className: content.help_text && content.help_text.position === "footer" || showImportableSitesDisclaimer ? "steps has-helptext" : "steps",
|
||||
"data-l10n-id": "onboarding-welcome-steps-indicator",
|
||||
"data-l10n-args": `{"current": ${parseInt(this.props.order, 10) + 1}, "total": ${this.props.totalNumberOfScreens}}`
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("br", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_5__["StepsIndicator"], {
|
||||
order: this.props.order,
|
||||
totalNumberOfScreens: this.props.totalNumberOfScreens
|
||||
})), content.help_text && content.help_text.position === "footer" || showImportableSitesDisclaimer ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_HelpText__WEBPACK_IMPORTED_MODULE_4__["HelpText"], {
|
||||
text: content.help_text.text,
|
||||
position: content.help_text.position,
|
||||
hasImg: content.help_text.img
|
||||
}) : null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***/ }),
|
||||
/* 7 */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Zap", function() { return Zap; });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
|
||||
/* 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/. */
|
||||
|
||||
|
||||
const MS_STRING_PROP = "string_id";
|
||||
const ZAP_SIZE_THRESHOLD = 160;
|
||||
|
||||
function calculateZapLength() {
|
||||
let span = document.querySelector(".zap");
|
||||
|
||||
if (!span) {
|
||||
return;
|
||||
}
|
||||
|
||||
let rect = span.getBoundingClientRect();
|
||||
|
||||
if (rect && rect.width > ZAP_SIZE_THRESHOLD) {
|
||||
span.classList.add("long");
|
||||
} else {
|
||||
span.classList.add("short");
|
||||
}
|
||||
}
|
||||
|
||||
const Zap = props => {
|
||||
Object(react__WEBPACK_IMPORTED_MODULE_0__["useEffect"])(() => {
|
||||
requestAnimationFrame(() => calculateZapLength());
|
||||
});
|
||||
|
||||
if (!props.text) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (props.hasZap) {
|
||||
if (typeof props.text === "object" && props.text[MS_STRING_PROP]) {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: props.text
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", {
|
||||
className: "welcomeZap"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", {
|
||||
"data-l10n-name": "zap",
|
||||
className: "zap"
|
||||
})));
|
||||
} else if (typeof props.text === "string") {
|
||||
// Parse string to zap style last word of the props.text
|
||||
let titleArray = props.text.split(" ");
|
||||
let lastWord = `${titleArray.pop()}`;
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", {
|
||||
className: "welcomeZap"
|
||||
}, titleArray.join(" ").concat(" "), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", {
|
||||
className: "zap"
|
||||
}, lastWord));
|
||||
}
|
||||
} else {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: props.text
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", null));
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/***/ }),
|
||||
/* 8 */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HelpText", function() { return HelpText; });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
|
||||
/* 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/. */
|
||||
|
||||
|
||||
const MS_STRING_PROP = "string_id";
|
||||
const HelpText = props => {
|
||||
if (!props.text) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (props.hasImg) {
|
||||
if (typeof props.text === "object" && props.text[MS_STRING_PROP]) {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: props.text
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", {
|
||||
className: `helptext ${props.position}`
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("img", {
|
||||
"data-l10n-name": "help-img",
|
||||
className: `helptext-img ${props.position}`,
|
||||
src: props.hasImg.src,
|
||||
alt: ""
|
||||
})));
|
||||
} else if (typeof props.text === "string") {
|
||||
// Add the img at the end of the props.text
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", {
|
||||
className: `helptext ${props.position}`
|
||||
}, props.text, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("img", {
|
||||
className: `helptext-img ${props.position} end`,
|
||||
src: props.hasImg.src,
|
||||
alt: ""
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: props.text
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", {
|
||||
className: `helptext ${props.position}`
|
||||
}));
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/***/ }),
|
||||
/* 9 */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiStageProtonScreen", function() { return MultiStageProtonScreen; });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
|
||||
/* 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/. */
|
||||
|
||||
|
||||
class MultiStageProtonScreen extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
|
||||
render() {
|
||||
const {
|
||||
content
|
||||
} = this.props;
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("main", {
|
||||
className: `screen ${this.props.id}`
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
|
||||
className: "welcome-text"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: content.title
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: content.subtitle
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h2", null))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
|
||||
text: content.primary_button ? content.primary_button.label : null
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
|
||||
className: "primary",
|
||||
value: "primary_button",
|
||||
onClick: this.props.handleAction
|
||||
}))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***/ }),
|
||||
/* 10 */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BASE_PARAMS", function() { return BASE_PARAMS; });
|
||||
|
@ -1006,7 +1110,7 @@ function addUtmParams(url, utmTerm) {
|
|||
}
|
||||
|
||||
/***/ }),
|
||||
/* 9 */
|
||||
/* 11 */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
@ -1014,7 +1118,7 @@ __webpack_require__.r(__webpack_exports__);
|
|||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ReturnToAMO", function() { return ReturnToAMO; });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
|
||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
|
||||
/* 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,
|
||||
|
|
|
@ -358,3 +358,9 @@ body {
|
|||
opacity: 0.25; }
|
||||
.onboardingContainer .steps .indicator.current {
|
||||
opacity: 1; }
|
||||
.onboardingContainer.proton {
|
||||
background-image: url("chrome://branding/content/about-logo.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 25em; }
|
||||
.onboardingContainer.proton .welcome-text {
|
||||
margin-top: 10vw; }
|
||||
|
|
|
@ -74,6 +74,7 @@ class AboutWelcome extends React.PureComponent {
|
|||
metricsFlowUri={this.state.metricsFlowUri}
|
||||
message_id={props.messageId}
|
||||
utm_term={props.UTMTerm}
|
||||
design={props.design}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -109,8 +109,6 @@ body {
|
|||
background-image: url('chrome://activity-stream/content/data/content/assets/long-zap.svg');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.welcome-text {
|
||||
|
@ -510,4 +508,15 @@ body {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TBD: Styles specific to Proton multistage welcome UI
|
||||
&.proton {
|
||||
background-image: url('chrome://branding/content/about-logo.svg');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 25em;
|
||||
|
||||
.welcome-text {
|
||||
margin-top: 10vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { Localized } from "./MSLocalized";
|
||||
import { Zap } from "./Zap";
|
||||
import { HelpText } from "./HelpText";
|
||||
import { AboutWelcomeUtils } from "../../lib/aboutwelcome-utils";
|
||||
import { MultiStageScreen } from "./MultiStageScreen";
|
||||
import { MultiStageProtonScreen } from "./MultiStageProtonScreen";
|
||||
import {
|
||||
BASE_PARAMS,
|
||||
addUtmParams,
|
||||
|
@ -108,7 +108,7 @@ export const MultiStageAboutWelcome = props => {
|
|||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className={`outer-wrapper onboardingContainer`}>
|
||||
<div className={`outer-wrapper onboardingContainer ${props.design}`}>
|
||||
{props.screens.map(screen => {
|
||||
return index === screen.order ? (
|
||||
<WelcomeScreen
|
||||
|
@ -125,6 +125,7 @@ export const MultiStageAboutWelcome = props => {
|
|||
activeTheme={activeTheme}
|
||||
initialTheme={initialTheme}
|
||||
setActiveTheme={setActiveTheme}
|
||||
design={props.design}
|
||||
/>
|
||||
) : null;
|
||||
})}
|
||||
|
@ -133,6 +134,39 @@ export const MultiStageAboutWelcome = props => {
|
|||
);
|
||||
};
|
||||
|
||||
export const SecondaryCTA = props => {
|
||||
let targetElement = props.position
|
||||
? `secondary_button_${props.position}`
|
||||
: `secondary_button`;
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
props.position ? `secondary-cta ${props.position}` : "secondary-cta"
|
||||
}
|
||||
>
|
||||
<Localized text={props.content[targetElement].text}>
|
||||
<span />
|
||||
</Localized>
|
||||
<Localized text={props.content[targetElement].label}>
|
||||
<button
|
||||
className="secondary"
|
||||
value={targetElement}
|
||||
onClick={props.handleAction}
|
||||
/>
|
||||
</Localized>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const StepsIndicator = props => {
|
||||
let steps = [];
|
||||
for (let i = 0; i < props.totalNumberOfScreens; i++) {
|
||||
let className = i === props.order ? "current" : "";
|
||||
steps.push(<div key={i} className={`indicator ${className}`} />);
|
||||
}
|
||||
return steps;
|
||||
};
|
||||
|
||||
export class WelcomeScreen extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -230,242 +264,36 @@ export class WelcomeScreen extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
renderSecondaryCTA(position) {
|
||||
let targetElement = position
|
||||
? `secondary_button_${position}`
|
||||
: `secondary_button`;
|
||||
return (
|
||||
<div className={position ? `secondary-cta ${position}` : "secondary-cta"}>
|
||||
<Localized text={this.props.content[targetElement].text}>
|
||||
<span />
|
||||
</Localized>
|
||||
<Localized text={this.props.content[targetElement].label}>
|
||||
<button
|
||||
className="secondary"
|
||||
value={targetElement}
|
||||
onClick={this.handleAction}
|
||||
/>
|
||||
</Localized>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderTiles() {
|
||||
switch (this.props.content.tiles.type) {
|
||||
case "topsites":
|
||||
return this.props.topSites && this.props.topSites.data ? (
|
||||
<div
|
||||
className={`tiles-container ${
|
||||
this.props.content.tiles.info ? "info" : ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="tiles-topsites-section"
|
||||
name="topsites-section"
|
||||
id="topsites-section"
|
||||
aria-labelledby="helptext"
|
||||
role="region"
|
||||
>
|
||||
{this.props.topSites.data
|
||||
.slice(0, 5)
|
||||
.map(({ icon, label, title }) => (
|
||||
<div
|
||||
className="site"
|
||||
key={icon + label}
|
||||
aria-label={title ? title : label}
|
||||
role="img"
|
||||
>
|
||||
<div
|
||||
className="icon"
|
||||
style={
|
||||
icon
|
||||
? {
|
||||
backgroundColor: "transparent",
|
||||
backgroundImage: `url(${icon})`,
|
||||
}
|
||||
: {}
|
||||
}
|
||||
>
|
||||
{icon ? "" : label && label[0].toUpperCase()}
|
||||
</div>
|
||||
{this.props.content.tiles.showTitles && (
|
||||
<div className="host">{title || label}</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : null;
|
||||
case "theme":
|
||||
return this.props.content.tiles.data ? (
|
||||
<div className="tiles-theme-container">
|
||||
<div>
|
||||
<fieldset className="tiles-theme-section">
|
||||
<Localized text={this.props.content.subtitle}>
|
||||
<legend className="sr-only" />
|
||||
</Localized>
|
||||
{this.props.content.tiles.data.map(
|
||||
({ theme, label, tooltip, description }) => (
|
||||
<Localized
|
||||
key={theme + label}
|
||||
text={typeof tooltip === "object" ? tooltip : {}}
|
||||
>
|
||||
<label
|
||||
className={`theme${
|
||||
theme === this.props.activeTheme ? " selected" : ""
|
||||
}`}
|
||||
title={theme + label}
|
||||
>
|
||||
<Localized
|
||||
text={
|
||||
typeof description === "object" ? description : {}
|
||||
}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
value={theme}
|
||||
name="theme"
|
||||
checked={theme === this.props.activeTheme}
|
||||
className="sr-only input"
|
||||
onClick={this.handleAction}
|
||||
data-l10n-attrs="aria-description"
|
||||
/>
|
||||
</Localized>
|
||||
<div className={`icon ${theme}`} />
|
||||
{label && (
|
||||
<Localized text={label}>
|
||||
<div className="text" />
|
||||
</Localized>
|
||||
)}
|
||||
</label>
|
||||
</Localized>
|
||||
)
|
||||
)}
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
) : null;
|
||||
case "video":
|
||||
return this.props.content.tiles.source ? (
|
||||
<div
|
||||
className={`tiles-media-section ${this.props.content.tiles.media_type}`}
|
||||
>
|
||||
<div className="fade" />
|
||||
<video
|
||||
className="media"
|
||||
autoPlay="true"
|
||||
loop="true"
|
||||
muted="true"
|
||||
src={
|
||||
AboutWelcomeUtils.hasDarkMode()
|
||||
? this.props.content.tiles.source.dark
|
||||
: this.props.content.tiles.source.default
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
) : null;
|
||||
case "image":
|
||||
return this.props.content.tiles.source ? (
|
||||
<div className={`${this.props.content.tiles.media_type}`}>
|
||||
<img
|
||||
src={
|
||||
AboutWelcomeUtils.hasDarkMode() &&
|
||||
this.props.content.tiles.source.dark
|
||||
? this.props.content.tiles.source.dark
|
||||
: this.props.content.tiles.source.default
|
||||
}
|
||||
role="presentation"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
) : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
renderStepsIndicator() {
|
||||
let steps = [];
|
||||
for (let i = 0; i < this.props.totalNumberOfScreens; i++) {
|
||||
let className = i === this.props.order ? "current" : "";
|
||||
steps.push(<div key={i} className={`indicator ${className}`} />);
|
||||
}
|
||||
return steps;
|
||||
}
|
||||
|
||||
renderHelpText() {
|
||||
return (
|
||||
<HelpText
|
||||
text={this.props.content.help_text.text}
|
||||
position={this.props.content.help_text.position}
|
||||
hasImg={this.props.content.help_text.img}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
// Use the provided content or switch to an alternate one.
|
||||
const { content, topSites } = this.props;
|
||||
let newContent = content;
|
||||
if (content[this.state.alternateContent]) {
|
||||
Object.assign(content, content[this.state.alternateContent]);
|
||||
newContent = {
|
||||
...content,
|
||||
...content[this.state.alternateContent],
|
||||
};
|
||||
}
|
||||
|
||||
const showImportableSitesDisclaimer =
|
||||
content.tiles &&
|
||||
content.tiles.type === "topsites" &&
|
||||
topSites &&
|
||||
topSites.showImportable;
|
||||
|
||||
return (
|
||||
<main className={`screen ${this.props.id}`}>
|
||||
{content.secondary_button_top ? this.renderSecondaryCTA("top") : null}
|
||||
<div
|
||||
className={`brand-logo ${
|
||||
content.secondary_button_top ? "cta-top" : ""
|
||||
}`}
|
||||
if (this.props.design === "proton") {
|
||||
return (
|
||||
<MultiStageProtonScreen
|
||||
content={newContent}
|
||||
id={this.props.id}
|
||||
handleAction={this.handleAction}
|
||||
/>
|
||||
<div className="welcome-text">
|
||||
<Zap hasZap={content.zap} text={content.title} />
|
||||
<Localized text={content.subtitle}>
|
||||
<h2 />
|
||||
</Localized>
|
||||
</div>
|
||||
{content.tiles ? this.renderTiles() : null}
|
||||
<div>
|
||||
<Localized
|
||||
text={content.primary_button ? content.primary_button.label : null}
|
||||
>
|
||||
<button
|
||||
className="primary"
|
||||
value="primary_button"
|
||||
onClick={this.handleAction}
|
||||
/>
|
||||
</Localized>
|
||||
</div>
|
||||
{content.help_text && content.help_text.position === "default"
|
||||
? this.renderHelpText()
|
||||
: null}
|
||||
{content.secondary_button ? this.renderSecondaryCTA() : null}
|
||||
<nav
|
||||
className={
|
||||
(content.help_text && content.help_text.position === "footer") ||
|
||||
showImportableSitesDisclaimer
|
||||
? "steps has-helptext"
|
||||
: "steps"
|
||||
}
|
||||
data-l10n-id={"onboarding-welcome-steps-indicator"}
|
||||
data-l10n-args={`{"current": ${parseInt(this.props.order, 10) +
|
||||
1}, "total": ${this.props.totalNumberOfScreens}}`}
|
||||
>
|
||||
{/* These empty elements are here to help trigger the nav for screen readers. */}
|
||||
<br />
|
||||
<p />
|
||||
{this.renderStepsIndicator()}
|
||||
</nav>
|
||||
{(content.help_text && content.help_text.position === "footer") ||
|
||||
showImportableSitesDisclaimer
|
||||
? this.renderHelpText()
|
||||
: null}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<MultiStageScreen
|
||||
content={newContent}
|
||||
id={this.props.id}
|
||||
order={this.props.order}
|
||||
topSites={topSites}
|
||||
activeTheme={this.props.activeTheme}
|
||||
totalNumberOfScreens={this.props.totalNumberOfScreens}
|
||||
handleAction={this.handleAction}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/* 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 { Localized } from "./MSLocalized";
|
||||
|
||||
export class MultiStageProtonScreen extends React.PureComponent {
|
||||
render() {
|
||||
const { content } = this.props;
|
||||
|
||||
return (
|
||||
<main className={`screen ${this.props.id}`}>
|
||||
<div className="welcome-text">
|
||||
<Localized text={content.title}>
|
||||
<h1 />
|
||||
</Localized>
|
||||
<Localized text={content.subtitle}>
|
||||
<h2 />
|
||||
</Localized>
|
||||
</div>
|
||||
<div>
|
||||
<Localized
|
||||
text={content.primary_button ? content.primary_button.label : null}
|
||||
>
|
||||
<button
|
||||
className="primary"
|
||||
value="primary_button"
|
||||
onClick={this.props.handleAction}
|
||||
/>
|
||||
</Localized>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
/* 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 { AboutWelcomeUtils } from "../../lib/aboutwelcome-utils";
|
||||
import { Localized } from "./MSLocalized";
|
||||
import { Zap } from "./Zap";
|
||||
import { HelpText } from "./HelpText";
|
||||
import { SecondaryCTA, StepsIndicator } from "./MultiStageAboutWelcome";
|
||||
|
||||
export class MultiStageScreen extends React.PureComponent {
|
||||
renderTiles() {
|
||||
switch (this.props.content.tiles.type) {
|
||||
case "topsites":
|
||||
return this.props.topSites && this.props.topSites.data ? (
|
||||
<div
|
||||
className={`tiles-container ${
|
||||
this.props.content.tiles.info ? "info" : ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="tiles-topsites-section"
|
||||
name="topsites-section"
|
||||
id="topsites-section"
|
||||
aria-labelledby="helptext"
|
||||
role="region"
|
||||
>
|
||||
{this.props.topSites.data
|
||||
.slice(0, 5)
|
||||
.map(({ icon, label, title }) => (
|
||||
<div
|
||||
className="site"
|
||||
key={icon + label}
|
||||
aria-label={title ? title : label}
|
||||
role="img"
|
||||
>
|
||||
<div
|
||||
className="icon"
|
||||
style={
|
||||
icon
|
||||
? {
|
||||
backgroundColor: "transparent",
|
||||
backgroundImage: `url(${icon})`,
|
||||
}
|
||||
: {}
|
||||
}
|
||||
>
|
||||
{icon ? "" : label && label[0].toUpperCase()}
|
||||
</div>
|
||||
{this.props.content.tiles.showTitles && (
|
||||
<div className="host">{title || label}</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : null;
|
||||
case "theme":
|
||||
return this.props.content.tiles.data ? (
|
||||
<div className="tiles-theme-container">
|
||||
<div>
|
||||
<fieldset className="tiles-theme-section">
|
||||
<Localized text={this.props.content.subtitle}>
|
||||
<legend className="sr-only" />
|
||||
</Localized>
|
||||
{this.props.content.tiles.data.map(
|
||||
({ theme, label, tooltip, description }) => (
|
||||
<Localized
|
||||
key={theme + label}
|
||||
text={typeof tooltip === "object" ? tooltip : {}}
|
||||
>
|
||||
<label
|
||||
className={`theme${
|
||||
theme === this.props.activeTheme ? " selected" : ""
|
||||
}`}
|
||||
title={theme + label}
|
||||
>
|
||||
<Localized
|
||||
text={
|
||||
typeof description === "object" ? description : {}
|
||||
}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
value={theme}
|
||||
name="theme"
|
||||
checked={theme === this.props.activeTheme}
|
||||
className="sr-only input"
|
||||
onClick={this.props.handleAction}
|
||||
data-l10n-attrs="aria-description"
|
||||
/>
|
||||
</Localized>
|
||||
<div className={`icon ${theme}`} />
|
||||
{label && (
|
||||
<Localized text={label}>
|
||||
<div className="text" />
|
||||
</Localized>
|
||||
)}
|
||||
</label>
|
||||
</Localized>
|
||||
)
|
||||
)}
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
) : null;
|
||||
case "video":
|
||||
return this.props.content.tiles.source ? (
|
||||
<div
|
||||
className={`tiles-media-section ${this.props.content.tiles.media_type}`}
|
||||
>
|
||||
<div className="fade" />
|
||||
<video
|
||||
className="media"
|
||||
autoPlay="true"
|
||||
loop="true"
|
||||
muted="true"
|
||||
src={
|
||||
AboutWelcomeUtils.hasDarkMode()
|
||||
? this.props.content.tiles.source.dark
|
||||
: this.props.content.tiles.source.default
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
) : null;
|
||||
case "image":
|
||||
return this.props.content.tiles.source ? (
|
||||
<div className={`${this.props.content.tiles.media_type}`}>
|
||||
<img
|
||||
src={
|
||||
AboutWelcomeUtils.hasDarkMode() &&
|
||||
this.props.content.tiles.source.dark
|
||||
? this.props.content.tiles.source.dark
|
||||
: this.props.content.tiles.source.default
|
||||
}
|
||||
role="presentation"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
) : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { content, topSites } = this.props;
|
||||
|
||||
const showImportableSitesDisclaimer =
|
||||
content.tiles &&
|
||||
content.tiles.type === "topsites" &&
|
||||
topSites &&
|
||||
topSites.showImportable;
|
||||
|
||||
return (
|
||||
<main className={`screen ${this.props.id}`}>
|
||||
{content.secondary_button_top ? (
|
||||
<SecondaryCTA
|
||||
content={content}
|
||||
handleAction={this.props.handleAction}
|
||||
position="top"
|
||||
/>
|
||||
) : null}
|
||||
<div
|
||||
className={`brand-logo ${
|
||||
content.secondary_button_top ? "cta-top" : ""
|
||||
}`}
|
||||
/>
|
||||
<div className="welcome-text">
|
||||
<Zap hasZap={content.zap} text={content.title} />
|
||||
<Localized text={content.subtitle}>
|
||||
<h2 />
|
||||
</Localized>
|
||||
</div>
|
||||
{content.tiles ? this.renderTiles() : null}
|
||||
<div>
|
||||
<Localized
|
||||
text={content.primary_button ? content.primary_button.label : null}
|
||||
>
|
||||
<button
|
||||
className="primary"
|
||||
value="primary_button"
|
||||
onClick={this.props.handleAction}
|
||||
/>
|
||||
</Localized>
|
||||
</div>
|
||||
{content.help_text && content.help_text.position === "default" ? (
|
||||
<HelpText
|
||||
text={content.help_text.text}
|
||||
position={content.help_text.position}
|
||||
hasImg={content.help_text.img}
|
||||
/>
|
||||
) : null}
|
||||
{content.secondary_button ? (
|
||||
<SecondaryCTA
|
||||
content={content}
|
||||
handleAction={this.props.handleAction}
|
||||
/>
|
||||
) : null}
|
||||
<nav
|
||||
className={
|
||||
(content.help_text && content.help_text.position === "footer") ||
|
||||
showImportableSitesDisclaimer
|
||||
? "steps has-helptext"
|
||||
: "steps"
|
||||
}
|
||||
data-l10n-id={"onboarding-welcome-steps-indicator"}
|
||||
data-l10n-args={`{"current": ${parseInt(this.props.order, 10) +
|
||||
1}, "total": ${this.props.totalNumberOfScreens}}`}
|
||||
>
|
||||
{/* These empty elements are here to help trigger the nav for screen readers. */}
|
||||
<br />
|
||||
<p />
|
||||
<StepsIndicator
|
||||
order={this.props.order}
|
||||
totalNumberOfScreens={this.props.totalNumberOfScreens}
|
||||
/>
|
||||
</nav>
|
||||
{(content.help_text && content.help_text.position === "footer") ||
|
||||
showImportableSitesDisclaimer ? (
|
||||
<HelpText
|
||||
text={content.help_text.text}
|
||||
position={content.help_text.position}
|
||||
hasImg={content.help_text.img}
|
||||
/>
|
||||
) : null}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -191,7 +191,7 @@ module.exports = function(config) {
|
|||
"content-src/aboutwelcome/**/*.jsx": {
|
||||
statements: 62,
|
||||
lines: 60,
|
||||
functions: 83,
|
||||
functions: 75,
|
||||
branches: 50,
|
||||
},
|
||||
"content-src/components/**/*.jsx": {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import { MultiStageProtonScreen } from "content-src/aboutwelcome/components/MultiStageProtonScreen";
|
||||
import React from "react";
|
||||
import { mount } from "enzyme";
|
||||
|
||||
describe("MultiStageAboutWelcomeProton module", () => {
|
||||
describe("MultiStageAWProton component", () => {
|
||||
it("should render MultiStageProton Screen", () => {
|
||||
const SCREEN_PROPS = {
|
||||
content: {
|
||||
title: "test title",
|
||||
subtitle: "test subtitle",
|
||||
},
|
||||
};
|
||||
const wrapper = mount(<MultiStageProtonScreen {...SCREEN_PROPS} />);
|
||||
assert.ok(wrapper.exists());
|
||||
assert.equal(wrapper.find("h1").text(), "test title");
|
||||
assert.equal(wrapper.find("h2").text(), "test subtitle");
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,8 +1,11 @@
|
|||
import { GlobalOverrider } from "test/unit/utils";
|
||||
import {
|
||||
MultiStageAboutWelcome,
|
||||
SecondaryCTA,
|
||||
StepsIndicator,
|
||||
WelcomeScreen,
|
||||
} from "content-src/aboutwelcome/components/MultiStageAboutWelcome";
|
||||
import { MultiStageScreen } from "content-src/aboutwelcome/components/MultiStageScreen";
|
||||
import React from "react";
|
||||
import { shallow, mount } from "enzyme";
|
||||
import { AboutWelcomeDefaults } from "aboutwelcome/lib/AboutWelcomeDefaults.jsm";
|
||||
|
@ -30,6 +33,9 @@ describe("MultiStageAboutWelcome module", () => {
|
|||
AWSendEventTelemetry: () => {},
|
||||
AWWaitForRegionChange: () => Promise.resolve(),
|
||||
AWGetRegion: () => Promise.resolve(),
|
||||
AWIsDefaultBrowser: () => Promise.resolve("true"),
|
||||
AWWaitForMigrationClose: () => Promise.resolve(),
|
||||
AWSelectTheme: () => Promise.resolve(),
|
||||
});
|
||||
sandbox = sinon.createSandbox();
|
||||
});
|
||||
|
@ -131,6 +137,31 @@ describe("MultiStageAboutWelcome module", () => {
|
|||
assert.ok(wrapper.exists());
|
||||
});
|
||||
|
||||
it("should render secondary.top button", () => {
|
||||
let SCREEN_PROPS = {
|
||||
content: {
|
||||
title: "Step",
|
||||
secondary_button_top: {
|
||||
text: "test",
|
||||
label: "test label",
|
||||
},
|
||||
},
|
||||
position: "top",
|
||||
};
|
||||
const wrapper = mount(<SecondaryCTA {...SCREEN_PROPS} />);
|
||||
assert.ok(wrapper.find("div.secondary_button_top"));
|
||||
});
|
||||
|
||||
it("should render steps indicator", () => {
|
||||
let SCREEN_PROPS = {
|
||||
totalNumberOfScreens: 1,
|
||||
order: 0,
|
||||
};
|
||||
<StepsIndicator {...SCREEN_PROPS} />;
|
||||
const wrapper = mount(<StepsIndicator {...SCREEN_PROPS} />);
|
||||
assert.ok(wrapper.find("div.indicator"));
|
||||
});
|
||||
|
||||
it("should have a primary, secondary and secondary.top button in the rendered input", () => {
|
||||
const wrapper = mount(<WelcomeScreen {...GET_STARTED_SCREEN_PROPS} />);
|
||||
assert.ok(wrapper.find(".primary"));
|
||||
|
@ -140,6 +171,70 @@ describe("MultiStageAboutWelcome module", () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("multistagescreen tiles", () => {
|
||||
let SCREEN_PROPS = {
|
||||
content: {
|
||||
title: "test title",
|
||||
},
|
||||
totalNumberOfScreens: 1,
|
||||
order: 0,
|
||||
id: "test",
|
||||
topSites: {
|
||||
data: [],
|
||||
},
|
||||
};
|
||||
it("should render multistage Screen", () => {
|
||||
const wrapper = mount(<MultiStageScreen {...SCREEN_PROPS} />);
|
||||
assert.ok(wrapper.exists());
|
||||
});
|
||||
it("no image displayed without source", () => {
|
||||
SCREEN_PROPS.content.tiles = {
|
||||
type: "image",
|
||||
media_type: "test-img",
|
||||
};
|
||||
const wrapper = mount(<MultiStageScreen {...SCREEN_PROPS} />);
|
||||
assert.isFalse(wrapper.find("div.test-img").exists());
|
||||
});
|
||||
it("should have image displayed with source", () => {
|
||||
SCREEN_PROPS.content.tiles = {
|
||||
type: "image",
|
||||
media_type: "test-img",
|
||||
source: {
|
||||
default: "",
|
||||
},
|
||||
};
|
||||
const wrapper = mount(<MultiStageScreen {...SCREEN_PROPS} />);
|
||||
assert.ok(wrapper.find("div.test-img").exists());
|
||||
});
|
||||
it("should have video container displayed", () => {
|
||||
SCREEN_PROPS.content.tiles = {
|
||||
type: "video",
|
||||
media_type: "test-video",
|
||||
source: {
|
||||
default: "",
|
||||
},
|
||||
};
|
||||
const wrapper = mount(<MultiStageScreen {...SCREEN_PROPS} />);
|
||||
assert.ok(wrapper.find("div.test-video").exists());
|
||||
});
|
||||
it("should have topsites section displayed", () => {
|
||||
SCREEN_PROPS.content.tiles = {
|
||||
type: "topsites",
|
||||
};
|
||||
const wrapper = mount(<MultiStageScreen {...SCREEN_PROPS} />);
|
||||
assert.ok(wrapper.find("div.tiles-topsites-section").exists());
|
||||
});
|
||||
it("should have theme container displayed", () => {
|
||||
SCREEN_PROPS.content.tiles = {
|
||||
type: "theme",
|
||||
data: [],
|
||||
};
|
||||
const wrapper = mount(<MultiStageScreen {...SCREEN_PROPS} />);
|
||||
assert.ok(wrapper.find("div.tiles-theme-container").exists());
|
||||
});
|
||||
});
|
||||
|
||||
describe("theme screen", () => {
|
||||
const themeScreen = DEFAULT_WELCOME_CONTENT.screens.find(screen => {
|
||||
return screen.id === "AW_CHOOSE_THEME";
|
||||
|
@ -165,7 +260,7 @@ describe("MultiStageAboutWelcome module", () => {
|
|||
});
|
||||
|
||||
it("should select this.props.activeTheme in the rendered input", () => {
|
||||
const wrapper = shallow(<WelcomeScreen {...THEME_SCREEN_PROPS} />);
|
||||
const wrapper = shallow(<MultiStageScreen {...THEME_SCREEN_PROPS} />);
|
||||
|
||||
const selectedThemeInput = wrapper.find(".theme.selected input");
|
||||
assert.strictEqual(
|
||||
|
@ -175,7 +270,7 @@ describe("MultiStageAboutWelcome module", () => {
|
|||
});
|
||||
|
||||
it("should check this.props.activeTheme in the rendered input", () => {
|
||||
const wrapper = shallow(<WelcomeScreen {...THEME_SCREEN_PROPS} />);
|
||||
const wrapper = shallow(<MultiStageScreen {...THEME_SCREEN_PROPS} />);
|
||||
|
||||
const selectedThemeInput = wrapper.find(".theme input[checked=true]");
|
||||
assert.strictEqual(
|
||||
|
|
Загрузка…
Ссылка в новой задаче