Skip to content

Conversation

@jsoningram
Copy link
Contributor

@jsoningram jsoningram commented Dec 3, 2025

Asana Task/Github Issue: Allow requesting NTP to scroll widgets into focus

Description

Adds messaging subscription to automatically scroll to the protections report heading when the protections_scroll message is received and minor styling adjustments requested during the ship review. Late addition to this PR is the replacement of the NewBadgeIcon with a component that accepts translations.

cpm-scroll.mov

Testing Steps

To simply view the new UI and review the style edits called out in the ship review visit the preview deployment

To test the scrollto functionality…

  • Make sure you have been added to the DDG org in your Apple Developer account
  • Clone the Apple Browsers repo
  • Checkout branch michal/cpm-on-ntp-4-dialog
  • Launch Xcode (v16.4.0)
  • Select “Open Existing Project…”
  • Choose the DuckDuckGo.xcworkspace file from the Apple Browsers repo (located at the root level)
  • Find the install command from the section below titled "Temporary Branch Update"
  • Run this command in the repository directory, followed by npm install e.g.:
npm i github:duckduckgo/content-scope-scripts#57121485acd9b785b00ef89e78063e5c7e173919 && npm install
  • You’re now ready to build the app. You can verify Xcode is linked to your codebase by selecting the macOS app from the left sidebar, then opening the sidebar (top right) and check that the full path shows the expected value.
cpm-scroll

Checklist

Please tick all that apply:

  • I have tested this change locally
  • I have tested this change locally in all supported browsers
  • This change will be visible to users
  • I have added automated tests that cover this change
  • I have ensured the change is gated by config
  • This change was covered by a ship review
  • This change was covered by a tech design
  • Any dependent config has been merged

Note

Adds a subscription-triggered scroll to the Protections heading, animates counts only when in viewport, replaces the badge SVG with a translatable NewBadge component, and updates styles, strings, types, and tests.

  • Protections UI:
    • ProtectionsHeading: subscribes to protections_scroll and scrolls into view; uses refs and integrates NewBadge for cookie popup stats; minor layout tweaks.
    • useAnimatedCount: adds IntersectionObserver-based viewport awareness; snaps/continues on visibility changes; maintains last seen value.
    • animateCount: minor performance optimizations; ensures exact final value; caps and thresholds retained.
  • Components:
    • Replaces NewBadgeIcon with translatable NewBadge (NewBadge.js + NewBadge.module.css).
  • Messaging & Types:
    • Adds protections_scroll.subscribe.json and ProtectionsScrollSubscription to types/new-tab.ts.
  • Styles:
    • Tweak TickPill spacing/radius; adjust PrivacyStats info icon margin; reduce Protections block top margin.
  • i18n:
    • Adds protections_newBadge key and translations; trims tooltip copy across locales.
  • Tests:
    • Integration: verifies tooltip a11y and scroll-to heading behavior.
    • Unit: refocused animateCount tests with improved RAF/time mocks and snapshot validation.

Written by Cursor Bugbot for commit 3e6994b. This will update automatically on new commits. Configure here.

Handle undefined trackingStatus when sites are first logged. The
component now provides a safe default and reactively updates when
tracking status data arrives, fixing the issue where "no trackers
blocked" was shown initially even when trackers were actually blocked.
Updated the component to use reactive computed signals. Changes:
  1. `trackingStatus` — computed signal tracking
activity.value.trackingStatus[id]
  2. `totalTrackersBlocked` — computed signal derived from
trackingStatus
  3. `totalTrackersPillText` — computed signal that updates when the
count changes
  4. `cookiePopUpBlocked` — kept as a computed signal (removed the
.value that read it once)
1. Added `useSignalEffect`: Tracks when computed signals
(totalTrackersPillText, totalTrackersBlocked, cookiePopUpBlocked)
change.
2. Used a ref to track previous values: prevValuesRef stores the last
values to avoid unnecessary re-renders.
3. State update on change: When computed values change, update state via
setRenderKey to trigger a re-render.
4. Conditional updates: Only update state when values actually change,
reducing unnecessary re-renders.

How it works:
• useSignalEffect runs whenever the computed signals change.
• It compares current values with previous values stored in the ref.
• If values changed, it updates the ref and calls setRenderKey to force
a re-render.
• The re-render causes TickPill to display the updated values.
1. Created `activityData` computed: Tracks activity.value directly so
when normalizeData creates a new object (line 228 in
NormalizeDataProvider), this computed re-evaluates.
2. Updated all computed signals: They now depend on activityData.value
instead of activity.value directly, ensuring they re-evaluate when
activityData changes.
3. Added `useSignalEffect`: Tracks activityData changes and forces a
re-render via state update when activity.value changes.
4. Access computed values during render: Accessing .value during render
(not just in JSX) ensures Preact Signals tracks them for reactivity.

How it works:
• When trackingStatus data arrives via activity_onDataUpdate or
activity_onDataPatch, normalizeData runs
• normalizeData creates a new activity.value object (new reference)
• activityData computed detects the change and re-evaluates
• All dependent computed signals (trackingStatus, totalTrackersBlocked,
etc.) re-evaluate
• useSignalEffect runs and calls setRenderKey to force a re-render
• Component re-renders with updated TickPill values
@netlify
Copy link

