Skip to content

Commit 0a20a45

Browse files
committed
Bug 1882830 - Home and newtab adding message variants for sponsored content. r=nbarrett
Differential Revision: https://phabricator.services.mozilla.com/D203297
1 parent 876de8d commit 0a20a45

File tree

27 files changed

+1010
-76
lines changed

27 files changed

+1010
-76
lines changed

browser/app/profile/firefox.js

+1
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,7 @@ pref("browser.newtabpage.activity-stream.discoverystream.spocTopsitesPlacement.e
17631763
pref("browser.newtabpage.activity-stream.discoverystream.spocSiteId", "");
17641764
pref("browser.newtabpage.activity-stream.discoverystream.ctaButtonSponsors", "");
17651765
pref("browser.newtabpage.activity-stream.discoverystream.ctaButtonVariant", "");
1766+
pref("browser.newtabpage.activity-stream.discoverystream.spocMessageVariant", "");
17661767

17671768
pref("browser.newtabpage.activity-stream.discoverystream.sendToPocket.enabled", true);
17681769

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

+14-1
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,22 @@ export class BaseContent extends React.PureComponent {
165165
const { App } = props;
166166
const { initialized, customizeMenuVisible } = App;
167167
const prefs = props.Prefs.values;
168+
const { pocketConfig } = prefs;
168169

169170
const isDiscoveryStream =
170171
props.DiscoveryStream.config && props.DiscoveryStream.config.enabled;
171172
let filteredSections = props.Sections.filter(
172173
section => section.id !== "topstories"
173174
);
174175

176+
let spocMessageVariant = "";
177+
if (
178+
props.App.locale?.startsWith("en-") &&
179+
pocketConfig?.spocMessageVariant === "variant-c"
180+
) {
181+
spocMessageVariant = pocketConfig.spocMessageVariant;
182+
}
183+
175184
const pocketEnabled =
176185
prefs["feeds.section.topstories"] && prefs["feeds.system.topstories"];
177186
const noSectionsEnabled =
@@ -218,6 +227,7 @@ export class BaseContent extends React.PureComponent {
218227
pocketRegion={pocketRegion}
219228
mayHaveSponsoredTopSites={mayHaveSponsoredTopSites}
220229
mayHaveSponsoredStories={mayHaveSponsoredStories}
230+
spocMessageVariant={spocMessageVariant}
221231
showing={customizeMenuVisible}
222232
/>
223233
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions*/}
@@ -239,7 +249,10 @@ export class BaseContent extends React.PureComponent {
239249
<div className={`body-wrapper${initialized ? " on" : ""}`}>
240250
{isDiscoveryStream ? (
241251
<ErrorBoundary className="borderless-error">
242-
<DiscoveryStreamBase locale={props.App.locale} />
252+
<DiscoveryStreamBase
253+
locale={props.App.locale}
254+
mayHaveSponsoredStories={mayHaveSponsoredStories}
255+
/>
243256
</ErrorBoundary>
244257
) : (
245258
<Sections />

browser/components/newtab/content-src/components/CollapsibleSection/CollapsibleSection.jsx

+16-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import { ErrorBoundary } from "content-src/components/ErrorBoundary/ErrorBoundary";
66
import { FluentOrText } from "content-src/components/FluentOrText/FluentOrText";
7+
import { SponsoredContentHighlight } from "../DiscoveryStreamComponents/FeatureHighlight/SponsoredContentHighlight";
78
import React from "react";
89
import { connect } from "react-redux";
910

@@ -48,7 +49,14 @@ export class _CollapsibleSection extends React.PureComponent {
4849
render() {
4950
const { isAnimating, maxHeight, menuButtonHover, showContextMenu } =
5051
this.state;
51-
const { id, collapsed, learnMore, title, subTitle } = this.props;
52+
const {
53+
id,
54+
collapsed,
55+
learnMore,
56+
title,
57+
subTitle,
58+
mayHaveSponsoredStories,
59+
} = this.props;
5260
const active = menuButtonHover || showContextMenu;
5361
let bodyStyle;
5462
if (isAnimating && !collapsed) {
@@ -91,6 +99,13 @@ export class _CollapsibleSection extends React.PureComponent {
9199
<FluentOrText message={subTitle} />
92100
</span>
93101
)}
102+
{mayHaveSponsoredStories &&
103+
this.props.spocMessageVariant === "variant-a" && (
104+
<SponsoredContentHighlight
105+
position="inset-block-start inset-inline-start"
106+
dispatch={this.props.dispatch}
107+
/>
108+
)}
94109
</h3>
95110
</div>
96111
<ErrorBoundary className="section-body-fallback">

browser/components/newtab/content-src/components/CustomizeMenu/ContentSection/ContentSection.jsx

+19
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import React from "react";
66
import { actionCreators as ac } from "common/Actions.sys.mjs";
7+
import { SafeAnchor } from "../../DiscoveryStreamComponents/SafeAnchor/SafeAnchor";
78

89
export class ContentSection extends React.PureComponent {
910
constructor(props) {
@@ -96,6 +97,7 @@ export class ContentSection extends React.PureComponent {
9697
mayHaveSponsoredStories,
9798
mayHaveRecentSaves,
9899
openPreferences,
100+
spocMessageVariant,
99101
} = this.props;
100102
const {
101103
topSitesEnabled,
@@ -254,6 +256,23 @@ export class ContentSection extends React.PureComponent {
254256
</label>
255257
</div>
256258

259+
{pocketRegion &&
260+
mayHaveSponsoredStories &&
261+
spocMessageVariant === "variant-c" && (
262+
<div className="sponsored-content-info">
263+
<div className="icon icon-help"></div>
264+
<div>
265+
Sponsored content supports our mission to build a better web.{" "}
266+
<SafeAnchor
267+
dispatch={this.props.dispatch}
268+
url="https://support.mozilla.org/kb/pocket-sponsored-stories-new-tabs"
269+
>
270+
Find out how
271+
</SafeAnchor>
272+
</div>
273+
</div>
274+
)}
275+
257276
<span className="divider" role="separator"></span>
258277

259278
<div>

browser/components/newtab/content-src/components/CustomizeMenu/CustomizeMenu.jsx

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export class _CustomizeMenu extends React.PureComponent {
7171
mayHaveSponsoredTopSites={this.props.mayHaveSponsoredTopSites}
7272
mayHaveSponsoredStories={this.props.mayHaveSponsoredStories}
7373
mayHaveRecentSaves={this.props.DiscoveryStream.recentSavesEnabled}
74+
spocMessageVariant={this.props.spocMessageVariant}
7475
dispatch={this.props.dispatch}
7576
/>
7677
</div>

browser/components/newtab/content-src/components/CustomizeMenu/_CustomizeMenu.scss

+19
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,25 @@
217217
}
218218
}
219219

220+
.sponsored-content-info {
221+
display: flex;
222+
gap: var(--space-small);
223+
font-size: var(--font-size-small);
224+
border-radius: var(--border-radius-medium);
225+
background-color: var(--newtab-element-secondary-color);
226+
padding: var(--space-small) var(--space-large);
227+
228+
.icon-help {
229+
flex-shrink: 0;
230+
color: var(--color-accent-primary);
231+
height: 20px;
232+
}
233+
234+
a {
235+
color: var(--newtab-primary-action-background);
236+
}
237+
}
238+
220239
.divider {
221240
border-top: 1px var(--newtab-border-color) solid;
222241
margin: 0 -16px;

browser/components/newtab/content-src/components/DiscoveryStreamBase/DiscoveryStreamBase.jsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ export class _DiscoveryStreamBase extends React.PureComponent {
196196
onboardingExperience={component.properties.onboardingExperience}
197197
ctaButtonSponsors={component.properties.ctaButtonSponsors}
198198
ctaButtonVariant={component.properties.ctaButtonVariant}
199+
spocMessageVariant={component.properties.spocMessageVariant}
199200
editorsPicksHeader={component.properties.editorsPicksHeader}
200201
recentSavesEnabled={this.props.DiscoveryStream.recentSavesEnabled}
201202
hideDescriptions={this.props.DiscoveryStream.hideDescriptions}
@@ -218,7 +219,7 @@ export class _DiscoveryStreamBase extends React.PureComponent {
218219
}
219220

220221
render() {
221-
const { locale } = this.props;
222+
const { locale, mayHaveSponsoredStories } = this.props;
222223
// Select layout render data by adding spocs and position to recommendations
223224
const { layoutRender } = selectLayoutRender({
224225
state: this.props.DiscoveryStream,
@@ -322,6 +323,8 @@ export class _DiscoveryStreamBase extends React.PureComponent {
322323
showPrefName={topStories.pref.feed}
323324
title={sectionTitle}
324325
subTitle={subTitle}
326+
mayHaveSponsoredStories={mayHaveSponsoredStories}
327+
spocMessageVariant={message?.properties?.spocMessageVariant}
325328
eventSource="CARDGRID"
326329
>
327330
{this.renderLayout(layoutRender)}

browser/components/newtab/content-src/components/DiscoveryStreamComponents/CardGrid/CardGrid.jsx

+2
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ export class _CardGrid extends React.PureComponent {
326326
onboardingExperience,
327327
ctaButtonSponsors,
328328
ctaButtonVariant,
329+
spocMessageVariant,
329330
widgets,
330331
recentSavesEnabled,
331332
hideDescriptions,
@@ -374,6 +375,7 @@ export class _CardGrid extends React.PureComponent {
374375
saveToPocketCard={saveToPocketCard}
375376
ctaButtonSponsors={ctaButtonSponsors}
376377
ctaButtonVariant={ctaButtonVariant}
378+
spocMessageVariant={spocMessageVariant}
377379
recommendation_id={rec.recommendation_id}
378380
/>
379381
)

browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSCard/DSCard.jsx

+33-27
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ export const DefaultMeta = ({
8686
sponsored_by_override,
8787
saveToPocketCard,
8888
ctaButtonVariant,
89+
dispatch,
90+
spocMessageVariant,
8991
}) => (
9092
<div className="meta">
9193
<div className="info-wrap">
@@ -112,6 +114,8 @@ export const DefaultMeta = ({
112114
sponsored_by_override={sponsored_by_override}
113115
cta_button_variant={ctaButtonVariant}
114116
source={source}
117+
dispatch={dispatch}
118+
spocMessageVariant={spocMessageVariant}
115119
/>
116120
)}
117121
{/* Sponsored label is normally in the way of any message.
@@ -411,39 +415,23 @@ export class _DSCard extends React.PureComponent {
411415
className={`ds-card ${compactImagesClassName} ${imageGradientClassName} ${titleLinesName} ${descLinesClassName} ${ctaButtonClassName} ${ctaButtonVariantClassName}`}
412416
ref={this.setContextMenuButtonHostRef}
413417
>
418+
<div className="img-wrapper">
419+
<DSImage
420+
extraClassNames="img"
421+
source={this.props.image_src}
422+
rawSource={this.props.raw_image_src}
423+
sizes={this.dsImageSizes}
424+
url={this.props.url}
425+
title={this.props.title}
426+
isRecentSave={isRecentSave}
427+
/>
428+
</div>
414429
<SafeAnchor
415430
className="ds-card-link"
416431
dispatch={this.props.dispatch}
417432
onLinkClick={!this.props.placeholder ? this.onLinkClick : undefined}
418433
url={this.props.url}
419434
>
420-
<div className="img-wrapper">
421-
<DSImage
422-
extraClassNames="img"
423-
source={this.props.image_src}
424-
rawSource={this.props.raw_image_src}
425-
sizes={this.dsImageSizes}
426-
url={this.props.url}
427-
title={this.props.title}
428-
isRecentSave={isRecentSave}
429-
/>
430-
</div>
431-
{ctaButtonVariant === "variant-b" && (
432-
<div className="cta-header">Shop Now</div>
433-
)}
434-
<DefaultMeta
435-
source={source}
436-
title={this.props.title}
437-
excerpt={excerpt}
438-
newSponsoredLabel={newSponsoredLabel}
439-
timeToRead={timeToRead}
440-
context={this.props.context}
441-
context_type={this.props.context_type}
442-
sponsor={this.props.sponsor}
443-
sponsored_by_override={this.props.sponsored_by_override}
444-
saveToPocketCard={saveToPocketCard}
445-
ctaButtonVariant={ctaButtonVariant}
446-
/>
447435
<ImpressionStats
448436
flightId={this.props.flightId}
449437
rows={[
@@ -460,6 +448,24 @@ export class _DSCard extends React.PureComponent {
460448
source={this.props.type}
461449
/>
462450
</SafeAnchor>
451+
{ctaButtonVariant === "variant-b" && (
452+
<div className="cta-header">Shop Now</div>
453+
)}
454+
<DefaultMeta
455+
source={source}
456+
title={this.props.title}
457+
excerpt={excerpt}
458+
newSponsoredLabel={newSponsoredLabel}
459+
timeToRead={timeToRead}
460+
context={this.props.context}
461+
context_type={this.props.context_type}
462+
sponsor={this.props.sponsor}
463+
sponsored_by_override={this.props.sponsored_by_override}
464+
saveToPocketCard={saveToPocketCard}
465+
ctaButtonVariant={ctaButtonVariant}
466+
dispatch={this.props.dispatch}
467+
spocMessageVariant={this.props.spocMessageVariant}
468+
/>
463469
{saveToPocketCard && (
464470
<div className="card-stp-button-hover-background">
465471
<div className="card-stp-button-position-wrapper">

browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSCard/_DSCard.scss

+3-3
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ $ds-card-image-gradient-solid: rgba(0, 0, 0, 100%);
131131
}
132132

133133
.ds-card-link {
134+
position: absolute;
134135
height: 100%;
135-
display: flex;
136-
flex-direction: column;
136+
width: 100%;
137137
text-decoration: none;
138138

139139
&:hover {
@@ -255,7 +255,7 @@ $ds-card-image-gradient-solid: rgba(0, 0, 0, 100%);
255255
flex-wrap: wrap;
256256
justify-content: space-between;
257257
align-items: center;
258-
column-gap: var(--space-small);
258+
gap: 0 var(--space-small);
259259
margin-top: 0;
260260
}
261261

browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSContextFooter/DSContextFooter.jsx

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* You can obtain one at http://mozilla.org/MPL/2.0/. */
44

55
import { cardContextTypes } from "../../Card/types.js";
6+
import { SponsoredContentHighlight } from "../FeatureHighlight/SponsoredContentHighlight";
67
import { CSSTransition, TransitionGroup } from "react-transition-group";
78
import { FluentOrText } from "../../FluentOrText/FluentOrText.jsx";
89
import React from "react";
@@ -82,6 +83,8 @@ export class DSContextFooter extends React.PureComponent {
8283
sponsored_by_override,
8384
cta_button_variant,
8485
source,
86+
spocMessageVariant,
87+
dispatch,
8588
} = this.props;
8689

8790
const sponsorLabel = SponsorLabel({
@@ -119,6 +122,12 @@ export class DSContextFooter extends React.PureComponent {
119122
return (
120123
<div className="story-footer">
121124
{sponsorLabel}
125+
{sponsorLabel && spocMessageVariant === "variant-b" && (
126+
<SponsoredContentHighlight
127+
dispatch={dispatch}
128+
position="inset-block-end inset-inline-start"
129+
/>
130+
)}
122131
{dsMessageLabel}
123132
</div>
124133
);

browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSContextFooter/_DSContextFooter.scss

+3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
color: var(--newtab-text-secondary-color);
33
inset-inline-start: 0;
44
margin-top: 12px;
5+
display: flex;
6+
gap: var(--space-large);
57
position: relative;
8+
pointer-events: none;
69

710
.story-sponsored-label span {
811
display: inline-block;

0 commit comments

Comments
 (0)