Version 0.1.0
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* 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';
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user