netlify bot commented Dec 3, 2025

Deploy Preview for content-scope-scripts ready!

Name Link
🔨 Latest commit 3e6994b
🔍 Latest deploy log https://app.netlify.com/projects/content-scope-scripts/deploys/69320141060c3d0008013298
😎 Deploy Preview https://deploy-preview-2073--content-scope-scripts.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@jsoningram jsoningram changed the title Jingram/cpm stats on ntp with scroll jingram/cpm-stats-on-ntp-with-scroll Dec 3, 2025
@github-actions
Copy link

github-actions bot commented Dec 3, 2025

[Beta] Generated file diff

Time updated: Thu, 04 Dec 2025 21:47:39 GMT

Apple
    - apple/pages/new-tab/dist/index.css
  • apple/pages/new-tab/dist/index.js
  • apple/pages/new-tab/locales/de/new-tab.json
  • apple/pages/new-tab/locales/en/new-tab.json
  • apple/pages/new-tab/locales/es/new-tab.json
  • apple/pages/new-tab/locales/fr/new-tab.json
  • apple/pages/new-tab/locales/it/new-tab.json
  • apple/pages/new-tab/locales/nl/new-tab.json
  • apple/pages/new-tab/locales/pl/new-tab.json
  • apple/pages/new-tab/locales/pt/new-tab.json
  • apple/pages/new-tab/locales/ru/new-tab.json

File has changed

Integration
    - integration/pages/new-tab/dist/index.css
  • integration/pages/new-tab/dist/index.js
  • integration/pages/new-tab/locales/de/new-tab.json
  • integration/pages/new-tab/locales/en/new-tab.json
  • integration/pages/new-tab/locales/es/new-tab.json
  • integration/pages/new-tab/locales/fr/new-tab.json
  • integration/pages/new-tab/locales/it/new-tab.json
  • integration/pages/new-tab/locales/nl/new-tab.json
  • integration/pages/new-tab/locales/pl/new-tab.json
  • integration/pages/new-tab/locales/pt/new-tab.json
  • integration/pages/new-tab/locales/ru/new-tab.json

File has changed

Windows
    - windows/pages/new-tab/dist/index.css
  • windows/pages/new-tab/dist/index.js
  • windows/pages/new-tab/locales/de/new-tab.json
  • windows/pages/new-tab/locales/en/new-tab.json
  • windows/pages/new-tab/locales/es/new-tab.json
  • windows/pages/new-tab/locales/fr/new-tab.json
  • windows/pages/new-tab/locales/it/new-tab.json
  • windows/pages/new-tab/locales/nl/new-tab.json
  • windows/pages/new-tab/locales/pl/new-tab.json
  • windows/pages/new-tab/locales/pt/new-tab.json
  • windows/pages/new-tab/locales/ru/new-tab.json

File has changed

@github-actions
Copy link

github-actions bot commented Dec 3, 2025

Temporary Branch Update

The temporary branch has been updated with the latest changes. Below are the details:

Please use the above install command to update to the latest version.

These changes are not needed until we decide if we will keep the blocked
counts aligned with native
@jsoningram jsoningram force-pushed the jingram/cpm-stats-on-ntp-with-scroll branch from 437c876 to ae0af36 Compare December 3, 2025 23:13
@jsoningram jsoningram marked this pull request as ready for review December 4, 2025 00:24
@jsoningram jsoningram requested review from a team, mgurgel and shakyShane as code owners December 4, 2025 00:24
Bug: IntersectionObserver not set up due to ref timing

The useEffect that sets up the IntersectionObserver has [elementRef] as
its dependency, but ref objects maintain a stable identity - only
elementRef.current changes after the DOM renders. When the component
first mounts, elementRef.current is null, causing the effect to set
isInViewport(true) and return without creating the observer. Since
elementRef (the object itself) never changes, the effect won't re-run
after the DOM assigns ref.current. This defeats the viewport detection
feature, causing animations to always start immediately instead of
waiting for the element to be visible.
When the targetValue changes while the element is out of viewport, the
else-if branch (lines 96-100) correctly snaps the display to the new
target but fails to clear lastSeenValueRef. This ref retains a stale
mid-animation value from when the element exited viewport. When the
element later re-enters viewport, the condition at line 88 evaluates
true (stale value differs from new target), causing the animation to
start from the old saved value instead of the current displayed value.
This produces a visible backward jump in the counter before it animates
forward.
More linter issues
@jsoningram jsoningram force-pushed the jingram/cpm-stats-on-ntp-with-scroll branch from e826b16 to 5f50fb7 Compare December 4, 2025 17:12
@jsoningram jsoningram added this pull request to the merge queue Dec 4, 2025
Merged via the queue into main with commit 867ec4d Dec 4, 2025
17 checks passed
@jsoningram jsoningram deleted the jingram/cpm-stats-on-ntp-with-scroll branch December 4, 2025 22:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants