diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e6f943..d6a8a2f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,41 @@
- Added translations and data attributes for almost all user-facing text
- Extend i18n support: Add new translation keys for Download and Share modals
+- **Slider Integration:**
+ - Added a slider UI (range input, label, and value display) directly above the gallery grid.
+ - The slider allows users to adjust the number of columns in the gallery from 1 to 6.
+- **Dynamic Grid Updates:**
+ - The gallery grid’s CSS is updated in real time via the slider’s value by setting the grid-template-columns property.
+ - As the slider value changes, the layout instantly reflects the new column count.
+- **Dynamic Image Resizing:**
+ - Introduced a helper function (getMaxImageHeight) that calculates the maximum image height based on the current column count.
+ - The max height of each image is updated immediately when the slider is adjusted to create a more dynamic display.
+- **Image Caching:**
+ - Implemented an image caching mechanism using a global window.imageCache object.
+ - Images are cached on load (via an onload event) to prevent unnecessary reloading, improving performance.
+- **Event Handling:**
+ - The slider’s event listener is set up to update both the gallery grid layout and the dimensions of the thumbnails dynamically.
+ - Share button event listeners remain attached for proper functionality across the updated gallery view.
+
+- **Input Validation & Security:**
+ - Used `filter_input()` to sanitize and validate incoming GET parameters (token, pass, page).
+ - Validated file system paths using `realpath()` and ensured the shared folder lies within `UPLOAD_DIR`.
+ - Escaped all dynamic outputs with `htmlspecialchars()` to prevent XSS.
+- **Share Link Verification:**
+ - Loaded and validated share records from the JSON file.
+ - Handled expiration and password protection (with proper HTTP status codes for errors).
+- **Pagination:**
+ - Implemented pagination by slicing the full file list into a limited number of files per page (default of 10).
+ - Calculated total pages and current page to create navigation links.
+- **View Toggle (List vs. Gallery):**
+ - Added a toggle button that switches between a traditional list view and a gallery view.
+ - Maintained two separate view containers (`#listViewContainer` and `#galleryViewContainer`) to support this switching.
+- **Gallery View with Image Caching:**
+ - For the gallery view, implemented a JavaScript function that creates a grid of image thumbnails.
+ - Each image uses a cache-busting query string on first load and caches its URL in a global `window.imageCache` for subsequent renders.
+- **Persistent Pagination Controls:**
+ - Moved the pagination controls outside the individual view containers so that they remain visible regardless of the selected view.
+
---
## Changes 4/12/2025
diff --git a/js/fileListView.js b/js/fileListView.js
index ef2032f..3adfb23 100644
--- a/js/fileListView.js
+++ b/js/fileListView.js
@@ -90,6 +90,13 @@ function toggleAdvancedSearch() {
renderFileTable(window.currentFolder);
}
+window.imageCache = window.imageCache || {};
+function cacheImage(imgElem, key) {
+ // Save the current src for future renders.
+ window.imageCache[key] = imgElem.src;
+}
+window.cacheImage = cacheImage;
+
/**
* --- Fuse.js Search Helper ---
* Uses Fuse.js to perform a fuzzy search on fileData.
@@ -388,76 +395,142 @@ export function renderFileTable(folder, container) {
/**
* Similarly, update renderGalleryView to accept an optional container.
*/
-export function renderGalleryView(folder, container) {
+// A helper to compute the max image height based on the current column count.
+function getMaxImageHeight() {
+ // Use the slider value (default to 3 if undefined).
+ const columns = parseInt(window.galleryColumns || 3, 10);
+ // Simple scaling: fewer columns yield bigger images.
+ // For instance, if columns === 6, max-height is 150px,
+ // and if columns === 1, max-height could be 150 * 6 = 900px.
+ return 150 * (7 - columns); // adjust the multiplier as needed.
+ }
+
+ export function renderGalleryView(folder, container) {
const fileListContent = container || document.getElementById("fileList");
const searchTerm = (window.currentSearchTerm || "").toLowerCase();
- // Use Fuse.js search for gallery view as well.
const filteredFiles = searchFiles(searchTerm);
const folderPath = folder === "root"
- ? "uploads/"
- : "uploads/" + folder.split("/").map(encodeURIComponent).join("/") + "/";
- const gridStyle = "display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; padding: 10px;";
- let galleryHTML = `
`;
+ ? "uploads/"
+ : "uploads/" + folder.split("/").map(encodeURIComponent).join("/") + "/";
+
+ // Use the current global column value (default to 3).
+ const numColumns = window.galleryColumns || 3;
+
+ // --- Insert slider controls ---
+ // Build the slider HTML.
+ const sliderHTML = `
+
+
+
+ ${numColumns}
+
+ `;
+
+ // Set up the grid container using the slider's value.
+ const gridStyle = `display: grid; grid-template-columns: repeat(${numColumns}, 1fr); gap: 10px; padding: 10px;`;
+
+ // Build the gallery container HTML and include the slider above it.
+ let galleryHTML = sliderHTML;
+ galleryHTML += `