diff --git a/static/css/style-imageviewer.css b/static/css/style-imageviewer.css new file mode 100644 index 0000000..4c0696f --- /dev/null +++ b/static/css/style-imageviewer.css @@ -0,0 +1,187 @@ +/* Image Viewer Overlay */ +#image-viewer-overlay { + position: fixed; + top: 105px; + right: 0; + width: 33%; /* Occupies the right space for the viewer */ + height: calc(100% - 105px); /* Adjust height */ + z-index: 999; + display: none; /* Initially hidden */ + + /* Added transition for opening animation */ + /* transform: translateX(100%); + transition: transform 0.3s ease-in-out; */ +} + +/* Image Viewer Container */ +#image-viewer { + position: fixed; + top: 105px; + right: 0; + width: 33%; /* Match the width of the overlay */ + height: calc(100% - 105px); /* Adjust height */ + background: var(--search-bg); + padding: 20px; + box-sizing: border-box; + overflow-y: auto; + text-align: center; + border-left: 1px solid var(--border); + scroll-behavior: smooth; +} + +/* Viewer Image */ +#viewer-image { + max-width: 100%; + max-height: 60vh; +} + +/* Viewer Title */ +#viewer-title { + font-size: 18px; + color: var(--text-color); + margin-bottom: 10px; +} + +/* Viewer Source Button */ +#viewer-source-button { + color: var(--link); + text-decoration: none; + font-size: 16px; +} + +/* Image Viewer Close and Navigation Buttons */ +.image-view-close { + position: absolute; + top: 5px; + right: 10px; + display: flex; + flex-direction: row; + align-items: center; + gap: 5px; /* Add spacing between buttons */ +} + +.image-view-close .btn-nostyle { + background-color: inherit; + border: none; + padding: 0px; + cursor: pointer; +} + +#viewer-close-button, +#viewer-prev-button, +#viewer-next-button { + color: var(--text-color); + font-size: 36px; + cursor: pointer; + user-select: none; +} + +/* Hide and Show Classes */ +.image_hide { + display: none !important; +} + +.image_show { + display: block !important; +} + +/* Adjust the images container when the viewer is hidden */ +.images_viewer_hidden { + margin-right: 1.2% !important; +} + +/* Adjust the images container when the viewer is visible */ +.images { + margin-right: 33%; /* Reserve space for the image viewer */ +} + +/* Clickable Elements */ +.clickable { + cursor: pointer; +} + +/* Viewer Image Link */ +#viewer-image-link { + text-decoration: none; + color: var(--link); +} + +/* View Image Container */ +#viewer-image-container { + background-color: var(--view-image-color); + width: 100%; + height: auto; + display: flex; + justify-content: center; + align-items: center; + margin-top: 50px; +} + +/* Full Size and Proxy Size Links */ +.full-size, +.proxy-size { + margin: 10px; + color: var(--link); + text-decoration: none; + font-size: 16px; +} + +.full-size:hover, +.proxy-size:hover { + text-decoration: underline; +} + +/* Icon Visibility */ +.icon_visibility { + visibility: visible; +} + +/* Button No Style */ +.btn-nostyle { + background-color: inherit; + border: none; + padding: 0px; + width: fit-content; + cursor: pointer; +} + +/* Image Navigation Icons */ +.image-close, +.image-next, +.image-before { + margin-left: -1px; + border-radius: 50%; + padding: 5px; + color: var(--search-button); + font-weight: normal; +} + +.image-close { + margin-right: 10px; +} + +.image-close:hover, +.image-next:hover, +.image-before:hover { + background-color: var(--image-select); +} + +/* Responsive Design */ +@media only screen and (max-width: 750px) { + #image-viewer { + width: 100%; + height: 77%; + margin-top: -33px; + margin-right: 0%; + border-top-right-radius: 0px; + border-top-left-radius: 0px; + } + + #viewer-image { + max-height: 250px; + } + + .images { + margin-right: 0; /* No reserved space on smaller screens */ + } +} diff --git a/static/css/style.css b/static/css/style.css index 29c8eb9..834a0ae 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -339,53 +339,6 @@ html { border: 1px solid var(--border); } -.image_view { - position: fixed; - width: 33%; - height: 82%; - z-index: 70; - background-color: var(--image-view); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); - transition: all 0.3s cubic-bezier(.25, .8, .25, 1); - border: 1px solid var(--border); - border-radius: 10px; - margin-top: 0px; - margin-bottom: 20px; - margin-right: 1.2%; - right: 0px; -} - -.image-view-close { - background-color: var(--image-view-titlebar); - height: 7%; - width: 100%; - border-top-left-radius: 10px; - border-top-right-radius: 10px; - display: flex; - justify-content: flex-end; - align-items: center; -} - -.image-close, -.image-next, -.image-before { - margin-left: -1px; - border-radius: 50%; - padding: 5px; - color: var(--search-button); - font-weight: normal; -} - -.image-close { - margin-right: 10px; -} - -.image-close:hover, -.image-next:hover, -.image-before:hover { - background-color: var(--image-select); -} - .btn-nostyle { background-color: inherit; border: none; @@ -442,17 +395,13 @@ hr { } .image_show { - display: initial !important; + display: block !important; } .icon_visibility { visibility: visible; } -.images_viewer_hidden { - margin-right: 1.2% !important; -} - .stats { color: var(--green); max-width: 48em; @@ -1550,70 +1499,6 @@ p { box-shadow: 0 0 10px var(--box-shadow); } - -#image-viewer-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0,0,0,0.9); - z-index: 999; - display: none; - justify-content: center; - align-items: center; -} - -#image-viewer { - position: relative; - max-width: 80%; - max-height: 80%; - background: var(--search-bg); - padding: 20px; - box-sizing: border-box; - overflow: hidden; - text-align: center; -} - -#viewer-image { - max-width: 100%; - max-height: 60vh; -} - -#viewer-title { - font-size: 18px; - color: var(--text-color); - margin-bottom: 10px; -} - -#viewer-source-button { - color: var(--link); - text-decoration: none; - font-size: 16px; -} - -.image-view-close { - position: absolute; - top: 10px; - right: 10px; - display: flex; - flex-direction: row; - align-items: center; -} - -.image-view-close .btn-nostyle { - margin-left: 5px; -} - -#viewer-close-button, -#viewer-prev-button, -#viewer-next-button { - color: var(--text-color); - font-size: 36px; - cursor: pointer; - user-select: none; -} - body, h1, p, a, input, button { color: var(--text-color); /* Applies the text color based on theme */ background-color: var(--background-color); /* Applies the background color based on theme */ diff --git a/static/js/imageviewer.js b/static/js/imageviewer.js index 740c4d1..5414cd2 100644 --- a/static/js/imageviewer.js +++ b/static/js/imageviewer.js @@ -9,6 +9,8 @@ document.addEventListener('DOMContentLoaded', function() { } const viewerOverlay = document.getElementById('image-viewer-overlay'); + + // Set the innerHTML of viewerOverlay viewerOverlay.innerHTML = `
@@ -22,13 +24,10 @@ document.addEventListener('DOMContentLoaded', function() {
close
- -
- -
-
+
+ +

-

View source:

Show source website Show in fullscreen @@ -36,7 +35,15 @@ document.addEventListener('DOMContentLoaded', function() {

`; - const imageView = document.getElementById('image-viewer'); + const imageView = viewerOverlay.querySelector('#image-viewer'); + if (!imageView) { + console.error('imageView is null'); + } + + const imagesContainer = document.querySelector('.images'); + if (!imagesContainer) { + console.error('imagesContainer is null'); + } function openImageViewer(element) { initializeImageList(); // Update the image list @@ -50,29 +57,31 @@ document.addEventListener('DOMContentLoaded', function() { displayImage(currentIndex); viewerOpen = true; - viewerOverlay.style.display = 'flex'; + imagesContainer.classList.remove('images_viewer_hidden'); + document.body.classList.add('viewer-open'); + viewerOverlay.style.display = 'block'; + imageView.classList.remove('image_hide'); imageView.classList.add('image_show'); } function displayImage(index) { if (index < 0 || index >= imageList.length) return; - + const imgElement = imageList[index]; const parentImageDiv = imgElement.closest('.image'); - + if (!parentImageDiv) { console.warn('Parent image div not found'); return; } - + // Use the `data-full` attribute for the full image URL let fullImageUrl = imgElement.getAttribute('data-full') || imgElement.src; const title = imgElement.alt || 'Untitled'; - // Gracefully handle the source URL or other attributes - const sourceElement = parentImageDiv.querySelector('.img_source'); - const sourceUrl = sourceElement ? sourceElement.href : null; + // Get the source URL from the data-source attribute + const sourceUrl = imgElement.getAttribute('data-source'); // Fallback logic: if sourceUrl is null, use `data-proxy-full` or a meaningful default const proxyFullUrl = imgElement.getAttribute('data-proxy-full') || fullImageUrl; @@ -85,22 +94,16 @@ document.addEventListener('DOMContentLoaded', function() { // Elements in the viewer const viewerImage = document.getElementById('viewer-image'); const viewerTitle = document.getElementById('viewer-title'); - const viewerSourceButton = document.getElementById('viewer-source-button'); const fullSizeLink = document.getElementById('viewer-full-size-link'); const proxySizeLink = document.getElementById('viewer-proxy-size-link'); - const viewerImageLink = document.getElementById('viewer-image-link'); - - // Assign values to the viewer elements - viewerImage.src = fullImageUrl; // Full-size image in the viewer + + viewerImage.src = fullImageUrl; viewerTitle.textContent = title; - - viewerSourceButton.href = sourceUrl || proxyFullUrl; // Use proxy URL if source is missing - fullSizeLink.href = sourceUrl || proxyFullUrl; // Link to source website or proxy - proxySizeLink.href = fullImageUrl; // Link to the proxied full-size image - viewerImageLink.href = fullImageUrl; // Make image clickable to open in a new tab + + fullSizeLink.href = sourceUrl || proxyFullUrl; + proxySizeLink.href = fullImageUrl; } - // Attach event listener to the document body document.body.addEventListener('click', function(e) { let target = e.target; let clickableElement = target.closest('img.clickable, .img_title.clickable'); @@ -114,9 +117,12 @@ document.addEventListener('DOMContentLoaded', function() { function closeImageViewer() { imageView.classList.remove('image_show'); imageView.classList.add('image_hide'); - viewerOverlay.style.display = 'none'; viewerOpen = false; currentIndex = -1; + + imagesContainer.classList.add('images_viewer_hidden'); + document.body.classList.remove('viewer-open'); + viewerOverlay.style.display = 'none'; } // Navigation functions @@ -140,15 +146,19 @@ document.addEventListener('DOMContentLoaded', function() { document.getElementById('viewer-next-button').addEventListener('click', showNextImage); // Close viewer when clicking outside the image - viewerOverlay.addEventListener('click', function(e) { - if (e.target === viewerOverlay) { - closeImageViewer(); + document.addEventListener('click', function(e) { + if (viewerOpen) { + const target = e.target; + const clickedInsideViewer = viewerOverlay.contains(target) || target.closest('.image'); + if (!clickedInsideViewer) { + closeImageViewer(); + } } }); // Handle keyboard events for closing and navigation document.addEventListener('keydown', function(e) { - if (viewerOverlay.style.display === 'flex') { + if (viewerOpen) { if (e.key === 'Escape') { closeImageViewer(); } else if (e.key === 'ArrowLeft') { @@ -157,5 +167,5 @@ document.addEventListener('DOMContentLoaded', function() { showNextImage(); } } - }); + }); }); diff --git a/templates/images.html b/templates/images.html index 837d5ed..4eb9025 100755 --- a/templates/images.html +++ b/templates/images.html @@ -15,6 +15,7 @@ } + @@ -28,7 +29,7 @@

- + logo

@@ -106,6 +107,7 @@ data-id="{{ $result.ID }}" data-full="{{ $result.ProxyFull }}" data-proxy-full="{{ $result.ProxyThumb }}" + data-source="{{ $result.Source }}" alt="{{ $result.Title }}" class="clickable placeholder-img" /> diff --git a/templates/images_only.html b/templates/images_only.html index 2e3aa18..8183830 100644 --- a/templates/images_only.html +++ b/templates/images_only.html @@ -6,6 +6,7 @@ data-id="{{ $result.ID }}" data-full="{{ $result.ProxyFull }}" data-proxy-full="{{ $result.ProxyThumb }}" + data-source="{{ $result.Source }}" alt="{{ $result.Title }}" class="clickable placeholder-img" />