|
|
|
@@ -99,6 +99,8 @@
|
|
|
|
const previewMetadataList = document.getElementById('preview-metadata-list');
|
|
|
|
const previewMetadataList = document.getElementById('preview-metadata-list');
|
|
|
|
const previewPlaceholder = document.getElementById('preview-placeholder');
|
|
|
|
const previewPlaceholder = document.getElementById('preview-placeholder');
|
|
|
|
const previewPlaceholderDefault = previewPlaceholder ? previewPlaceholder.innerHTML : '';
|
|
|
|
const previewPlaceholderDefault = previewPlaceholder ? previewPlaceholder.innerHTML : '';
|
|
|
|
|
|
|
|
const previewErrorAlert = document.getElementById('preview-error-alert');
|
|
|
|
|
|
|
|
const previewDetailsMeta = document.getElementById('preview-details-meta');
|
|
|
|
const previewImage = document.getElementById('preview-image');
|
|
|
|
const previewImage = document.getElementById('preview-image');
|
|
|
|
const previewVideo = document.getElementById('preview-video');
|
|
|
|
const previewVideo = document.getElementById('preview-video');
|
|
|
|
const previewAudio = document.getElementById('preview-audio');
|
|
|
|
const previewAudio = document.getElementById('preview-audio');
|
|
|
|
@@ -1990,6 +1992,34 @@
|
|
|
|
previewPlaceholder.classList.remove('d-none');
|
|
|
|
previewPlaceholder.classList.remove('d-none');
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let previewFailed = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handlePreviewError = () => {
|
|
|
|
|
|
|
|
previewFailed = true;
|
|
|
|
|
|
|
|
if (downloadButton) {
|
|
|
|
|
|
|
|
downloadButton.classList.add('disabled');
|
|
|
|
|
|
|
|
downloadButton.removeAttribute('href');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (presignButton) presignButton.disabled = true;
|
|
|
|
|
|
|
|
if (generatePresignButton) generatePresignButton.disabled = true;
|
|
|
|
|
|
|
|
if (previewDetailsMeta) previewDetailsMeta.classList.add('d-none');
|
|
|
|
|
|
|
|
if (previewMetadata) previewMetadata.classList.add('d-none');
|
|
|
|
|
|
|
|
const tagsPanel = document.getElementById('preview-tags');
|
|
|
|
|
|
|
|
if (tagsPanel) tagsPanel.classList.add('d-none');
|
|
|
|
|
|
|
|
const versionPanel = document.getElementById('version-panel');
|
|
|
|
|
|
|
|
if (versionPanel) versionPanel.classList.add('d-none');
|
|
|
|
|
|
|
|
if (previewErrorAlert) {
|
|
|
|
|
|
|
|
previewErrorAlert.textContent = 'Unable to load object \u2014 it may have been deleted, or the server returned an error.';
|
|
|
|
|
|
|
|
previewErrorAlert.classList.remove('d-none');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const clearPreviewError = () => {
|
|
|
|
|
|
|
|
previewFailed = false;
|
|
|
|
|
|
|
|
if (previewErrorAlert) previewErrorAlert.classList.add('d-none');
|
|
|
|
|
|
|
|
if (previewDetailsMeta) previewDetailsMeta.classList.remove('d-none');
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
async function fetchMetadata(metadataUrl) {
|
|
|
|
async function fetchMetadata(metadataUrl) {
|
|
|
|
if (!metadataUrl) return null;
|
|
|
|
if (!metadataUrl) return null;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
@@ -2011,6 +2041,7 @@
|
|
|
|
previewPanel.classList.remove('d-none');
|
|
|
|
previewPanel.classList.remove('d-none');
|
|
|
|
activeRow = row;
|
|
|
|
activeRow = row;
|
|
|
|
renderMetadata(null);
|
|
|
|
renderMetadata(null);
|
|
|
|
|
|
|
|
clearPreviewError();
|
|
|
|
|
|
|
|
|
|
|
|
previewKey.textContent = row.dataset.key;
|
|
|
|
previewKey.textContent = row.dataset.key;
|
|
|
|
previewSize.textContent = formatBytes(Number(row.dataset.size));
|
|
|
|
previewSize.textContent = formatBytes(Number(row.dataset.size));
|
|
|
|
@@ -2036,25 +2067,69 @@
|
|
|
|
if (previewUrl && lower.match(/\.(png|jpg|jpeg|gif|webp|svg|ico|bmp)$/)) {
|
|
|
|
if (previewUrl && lower.match(/\.(png|jpg|jpeg|gif|webp|svg|ico|bmp)$/)) {
|
|
|
|
previewPlaceholder.innerHTML = '<div class="spinner-border spinner-border-sm text-secondary" role="status"></div><div class="small mt-2">Loading preview\u2026</div>';
|
|
|
|
previewPlaceholder.innerHTML = '<div class="spinner-border spinner-border-sm text-secondary" role="status"></div><div class="small mt-2">Loading preview\u2026</div>';
|
|
|
|
const currentRow = row;
|
|
|
|
const currentRow = row;
|
|
|
|
previewImage.onload = () => {
|
|
|
|
fetch(previewUrl)
|
|
|
|
if (activeRow !== currentRow) return;
|
|
|
|
.then((r) => {
|
|
|
|
previewImage.classList.remove('d-none');
|
|
|
|
if (activeRow !== currentRow) return;
|
|
|
|
previewPlaceholder.classList.add('d-none');
|
|
|
|
if (!r.ok) {
|
|
|
|
};
|
|
|
|
previewPlaceholder.innerHTML = '<div class="small text-muted">Failed to load preview</div>';
|
|
|
|
previewImage.onerror = () => {
|
|
|
|
handlePreviewError();
|
|
|
|
if (activeRow !== currentRow) return;
|
|
|
|
return;
|
|
|
|
previewPlaceholder.innerHTML = '<div class="small text-muted">Failed to load preview</div>';
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return r.blob();
|
|
|
|
previewImage.src = previewUrl;
|
|
|
|
})
|
|
|
|
|
|
|
|
.then((blob) => {
|
|
|
|
|
|
|
|
if (!blob || activeRow !== currentRow) return;
|
|
|
|
|
|
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
|
|
|
|
previewImage.onload = () => {
|
|
|
|
|
|
|
|
if (activeRow !== currentRow) { URL.revokeObjectURL(url); return; }
|
|
|
|
|
|
|
|
previewImage.classList.remove('d-none');
|
|
|
|
|
|
|
|
previewPlaceholder.classList.add('d-none');
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
previewImage.onerror = () => {
|
|
|
|
|
|
|
|
if (activeRow !== currentRow) { URL.revokeObjectURL(url); return; }
|
|
|
|
|
|
|
|
URL.revokeObjectURL(url);
|
|
|
|
|
|
|
|
previewPlaceholder.innerHTML = '<div class="small text-muted">Failed to load preview</div>';
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
previewImage.src = url;
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.catch(() => {
|
|
|
|
|
|
|
|
if (activeRow !== currentRow) return;
|
|
|
|
|
|
|
|
previewPlaceholder.innerHTML = '<div class="small text-muted">Failed to load preview</div>';
|
|
|
|
|
|
|
|
handlePreviewError();
|
|
|
|
|
|
|
|
});
|
|
|
|
} else if (previewUrl && lower.match(/\.(mp4|webm|ogv|mov|avi|mkv)$/)) {
|
|
|
|
} else if (previewUrl && lower.match(/\.(mp4|webm|ogv|mov|avi|mkv)$/)) {
|
|
|
|
|
|
|
|
const currentRow = row;
|
|
|
|
|
|
|
|
previewVideo.onerror = () => {
|
|
|
|
|
|
|
|
if (activeRow !== currentRow) return;
|
|
|
|
|
|
|
|
previewVideo.classList.add('d-none');
|
|
|
|
|
|
|
|
previewPlaceholder.classList.remove('d-none');
|
|
|
|
|
|
|
|
previewPlaceholder.innerHTML = '<div class="small text-muted">Failed to load preview</div>';
|
|
|
|
|
|
|
|
handlePreviewError();
|
|
|
|
|
|
|
|
};
|
|
|
|
previewVideo.src = previewUrl;
|
|
|
|
previewVideo.src = previewUrl;
|
|
|
|
previewVideo.classList.remove('d-none');
|
|
|
|
previewVideo.classList.remove('d-none');
|
|
|
|
previewPlaceholder.classList.add('d-none');
|
|
|
|
previewPlaceholder.classList.add('d-none');
|
|
|
|
} else if (previewUrl && lower.match(/\.(mp3|wav|flac|ogg|aac|m4a|wma)$/)) {
|
|
|
|
} else if (previewUrl && lower.match(/\.(mp3|wav|flac|ogg|aac|m4a|wma)$/)) {
|
|
|
|
|
|
|
|
const currentRow = row;
|
|
|
|
|
|
|
|
previewAudio.onerror = () => {
|
|
|
|
|
|
|
|
if (activeRow !== currentRow) return;
|
|
|
|
|
|
|
|
previewAudio.classList.add('d-none');
|
|
|
|
|
|
|
|
previewPlaceholder.classList.remove('d-none');
|
|
|
|
|
|
|
|
previewPlaceholder.innerHTML = '<div class="small text-muted">Failed to load preview</div>';
|
|
|
|
|
|
|
|
handlePreviewError();
|
|
|
|
|
|
|
|
};
|
|
|
|
previewAudio.src = previewUrl;
|
|
|
|
previewAudio.src = previewUrl;
|
|
|
|
previewAudio.classList.remove('d-none');
|
|
|
|
previewAudio.classList.remove('d-none');
|
|
|
|
previewPlaceholder.classList.add('d-none');
|
|
|
|
previewPlaceholder.classList.add('d-none');
|
|
|
|
} else if (previewUrl && lower.match(/\.(pdf)$/)) {
|
|
|
|
} else if (previewUrl && lower.match(/\.(pdf)$/)) {
|
|
|
|
|
|
|
|
const currentRow = row;
|
|
|
|
|
|
|
|
previewIframe.onerror = () => {
|
|
|
|
|
|
|
|
if (activeRow !== currentRow) return;
|
|
|
|
|
|
|
|
previewIframe.classList.add('d-none');
|
|
|
|
|
|
|
|
previewPlaceholder.classList.remove('d-none');
|
|
|
|
|
|
|
|
previewPlaceholder.innerHTML = '<div class="small text-muted">Failed to load preview</div>';
|
|
|
|
|
|
|
|
handlePreviewError();
|
|
|
|
|
|
|
|
};
|
|
|
|
previewIframe.src = previewUrl;
|
|
|
|
previewIframe.src = previewUrl;
|
|
|
|
previewIframe.style.minHeight = '500px';
|
|
|
|
previewIframe.style.minHeight = '500px';
|
|
|
|
previewIframe.classList.remove('d-none');
|
|
|
|
previewIframe.classList.remove('d-none');
|
|
|
|
@@ -2079,14 +2154,17 @@
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
.catch(() => {
|
|
|
|
if (activeRow !== currentRow) return;
|
|
|
|
if (activeRow !== currentRow) return;
|
|
|
|
previewText.textContent = 'Failed to load preview';
|
|
|
|
previewText.classList.add('d-none');
|
|
|
|
|
|
|
|
previewPlaceholder.classList.remove('d-none');
|
|
|
|
|
|
|
|
previewPlaceholder.innerHTML = '<div class="small text-muted">Failed to load preview</div>';
|
|
|
|
|
|
|
|
handlePreviewError();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const metadataUrl = row.dataset.metadataUrl;
|
|
|
|
const metadataUrl = row.dataset.metadataUrl;
|
|
|
|
if (metadataUrl) {
|
|
|
|
if (metadataUrl) {
|
|
|
|
const metadata = await fetchMetadata(metadataUrl);
|
|
|
|
const metadata = await fetchMetadata(metadataUrl);
|
|
|
|
if (activeRow === row) {
|
|
|
|
if (activeRow === row && !previewFailed) {
|
|
|
|
renderMetadata(metadata);
|
|
|
|
renderMetadata(metadata);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -3993,6 +4071,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
const loadObjectTags = async (row) => {
|
|
|
|
const loadObjectTags = async (row) => {
|
|
|
|
if (!row || !previewTagsPanel) return;
|
|
|
|
if (!row || !previewTagsPanel) return;
|
|
|
|
|
|
|
|
if (previewFailed) {
|
|
|
|
|
|
|
|
previewTagsPanel.classList.add('d-none');
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
const tagsUrl = row.dataset.tagsUrl;
|
|
|
|
const tagsUrl = row.dataset.tagsUrl;
|
|
|
|
if (!tagsUrl) {
|
|
|
|
if (!tagsUrl) {
|
|
|
|
previewTagsPanel.classList.add('d-none');
|
|
|
|
previewTagsPanel.classList.add('d-none');
|
|
|
|
|