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"
 | 
			
		||||
        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">
 | 
			
		||||
              <a href="#">
 | 
			
		||||
                <svg
 | 
			
		||||
@ -152,6 +153,8 @@
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
	  </div>
 | 
			
		||||
	  <div id="toc" class="w-full text-center max-h-[50%] overflow-scroll no-scrollbar"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div
 | 
			
		||||
 | 
			
		||||
@ -64,6 +64,47 @@ function populateMetadata(data) {
 | 
			
		||||
  let [titleEl, authorEl] = document.querySelectorAll("#top-bar p + p");
 | 
			
		||||
  titleEl.innerText = data.title;
 | 
			
		||||
  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 ---------------- //
 | 
			
		||||
    // ------------------------------------------------ //
 | 
			
		||||
    let disablePagination = false;
 | 
			
		||||
    let touchStartX,
 | 
			
		||||
      touchStartY,
 | 
			
		||||
      touchEndX,
 | 
			
		||||
@ -459,25 +501,36 @@ class EBookReader {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Swipe Left
 | 
			
		||||
      if (touchEndX + drasticity < touchStartX) {
 | 
			
		||||
      if (!disablePagination && touchEndX + drasticity < touchStartX) {
 | 
			
		||||
        nextPage();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Swipe Right
 | 
			
		||||
      if (touchEndX - drasticity > touchStartX) {
 | 
			
		||||
      if (!disablePagination && touchEndX - drasticity > touchStartX) {
 | 
			
		||||
        prevPage();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function handleSwipeDown() {
 | 
			
		||||
      if (bottomBar.classList.contains("bottom-0"))
 | 
			
		||||
      if (bottomBar.classList.contains("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() {
 | 
			
		||||
      if (topBar.classList.contains("top-0")) topBar.classList.remove("top-0");
 | 
			
		||||
      else bottomBar.classList.add("bottom-0");
 | 
			
		||||
      if (topBar.classList.contains("top-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) {
 | 
			
		||||
@ -523,8 +576,8 @@ class EBookReader {
 | 
			
		||||
          // Handle Event
 | 
			
		||||
          if (yCoord < top) handleSwipeDown();
 | 
			
		||||
          else if (yCoord > bottom) handleSwipeUp();
 | 
			
		||||
          else if (xCoord < left) prevPage();
 | 
			
		||||
          else if (xCoord > right) nextPage();
 | 
			
		||||
          else if (!disablePagination && xCoord < left) prevPage();
 | 
			
		||||
          else if (!disablePagination && xCoord > right) nextPage();
 | 
			
		||||
          else {
 | 
			
		||||
            bottomBar.classList.remove("bottom-0");
 | 
			
		||||
            topBar.classList.remove("top-0");
 | 
			
		||||
@ -670,6 +723,7 @@ class EBookReader {
 | 
			
		||||
    // Close Top Bar
 | 
			
		||||
    document.querySelector(".close-top-bar").addEventListener("click", () => {
 | 
			
		||||
      topBar.classList.remove("top-0");
 | 
			
		||||
      document.querySelector("#toc").innerHTML = "";
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1271,14 +1325,3 @@ class EBookReader {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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