Add TypeScript type definitions for reader feature
Define comprehensive TypeScript interfaces for reader functionality: - Common Intermediate Format (CIF) for universal ebook representation - Parser capabilities and format detection types - Reader metadata and chapter structure interfaces - Panel layout and dock system types - Reading progress and settings interfaces - Dictionary and search functionality types These types provide the foundation for type-safe reader implementation across all media types (ebook, comic, manga, pdf).
This commit is contained in:
Vendored
+203
@@ -0,0 +1,203 @@
|
|||||||
|
// ============================================================
|
||||||
|
// Common Intermediate Format (CIF) Types
|
||||||
|
// Universal format for all reflowable ebooks after parsing
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
interface EbookCIF {
|
||||||
|
// Universal metadata (all formats)
|
||||||
|
metadata: {
|
||||||
|
title: string;
|
||||||
|
author: string;
|
||||||
|
language: string;
|
||||||
|
publisher?: string;
|
||||||
|
isbn?: string;
|
||||||
|
coverImage?: Blob;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Unified navigation structure
|
||||||
|
toc: TOCNode[];
|
||||||
|
|
||||||
|
// Content spine (reading order)
|
||||||
|
spine: SpineItem[];
|
||||||
|
|
||||||
|
// Resources (CSS, fonts, images)
|
||||||
|
resources: Map<string, Blob>;
|
||||||
|
|
||||||
|
// Progress tracking (minimal - backend handles detailed tracking)
|
||||||
|
locations: {
|
||||||
|
totalCharacters: number;
|
||||||
|
estimatedPages: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SpineItem {
|
||||||
|
id: string;
|
||||||
|
type: "html" | "image";
|
||||||
|
content: string;
|
||||||
|
properties?: string[];
|
||||||
|
|
||||||
|
// Minimal position info for UI
|
||||||
|
index: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TOCNode {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
href: string;
|
||||||
|
children: TOCNode[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Parser Types (Procedural, not OOP)
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
type ParserFormat =
|
||||||
|
| "epub"
|
||||||
|
| "fb2"
|
||||||
|
| "txt"
|
||||||
|
| "html"
|
||||||
|
| "mobi"
|
||||||
|
| "azw3"
|
||||||
|
| "docx"
|
||||||
|
| "rtf";
|
||||||
|
|
||||||
|
interface ParserCapabilities {
|
||||||
|
canParse(mimeType: string, extension: string): boolean;
|
||||||
|
parse(file: Blob): Promise<EbookCIF>;
|
||||||
|
extractMetadata(file: Blob): Promise<Partial<EbookCIF["metadata"]>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Reader Metadata (from API)
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
interface ReaderMetadata {
|
||||||
|
media_item_id: string;
|
||||||
|
title: string;
|
||||||
|
author: string;
|
||||||
|
cover_image_path: string;
|
||||||
|
library_type: "ebook" | "comic" | "manga" | "pdf";
|
||||||
|
mime_type: string;
|
||||||
|
file_path: string;
|
||||||
|
chapter_metadata?: ChapterMetadata;
|
||||||
|
total_pages?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Other Shared Types
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
interface ChapterMetadata {
|
||||||
|
chapters: Chapter[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Chapter {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
start_page: number;
|
||||||
|
page_count: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PanelData {
|
||||||
|
media_item_id: string;
|
||||||
|
page_number: number;
|
||||||
|
detection_method: "grid" | "ml" | "manual";
|
||||||
|
panels: Panel[];
|
||||||
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Panel {
|
||||||
|
id: string;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
reading_order: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ReadingSpeed {
|
||||||
|
words_per_minute: number;
|
||||||
|
pages_per_minute: number;
|
||||||
|
pages_read: number;
|
||||||
|
total_reading_minutes: number;
|
||||||
|
last_read_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DictionaryEntry {
|
||||||
|
word: string;
|
||||||
|
definition: string;
|
||||||
|
part_of_speech?: string;
|
||||||
|
example?: string;
|
||||||
|
etymology?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ReaderSettings {
|
||||||
|
chrome_behavior: "auto-hide" | "always-visible" | "hide-on-scroll";
|
||||||
|
progress_mode: "pages" | "chapter" | "percentage" | "time-left";
|
||||||
|
|
||||||
|
chrome_theme: string;
|
||||||
|
reading_theme: "light" | "sepia" | "dark" | "night" | "high-contrast";
|
||||||
|
|
||||||
|
reading_font:
|
||||||
|
| "literata"
|
||||||
|
| "crimson"
|
||||||
|
| "source-serif"
|
||||||
|
| "eb-garamond"
|
||||||
|
| "libertinus"
|
||||||
|
| "noto-serif"
|
||||||
|
| "charis-sil"
|
||||||
|
| "ibm-plex";
|
||||||
|
font_size: number;
|
||||||
|
line_height: number;
|
||||||
|
margin_width: number;
|
||||||
|
|
||||||
|
tap_zone_size: number;
|
||||||
|
auto_scroll: boolean;
|
||||||
|
panel_zoom_enabled: boolean;
|
||||||
|
|
||||||
|
double_page_spread: boolean;
|
||||||
|
reading_direction: "ltr" | "rtl" | "vertical";
|
||||||
|
|
||||||
|
pdf_fit_mode: "fit-width" | "fit-page" | "fit-height" | "none";
|
||||||
|
pdf_zoom_level: number;
|
||||||
|
pdf_text_layer_enabled: boolean;
|
||||||
|
pdf_dual_page_mode: "auto" | "single" | "dual";
|
||||||
|
pdf_dual_page_threshold: number;
|
||||||
|
pdf_minimap_enabled: boolean;
|
||||||
|
pdf_outline_visible: boolean;
|
||||||
|
media_bookmarks_visible: boolean;
|
||||||
|
|
||||||
|
hardware_acceleration: boolean;
|
||||||
|
|
||||||
|
// Dockable panel layout configuration (per-user, media-type-aware)
|
||||||
|
panel_layout: PanelLayoutSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PanelLayoutSettings {
|
||||||
|
// Per panel state: which side, visible, collapsed (window-shade), width
|
||||||
|
toc: PanelState;
|
||||||
|
settings: PanelState;
|
||||||
|
navigator: PanelState;
|
||||||
|
bookmarks: PanelState;
|
||||||
|
|
||||||
|
// Mobile override
|
||||||
|
mobile_nav_visible: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PanelState {
|
||||||
|
side: "left" | "right" | "hidden";
|
||||||
|
visible: boolean;
|
||||||
|
collapsed: boolean; // Window-shade: true = collapsed to title bar
|
||||||
|
width_px: number; // Panel width in pixels
|
||||||
|
order: number; // Order within the side
|
||||||
|
locked: boolean; // Lock toggle: prevents accidental drag/move
|
||||||
|
last_valid_side: "left" | "right" | "hidden"; // Snap-back target if dropped in invalid area
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ProgressDisplay {
|
||||||
|
mode: "pages" | "chapter" | "percentage" | "time-left";
|
||||||
|
current: number;
|
||||||
|
total: number;
|
||||||
|
label?: string;
|
||||||
|
time_left?: string;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user