better cards, local weather codes

This commit is contained in:
Vincent van der Wal
2026-08-01 10:11:06 +02:00
parent 315d4e2bdc
commit 2f86d86165
7 changed files with 344 additions and 126 deletions
+29 -10
View File
@@ -17,6 +17,7 @@
import { type WeekForecastResult, fetchWeekForecast } from '$lib/services/weather';
import { defaultParameters } from '../../options';
import { computeDayNightWeatherCodes } from '../../utils/weather-codes';
import DailyCards from './DailyCards.svelte';
import DailyStripSticky from './DailyStripSticky.svelte';
import HourlyTable from './HourlyTable.svelte';
@@ -50,13 +51,18 @@
let enabledChartCount = $derived($storedChartLayout.filter((p) => p.variables.length > 0).length);
// Request only the hourly variables the table rows and meteograms actually
// show, so unused variables are never fetched.
let hourlyVars = $derived(
neededHourlyApiVars(
$storedVariablePrefs.table,
$storedChartLayout.flatMap((p) => p.variables)
)
);
// show, so unused variables are never fetched. weather_code is always
// included: the day cards / strip derive their day- and night-period icons
// from the hourly codes locally.
let hourlyVars = $derived([
...new Set([
...neededHourlyApiVars(
$storedVariablePrefs.table,
$storedChartLayout.flatMap((p) => p.variables)
),
'weather_code'
])
]);
// the URL is the source of truth: location comes from the load function,
// which is also correct on hydrated prerendered pages. The persisted store
@@ -129,10 +135,21 @@
daylightBands: result.daylightBands
};
// Split the hourly codes into daylight / following-night buckets so
// the night badge shows the actual night conditions instead of a
// night-styled copy of the day icon.
const parts = computeDayNightWeatherCodes(
result.hourlyTimestamps,
result.hourly.weather_code,
result.daily.sunrise,
result.daily.sunset
);
fetchedDaily = {
daily: result.daily,
timezone: result.timezone,
dailyDates: result.dailyDates
dailyDates: result.dailyDates,
dayCodes: parts.day.map((c, i) => c ?? result.daily.weather_code[i]),
nightCodes: parts.night.map((c, i) => c ?? parts.day[i] ?? result.daily.weather_code[i])
};
loading = false;
@@ -217,8 +234,10 @@
<!-- Mobile: a compact day strip and the hourly table share this wrapper, so
the strip stays stuck (collapsing as it goes) while scrolling the table
and then releases exactly at the table's bottom, freeing the meteograms.
The strip itself is hidden on md+ (the desktop cards above take over). -->
<div>
The strip itself is hidden on md+ (the desktop cards above take over).
timeline-scope hoists the strip's sentinel view-timeline so the sticky
strip (a sibling of the sentinel) can scrub its collapse from it. -->
<div style="timeline-scope: --daystrip-sentinel">
{#if fetchedDaily}
<DailyStripSticky
daily={fetchedDaily}