feat: add table of contents
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
e2cfdb3a0c
commit
5cbef19507
@ -82,7 +82,8 @@
|
|||||||
id="top-bar"
|
id="top-bar"
|
||||||
class="transition-all duration-200 absolute z-10 bg-gray-100 dark:bg-gray-800 w-full px-2"
|
class="transition-all duration-200 absolute z-10 bg-gray-100 dark:bg-gray-800 w-full px-2"
|
||||||
>
|
>
|
||||||
<div class="w-full h-32 flex items-center justify-around relative">
|
<div class="max-h-[75vh] w-full flex flex-col items-center justify-around relative dark:text-white">
|
||||||
|
<div class="h-32">
|
||||||
<div class="text-gray-500 absolute top-6 left-4 flex flex-col gap-4">
|
<div class="text-gray-500 absolute top-6 left-4 flex flex-col gap-4">
|
||||||
<a href="#">
|
<a href="#">
|
||||||
<svg
|
<svg
|
||||||
@ -152,6 +153,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="toc" class="w-full text-center max-h-[50%] overflow-scroll no-scrollbar"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -64,6 +64,47 @@ function populateMetadata(data) {
|
|||||||
let [titleEl, authorEl] = document.querySelectorAll("#top-bar p + p");
|
let [titleEl, authorEl] = document.querySelectorAll("#top-bar p + p");
|
||||||
titleEl.innerText = data.title;
|
titleEl.innerText = data.title;
|
||||||
authorEl.innerText = data.author;
|
authorEl.innerText = data.author;
|
||||||
|
|
||||||
|
populateTOC();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the Table of Contents
|
||||||
|
**/
|
||||||
|
function populateTOC() {
|
||||||
|
// Parse the Table of Contents
|
||||||
|
let parsedTOC = currentReader.book.navigation.toc.reduce((agg, item) => {
|
||||||
|
let sectionTitle = item.label.trim();
|
||||||
|
agg.push({ title: sectionTitle, href: item.href });
|
||||||
|
if (item.subitems.length == 0) {
|
||||||
|
return agg;
|
||||||
|
}
|
||||||
|
|
||||||
|
let allSubSections = item.subitems.map(item => {
|
||||||
|
let itemTitle = item.label.trim();
|
||||||
|
if (sectionTitle != "") {
|
||||||
|
itemTitle = sectionTitle + " - " + item.label.trim();
|
||||||
|
}
|
||||||
|
return { title: itemTitle, href: item.href };
|
||||||
|
});
|
||||||
|
agg.push(...allSubSections);
|
||||||
|
|
||||||
|
return agg;
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// Add Table of Contents to DOM
|
||||||
|
let listEl = document.createElement("ul");
|
||||||
|
listEl.classList.add("m-4")
|
||||||
|
parsedTOC.forEach(item => {
|
||||||
|
let listItem = document.createElement("li");
|
||||||
|
listItem.style.cursor = "pointer";
|
||||||
|
listItem.addEventListener("click", () => {
|
||||||
|
currentReader.rendition.display(item.href);
|
||||||
|
});
|
||||||
|
listItem.textContent = item.title;
|
||||||
|
listEl.appendChild(listItem);
|
||||||
|
});
|
||||||
|
document.querySelector("#toc").appendChild(listEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -439,6 +480,7 @@ class EBookReader {
|
|||||||
// ------------------------------------------------ //
|
// ------------------------------------------------ //
|
||||||
// ----------------- Swipe Helpers ---------------- //
|
// ----------------- Swipe Helpers ---------------- //
|
||||||
// ------------------------------------------------ //
|
// ------------------------------------------------ //
|
||||||
|
let disablePagination = false;
|
||||||
let touchStartX,
|
let touchStartX,
|
||||||
touchStartY,
|
touchStartY,
|
||||||
touchEndX,
|
touchEndX,
|
||||||
@ -459,25 +501,36 @@ class EBookReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Swipe Left
|
// Swipe Left
|
||||||
if (touchEndX + drasticity < touchStartX) {
|
if (!disablePagination && touchEndX + drasticity < touchStartX) {
|
||||||
nextPage();
|
nextPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swipe Right
|
// Swipe Right
|
||||||
if (touchEndX - drasticity > touchStartX) {
|
if (!disablePagination && touchEndX - drasticity > touchStartX) {
|
||||||
prevPage();
|
prevPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSwipeDown() {
|
function handleSwipeDown() {
|
||||||
if (bottomBar.classList.contains("bottom-0"))
|
if (bottomBar.classList.contains("bottom-0")) {
|
||||||
bottomBar.classList.remove("bottom-0");
|
bottomBar.classList.remove("bottom-0");
|
||||||
else topBar.classList.add("top-0");
|
disablePagination = false;
|
||||||
|
} else {
|
||||||
|
topBar.classList.add("top-0");
|
||||||
|
populateTOC()
|
||||||
|
disablePagination = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSwipeUp() {
|
function handleSwipeUp() {
|
||||||
if (topBar.classList.contains("top-0")) topBar.classList.remove("top-0");
|
if (topBar.classList.contains("top-0")) {
|
||||||
else bottomBar.classList.add("bottom-0");
|
topBar.classList.remove("top-0");
|
||||||
|
disablePagination = false;
|
||||||
|
document.querySelector("#toc").innerHTML = "";
|
||||||
|
} else {
|
||||||
|
bottomBar.classList.add("bottom-0");
|
||||||
|
disablePagination = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rendition.hooks.render.register(function (doc, data) {
|
this.rendition.hooks.render.register(function (doc, data) {
|
||||||
@ -523,8 +576,8 @@ class EBookReader {
|
|||||||
// Handle Event
|
// Handle Event
|
||||||
if (yCoord < top) handleSwipeDown();
|
if (yCoord < top) handleSwipeDown();
|
||||||
else if (yCoord > bottom) handleSwipeUp();
|
else if (yCoord > bottom) handleSwipeUp();
|
||||||
else if (xCoord < left) prevPage();
|
else if (!disablePagination && xCoord < left) prevPage();
|
||||||
else if (xCoord > right) nextPage();
|
else if (!disablePagination && xCoord > right) nextPage();
|
||||||
else {
|
else {
|
||||||
bottomBar.classList.remove("bottom-0");
|
bottomBar.classList.remove("bottom-0");
|
||||||
topBar.classList.remove("top-0");
|
topBar.classList.remove("top-0");
|
||||||
@ -670,6 +723,7 @@ class EBookReader {
|
|||||||
// Close Top Bar
|
// Close Top Bar
|
||||||
document.querySelector(".close-top-bar").addEventListener("click", () => {
|
document.querySelector(".close-top-bar").addEventListener("click", () => {
|
||||||
topBar.classList.remove("top-0");
|
topBar.classList.remove("top-0");
|
||||||
|
document.querySelector("#toc").innerHTML = "";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1271,14 +1325,3 @@ class EBookReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", initReader);
|
document.addEventListener("DOMContentLoaded", initReader);
|
||||||
|
|
||||||
// WIP
|
|
||||||
async function getTOC() {
|
|
||||||
let toc = currentReader.book.navigation.toc;
|
|
||||||
|
|
||||||
// Alternatively:
|
|
||||||
// let nav = await currentReader.book.loaded.navigation;
|
|
||||||
// let toc = nav.toc;
|
|
||||||
|
|
||||||
currentReader.rendition.display(nav.toc[10].href);
|
|
||||||
}
|
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user