feat: extract built-in view presets and add filter chips
This commit is contained in:
@@ -14,13 +14,14 @@
|
||||
|
||||
<ScrollArea class="h-full w-full">
|
||||
<div class="mr-2 flex flex-col gap-8 p-4">
|
||||
<BookList books={data.continueReading} title="Continue Reading" />
|
||||
<BookList books={data.recentlyAdded} title="Recently Added" />
|
||||
<BookList books={data.discover} title="Discover" />
|
||||
<BookList books={data.readAgain} title="Read Again" />
|
||||
<!-- One shelf per built-in preset, in the order they are defined -->
|
||||
{#each data.presets as preset (preset.id)}
|
||||
<BookList books={data.shelves[preset.id]} title={preset.heading} />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if data.recentlyAdded.length === 0 }
|
||||
<!-- Empty when no preset returned anything, i.e. the library has no books -->
|
||||
{#if data.presets.every((preset) => data.shelves[preset.id].length === 0)}
|
||||
<div class="flex flex-col items-center justify-center w-full h-full">
|
||||
<!-- Show a CTA to upload books if the library is empty -->
|
||||
<Empty.Root class="mb-[12vh]">
|
||||
|
||||
@@ -1,40 +1,32 @@
|
||||
import { BOOK_PRESETS, presetQuery } from '$lib/presets';
|
||||
|
||||
export async function load({ params, fetch }) {
|
||||
try {
|
||||
const continueReadingResponse = await fetch(
|
||||
`/api/books?libraries=${params.libraryId}&progress=in_progress&orderBy=last_accessed&sortOrder=desc`
|
||||
// The shelves are the built-in presets, fetched in parallel rather than
|
||||
// one after another as before.
|
||||
const responses = await Promise.all(
|
||||
BOOK_PRESETS.map(async (preset) => {
|
||||
const response = await fetch(`/api/books?${presetQuery(preset, params.libraryId)}`);
|
||||
const result = await response.json();
|
||||
return [preset.id, result['items'] ?? []] as const;
|
||||
})
|
||||
);
|
||||
let results = await continueReadingResponse.json();
|
||||
let continueReading = results['items'];
|
||||
|
||||
const discoverResponse = await fetch(
|
||||
`/api/books?libraries=${params.libraryId}&progress=unread&sortOrder=random`
|
||||
);
|
||||
results = await discoverResponse.json();
|
||||
let discover = results['items'];
|
||||
|
||||
const readAgainResponse = await fetch(
|
||||
`/api/books?libraries=${params.libraryId}&progress=read&sortOrder=random`
|
||||
);
|
||||
results = await readAgainResponse.json();
|
||||
let readAgain = results['items'];
|
||||
|
||||
const recentlyAddedResponse = await fetch(
|
||||
`/api/books?libraries=${params.libraryId}&orderBy=create_at&sortOrder=desc&progress=unread`
|
||||
);
|
||||
results = await recentlyAddedResponse.json();
|
||||
let recentlyAdded = results['items'];
|
||||
const shelves = Object.fromEntries(responses);
|
||||
|
||||
return {
|
||||
continueReading,
|
||||
discover,
|
||||
readAgain,
|
||||
recentlyAdded
|
||||
presets: BOOK_PRESETS,
|
||||
shelves
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching books from library: ', error);
|
||||
|
||||
// Same shape as the success path, so the page renders its empty state
|
||||
// instead of the caller having to guard every field. The previous
|
||||
// {status, error} return was consumed by nothing.
|
||||
return {
|
||||
status: error.status || 500,
|
||||
error: error.message
|
||||
presets: BOOK_PRESETS,
|
||||
shelves: Object.fromEntries(BOOK_PRESETS.map((preset) => [preset.id, []]))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user