feat: Add ebook view modes with Feature Registration Pattern

Convert view-modes.ts to init(context) pattern with:
- Paginated mode with pagination controls
- Scrolled mode for continuous reading
- Single and double column layouts
- Event-based navigation and mode switching
This commit is contained in:
2026-04-04 13:48:47 -04:00
parent d03ac20f66
commit 4b2b7ee66a
+53 -9
View File
@@ -1,4 +1,38 @@
// Different viewing modes for ebooks // Different viewing modes for ebooks
// Feature Registration Pattern implementation
import type { ReaderContext } from "../core/reader-context";
export function init(context: ReaderContext): void {
let state: ViewModeState | null = null;
context.events.on("reader:loaded", (detail: { container: HTMLElement }) => {
state = { currentMode: "paginated", currentPage: 1 };
setViewMode(detail.container, "paginated");
});
context.events.on("view-mode:set", (detail: { mode: ViewMode }) => {
if (state && context.elements.readerContent) {
state.currentMode = detail.mode;
setViewMode(context.elements.readerContent, detail.mode);
context.events.emit("view-mode:changed", { mode: detail.mode });
}
});
context.events.on("view-mode:get", () => {
if (state) {
context.events.emit("view-mode:current", state);
}
});
context.events.on("pagination:go-to-page", (detail: { page: number }) => {
if (state && context.elements.readerContent) {
state.currentPage = detail.page;
goToPage(context.elements.readerContent, detail.page);
context.events.emit("pagination:page-changed", { page: detail.page });
}
});
}
type ViewMode = "paginated" | "scrolled" | "single-column" | "double-column"; type ViewMode = "paginated" | "scrolled" | "single-column" | "double-column";
@@ -11,7 +45,9 @@ function setViewMode(container: HTMLElement, mode: ViewMode): void {
const content = container.querySelector(".ebook-content"); const content = container.querySelector(".ebook-content");
if (!content) return; if (!content) return;
content.classList.remove( const element = content as HTMLElement;
element.classList.remove(
"paginated", "paginated",
"scrolled", "scrolled",
"single-column", "single-column",
@@ -20,16 +56,16 @@ function setViewMode(container: HTMLElement, mode: ViewMode): void {
switch (mode) { switch (mode) {
case "paginated": case "paginated":
applyPaginatedMode(container, content as HTMLElement); applyPaginatedMode(container, element);
break; break;
case "scrolled": case "scrolled":
applyScrolledMode(container, content as HTMLElement); applyScrolledMode(container, element);
break; break;
case "single-column": case "single-column":
applySingleColumn(content as HTMLElement); applySingleColumn(element);
break; break;
case "double-column": case "double-column":
applyDoubleColumn(content as HTMLElement); applyDoubleColumn(element);
break; break;
} }
} }
@@ -93,7 +129,7 @@ function disablePagination(container: HTMLElement): void {
function addPaginationControls( function addPaginationControls(
container: HTMLElement, container: HTMLElement,
pageCount: number, pageCount: number,
): ViewModeState { ): void {
let currentPage = 1; let currentPage = 1;
const controls = document.createElement("div"); const controls = document.createElement("div");
@@ -120,8 +156,6 @@ function addPaginationControls(
}); });
container.appendChild(controls); container.appendChild(controls);
return { currentMode: "paginated", currentPage };
} }
function goToPage(container: HTMLElement, pageNumber: number): void { function goToPage(container: HTMLElement, pageNumber: number): void {
@@ -152,4 +186,14 @@ function getTotalPageCount(container: HTMLElement): number {
return Math.ceil(totalHeight / pageHeight); return Math.ceil(totalHeight / pageHeight);
} }
export { setViewMode, getCurrentViewMode }; export function getCurrentViewMode(container: HTMLElement): ViewMode {
const content = container.querySelector(".ebook-content") as HTMLElement;
if (!content) return "paginated";
if (content.classList.contains("paginated")) return "paginated";
if (content.classList.contains("scrolled")) return "scrolled";
if (content.classList.contains("single-column")) return "single-column";
if (content.classList.contains("double-column")) return "double-column";
return "paginated";
}