Skip to content

Commit 5ce4a60

Browse files
committed
One more attempt
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
1 parent 07f57ab commit 5ce4a60

File tree

1 file changed

+31
-35
lines changed
  • special-pages/pages/new-tab/app/activity/components

1 file changed

+31
-35
lines changed

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

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,15 @@ function TrackerStatus({ id, trackersFound }) {
253253
const { t } = useTypedTranslationWith(/** @type {enStrings} */ ({}));
254254
const { activity } = useContext(NormalizedDataContext);
255255

256+
// Track activity.value directly to ensure we react to any changes
257+
// When normalizeData updates activity.value (line 228 in NormalizeDataProvider),
258+
// this computed will re-evaluate because activity.value is a new object reference
259+
const activityData = useComputed(() => activity.value);
260+
256261
// Use computed to reactively track trackingStatus changes
257-
// Access activity.value directly to ensure Preact Signals tracks it properly
258-
// This ensures the component updates when trackingStatus is populated via activity_onDataUpdate
259-
// or activity_onDataPatch messages
262+
// Access activityData.value.trackingStatus[id] to ensure we track the nested property
260263
const trackingStatus = useComputed(() => {
261-
const status = activity.value.trackingStatus[id];
264+
const status = activityData.value.trackingStatus[id];
262265
// Provide default if trackingStatus hasn't been populated yet
263266
// This handles the case where a site is first logged but trackingStatus hasn't been updated
264267
return status || { totalCount: 0, trackerCompanies: [] };
@@ -276,49 +279,42 @@ function TrackerStatus({ id, trackersFound }) {
276279
count: String(count),
277280
});
278281
});
279-
const cookiePopUpBlocked = useComputed(() => activity.value.cookiePopUpBlocked?.[id]);
282+
const cookiePopUpBlocked = useComputed(() => activityData.value.cookiePopUpBlocked?.[id]);
280283

281-
// Use a ref to track previous values and state to force re-renders
284+
// Force re-render when activityData changes by tracking it with useSignalEffect
282285
// This ensures TickPill updates when trackingStatus data arrives
283-
// Initialize ref with current values to avoid false positives on first render
284-
const prevValuesRef = useRef({
285-
pillText: totalTrackersPillText.value,
286-
blocked: totalTrackersBlocked.value,
287-
cookieBlocked: !!cookiePopUpBlocked.value,
288-
});
286+
// The key insight: activityData.value changes when normalizeData creates a new object,
287+
// so tracking activityData ensures we react to any updates
289288
const [, setRenderKey] = useState(0);
290289

291-
// Track computed signal changes and update state only when values actually change
292-
// This ensures the component re-renders when trackingStatus data arrives
290+
// Track activityData changes - this computed changes when activity.value changes
291+
// which happens when normalizeData runs (line 228 in NormalizeDataProvider)
293292
useSignalEffect(() => {
294-
// Access computed values to ensure Preact Signals tracks them
295-
const currentPillText = totalTrackersPillText.value;
296-
const currentBlocked = totalTrackersBlocked.value;
297-
const currentCookieBlocked = !!cookiePopUpBlocked.value;
293+
// Access activityData.value to ensure Preact Signals tracks it
294+
// This will run whenever activity.value changes, even if trackingStatus[id]
295+
// is updated within the same normalizeData call
296+
const currentData = activityData.value;
298297

299-
const prev = prevValuesRef.current;
298+
// Access the specific properties we care about
299+
void currentData.trackingStatus[id];
300+
void currentData.cookiePopUpBlocked?.[id];
300301

301-
// Only update state if values have actually changed
302-
if (
303-
prev.pillText !== currentPillText ||
304-
prev.blocked !== currentBlocked ||
305-
prev.cookieBlocked !== currentCookieBlocked
306-
) {
307-
prevValuesRef.current = {
308-
pillText: currentPillText,
309-
blocked: currentBlocked,
310-
cookieBlocked: currentCookieBlocked,
311-
};
312-
// Update state to force re-render
313-
setRenderKey((prev) => prev + 1);
314-
}
302+
// Force re-render by updating state
303+
// This ensures the component updates when trackingStatus data arrives
304+
setRenderKey((prev) => prev + 1);
315305
});
316306

307+
// Access computed values during render to ensure Preact Signals tracks them
308+
// This is the key - accessing .value in JSX should trigger reactivity
309+
const pillText = totalTrackersPillText.value;
310+
const showTick = totalTrackersBlocked.value > 0;
311+
const showCookiePill = cookiePopUpBlocked.value;
312+
317313
return (
318314
<div class={styles.companiesIconRow} data-testid="TrackerStatus">
319315
<div class={styles.companiesText}>
320-
<TickPill text={totalTrackersPillText.value} displayTick={totalTrackersBlocked.value > 0} />
321-
{cookiePopUpBlocked.value && <TickPill text={t('activity_cookiePopUpBlocked')} />}
316+
<TickPill text={pillText} displayTick={showTick} />
317+
{showCookiePill && <TickPill text={t('activity_cookiePopUpBlocked')} />}
322318
</div>
323319
</div>
324320
);

0 commit comments

Comments
 (0)