mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
feat(authors): collapse series on author pages (#1271)
Reduce large author listings to one card per series while preserving book counts, scoped visibility, and row-based pagination. Compute both totals in the collapsed query so deep pages remain consistent without a second author-wide scan. Closes #301 Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
This commit is contained in:
@@ -43,7 +43,15 @@ export type AuthorsPage = {
|
||||
size: number;
|
||||
};
|
||||
|
||||
export type AuthorBooksPage = BooksPage;
|
||||
/**
|
||||
* `total` counts rows in the page's own unit, so it is the number of cards once
|
||||
* `collapseSeries` folds a series into one card - that is what paginating and "is there more"
|
||||
* have to be driven by. `bookTotal` stays the number of books behind those rows, for the
|
||||
* places that count books rather than cards. The two are equal while the list is flat.
|
||||
*/
|
||||
export type AuthorBooksPage = BooksPage & {
|
||||
bookTotal: number;
|
||||
};
|
||||
|
||||
export type MergeAuthorsResult = {
|
||||
target: AuthorDetail;
|
||||
|
||||
@@ -3,6 +3,13 @@ export type SeriesCollapsePreferences = {
|
||||
libraries: Record<string, boolean>;
|
||||
collections: Record<string, boolean>;
|
||||
smartScopes?: Record<string, boolean>;
|
||||
/**
|
||||
* Author pages share one flag instead of a per-author bucket: the bucket would grow with every
|
||||
* author browsed, and "collapsed for King but not for Pratchett" is not a distinction anyone
|
||||
* asks for. Absent means off, so an upgrade leaves author pages flat even for a user whose
|
||||
* {@link SeriesCollapsePreferences.global} is on.
|
||||
*/
|
||||
authorPages?: boolean;
|
||||
};
|
||||
|
||||
export type CollapsedSeriesInfo = {
|
||||
@@ -18,9 +25,12 @@ export type CollapsedSeriesInfo = {
|
||||
|
||||
export function resolveCollapsePreference(
|
||||
prefs: SeriesCollapsePreferences | undefined,
|
||||
ctx: { libraryId?: number; collectionId?: number; smartScopeId?: number },
|
||||
ctx: { libraryId?: number; collectionId?: number; smartScopeId?: number; authorPages?: boolean },
|
||||
): boolean {
|
||||
if (!prefs) return false;
|
||||
// Author pages resolve to their own flag and stop there - they deliberately do not inherit the
|
||||
// global default, and the library filter on an author page is a filter, not a scope to override.
|
||||
if (ctx.authorPages) return prefs.authorPages ?? false;
|
||||
if (ctx.smartScopeId !== undefined) {
|
||||
const override = prefs.smartScopes?.[String(ctx.smartScopeId)];
|
||||
if (override !== undefined) return override;
|
||||
|
||||
Reference in New Issue
Block a user