Feed date filter: early-stop global feed load, fix cross-date validation, show Loading while fetching
- Stop fetching combined-feed pages once the oldest activity in a batch predates the from-date (feed is newest-first, so everything needed is already loaded) - Show "Loading…" instead of "No activities found" while eager-load is in progress - Constrain From max to customTo (or today) and To min to customFrom so the range can't be inverted via the date pickers
This commit is contained in:
@@ -161,6 +161,8 @@
|
|||||||
$: if ((query.trim() || customFrom || customTo || datePre !== 'all') && feedNextPage > 0 && !loadingAllFeedPages) {
|
$: if ((query.trim() || customFrom || customTo || datePre !== 'all') && feedNextPage > 0 && !loadingAllFeedPages) {
|
||||||
loadingAllFeedPages = true;
|
loadingAllFeedPages = true;
|
||||||
(async () => {
|
(async () => {
|
||||||
|
// Snapshot at loop start — customFrom may change while we're fetching.
|
||||||
|
const fromFilter = customFrom;
|
||||||
while (feedNextPage > 0) {
|
while (feedNextPage > 0) {
|
||||||
const page = feedNextPage;
|
const page = feedNextPage;
|
||||||
feedNextPage = page < feedTotalPages ? page + 1 : 0;
|
feedNextPage = page < feedTotalPages ? page + 1 : 0;
|
||||||
@@ -171,6 +173,12 @@
|
|||||||
all = [...existing.values()].sort((a, b) =>
|
all = [...existing.values()].sort((a, b) =>
|
||||||
(b.started_at ?? '').localeCompare(a.started_at ?? ''),
|
(b.started_at ?? '').localeCompare(a.started_at ?? ''),
|
||||||
);
|
);
|
||||||
|
// Feed is sorted newest-first. Once the oldest activity in this page
|
||||||
|
// predates our from-filter, everything needed is already loaded.
|
||||||
|
if (fromFilter && fresh.length > 0) {
|
||||||
|
const oldest = fresh.reduce((m, a) => (a.started_at ?? '') < (m.started_at ?? '') ? a : m);
|
||||||
|
if ((oldest.started_at ?? '') < fromFilter) { feedNextPage = 0; break; }
|
||||||
|
}
|
||||||
} catch { /* ignore — partial results still useful */ }
|
} catch { /* ignore — partial results still useful */ }
|
||||||
}
|
}
|
||||||
loadingAllFeedPages = false;
|
loadingAllFeedPages = false;
|
||||||
@@ -260,7 +268,7 @@
|
|||||||
<input
|
<input
|
||||||
type="date"
|
type="date"
|
||||||
bind:value={customFrom}
|
bind:value={customFrom}
|
||||||
max={today}
|
max={customTo || today}
|
||||||
on:change={() => { datePre = 'all'; }}
|
on:change={() => { datePre = 'all'; }}
|
||||||
class="bg-transparent text-white text-sm focus:outline-none [color-scheme:dark]"
|
class="bg-transparent text-white text-sm focus:outline-none [color-scheme:dark]"
|
||||||
/>
|
/>
|
||||||
@@ -270,6 +278,7 @@
|
|||||||
<input
|
<input
|
||||||
type="date"
|
type="date"
|
||||||
bind:value={customTo}
|
bind:value={customTo}
|
||||||
|
min={customFrom}
|
||||||
max={today}
|
max={today}
|
||||||
on:change={() => { datePre = 'all'; }}
|
on:change={() => { datePre = 'all'; }}
|
||||||
class="bg-transparent text-white text-sm focus:outline-none [color-scheme:dark]"
|
class="bg-transparent text-white text-sm focus:outline-none [color-scheme:dark]"
|
||||||
@@ -332,7 +341,7 @@
|
|||||||
<p class="text-red-400 text-center py-12">Could not load activities: {error}</p>
|
<p class="text-red-400 text-center py-12">Could not load activities: {error}</p>
|
||||||
{:else if withSearch.length === 0}
|
{:else if withSearch.length === 0}
|
||||||
<p class="text-zinc-500 text-center py-12">
|
<p class="text-zinc-500 text-center py-12">
|
||||||
{#if query.trim()}No activities match "{query.trim()}".{:else}No activities found.{/if}
|
{#if loadingAllFeedPages || loadingAllShards}Loading…{:else if query.trim()}No activities match "{query.trim()}".{:else}No activities found.{/if}
|
||||||
</p>
|
</p>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
|
|||||||
Reference in New Issue
Block a user