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>
67 lines
2.0 KiB
Rust
67 lines
2.0 KiB
Rust
use chrono::{DateTime, Utc};
|
|
use serde::{Deserialize, Serialize};
|
|
use sqlx::FromRow;
|
|
use uuid::Uuid;
|
|
|
|
use super::patch::Patch;
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct Collection {
|
|
pub id: Uuid,
|
|
pub user_id: Uuid,
|
|
pub name: String,
|
|
pub description: Option<String>,
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
/// Shape returned by `GET /me/collections`. Enriched with the manga
|
|
/// count and up to three sample cover paths so a collection card can
|
|
/// render without extra round-trips.
|
|
#[derive(Debug, Clone, Serialize, FromRow)]
|
|
pub struct CollectionSummary {
|
|
pub id: Uuid,
|
|
pub user_id: Uuid,
|
|
pub name: String,
|
|
pub description: Option<String>,
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
pub manga_count: i64,
|
|
/// Cover image keys of up to three sample mangas (newest-added
|
|
/// first). `Vec<String>` rather than `Option<...>` so an empty
|
|
/// collection renders as `[]` rather than `null`.
|
|
pub sample_covers: Vec<String>,
|
|
}
|
|
|
|
/// Row returned by `GET /collections/:id/pages`. Joins through
|
|
/// `chapters` and `mangas` so the collection detail view can render a
|
|
/// thumbnail + breadcrumb without per-row follow-up fetches.
|
|
#[derive(Debug, Clone, Serialize, FromRow)]
|
|
pub struct CollectionPageItem {
|
|
pub page_id: Uuid,
|
|
pub chapter_id: Uuid,
|
|
pub manga_id: Uuid,
|
|
pub page_number: i32,
|
|
pub chapter_number: i32,
|
|
pub chapter_title: Option<String>,
|
|
pub manga_title: String,
|
|
pub storage_key: String,
|
|
pub added_at: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize)]
|
|
pub struct NewCollection {
|
|
pub name: String,
|
|
#[serde(default)]
|
|
pub description: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Default)]
|
|
pub struct CollectionPatch {
|
|
pub name: Option<String>,
|
|
/// Three-state: missing key leaves description alone; explicit
|
|
/// `null` clears it; a string sets it. See `Patch`.
|
|
#[serde(default)]
|
|
pub description: Patch<String>,
|
|
}
|