Skip to content

Commit cc071f2

Browse files
committed
Bug 2011449 - Part 2: Add activation window message component. r=home-newtab-reviewers,fluent-reviewers,omc-reviewers,bolsson,frontend-codestyle-reviewers,nbarrett,emcminn
Differential Revision: https://phabricator.services.mozilla.com/D280829
1 parent 780d429 commit cc071f2

File tree

12 files changed

+1026
-4
lines changed

12 files changed

+1026
-4
lines changed

browser/components/asrouter/modules/PanelTestProvider.sys.mjs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2613,6 +2613,43 @@ const MESSAGES = () => [
26132613
},
26142614
groups: [],
26152615
},
2616+
{
2617+
id: "TEST_ACTIVATION_WINDOW_ENTER_MESSAGE",
2618+
template: "newtab_message",
2619+
content: {
2620+
messageType: "ActivationWindowMessage",
2621+
heading: "On your terms, from the start",
2622+
message:
2623+
"Every tab you open helps supports an independent internet—powered by people like you. Settle in and make Firefox your own.",
2624+
primaryButton: {
2625+
label: "Begin Customizing",
2626+
action: { type: "SHOW_PERSONALIZE" },
2627+
},
2628+
},
2629+
trigger: {
2630+
id: "newtabMessageCheck",
2631+
},
2632+
groups: [],
2633+
},
2634+
{
2635+
id: "TEST_ACTIVATION_WINDOW_EXIT_MESSAGE",
2636+
template: "newtab_message",
2637+
content: {
2638+
messageType: "ActivationWindowMessage",
2639+
heading:
2640+
"We've updated your New Tab with more content we think you'll like",
2641+
message:
2642+
"To make changes, select the pencil icon in the bottom right corner.",
2643+
primaryButton: {
2644+
label: "Got It",
2645+
action: { dismiss: true },
2646+
},
2647+
},
2648+
trigger: {
2649+
id: "newtabMessageCheck",
2650+
},
2651+
groups: [],
2652+
},
26162653
{
26172654
id: "UNIVERSAL_INFOBAR_WITH_EMBEDDED_LINKS",
26182655
content: {

browser/components/asrouter/tests/xpcshell/test_PanelTestProvider.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ add_task(async function test_PanelTestProvider() {
2828
toast_notification: 3,
2929
bookmarks_bar_button: 1,
3030
menu_message: 1,
31-
newtab_message: 2,
31+
newtab_message: 4,
3232
infobar: 1,
3333
};
3434

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
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, { useCallback } from "react";
6+
import { actionCreators as ac, actionTypes as at } from "common/Actions.mjs";
7+
8+
export function ActivationWindowMessage({
9+
dispatch,
10+
handleBlock,
11+
handleClick,
12+
handleDismiss,
13+
messageData,
14+
}) {
15+
const { content } = messageData;
16+
const hasButtons = content.primaryButton || content.secondaryButton;
17+
18+
const onDismiss = useCallback(() => {
19+
handleDismiss();
20+
handleBlock();
21+
}, [handleDismiss, handleBlock]);
22+
23+
const onPrimaryClick = useCallback(() => {
24+
handleClick("primary-button");
25+
if (content.primaryButton?.action?.dismiss) {
26+
handleDismiss();
27+
handleBlock();
28+
}
29+
30+
if (content.primaryButton?.action?.type === "SHOW_PERSONALIZE") {
31+
dispatch({ type: at.SHOW_PERSONALIZE });
32+
dispatch(ac.UserEvent({ event: "SHOW_PERSONALIZE" }));
33+
}
34+
}, [dispatch, handleClick, handleDismiss, handleBlock, content]);
35+
36+
const onSecondaryClick = useCallback(() => {
37+
handleClick("secondary-button");
38+
if (content.secondaryButton?.action?.dismiss) {
39+
handleDismiss();
40+
handleBlock();
41+
}
42+
}, [handleClick, handleDismiss, handleBlock, content]);
43+
44+
return (
45+
<aside
46+
className={
47+
hasButtons
48+
? "activation-window-message"
49+
: "activation-window-message no-buttons"
50+
}
51+
>
52+
<div className="activation-window-message-dismiss">
53+
<moz-button
54+
type="icon ghost"
55+
iconSrc="chrome://global/skin/icons/close.svg"
56+
onClick={onDismiss}
57+
data-l10n-id="newtab-activation-window-message-dismiss-button"
58+
></moz-button>
59+
</div>
60+
<div className="activation-window-message-inner">
61+
<img
62+
src={
63+
content.imageSrc ||
64+
"chrome://newtab/content/data/content/assets/kit-in-circle.svg"
65+
}
66+
alt=""
67+
role="presentation"
68+
/>
69+
<div>
70+
{content.heading &&
71+
(typeof content.heading === "string" ? (
72+
<h2>{content.heading}</h2>
73+
) : (
74+
<h2 data-l10n-id={content.heading.string_id}></h2>
75+
))}
76+
{content.message &&
77+
(typeof content.message === "string" ? (
78+
<p>{content.message}</p>
79+
) : (
80+
<p data-l10n-id={content.message.string_id}></p>
81+
))}
82+
{(content.primaryButton || content.secondaryButton) && (
83+
<moz-button-group>
84+
{content.primaryButton &&
85+
(typeof content.primaryButton.label === "string" ? (
86+
<moz-button type="primary" onClick={onPrimaryClick}>
87+
{content.primaryButton.label}
88+
</moz-button>
89+
) : (
90+
<moz-button
91+
type="primary"
92+
onClick={onPrimaryClick}
93+
data-l10n-id={content.primaryButton.label.string_id}
94+
/>
95+
))}
96+
{content.secondaryButton &&
97+
(typeof content.secondaryButton.label === "string" ? (
98+
<moz-button type="default" onClick={onSecondaryClick}>
99+
{content.secondaryButton.label}
100+
</moz-button>
101+
) : (
102+
<moz-button
103+
type="default"
104+
onClick={onSecondaryClick}
105+
data-l10n-id={content.secondaryButton.label.string_id}
106+
/>
107+
))}
108+
</moz-button-group>
109+
)}
110+
</div>
111+
</div>
112+
</aside>
113+
);
114+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
.activation-window-message {
6+
--image-size-small: 60px;
7+
--image-size-medium: 90px;
8+
--image-size-large: 120px;
9+
10+
background-color: var(--background-color-canvas);
11+
border: 2px solid var(--border-color-card);
12+
color: var(--text-color);
13+
padding: var(--space-large);
14+
border-radius: var(--border-radius-medium);
15+
margin-block: 0 var(--space-xlarge);
16+
margin-inline: auto;
17+
position: relative;
18+
19+
@media (min-width: $break-point-medium) {
20+
width: $searchbar-width-medium;
21+
}
22+
23+
@media (min-width: $break-point-large) {
24+
width: 510px;
25+
}
26+
27+
@media (min-width: $break-point-widest) {
28+
width: 720px;
29+
}
30+
31+
.activation-window-message-dismiss {
32+
position: absolute;
33+
inset-inline-end: var(--space-medium);
34+
inset-block-start: var(--space-medium);
35+
}
36+
37+
.activation-window-message-inner {
38+
display: flex;
39+
gap: var(--space-medium);
40+
align-items: flex-start;
41+
flex-direction: column;
42+
43+
img {
44+
max-width: var(--image-size-small);
45+
max-height: var(--image-size-small);
46+
object-fit: contain;
47+
align-self: start;
48+
}
49+
50+
> div {
51+
flex: 1;
52+
display: flex;
53+
flex-direction: column;
54+
padding-inline-end: var(--space-xxlarge);
55+
56+
moz-button-group {
57+
margin-block-start: var(--space-xlarge);
58+
}
59+
}
60+
61+
h2 {
62+
margin: 0;
63+
font-size: var(--font-size-large);
64+
font-weight: var(--heading-font-weight);
65+
}
66+
67+
p {
68+
margin-block: var(--space-medium) 0;
69+
color: var(--text-color-deemphasized);
70+
}
71+
}
72+
73+
@media (min-width: $break-point-large) {
74+
.activation-window-message-inner {
75+
flex-direction: row;
76+
gap: var(--space-xlarge);
77+
78+
img {
79+
max-width: var(--image-size-medium);
80+
max-height: var(--image-size-medium);
81+
}
82+
}
83+
84+
&.no-buttons .activation-window-message-inner img {
85+
max-width: var(--image-size-medium);
86+
max-height: var(--image-size-medium);
87+
}
88+
}
89+
90+
@media (min-width: $break-point-widest) {
91+
.activation-window-message-inner img {
92+
max-width: var(--image-size-large);
93+
max-height: var(--image-size-large);
94+
}
95+
}
96+
97+
moz-button-group {
98+
display: flex;
99+
gap: var(--space-small);
100+
justify-content: start;
101+
}
102+
103+
moz-button {
104+
min-width: fit-content;
105+
}
106+
}

browser/extensions/newtab/content-src/components/Base/Base.jsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { Notifications } from "content-src/components/Notifications/Notification
1919
import { TopicSelection } from "content-src/components/DiscoveryStreamComponents/TopicSelection/TopicSelection";
2020
import { DownloadMobilePromoHighlight } from "../DiscoveryStreamComponents/FeatureHighlight/DownloadMobilePromoHighlight";
2121
import { WallpaperFeatureHighlight } from "../DiscoveryStreamComponents/FeatureHighlight/WallpaperFeatureHighlight";
22+
import { ActivationWindowMessage } from "../ActivationWindowMessage/ActivationWindowMessage";
2223
import { MessageWrapper } from "content-src/components/MessageWrapper/MessageWrapper";
2324
import { selectWeatherPlacement } from "../../lib/utils";
2425

@@ -620,7 +621,8 @@ export class BaseContent extends React.PureComponent {
620621

621622
shouldShowOMCHighlight(componentId) {
622623
const messageData = this.props.Messages?.messageData;
623-
if (!messageData || Object.keys(messageData).length === 0) {
624+
const isVisible = this.props.Messages?.isVisible;
625+
if (!messageData || Object.keys(messageData).length === 0 || !isVisible) {
624626
return false;
625627
}
626628
return messageData?.content?.messageType === componentId;
@@ -918,6 +920,14 @@ export class BaseContent extends React.PureComponent {
918920
{/* Bug 1914055: Show logo regardless if search is enabled */}
919921
{!prefs.showSearch && !noSectionsEnabled && <Logo />}
920922
<div className={`body-wrapper${initialized ? " on" : ""}`}>
923+
{this.shouldShowOMCHighlight("ActivationWindowMessage") && (
924+
<MessageWrapper dispatch={this.props.dispatch}>
925+
<ActivationWindowMessage
926+
dispatch={this.props.dispatch}
927+
messageData={this.props.Messages.messageData}
928+
/>
929+
</MessageWrapper>
930+
)}
921931
{isDiscoveryStream ? (
922932
<ErrorBoundary className="borderless-error">
923933
<DiscoveryStreamBase

browser/extensions/newtab/content-src/styles/activity-stream.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ panel-item::part(button) {
149149

150150
// Components
151151
// stylelint-disable no-invalid-position-at-import-rule
152+
@import '../components/ActivationWindowMessage/ActivationWindowMessage';
152153
@import '../components/A11yLinkButton/A11yLinkButton';
153154
@import '../components/Base/Base';
154155
@import '../components/ErrorBoundary/ErrorBoundary';

0 commit comments

Comments
 (0)