refactor: merge onDeck and ongoingBooks into single "continue reading" carousel
Some checks failed
Build, Push & Deploy / deploy (push) Has been cancelled
Some checks failed
Build, Push & Deploy / deploy (push) Has been cancelled
Uses /books/ongoing as single source for Stripstream, displayed with featured header style. Removes separate "up next" section. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,12 +6,24 @@ interface HomeContentProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function HomeContent({ data }: HomeContentProps) {
|
export function HomeContent({ data }: HomeContentProps) {
|
||||||
|
// Merge onDeck (next unread per series) and ongoingBooks (currently reading),
|
||||||
|
// deduplicate by id, onDeck first
|
||||||
|
const continueReading = (() => {
|
||||||
|
const items = [...(data.onDeck ?? []), ...(data.ongoingBooks ?? [])];
|
||||||
|
const seen = new Set<string>();
|
||||||
|
return items.filter((item) => {
|
||||||
|
if (seen.has(item.id)) return false;
|
||||||
|
seen.add(item.id);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-10 pb-2">
|
<div className="space-y-10 pb-2">
|
||||||
{data.ongoingBooks && data.ongoingBooks.length > 0 && (
|
{continueReading.length > 0 && (
|
||||||
<MediaRow
|
<MediaRow
|
||||||
titleKey="home.sections.continue_reading"
|
titleKey="home.sections.continue_reading"
|
||||||
items={data.ongoingBooks}
|
items={continueReading}
|
||||||
iconName="BookOpen"
|
iconName="BookOpen"
|
||||||
featuredHeader
|
featuredHeader
|
||||||
/>
|
/>
|
||||||
@@ -33,14 +45,6 @@ export function HomeContent({ data }: HomeContentProps) {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{data.onDeck && data.onDeck.length > 0 && (
|
|
||||||
<MediaRow
|
|
||||||
titleKey="home.sections.up_next"
|
|
||||||
items={data.onDeck}
|
|
||||||
iconName="Clock"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{data.latestSeries && data.latestSeries.length > 0 && (
|
{data.latestSeries && data.latestSeries.length > 0 && (
|
||||||
<MediaRow
|
<MediaRow
|
||||||
titleKey="home.sections.latest_series"
|
titleKey="home.sections.latest_series"
|
||||||
|
|||||||
@@ -199,13 +199,14 @@ export class StripstreamProvider implements IMediaProvider {
|
|||||||
async getHomeData(): Promise<HomeData> {
|
async getHomeData(): Promise<HomeData> {
|
||||||
const homeOpts = { revalidate: CACHE_TTL_MED, tags: [HOME_CACHE_TAG] };
|
const homeOpts = { revalidate: CACHE_TTL_MED, tags: [HOME_CACHE_TAG] };
|
||||||
const [ongoingBooksResult, ongoingSeriesResult, booksPage, libraries] = await Promise.allSettled([
|
const [ongoingBooksResult, ongoingSeriesResult, booksPage, libraries] = await Promise.allSettled([
|
||||||
this.client.fetch<StripstreamBookItem[]>("books/ongoing", { limit: "10" }, homeOpts),
|
this.client.fetch<StripstreamBookItem[]>("books/ongoing", { limit: "20" }, homeOpts),
|
||||||
this.client.fetch<StripstreamSeriesItem[]>("series/ongoing", { limit: "10" }, homeOpts),
|
this.client.fetch<StripstreamSeriesItem[]>("series/ongoing", { limit: "10" }, homeOpts),
|
||||||
this.client.fetch<StripstreamBooksPage>("books", { limit: "10" }, homeOpts),
|
this.client.fetch<StripstreamBooksPage>("books", { limit: "10" }, homeOpts),
|
||||||
this.client.fetch<StripstreamLibraryResponse[]>("libraries", undefined, { revalidate: CACHE_TTL_LONG, tags: [HOME_CACHE_TAG] }),
|
this.client.fetch<StripstreamLibraryResponse[]>("libraries", undefined, { revalidate: CACHE_TTL_LONG, tags: [HOME_CACHE_TAG] }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const onDeck = ongoingBooksResult.status === "fulfilled"
|
// /books/ongoing returns both currently reading and next unread per series
|
||||||
|
const ongoingBooks = ongoingBooksResult.status === "fulfilled"
|
||||||
? ongoingBooksResult.value.map(StripstreamAdapter.toNormalizedBook)
|
? ongoingBooksResult.value.map(StripstreamAdapter.toNormalizedBook)
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
@@ -213,10 +214,6 @@ export class StripstreamProvider implements IMediaProvider {
|
|||||||
? ongoingSeriesResult.value.map(StripstreamAdapter.toNormalizedSeries)
|
? ongoingSeriesResult.value.map(StripstreamAdapter.toNormalizedSeries)
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
const ongoingBooks = booksPage.status === "fulfilled"
|
|
||||||
? booksPage.value.items.filter((b) => b.reading_status === "reading").map(StripstreamAdapter.toNormalizedBook)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const recentlyRead = booksPage.status === "fulfilled"
|
const recentlyRead = booksPage.status === "fulfilled"
|
||||||
? booksPage.value.items.map(StripstreamAdapter.toNormalizedBook)
|
? booksPage.value.items.map(StripstreamAdapter.toNormalizedBook)
|
||||||
: [];
|
: [];
|
||||||
@@ -241,9 +238,9 @@ export class StripstreamProvider implements IMediaProvider {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
ongoing: ongoingSeries,
|
ongoing: ongoingSeries,
|
||||||
ongoingBooks,
|
ongoingBooks: [],
|
||||||
recentlyRead,
|
recentlyRead,
|
||||||
onDeck,
|
onDeck: ongoingBooks,
|
||||||
latestSeries,
|
latestSeries,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user