fix(recipe): View-Beacon ueber \$effect statt onMount
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 33s
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 33s
Live-Test auf kochwas-dev: bei Hard-Reload/Cold-Start (nicht SPA-Click) landete kein view-Eintrag in der DB. Ursache: Recipe-Page-onMount feuert vor Layout-onMount, profileStore.load() laeuft aber im Layout- onMount und macht erst danach einen async fetch — zum Zeitpunkt des Beacons war profileStore.active noch null. Loesung: Beacon im \$effect, das auf profileStore.active reagiert. viewBeaconSent-Flag verhindert duplicate POSTs wenn der User waehrend der Page-Lifetime das Profil wechselt — der ursprueglich getrackte Profil-View bleibt der "richtige" fuer dieses Page-Open. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -356,19 +356,27 @@
|
|||||||
};
|
};
|
||||||
document.addEventListener('visibilitychange', onVisibility);
|
document.addEventListener('visibilitychange', onVisibility);
|
||||||
|
|
||||||
// Track view per active profile (fire-and-forget). Skipped when no
|
|
||||||
// profile is active — we'd just be writing rows nobody can sort against later.
|
|
||||||
if (profileStore.active) {
|
|
||||||
void fetch(`/api/recipes/${data.recipe.id}/view`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'content-type': 'application/json' },
|
|
||||||
body: JSON.stringify({ profile_id: profileStore.active.id })
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => document.removeEventListener('visibilitychange', onVisibility);
|
return () => document.removeEventListener('visibilitychange', onVisibility);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Track view per active profile (fire-and-forget). Lives in $effect, not
|
||||||
|
// onMount, because profileStore.load() runs from layout's onMount and the
|
||||||
|
// child onMount fires first — at mount time profileStore.active is still
|
||||||
|
// null on cold loads. The effect re-runs once active populates, the
|
||||||
|
// viewBeaconSent flag prevents duplicate POSTs on subsequent profile
|
||||||
|
// switches within the same page instance.
|
||||||
|
let viewBeaconSent = $state(false);
|
||||||
|
$effect(() => {
|
||||||
|
if (viewBeaconSent) return;
|
||||||
|
if (!profileStore.active) return;
|
||||||
|
viewBeaconSent = true;
|
||||||
|
void fetch(`/api/recipes/${data.recipe.id}/view`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'content-type': 'application/json' },
|
||||||
|
body: JSON.stringify({ profile_id: profileStore.active.id })
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
void releaseWakeLock();
|
void releaseWakeLock();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user