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
// 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";
@@ -11,7 +45,9 @@ function setViewMode(container: HTMLElement, mode: ViewMode): void {
const content = container.querySelector(".ebook-content");
if (!content) return;
content.classList.remove(
const element = content as HTMLElement;
element.classList.remove(
"paginated",
"scrolled",
"single-column",
@@ -20,16 +56,16 @@ function setViewMode(container: HTMLElement, mode: ViewMode): void {
switch (mode) {
case "paginated":
applyPaginatedMode(container, content as HTMLElement);
applyPaginatedMode(container, element);
break;
case "scrolled":
applyScrolledMode(container, content as HTMLElement);
applyScrolledMode(container, element);
break;
case "single-column":
applySingleColumn(content as HTMLElement);
applySingleColumn(element);
break;
case "double-column":
applyDoubleColumn(content as HTMLElement);
applyDoubleColumn(element);
break;
}
}
@@ -93,7 +129,7 @@ function disablePagination(container: HTMLElement): void {
function addPaginationControls(
container: HTMLElement,
pageCount: number,
): ViewModeState {
): void {
let currentPage = 1;
const controls = document.createElement("div");
@@ -120,8 +156,6 @@ function addPaginationControls(
});
container.appendChild(controls);
return { currentMode: "paginated", currentPage };
}
function goToPage(container: HTMLElement, pageNumber: number): void {
@@ -152,4 +186,14 @@ function getTotalPageCount(container: HTMLElement): number {
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";
}