Skip to content

Commit 0fcdffa

Browse files
committed
Wire up mock data and provide fallback for platforms not ready for update
1 parent d98ac17 commit 0fcdffa

File tree

18 files changed

+847
-39
lines changed

18 files changed

+847
-39
lines changed

special-pages/pages/new-tab/app/activity/NormalizeDataProvider.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import { ACTION_BURN } from '../burning/BurnProvider.js';
3636
* @property {Record<string, boolean>} favorites
3737
* @property {string[]} urls
3838
* @property {number} totalTrackers
39+
* @property {DomainActivity['cookiePopUpBlocked']} cookiePopUpBlocked
3940
*/
4041

4142
/**
@@ -52,6 +53,7 @@ export function normalizeData(prev, incoming) {
5253
trackingStatus: {},
5354
urls: [],
5455
totalTrackers: incoming.totalTrackers,
56+
cookiePopUpBlocked: null,
5557
};
5658

5759
if (shallowDiffers(prev.urls, incoming.urls)) {
@@ -64,6 +66,7 @@ export function normalizeData(prev, incoming) {
6466
const id = item.url;
6567

6668
output.favorites[id] = item.favorite;
69+
output.cookiePopUpBlocked = item.cookiePopUpBlocked;
6770

6871
/** @type {Item} */
6972
const next = {
@@ -73,6 +76,7 @@ export function normalizeData(prev, incoming) {
7376
faviconMax: item.favicon?.maxAvailableSize ?? DDG_DEFAULT_ICON_SIZE,
7477
favoriteSrc: item.favicon?.src,
7578
trackersFound: item.trackersFound,
79+
// cookiePopUpBlocked: item.cookiePopUpBlocked,
7680
};
7781
const differs = shallowDiffers(next, prev.items[id] || {});
7882
output.items[id] = differs ? next : prev.items[id] || {};
@@ -83,12 +87,14 @@ export function normalizeData(prev, incoming) {
8387
const prevItem = prev.trackingStatus[id] || {
8488
totalCount: 0,
8589
trackerCompanies: [],
90+
cookiePopUpBlocked: null,
8691
};
8792
const trackersDiffer = shallowDiffers(item.trackingStatus.trackerCompanies, prevItem.trackerCompanies);
8893
if (prevItem.totalCount !== item.trackingStatus.totalCount || trackersDiffer) {
8994
const next = {
9095
totalCount: item.trackingStatus.totalCount,
9196
trackerCompanies: [...item.trackingStatus.trackerCompanies],
97+
cookiePopUpBlocked: item.cookiePopUpBlocked,
9298
};
9399
output.trackingStatus[id] = next;
94100
} else {

special-pages/pages/new-tab/app/activity/activity.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ title: Activity
4848
"url": "https://youtube.com/watch?v=abc",
4949
"relativeTime": "Just now"
5050
}
51-
]
51+
],
52+
"cookiePopUpBlocked": true,
5253
}
5354
]
5455
}
@@ -178,4 +179,4 @@ example payload without id (for example, on history items)
178179
```
179180

180181
### `activity_burnAnimationComplete`
181-
- Sent when the burn animation completes
182+
- Sent when the burn animation completes

special-pages/pages/new-tab/app/activity/components/Activity.js

Lines changed: 166 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
import { h } from 'preact';
1+
import { h, Fragment } from 'preact';
22
import styles from './Activity.module.css';
3+
// @todo legacyProtections: `stylesLegacy` can be removed once all platforms
4+
// are ready for the new Protections Report
5+
import stylesLegacy from './ActivityLegacy.module.css';
36
import { useContext, useEffect, useRef } from 'preact/hooks';
47
import { memo } from 'preact/compat';
58
import { ActivityContext, ActivityServiceContext } from '../ActivityProvider.js';
69
import { useTypedTranslationWith } from '../../types.js';
710
import { useOnMiddleClick } from '../../utils.js';
811
import { useAdBlocking, useBatchedActivityApi, usePlatformName } from '../../settings.provider.js';
9-
import { ActivityItem } from './ActivityItem.js';
12+
import { CompanyIcon } from '../../components/CompanyIcon.js';
13+
import { Trans } from '../../../../../shared/components/TranslationsProvider.js';
14+
import { ActivityItem, ActivityItemLegacy } from './ActivityItem.js';
1015
import { ActivityBurningSignalContext, BurnProvider } from '../../burning/BurnProvider.js';
1116
import { useEnv } from '../../../../../shared/components/EnvironmentProvider.js';
1217
import { useComputed } from '@preact/signals';
@@ -54,8 +59,9 @@ export function ActivityEmptyState() {
5459
* @param {object} props
5560
* @param {boolean} props.canBurn
5661
* @param {DocumentVisibilityState} props.visibility
62+
* @param {boolean} props.shouldDisplayLegacyActivity
5763
*/
58-
export function ActivityBody({ canBurn, visibility }) {
64+
export function ActivityBody({ canBurn, visibility, shouldDisplayLegacyActivity }) {
5965
const { isReducedMotion } = useEnv();
6066
const { keys } = useContext(NormalizedDataContext);
6167
const { burning, exiting } = useContext(ActivityBurningSignalContext);
@@ -70,8 +76,33 @@ export function ActivityBody({ canBurn, visibility }) {
7076
return (
7177
<ul class={styles.activity} data-busy={busy} ref={ref} onClick={didClick}>
7278
{keys.value.map((id, _index) => {
73-
if (canBurn && !isReducedMotion) return <BurnableItem id={id} key={id} documentVisibility={visibility} />;
74-
return <RemovableItem id={id} key={id} canBurn={canBurn} documentVisibility={visibility} />;
79+
if (canBurn && !isReducedMotion) {
80+
return (
81+
<BurnableItem
82+
id={id}
83+
key={id}
84+
documentVisibility={visibility}
85+
// @todo legacyProtections:
86+
// `shouldDisplayLegacyActivity` can be removed once
87+
// all platforms are ready for the new protections
88+
// report
89+
shouldDisplayLegacyActivity={shouldDisplayLegacyActivity}
90+
/>
91+
);
92+
}
93+
94+
return (
95+
<RemovableItem
96+
id={id}
97+
key={id}
98+
canBurn={canBurn}
99+
documentVisibility={visibility}
100+
// @todo legacyProtections:
101+
// `shouldDisplayLegacyActivity` can be removed once all
102+
// platforms are ready for the new protections report
103+
shouldDisplayLegacyActivity={shouldDisplayLegacyActivity}
104+
/>
105+
);
75106
})}
76107
</ul>
77108
);
@@ -110,16 +141,25 @@ const BurnableItem = memo(
110141
* @param {object} props
111142
* @param {string} props.id
112143
* @param {'visible' | 'hidden'} props.documentVisibility
144+
* @param {boolean} props.shouldDisplayLegacyActivity
113145
*/
114-
function BurnableItem({ id, documentVisibility }) {
146+
function BurnableItem({ id, documentVisibility, shouldDisplayLegacyActivity }) {
115147
const { activity } = useContext(NormalizedDataContext);
116148
const item = useComputed(() => activity.value.items[id]);
149+
117150
if (!item.value) {
118151
return null;
119152
}
153+
154+
// @todo legacyProtections: Once all platforms are ready for the new
155+
// protections report we can use `ActivityItem`
156+
const ActivityItemComponent = shouldDisplayLegacyActivity
157+
? ActivityItemLegacy
158+
: ActivityItem;
159+
120160
return (
121161
<ActivityItemAnimationWrapper url={id}>
122-
<ActivityItem
162+
<ActivityItemComponent
123163
title={item.value.title}
124164
url={id}
125165
favoriteSrc={item.value.favoriteSrc}
@@ -128,9 +168,22 @@ const BurnableItem = memo(
128168
canBurn={true}
129169
documentVisibility={documentVisibility}
130170
>
131-
<TrackerStatus id={id} trackersFound={item.value.trackersFound} />
171+
{shouldDisplayLegacyActivity ? (
172+
// @todo legacyProtections: `TrackerStatusLegacy` and
173+
// supporting prop can be removed once all platforms are
174+
// ready for the new protections report
175+
<TrackerStatusLegacy
176+
id={id}
177+
trackersFound={item.value.trackersFound}
178+
/>
179+
) : (
180+
<TrackerStatus
181+
id={id}
182+
trackersFound={item.value.trackersFound}
183+
/>
184+
)}
132185
<HistoryItems id={id} />
133-
</ActivityItem>
186+
</ActivityItemComponent>
134187
</ActivityItemAnimationWrapper>
135188
);
136189
},
@@ -142,8 +195,9 @@ const RemovableItem = memo(
142195
* @param {string} props.id
143196
* @param {boolean} props.canBurn
144197
* @param {"visible" | "hidden"} props.documentVisibility
198+
* @param {boolean} props.shouldDisplayLegacyActivity
145199
*/
146-
function RemovableItem({ id, canBurn, documentVisibility }) {
200+
function RemovableItem({ id, canBurn, documentVisibility, shouldDisplayLegacyActivity }) {
147201
const { activity } = useContext(NormalizedDataContext);
148202
const item = useComputed(() => activity.value.items[id]);
149203
if (!item.value) {
@@ -153,8 +207,15 @@ const RemovableItem = memo(
153207
</p>
154208
);
155209
}
210+
211+
// @todo legacyProtections: Once all platforms are ready for the new
212+
// protections report we can use `ActivityItem`
213+
const ActivityItemComponent = shouldDisplayLegacyActivity
214+
? ActivityItemLegacy
215+
: ActivityItem;
216+
156217
return (
157-
<ActivityItem
218+
<ActivityItemComponent
158219
title={item.value.title}
159220
url={id}
160221
favoriteSrc={item.value.favoriteSrc}
@@ -163,9 +224,22 @@ const RemovableItem = memo(
163224
canBurn={canBurn}
164225
documentVisibility={documentVisibility}
165226
>
166-
<TrackerStatus id={id} trackersFound={item.value.trackersFound} />
227+
{shouldDisplayLegacyActivity ? (
228+
// @todo legacyProtections: `TrackerStatusLegacy` and
229+
// supporting prop can be removed once all platforms are
230+
// ready for the new protections report
231+
<TrackerStatusLegacy
232+
id={id}
233+
trackersFound={item.value.trackersFound}
234+
/>
235+
) : (
236+
<TrackerStatus
237+
id={id}
238+
trackersFound={item.value.trackersFound}
239+
/>
240+
)}
167241
<HistoryItems id={id} />
168-
</ActivityItem>
242+
</ActivityItemComponent>
169243
);
170244
},
171245
);
@@ -180,7 +254,8 @@ function TrackerStatus({ id, trackersFound }) {
180254
const { t } = useTypedTranslationWith(/** @type {enStrings} */ ({}));
181255
const { activity } = useContext(NormalizedDataContext);
182256
const status = useComputed(() => activity.value.trackingStatus[id]);
183-
const {totalCount, trackerCompanies, cookiePopUpBlocked} = status.value;
257+
const cookiePopUpBlocked = useComputed(() => activity.value.cookiePopUpBlocked);
258+
const {totalCount, trackerCompanies} = status.value;
184259
const other = trackerCompanies.slice(DDG_MAX_TRACKER_ICONS - 1);
185260
const adBlocking = useAdBlocking();
186261

@@ -195,12 +270,10 @@ function TrackerStatus({ id, trackersFound }) {
195270
}
196271

197272
if (totalCount === 0) {
198-
let text;
199-
if (trackersFound) {
200-
text = adBlocking ? t('activity_no_adsAndTrackers_blocked') : t('activity_no_trackers_blocked');
201-
} else {
202-
text = adBlocking ? t('activity_no_adsAndTrackers') : t('activity_no_trackers');
203-
}
273+
const text = trackersFound
274+
? t('activity_no_trackers_blocked')
275+
: t('activity_no_trackers')
276+
204277
return (
205278
<p class={styles.companiesIconRow} data-testid="TrackerStatus">
206279
<TickPill text={text} displayTick={false}/>
@@ -228,6 +301,67 @@ function TrackerStatus({ id, trackersFound }) {
228301
);
229302
}
230303

304+
// @todo legacyProtections: `TrackerStatusLegacy` can be removed once all
305+
// platforms are ready for the new protections report
306+
307+
/**
308+
* @param {object} props
309+
* @param {string} props.id
310+
* @param {boolean} props.trackersFound
311+
*/
312+
function TrackerStatusLegacy({ id, trackersFound }) {
313+
const { t } = useTypedTranslationWith(/** @type {enStrings} */ ({}));
314+
const { activity } = useContext(NormalizedDataContext);
315+
const status = useComputed(() => activity.value.trackingStatus[id]);
316+
const other = status.value.trackerCompanies.slice(DDG_MAX_TRACKER_ICONS - 1);
317+
const companyIconsMax = other.length === 0 ? DDG_MAX_TRACKER_ICONS : DDG_MAX_TRACKER_ICONS - 1;
318+
const adBlocking = useAdBlocking();
319+
320+
const icons = status.value.trackerCompanies.slice(0, companyIconsMax).map((item, _index) => {
321+
return <CompanyIcon displayName={item.displayName} key={item} />;
322+
});
323+
324+
let otherIcon = null;
325+
if (other.length > 0) {
326+
const title = other.map((item) => item.displayName).join('\n');
327+
otherIcon = (
328+
<span title={title} class={stylesLegacy.otherIcon}>
329+
+{other.length}
330+
</span>
331+
);
332+
}
333+
334+
if (status.value.totalCount === 0) {
335+
let text;
336+
if (trackersFound) {
337+
text = adBlocking ? t('activity_no_adsAndTrackers_blocked') : t('activity_no_trackers_blocked');
338+
} else {
339+
text = adBlocking ? t('activity_no_adsAndTrackers') : t('activity_no_trackers');
340+
}
341+
return (
342+
<p class={stylesLegacy.companiesIconRow} data-testid="TrackerStatus">
343+
{text}
344+
</p>
345+
);
346+
}
347+
348+
return (
349+
<div class={stylesLegacy.companiesIconRow} data-testid="TrackerStatus">
350+
<div class={stylesLegacy.companiesIcons}>
351+
{icons}
352+
{otherIcon}
353+
</div>
354+
<div class={stylesLegacy.companiesText}>
355+
{adBlocking ? (
356+
<Trans str={t('activity_countBlockedAdsAndTrackersPlural', { count: String(status.value.totalCount) })} values={{}} />
357+
) : (
358+
<Trans str={t('activity_countBlockedPluralLegacy', { count: String(status.value.totalCount) })} values={{}} />
359+
)}
360+
</div>
361+
</div>
362+
);
363+
}
364+
231365
/**
232366
* @param {object} props
233367
* @param {import("preact").ComponentChild} props.children
@@ -261,8 +395,9 @@ export function ActivityConfigured({ children }) {
261395
* ```
262396
* @param {object} props
263397
* @param {boolean} props.showBurnAnimation
398+
* @param {boolean} props.shouldDisplayLegacyActivity
264399
*/
265-
export function ActivityConsumer({ showBurnAnimation }) {
400+
export function ActivityConsumer({ showBurnAnimation, shouldDisplayLegacyActivity }) {
266401
const { state } = useContext(ActivityContext);
267402
const service = useContext(ActivityServiceContext);
268403
const platformName = usePlatformName();
@@ -272,7 +407,11 @@ export function ActivityConsumer({ showBurnAnimation }) {
272407
return (
273408
<SignalStateProvider>
274409
<ActivityConfigured>
275-
<ActivityBody canBurn={false} visibility={visibility} />
410+
<ActivityBody
411+
canBurn={false}
412+
visibility={visibility}
413+
shouldDisplayLegacyActivity={shouldDisplayLegacyActivity}
414+
/>
276415
</ActivityConfigured>
277416
</SignalStateProvider>
278417
);
@@ -281,7 +420,11 @@ export function ActivityConsumer({ showBurnAnimation }) {
281420
<SignalStateProvider>
282421
<BurnProvider service={service} showBurnAnimation={showBurnAnimation}>
283422
<ActivityConfigured>
284-
<ActivityBody canBurn={true} visibility={visibility} />
423+
<ActivityBody
424+
canBurn={true}
425+
visibility={visibility}
426+
shouldDisplayLegacyActivity={shouldDisplayLegacyActivity}
427+
/>
285428
</ActivityConfigured>
286429
</BurnProvider>
287430
</SignalStateProvider>

0 commit comments

Comments
 (0)