add lightbox for post image previews
This commit is contained in:
		@@ -176,7 +176,7 @@ pre code {
 | 
			
		||||
  font-size: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#delete-dialog {
 | 
			
		||||
#delete-dialog, .lightbox-dialog {
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
  border: 2px solid black;
 | 
			
		||||
@@ -190,6 +190,27 @@ pre code {
 | 
			
		||||
  padding: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lightbox-inner {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  padding: 20px;
 | 
			
		||||
  min-width: 400px;
 | 
			
		||||
  background-color: #c1ceb1;
 | 
			
		||||
  gap: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lightbox-image {
 | 
			
		||||
  max-width: 70vw;
 | 
			
		||||
  max-height: 70vh;
 | 
			
		||||
  object-fit: scale-down;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lightbox-nav {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.copy-code-container {
 | 
			
		||||
  position: sticky;
 | 
			
		||||
  width: calc(100% - 4px);
 | 
			
		||||
@@ -442,7 +463,6 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.contain-svg:not(.full) > svg {
 | 
			
		||||
  height: 50%;
 | 
			
		||||
  width: 50%;
 | 
			
		||||
@@ -710,7 +730,6 @@ ul, ol {
 | 
			
		||||
  padding: 5px 10px;
 | 
			
		||||
  min-width: 36px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.babycode-button > * {
 | 
			
		||||
  font-size: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										99
									
								
								js/ui.js
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								js/ui.js
									
									
									
									
									
								
							@@ -21,6 +21,86 @@ function activateSelfDeactivateSibs(button) {
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function openLightbox(post, idx) {
 | 
			
		||||
  lightboxCurrentPost = post;
 | 
			
		||||
  lightboxCurrentIdx = idx;
 | 
			
		||||
  lightboxObj.img.src = lightboxImages.get(post)[idx].src;
 | 
			
		||||
  lightboxObj.openOriginalAnchor.href = lightboxImages.get(post)[idx].src
 | 
			
		||||
  lightboxObj.prevButton.disabled = lightboxImages.get(post).length === 1
 | 
			
		||||
  lightboxObj.nextButton.disabled = lightboxImages.get(post).length === 1
 | 
			
		||||
  lightboxObj.imageCount.textContent = `Image ${idx + 1} of ${lightboxImages.get(post).length}`
 | 
			
		||||
  
 | 
			
		||||
  if (!lightboxObj.dialog.open) {
 | 
			
		||||
    lightboxObj.dialog.showModal();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const modulo = (n, m) => ((n % m) + m) % m
 | 
			
		||||
 | 
			
		||||
function lightboxNext() {
 | 
			
		||||
  const l = lightboxImages.get(lightboxCurrentPost).length;
 | 
			
		||||
  const target = modulo(lightboxCurrentIdx + 1, l);
 | 
			
		||||
  openLightbox(lightboxCurrentPost, target);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function lightboxPrev() {
 | 
			
		||||
  const l = lightboxImages.get(lightboxCurrentPost).length;
 | 
			
		||||
  const target = modulo(lightboxCurrentIdx - 1, l);
 | 
			
		||||
  openLightbox(lightboxCurrentPost, target);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function constructLightbox() {
 | 
			
		||||
  const dialog = document.createElement("dialog");
 | 
			
		||||
  dialog.classList.add("lightbox-dialog");
 | 
			
		||||
  dialog.addEventListener("click", (e) => {
 | 
			
		||||
    if (e.target === dialog) {
 | 
			
		||||
      dialog.close();
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const dialogInner = document.createElement("div");
 | 
			
		||||
  dialogInner.classList.add("lightbox-inner");
 | 
			
		||||
  dialog.appendChild(dialogInner);
 | 
			
		||||
  const img = document.createElement("img");
 | 
			
		||||
  img.classList.add("lightbox-image")
 | 
			
		||||
  dialogInner.appendChild(img);
 | 
			
		||||
  const openOriginalAnchor = document.createElement("a")
 | 
			
		||||
  openOriginalAnchor.text = "Open original in new window"
 | 
			
		||||
  openOriginalAnchor.target = "_blank"
 | 
			
		||||
  openOriginalAnchor.rel = "noopener noreferrer nofollow"
 | 
			
		||||
  dialogInner.appendChild(openOriginalAnchor);
 | 
			
		||||
  
 | 
			
		||||
  const navSpan = document.createElement("span");
 | 
			
		||||
  navSpan.classList.add("lightbox-nav");
 | 
			
		||||
  const prevButton = document.createElement("button");
 | 
			
		||||
  prevButton.type = "button";
 | 
			
		||||
  prevButton.textContent = "Previous";
 | 
			
		||||
  prevButton.addEventListener("click", lightboxPrev);
 | 
			
		||||
  const nextButton = document.createElement("button");
 | 
			
		||||
  nextButton.type = "button";
 | 
			
		||||
  nextButton.textContent = "Next";
 | 
			
		||||
  nextButton.addEventListener("click", lightboxNext);
 | 
			
		||||
  const imageCount = document.createElement("span");
 | 
			
		||||
  imageCount.textContent = "Image of ";
 | 
			
		||||
  navSpan.appendChild(prevButton);
 | 
			
		||||
  navSpan.appendChild(imageCount);
 | 
			
		||||
  navSpan.appendChild(nextButton);
 | 
			
		||||
  
 | 
			
		||||
  dialogInner.appendChild(navSpan);
 | 
			
		||||
  return {
 | 
			
		||||
    img: img,
 | 
			
		||||
    dialog: dialog,
 | 
			
		||||
    openOriginalAnchor: openOriginalAnchor,
 | 
			
		||||
    prevButton: prevButton,
 | 
			
		||||
    nextButton: nextButton,
 | 
			
		||||
    imageCount: imageCount,
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let lightboxImages = new Map(); //.post-inner : Array<Object>
 | 
			
		||||
let lightboxObj = null;
 | 
			
		||||
let lightboxCurrentPost = null;
 | 
			
		||||
let lightboxCurrentIdx = -1;
 | 
			
		||||
 | 
			
		||||
document.addEventListener("DOMContentLoaded", () => {
 | 
			
		||||
  // tabs
 | 
			
		||||
  document.querySelectorAll(".tab-button").forEach(button => {
 | 
			
		||||
@@ -45,4 +125,23 @@ document.addEventListener("DOMContentLoaded", () => {
 | 
			
		||||
    
 | 
			
		||||
    toggleButton.addEventListener("click", toggle);
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  //lightboxes
 | 
			
		||||
  lightboxObj = constructLightbox();
 | 
			
		||||
  document.body.appendChild(lightboxObj.dialog);
 | 
			
		||||
  const postImages = document.querySelectorAll(".post-inner img.block-img");
 | 
			
		||||
  postImages.forEach(postImage => {
 | 
			
		||||
    const belongingTo = postImage.closest(".post-inner");
 | 
			
		||||
    const images = lightboxImages.get(belongingTo) ?? [];
 | 
			
		||||
    images.push({
 | 
			
		||||
      src: postImage.src,
 | 
			
		||||
      alt: postImage.alt,
 | 
			
		||||
    });
 | 
			
		||||
    const idx = images.length - 1;
 | 
			
		||||
    lightboxImages.set(belongingTo, images);
 | 
			
		||||
    postImage.style.cursor = "pointer";
 | 
			
		||||
    postImage.addEventListener("click", () => {
 | 
			
		||||
      openLightbox(belongingTo, idx);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -220,7 +220,7 @@ pre code {
 | 
			
		||||
  font-size: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#delete-dialog {
 | 
			
		||||
#delete-dialog, .lightbox-dialog {
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
  border: 2px solid black;
 | 
			
		||||
@@ -234,6 +234,27 @@ pre code {
 | 
			
		||||
  padding: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lightbox-inner {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  padding: 20px;
 | 
			
		||||
  min-width: 400px;
 | 
			
		||||
  background-color: $accent_color;
 | 
			
		||||
  gap: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lightbox-image {
 | 
			
		||||
  max-width: 70vw;
 | 
			
		||||
  max-height: 70vh;
 | 
			
		||||
  object-fit: scale-down;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lightbox-nav {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.copy-code-container {
 | 
			
		||||
  position: sticky;
 | 
			
		||||
  // width: 100%;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user