diff --git a/src/client/src/routes/+page.svelte b/src/client/src/routes/+page.svelte index dec6c13..9b0084e 100644 --- a/src/client/src/routes/+page.svelte +++ b/src/client/src/routes/+page.svelte @@ -183,11 +183,15 @@ : selectedStoreIds.has(store.id) ? 'text-text-primary' : 'text-text-tertiary'}">{store.name} - {#if isBroken} - failing - {:else if store.last_scrape_ok === null} - untested - {/if} + + {#if isBroken} + failing + {:else if store.last_scrape_ok === null} + untested + {:else if store.avg_duration_ms} + ~{store.avg_duration_ms}ms + {/if} + {/each} diff --git a/src/client/src/routes/results/+page.svelte b/src/client/src/routes/results/+page.svelte index 134f33a..fe8ef6d 100644 --- a/src/client/src/routes/results/+page.svelte +++ b/src/client/src/routes/results/+page.svelte @@ -123,6 +123,37 @@ excludedStores = next; } + function retryStore(storeId, storeName) { + // Mark store as searching again + storeProgress = storeProgress.map((s) => + s.id === storeId ? { ...s, status: 'searching', error: null, resultCount: 0, duration: 0 } : s + ); + + // Remove old results from this store + results = results.filter((r) => r.storeId !== storeId); + + // Re-search just this store + searchProductsStream(query, { stores: String(storeId) }, (event) => { + switch (event.type) { + case 'store_complete': + results = [...results, ...event.results]; + storeProgress = storeProgress.map((s) => + s.id === event.storeId + ? { ...s, status: 'done', resultCount: event.resultCount, duration: event.duration } + : s + ); + break; + case 'store_error': + storeProgress = storeProgress.map((s) => + s.id === event.storeId + ? { ...s, status: 'error', error: event.error, duration: event.duration } + : s + ); + break; + } + }); + } + let shareMessage = $state(''); async function handleShare() { @@ -221,14 +252,17 @@