108 lines
3.1 KiB
JavaScript
108 lines
3.1 KiB
JavaScript
/**
|
|
* Utility functions and helpers
|
|
*/
|
|
export class Utils {
|
|
/**
|
|
* Format file size in human readable format
|
|
*/
|
|
static formatFileSize(bytes) {
|
|
if (bytes === 0) return '0 B';
|
|
const k = 1024;
|
|
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
|
|
}
|
|
|
|
/**
|
|
* Handle thumbnail highlighting from URL parameters
|
|
*/
|
|
static handleThumbnailHighlight() {
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const highlightPlot = urlParams.get('highlight');
|
|
|
|
if (highlightPlot) {
|
|
// Find and highlight the thumbnail
|
|
const gridItems = document.querySelectorAll('.grid-item');
|
|
gridItems.forEach(item => {
|
|
const plotName = item.querySelector('.plot-name');
|
|
if (plotName && plotName.textContent.trim() === highlightPlot) {
|
|
item.classList.add('highlighted');
|
|
// Scroll to the highlighted item
|
|
setTimeout(() => {
|
|
item.scrollIntoView({
|
|
behavior: 'smooth',
|
|
block: 'center'
|
|
});
|
|
}, 100);
|
|
// Remove highlight after animation
|
|
setTimeout(() => {
|
|
item.classList.remove('highlighted');
|
|
}, 3000);
|
|
}
|
|
});
|
|
|
|
// Clean up URL
|
|
const newUrl = new URL(window.location);
|
|
newUrl.searchParams.delete('highlight');
|
|
window.history.replaceState({}, document.title, newUrl.toString());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculate approximate total size of displayed files
|
|
*/
|
|
static async calculateApproximateSize() {
|
|
const images = document.querySelectorAll('.grid-item img');
|
|
let totalSize = 0;
|
|
let loadedCount = 0;
|
|
|
|
const sizeElement = document.getElementById('totalSize');
|
|
if (!sizeElement) return;
|
|
|
|
sizeElement.textContent = 'Loading...';
|
|
|
|
// Estimate size based on a sample of images
|
|
const sampleSize = Math.min(images.length, 5);
|
|
const sampleImages = Array.from(images).slice(0, sampleSize);
|
|
|
|
if (sampleImages.length === 0) {
|
|
sizeElement.textContent = '0 KB';
|
|
return;
|
|
}
|
|
|
|
// Calculate average size from sample
|
|
for (const img of sampleImages) {
|
|
try {
|
|
const response = await fetch(img.src, { method: 'HEAD' });
|
|
const size = parseInt(response.headers.get('content-length') || '0');
|
|
if (size > 0) {
|
|
totalSize += size;
|
|
loadedCount++;
|
|
}
|
|
} catch (e) {
|
|
// Fallback: estimate 100KB per image
|
|
totalSize += 102400;
|
|
loadedCount++;
|
|
}
|
|
}
|
|
|
|
if (loadedCount > 0) {
|
|
const averageSize = totalSize / loadedCount;
|
|
const estimatedTotal = averageSize * images.length;
|
|
sizeElement.textContent = Utils.formatFileSize(estimatedTotal);
|
|
} else {
|
|
sizeElement.textContent = 'Unknown';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Toggle keyboard shortcuts help display
|
|
*/
|
|
static toggleShortcutsHelp() {
|
|
const help = document.getElementById('shortcutsHelp');
|
|
if (help) {
|
|
help.style.display = help.style.display === 'block' ? 'none' : 'block';
|
|
}
|
|
}
|
|
}
|