added caching of images to the drive

This commit is contained in:
partisan 2024-10-13 00:04:46 +02:00
parent 48994ee32d
commit 3d47c80446
11 changed files with 451 additions and 33 deletions

View file

@ -74,13 +74,19 @@
<!-- Images Grid -->
{{ range $index, $result := .Results }}
<div class="image">
<img src="{{ .ThumbProxy }}" alt="{{ .Title }}" data-media="{{ .Media }}" class="clickable">
<img
src="/static/images/placeholder.svg"
data-id="{{ $result.ID }}"
alt="{{ .Title }}"
data-media="{{ .Media }}"
class="clickable"
>
<div class="resolution">{{ .Width }} × {{ .Height }}</div>
<div class="details">
<span class="img_title clickable">{{ .Title }}</span>
<a href="{{ .Source }}" target="_blank" class="img_source">{{ translate "source" }}</a>
</div>
</div>
</div>
{{ end }}
</div>
@ -216,6 +222,125 @@
});
});
</script>
<!-- JavaScript to Load Images -->
<script>
document.addEventListener("DOMContentLoaded", function() {
let imageMap = {}; // Map of image IDs to img elements
let loadedImageIDs = new Set(); // Keep track of loaded image IDs
let pollingInterval = 2000; // Initial polling interval in milliseconds
let polling = false;
function initializeImages() {
const images = document.querySelectorAll("img[data-id]");
images.forEach((img) => {
const id = img.dataset.id;
if (!imageMap[id]) {
imageMap[id] = img;
}
});
}
// Initialize with images present at page load
initializeImages();
// Set up MutationObserver to detect new images added to the DOM
const observer = new MutationObserver((mutationsList) => {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
if (node.matches && node.matches('img[data-id]')) {
const img = node;
const id = img.dataset.id;
if (!imageMap[id]) {
imageMap[id] = img;
console.log('New image added:', id);
if (!polling) {
checkImageStatus(); // Start polling if not already started
}
}
} else {
// Check for nested images within added nodes
const nestedImages = node.querySelectorAll && node.querySelectorAll('img[data-id]');
if (nestedImages && nestedImages.length > 0) {
nestedImages.forEach((img) => {
const id = img.dataset.id;
if (!imageMap[id]) {
imageMap[id] = img;
console.log('New nested image added:', id);
if (!polling) {
checkImageStatus(); // Start polling if not already started
}
}
});
}
}
}
});
}
}
});
// Start observing the document body for added nodes
observer.observe(document.body, { childList: true, subtree: true });
function checkImageStatus() {
polling = true;
const imageIDs = Object.keys(imageMap).filter(id => !loadedImageIDs.has(id));
if (imageIDs.length === 0) {
polling = false;
console.log('All images loaded.');
return;
}
console.log('Checking status for images:', imageIDs); // Debugging
fetch('/image_status?image_ids=' + imageIDs.join(','))
.then(response => response.json())
.then(statusMap => {
console.log('Status map:', statusMap); // Debugging
let imagesStillLoading = false;
for (const [id, url] of Object.entries(statusMap)) {
const img = imageMap[id];
if (url) {
// Append cache-busting query parameter
const cacheBustingUrl = url + '?t=' + new Date().getTime();
if (img.src !== cacheBustingUrl) {
img.src = cacheBustingUrl;
img.onload = function() {
// Image loaded successfully
img.classList.add('loaded');
loadedImageIDs.add(id);
};
img.onerror = function() {
console.error('Failed to load image:', url);
};
}
} else {
imagesStillLoading = true;
}
}
if (imagesStillLoading) {
// Poll again after a delay
setTimeout(checkImageStatus, pollingInterval);
} else {
polling = false;
console.log('All images loaded.');
}
})
.catch(error => {
console.error('Error checking image status:', error);
// Retry after a delay in case of error
setTimeout(checkImageStatus, pollingInterval * 2);
});
}
// Start polling
checkImageStatus();
});
</script>
<script>
// Check if JavaScript is enabled and modify the DOM accordingly
document.getElementById('content').classList.remove('js-enabled');