From 861748a059db12002f052e18464880f749fd7755 Mon Sep 17 00:00:00 2001 From: Davide Scaini Date: Wed, 13 May 2026 11:51:14 +0200 Subject: [PATCH] ActivityFeed: add title search bar with URL sync --- site/src/components/ActivityFeed.svelte | 34 +++++++++++++++++++------ 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/site/src/components/ActivityFeed.svelte b/site/src/components/ActivityFeed.svelte index 4c30284..63f4a1b 100644 --- a/site/src/components/ActivityFeed.svelte +++ b/site/src/components/ActivityFeed.svelte @@ -42,6 +42,7 @@ let datePre = 'all'; let dateFrom = ''; let dateTo = ''; + let query = ''; let shown = PAGE_SIZE; let loading = true; let loadingMore = false; @@ -87,8 +88,11 @@ (!dateFrom || a.started_at >= dateFrom) && (!dateTo || a.started_at < dateTo) ); $: filtered = sport === 'all' ? withDate : withDate.filter(a => a.sport === sport); - $: visible = filtered.slice(0, shown); - $: canShowMore = shown < filtered.length; + $: withSearch = query.trim() + ? filtered.filter(a => a.title?.toLowerCase().includes(query.trim().toLowerCase())) + : filtered; + $: visible = withSearch.slice(0, shown); + $: canShowMore = shown < withSearch.length; $: hasMore = canShowMore || pendingShards.length > 0 || feedNextPage > 0; async function loadMore() { @@ -122,12 +126,13 @@ } } - $: if (sport || datePre) shown = PAGE_SIZE; // reset pagination on filter change + $: if (sport || datePre || query) shown = PAGE_SIZE; // reset pagination on filter change $: if (mounted) { const params = new URLSearchParams(window.location.search); if (sport === 'all') params.delete('sport'); else params.set('sport', sport); if (datePre === 'all') params.delete('date'); else params.set('date', datePre); + if (!query.trim()) params.delete('q'); else params.set('q', query.trim()); const qs = params.toString(); history.replaceState(null, '', qs ? `?${qs}` : window.location.pathname); } @@ -136,6 +141,7 @@ const params = new URLSearchParams(window.location.search); sport = (params.get('sport') as Sport | 'all') ?? 'all'; datePre = params.get('date') ?? 'all'; + query = params.get('q') ?? ''; mounted = true; // Resolve the logged-in handle so we can show the owner their private activities. @@ -204,15 +210,25 @@ {/each} {#if all.length > 0} - {#if totalActivities > filtered.length} - {filtered.length} of {totalActivities} activities + {#if totalActivities > withSearch.length} + {withSearch.length} of {totalActivities} activities {:else} - {filtered.length} {filtered.length === 1 ? 'activity' : 'activities'} + {withSearch.length} {withSearch.length === 1 ? 'activity' : 'activities'} {/if} {/if} + +
+ +
+
{#each [{ value: 'all', label: 'All time' }, { value: '7d', label: '7 days' }, { value: '30d', label: '30 days' }, { value: '6mo', label: '6 months' }, ...allYears.map(y => ({ value: y, label: y }))] as d} @@ -238,8 +254,10 @@
{:else if error}

Could not load activities: {error}

-{:else if filtered.length === 0} -

No activities found.

+{:else if withSearch.length === 0} +

+ {#if query.trim()}No activities match "{query.trim()}".{:else}No activities found.{/if} +

{:else}
{#each visible as a (a.id)}