Files
Mangalord/frontend/src/lib/api/page_collections.ts
MechaCat02 6c901e64c9 feat(search): tag-based page search surface + per-page tags & collections
Add the /search surface (Pages / Chapters / Mangas tabs) backed by
per-user page tags and per-page collections: schema (migration 0023),
backend endpoints for page tags/collections and tagged-page aggregations
(with the OCR text-search param reserved at 501), plus the frontend API
clients, library Page-tags tab, collection page sections, page context
menu / AddTagsSheet, and reader long-press wiring. Includes the
continuous-reader navigation fixes (?page=N handling, chapter-reset
timing, back-button pops history) and tag-normalization hardening
accumulated on the branch.

Bump version 0.60.2 -> 0.62.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 15:51:38 +02:00

69 lines
1.9 KiB
TypeScript

import { request, type Page } from './client';
/** Row returned by `GET /v1/collections/:id/pages`. */
export type CollectionPageItem = {
page_id: string;
chapter_id: string;
manga_id: string;
page_number: number;
chapter_number: number;
chapter_title: string | null;
manga_title: string;
storage_key: string;
added_at: string;
};
export type CollectionPagesPage = {
items: CollectionPageItem[];
page: Page;
};
export type ListOptions = { limit?: number; offset?: number };
export async function listCollectionPages(
collectionId: string,
opts: ListOptions = {}
): Promise<CollectionPagesPage> {
const params = new URLSearchParams();
if (opts.limit != null) params.set('limit', String(opts.limit));
if (opts.offset != null) params.set('offset', String(opts.offset));
const qs = params.toString();
return request<CollectionPagesPage>(
`/v1/collections/${encodeURIComponent(collectionId)}/pages${qs ? `?${qs}` : ''}`
);
}
export async function addPageToCollection(
collectionId: string,
pageId: string
): Promise<void> {
await request<void>(
`/v1/collections/${encodeURIComponent(collectionId)}/pages`,
{
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ page_id: pageId })
}
);
}
export async function removePageFromCollection(
collectionId: string,
pageId: string
): Promise<void> {
await request<void>(
`/v1/collections/${encodeURIComponent(collectionId)}/pages/${encodeURIComponent(pageId)}`,
{ method: 'DELETE' }
);
}
/** Which of the user's collections currently contain this page. */
export async function getMyCollectionsContainingPage(
pageId: string
): Promise<string[]> {
const r = await request<{ collection_ids: string[] }>(
`/v1/pages/${encodeURIComponent(pageId)}/my-collections`
);
return r.collection_ids;
}