1 Commits
Author SHA1 Message Date
Vincent van der Wal 8fb12d03e0 past weather 2026-07-25 10:31:11 +02:00
3 changed files with 41 additions and 7 deletions
+1 -1
View File
@@ -81,7 +81,7 @@
{location.name}
{#if location.admin1 || location.country}
<span class="font-normal text-muted-foreground">
· {#if location.admin1}{location.admin1},
· {#if location.admin1}{location.admin1},&nbsp;
{/if}{location.country ?? ''}
</span>
{/if}
@@ -154,6 +154,11 @@
fetchedData ? fetchedData.timestamps.slice(0, validLength).map((t) => t / 1000) : []
);
// Surface a note when the chosen model's ensemble stops short of the request.
let fullHours = $derived(fetchedData?.timestamps.length ?? 0);
let validDays = $derived(Math.max(0, Math.round(validLength / 24)));
let isTrimmed = $derived(!!fetchedData && validLength > 0 && validLength < fullHours - 1);
interface ChartDef {
title?: string;
subtitle?: string;
@@ -285,6 +290,30 @@
<!-- ─── Chart Area ─────────────────────────────────────────────────────────── -->
{#if isTrimmed}
<div
class="mb-4 flex items-start gap-2 rounded-md border border-amber-300/60 bg-amber-50 px-3.5 py-2.5 text-sm text-amber-800 dark:border-amber-800/50 dark:bg-amber-950/30 dark:text-amber-200"
>
<svg
class="mt-0.5 h-4 w-4 shrink-0"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
stroke-width="2"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v4m0 4h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"
/>
</svg>
<span>
This model's ensemble only reaches about <strong>{validDays} days</strong> ahead — the spread
is trimmed to its available range.
</span>
</div>
{/if}
{#if loadError}
<div
class="mb-4 rounded-md border border-destructive/50 bg-destructive/10 px-4 py-3 text-sm text-destructive"
@@ -42,11 +42,16 @@
const d = daily;
if (!d || !canExtendPast || !scrollEl || !pastBtnEl || hiddenForRef === d) return;
hiddenForRef = d;
const btn = pastBtnEl.getBoundingClientRect();
const cont = scrollEl.getBoundingClientRect();
const el = scrollEl;
const btn = pastBtnEl;
// defer to after layout so the measured positions and scroll width are final
requestAnimationFrame(() => {
const b = btn.getBoundingClientRect();
const c = el.getBoundingClientRect();
// scroll so the button's right edge sits just past the left edge (a small
// gap of extra margin keeps the first day card from hugging the edge)
scrollEl.scrollLeft += btn.right - cont.left + 6;
el.scrollLeft += b.right - c.left + 6;
});
});
function getDaylightSeconds(index: number): number {
@@ -112,7 +117,7 @@
lines up with the page content edge -->
<div
bind:this={scrollEl}
class="-mx-3 flex gap-2 overflow-x-auto px-3 pt-4 pb-8"
class="-mx-3 flex gap-2 overflow-x-auto px-3 pt-5 pb-11"
style="scrollbar-width: thin"
>
{#if daily}