Refactor search results with asyncDerived store

This commit refactors the search results code to use the asyncDerived store for fetching and displaying results. This simplifies and improves the overall code structure by streamlining the state management and lifecycle of search-related data. Additionally, it switches to using derived stores for displaying results and states related to searching, showing loading, error, and result states as needed.

Changes:
- Remove the manual search fetching and state management code.
- Utilize asyncDerived and derived stores to handle fetching and displaying search results.
- Update use of loading, error, and result states to check the $searchState store instead of manually managing those states.
This commit is contained in:
Nikita Galaiko 2023-03-23 15:51:38 +01:00
parent a0eeeae645
commit b7e5e2a0c8

View File

@ -2,30 +2,17 @@
import type { PageData } from './$types';
import { search, type SearchResult } from '$lib';
import { listFiles } from '$lib/sessions';
import { asyncDerived } from '@square/svelte-store';
import { formatDistanceToNow } from 'date-fns';
import { list as listDeltas, type Delta } from '$lib/deltas';
import { list as listDeltas } from '$lib/deltas';
import { CodeViewer } from '$lib/components';
import { page } from '$app/stores';
import { derived } from 'svelte/store';
export let data: PageData;
const { project } = data;
let processedResults = [] as {
doc: string;
deltas: Delta[];
filepath: string;
highlight: string[];
}[];
let stopProcessing = false;
$: query = $page.url.searchParams.get('q');
$: {
if (query && $project?.id) {
stopProcessing = true;
processedResults = [];
fetchResults($project.id, query);
}
}
const query = derived(page, (page) => page.url.searchParams.get('q'));
const fetchResultData = async ({
sessionId,
@ -48,48 +35,56 @@
};
};
const fetchResults = async (projectId: string, query: string) => {
const results = await search({ projectId, query });
stopProcessing = false;
for (const result of results.page) {
if (stopProcessing) {
processedResults = [];
stopProcessing = false;
return;
}
processedResults = [...processedResults, await fetchResultData(result)];
}
};
const { store: searchResults, state: searchState } = asyncDerived(
[query, project],
async ([query, project]) => {
if (!query || !project) return { page: [], total: 0 };
const results = await search({ projectId: project.id, query, limit: 50 });
return {
page: await Promise.all(results.page.map(fetchResultData)),
total: results.total
};
},
{ trackState: true }
);
</script>
<figure class="mx-14 flex h-full flex-col gap-2">
{#if processedResults.length > 0}
<div class="mb-10 mt-14">
<p class="mb-2 text-xl text-[#D4D4D8]">Results for "{query}"</p>
<p class="text-lg text-[#717179]">{processedResults.length} change instances</p>
</div>
{:else}
<div class="mb-10 mt-14">
<p class="mb-2 text-xl text-[#D4D4D8]">No results for "{query}"</p>
</div>
{/if}
{#if $searchState?.isLoading || $searchState?.isReloading}
<figcaption class="m-auto">
<p class="mb-2 text-xl text-[#D4D4D8]">Looking for "{$query}"...</p>
</figcaption>
{:else if $searchState?.isError}
<figcaption class="m-auto">
<p class="mb-2 text-xl text-[#D4D4D8]">Error searching for "{$query}"</p>
</figcaption>
{:else if $searchState?.isLoaded}
<figcaption class="mb-10 mt-14">
{#if $searchResults.total > 0}
<p class="mb-2 text-xl text-[#D4D4D8]">Results for "{$query}"</p>
<p class="text-lg text-[#717179]">{$searchResults.total} change instances</p>
{:else}
<p class="mb-2 text-xl text-[#D4D4D8]">No results for "{$query}"</p>
{/if}
</figcaption>
<ul class="flex-auto overflow-auto">
{#each processedResults as { doc, deltas, filepath, highlight }}
{@const timestamp = deltas[deltas.length - 1].timestampMs}
<li class="mt-6">
<div class="flex flex-col gap-2">
<p class="flex justify-between text-lg">
<span>{filepath}</span>
<span>{formatDistanceToNow(timestamp)} ago</span>
</p>
<div
class="flex-auto overflow-auto rounded-lg border border-zinc-700 bg-[#2F2F33] text-[#EBDBB2] drop-shadow-lg"
>
<CodeViewer {doc} {deltas} {filepath} paddingLines={2} {highlight} />
<ul class="flex-auto overflow-auto">
{#each $searchResults.page as { doc, deltas, filepath, highlight }}
{@const timestamp = deltas[deltas.length - 1].timestampMs}
<li class="mt-6">
<div class="flex flex-col gap-2">
<p class="flex justify-between text-lg">
<span>{filepath}</span>
<span>{formatDistanceToNow(timestamp)} ago</span>
</p>
<div
class="flex-auto overflow-auto rounded-lg border border-zinc-700 bg-[#2F2F33] text-[#EBDBB2] drop-shadow-lg"
>
<CodeViewer {doc} {deltas} {filepath} paddingLines={2} {highlight} />
</div>
</div>
</div>
</li>
{/each}
</ul>
</li>
{/each}
</ul>
{/if}
</figure>