fix(fitness/stats): wrap streamed muscle heatmap in {#await}
The $state + $effect pattern I used for the muscle heatmap in
bb0895c didn't propagate the streamed promise into the component's
internal $derived(data.totals) chain — the hover counts stayed at
zero even after the data arrived.
Switch just the heatmap to an {#await} block so it mounts once with
the fully-resolved object. The nutrition card shells, periods, and
shared periods keep their $state pattern because the card templates
read individual fields directly (which gracefully fall through to
the "—" branches while pending) and re-rendering once the value
arrives is fine.
Also drops the two reverted commits for the set-subfield projection
(4d1fed6, fe8d036); those are replaced later with a safer narrowing
that keeps whole set objects.
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "homepage",
|
"name": "homepage",
|
||||||
"version": "1.46.19",
|
"version": "1.46.20",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -120,20 +120,17 @@
|
|||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
// Streamed panels: render empty shells on SSR/initial hydrate, then fill
|
// Streamed panels. nutrition / periods resolve through $state so the card
|
||||||
// in once the server-sent promise resolves. Defaults match the previous
|
// shells render immediately with "—" placeholders; muscle heatmap is
|
||||||
// error-fallback shapes so the existing `!= null` checks cascade to the
|
// wrapped in {#await} below instead because its internal $derived chain
|
||||||
// "—" branches while the data is in flight.
|
// needs the full resolved object in one shot to render correctly.
|
||||||
/** @type {any} */
|
/** @type {any} */
|
||||||
let ns = $state({});
|
let ns = $state({});
|
||||||
/** @type {{ weeks: any[]; totals: any; muscleGroups: any[] }} */
|
|
||||||
let muscleHeatmapData = $state({ weeks: [], totals: {}, muscleGroups: [] });
|
|
||||||
/** @type {any[]} */
|
/** @type {any[]} */
|
||||||
let periodsData = $state([]);
|
let periodsData = $state([]);
|
||||||
/** @type {any[]} */
|
/** @type {any[]} */
|
||||||
let sharedPeriodsData = $state([]);
|
let sharedPeriodsData = $state([]);
|
||||||
$effect(() => { Promise.resolve(data.nutritionStats).then(v => { ns = v ?? {}; }); });
|
$effect(() => { Promise.resolve(data.nutritionStats).then(v => { ns = v ?? {}; }); });
|
||||||
$effect(() => { Promise.resolve(data.muscleHeatmap).then(v => { muscleHeatmapData = v ?? { weeks: [], totals: {}, muscleGroups: [] }; }); });
|
|
||||||
$effect(() => { Promise.resolve(data.periods).then(v => { periodsData = v ?? []; }); });
|
$effect(() => { Promise.resolve(data.periods).then(v => { periodsData = v ?? []; }); });
|
||||||
$effect(() => { Promise.resolve(data.sharedPeriods).then(v => { sharedPeriodsData = v ?? []; }); });
|
$effect(() => { Promise.resolve(data.sharedPeriods).then(v => { sharedPeriodsData = v ?? []; }); });
|
||||||
|
|
||||||
@@ -500,7 +497,9 @@
|
|||||||
|
|
||||||
<div class="section-block muscle-heatmap-block">
|
<div class="section-block muscle-heatmap-block">
|
||||||
<h2 class="section-title">{t('muscle_balance', lang)}</h2>
|
<h2 class="section-title">{t('muscle_balance', lang)}</h2>
|
||||||
<MuscleHeatmap data={muscleHeatmapData} />
|
{#await data.muscleHeatmap then muscleHeatmap}
|
||||||
|
<MuscleHeatmap data={muscleHeatmap} />
|
||||||
|
{/await}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user