import type { ReaderContext } from "../core/reader-context"; let context: ReaderContext; export async function init(readerContext: ReaderContext): Promise { context = readerContext; setupKeyboardShortcuts(); } function setupKeyboardShortcuts() { const container = context.elements.readerContent; if (!container) return; const state = context.getState(); let maxPage = 0; if (state.currentReader?.type === "ebook") { maxPage = state.currentReader.cif.spine.length; } else if (state.currentReader?.type === "pdf") { maxPage = state.readerMetadata?.total_pages || 0; } else if ( state.currentReader?.type === "comic" || state.currentReader?.type === "manga" ) { const reader = state.currentReader as any; maxPage = reader.images.length; } container.addEventListener("keydown", (e) => { if ( e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement ) { return; } switch (e.key) { case "ArrowRight": case "PageDown": case "l": e.preventDefault(); context.navigation.nextPage(); break; case "ArrowLeft": case "PageUp": case "h": e.preventDefault(); context.navigation.previousPage(); break; case "ArrowUp": case "k": e.preventDefault(); context.navigation.previousPage(); break; case "ArrowDown": case "j": e.preventDefault(); context.navigation.nextPage(); break; case " ": e.preventDefault(); context.navigation.nextPage(); break; case "Home": e.preventDefault(); context.navigation.goToPage(1); break; case "End": e.preventDefault(); context.navigation.goToPage(maxPage); break; case "b": if (!e.ctrlKey && !e.metaKey) { e.preventDefault(); toggleBookmark(); } break; case "+": case "=": e.preventDefault(); zoomIn(); break; case "-": case "_": e.preventDefault(); zoomOut(); break; case "0": e.preventDefault(); zoomReset(); break; case "?": e.preventDefault(); showShortcutHelp(); break; case "f": if (!e.ctrlKey && !e.metaKey) { e.preventDefault(); toggleFullscreen(); } break; case "Escape": e.preventDefault(); exitFullscreen(); break; default: if (e.key >= "1" && e.key <= "9") { const targetPage = Math.floor((parseInt(e.key) / 10) * maxPage); e.preventDefault(); context.navigation.goToPage(targetPage); } } }); } function toggleBookmark() { // TODO: Implement bookmark toggle console.log("Toggle bookmark"); } function zoomIn() { const container = context.elements.readerContent; if (container) { const currentTransform = container.style.transform || ""; const currentScale = currentTransform.match(/scale\(([\d.]+)\)/); const scale = currentScale ? parseFloat(currentScale[1]) : 1; const newScale = Math.min(scale + 0.25, 3); container.style.transform = `scale(${newScale})`; container.style.transformOrigin = "center center"; context.events.emit("zoomChanged", newScale); } } function zoomOut() { const container = context.elements.readerContent; if (container) { const currentTransform = container.style.transform || ""; const currentScale = currentTransform.match(/scale\(([\d.]+)\)/); const scale = currentScale ? parseFloat(currentScale[1]) : 1; const newScale = Math.max(scale - 0.25, 0.5); container.style.transform = `scale(${newScale})`; container.style.transformOrigin = "center center"; context.events.emit("zoomChanged", newScale); } } function zoomReset() { const container = context.elements.readerContent; if (container) { container.style.transform = "scale(1)"; container.style.transformOrigin = "center center"; context.events.emit("zoomChanged", 1); } } function toggleFullscreen() { if (document.fullscreenElement) { document.exitFullscreen(); } else { document.documentElement.requestFullscreen(); } } function exitFullscreen() { if (document.fullscreenElement) { document.exitFullscreen(); } } function showShortcutHelp() { const help = document.createElement("div"); help.className = "keyboard-shortcut-help fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50"; help.innerHTML = `

Keyboard Shortcuts

/ Space Next page
Previous page
Home First page
End Last page
+ / - Zoom
B Toggle bookmark
? Show help
Esc Exit fullscreen
`; document.body.appendChild(help); help.addEventListener("click", (e) => { if (e.target === help) help.remove(); }); }