audio files playback added

This commit is contained in:
Ryan
2025-03-27 13:14:14 -04:00
committed by GitHub
parent ecb4ac2c75
commit 32469778dc
3 changed files with 33 additions and 95 deletions

View File

@@ -34,7 +34,7 @@ FileRise is a lightweight, secure, self-hosted web application for uploading, sy
- **Enhanced File Editing Check:** Files with a Content-Length of 0 KB are now allowed to be edited. - **Enhanced File Editing Check:** Files with a Content-Length of 0 KB are now allowed to be edited.
- **Built-in File Preview:** - **Built-in File Preview:**
- Users can quickly preview images, videos, and PDFs directly in modal popups without leaving the page. - Users can quickly preview images, videos, audio and PDFs directly in modal popups without leaving the page.
- The preview modal supports inline display of images (with proper scaling) and videos with playback controls. - The preview modal supports inline display of images (with proper scaling) and videos with playback controls.
- Navigation (prev/next) within image previews is supported for a seamless browsing experience. - Navigation (prev/next) within image previews is supported for a seamless browsing experience.

View File

@@ -136,18 +136,20 @@ export function buildFileTableRow(file, folderPath) {
const safeUploader = escapeHTML(file.uploader || "Unknown"); const safeUploader = escapeHTML(file.uploader || "Unknown");
let previewButton = ""; let previewButton = "";
if (/\.(jpg|jpeg|png|gif|bmp|webp|svg|ico|tif|tiff|eps|heic|pdf|mp4|webm|mov|ogg)$/i.test(file.name)) { if (/\.(jpg|jpeg|png|gif|bmp|webp|svg|ico|tif|tiff|eps|heic|pdf|mp4|webm|mov|mp3|wav|m4a|ogg|flac|aac|wma|opus)$/i.test(file.name)) {
let previewIcon = ""; let previewIcon = "";
if (/\.(jpg|jpeg|png|gif|bmp|webp|svg|ico|tif|tiff|eps|heic)$/i.test(file.name)) { if (/\.(jpg|jpeg|png|gif|bmp|webp|svg|ico|tif|tiff|eps|heic)$/i.test(file.name)) {
previewIcon = `<i class="material-icons">image</i>`; previewIcon = `<i class="material-icons">image</i>`;
} else if (/\.(mp4|webm|mov|ogg)$/i.test(file.name)) { } else if (/\.(mp4|webm|mov)$/i.test(file.name)) {
previewIcon = `<i class="material-icons">videocam</i>`; previewIcon = `<i class="material-icons">videocam</i>`;
} else if (/\.pdf$/i.test(file.name)) { } else if (/\.pdf$/i.test(file.name)) {
previewIcon = `<i class="material-icons">picture_as_pdf</i>`; previewIcon = `<i class="material-icons">picture_as_pdf</i>`;
} else if (/\.(mp3|wav|m4a|ogg|flac|aac|wma|opus)$/i.test(file.name)) {
previewIcon = `<i class="material-icons">audiotrack</i>`;
} }
previewButton = `<button class="btn btn-sm btn-info preview-btn" onclick="event.stopPropagation(); previewFile('${folderPath + encodeURIComponent(file.name)}', '${safeFileName}')"> previewButton = `<button class="btn btn-sm btn-info preview-btn" onclick="event.stopPropagation(); previewFile('${folderPath + encodeURIComponent(file.name)}', '${safeFileName}')">
${previewIcon} ${previewIcon}
</button>`; </button>`;
} }
return ` return `
@@ -231,86 +233,6 @@ export function toggleRowSelection(event, fileName) {
updateFileActionButtons(); updateFileActionButtons();
} }
export function previewFile(fileUrl, fileName) {
let modal = document.getElementById("filePreviewModal");
if (!modal) {
modal = document.createElement("div");
modal.id = "filePreviewModal";
Object.assign(modal.style, {
display: "none",
position: "fixed",
top: "0",
left: "0",
width: "100vw",
height: "100vh",
backgroundColor: "rgba(0,0,0,0.7)",
display: "flex",
justifyContent: "center",
alignItems: "center",
zIndex: "1000"
});
modal.innerHTML = `
<div class="modal-content image-preview-modal-content">
<span id="closeFileModal" class="close-image-modal">&times;</span>
<h4 class="image-modal-header"></h4>
<div class="file-preview-container"></div>
</div>`;
document.body.appendChild(modal);
document.getElementById("closeFileModal").addEventListener("click", function () {
const video = modal.querySelector("video");
if (video) {
video.pause();
video.currentTime = 0;
}
modal.style.display = "none";
});
modal.addEventListener("click", function (e) {
if (e.target === modal) {
const video = modal.querySelector("video");
if (video) {
video.pause();
video.currentTime = 0;
}
modal.style.display = "none";
}
});
}
modal.querySelector("h4").textContent = fileName;
const container = modal.querySelector(".file-preview-container");
container.innerHTML = "";
const extension = fileName.split('.').pop().toLowerCase();
if (/\.(jpg|jpeg|png|gif|bmp|webp|svg|ico|tif|tiff|eps|heic)$/i.test(fileName)) {
const img = document.createElement("img");
img.src = fileUrl;
img.className = "image-modal-img";
container.appendChild(img);
} else if (extension === "pdf") {
const embed = document.createElement("embed");
const separator = fileUrl.indexOf('?') === -1 ? '?' : '&';
embed.src = fileUrl + separator + 't=' + new Date().getTime();
embed.type = "application/pdf";
embed.style.width = "80vw";
embed.style.height = "80vh";
embed.style.border = "none";
container.appendChild(embed);
} else if (/\.(mp4|webm|mov|ogg)$/i.test(fileName)) {
const video = document.createElement("video");
video.src = fileUrl;
video.controls = true;
video.className = "image-modal-img";
container.appendChild(video);
} else {
container.textContent = "Preview not available for this file type.";
}
modal.style.display = "flex";
}
export function attachEnterKeyListener(modalId, buttonId) { export function attachEnterKeyListener(modalId, buttonId) {
const modal = document.getElementById(modalId); const modal = document.getElementById(modalId);
if (modal) { if (modal) {

View File

@@ -9,8 +9,7 @@ import {
showToast, showToast,
updateRowHighlight, updateRowHighlight,
toggleRowSelection, toggleRowSelection,
attachEnterKeyListener, attachEnterKeyListener
previewFile as originalPreviewFile
} from './domUtils.js'; } from './domUtils.js';
export let fileData = []; export let fileData = [];
@@ -153,7 +152,7 @@ function openShareModal(file, folder) {
// ============================================== // ==============================================
// FEATURE: Enhanced Preview Modal with Navigation // FEATURE: Enhanced Preview Modal with Navigation
// ============================================== // ==============================================
function enhancedPreviewFile(fileUrl, fileName) { function previewFile(fileUrl, fileName) {
let modal = document.getElementById("filePreviewModal"); let modal = document.getElementById("filePreviewModal");
if (!modal) { if (!modal) {
modal = document.createElement("div"); modal = document.createElement("div");
@@ -178,12 +177,24 @@ function enhancedPreviewFile(fileUrl, fileName) {
</div>`; </div>`;
document.body.appendChild(modal); document.body.appendChild(modal);
document.getElementById("closeFileModal").addEventListener("click", function () { function closeModal() {
// Pause and reset any video or audio elements within the modal
const mediaElements = modal.querySelectorAll("video, audio");
mediaElements.forEach(media => {
media.pause();
try {
media.currentTime = 0;
} catch(e) {
// Some media types might not support setting currentTime.
}
});
modal.style.display = "none"; modal.style.display = "none";
}); }
document.getElementById("closeFileModal").addEventListener("click", closeModal);
modal.addEventListener("click", function (e) { modal.addEventListener("click", function (e) {
if (e.target === modal) { if (e.target === modal) {
modal.style.display = "none"; closeModal();
} }
}); });
} }
@@ -253,6 +264,13 @@ function enhancedPreviewFile(fileUrl, fileName) {
video.controls = true; video.controls = true;
video.className = "image-modal-img"; video.className = "image-modal-img";
container.appendChild(video); container.appendChild(video);
} else if (/\.(mp3|wav|m4a|ogg|flac|aac|wma|opus)$/i.test(fileName)) {
const audio = document.createElement("audio");
audio.src = fileUrl;
audio.controls = true;
audio.className = "audio-modal";
audio.style.maxWidth = "80vw";
container.appendChild(audio);
} else { } else {
container.textContent = "Preview not available for this file type."; container.textContent = "Preview not available for this file type.";
} }
@@ -260,10 +278,6 @@ function enhancedPreviewFile(fileUrl, fileName) {
modal.style.display = "flex"; modal.style.display = "flex";
} }
export function previewFile(fileUrl, fileName) {
enhancedPreviewFile(fileUrl, fileName);
}
// ============================================== // ==============================================
// ORIGINAL FILE MANAGER FUNCTIONS // ORIGINAL FILE MANAGER FUNCTIONS
// ============================================== // ==============================================
@@ -519,6 +533,8 @@ export function renderGalleryView(folder) {
let thumbnail; let thumbnail;
if (/\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)$/i.test(file.name)) { if (/\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)$/i.test(file.name)) {
thumbnail = `<img src="${folderPath + encodeURIComponent(file.name)}?t=${new Date().getTime()}" class="gallery-thumbnail" alt="${escapeHTML(file.name)}" style="max-width: 100%; max-height: 150px; display: block; margin: 0 auto;">`; thumbnail = `<img src="${folderPath + encodeURIComponent(file.name)}?t=${new Date().getTime()}" class="gallery-thumbnail" alt="${escapeHTML(file.name)}" style="max-width: 100%; max-height: 150px; display: block; margin: 0 auto;">`;
} else if (/\.(mp3|wav|ogg|m4a)$/i.test(file.name)) {
thumbnail = `<span class="material-icons gallery-icon">audiotrack</span>`;
} else { } else {
thumbnail = `<span class="material-icons gallery-icon">insert_drive_file</span>`; thumbnail = `<span class="material-icons gallery-icon">insert_drive_file</span>`;
} }