diff --git a/index.html b/index.html index 7f585bb..ee300d2 100644 --- a/index.html +++ b/index.html @@ -7,45 +7,67 @@ -

Index of /

- - -
-

Mode Développement

-
- - +
+ + + + +
+ +
+ + + + + + + + + + + + + +
+ + + +
- - - - - - - - - - - - - - - - - - - - -
-
MinIO Explorer
- \ No newline at end of file diff --git a/script.js b/script.js index 0541e5d..e389551 100644 --- a/script.js +++ b/script.js @@ -25,6 +25,10 @@ function setupEventListeners() { // Gestion de la navigation arrière/avant du navigateur window.addEventListener('popstate', handlePopState); + + // Gestionnaires pour la prévisualisation + document.getElementById('close-preview').addEventListener('click', hidePreview); + document.getElementById('download-file').addEventListener('click', downloadCurrentFile); } function handlePopState(event) { @@ -309,6 +313,9 @@ function displayContents(contents) { // Afficher le tableau document.getElementById('files-table').style.display = 'table'; + + // Chercher et ouvrir automatiquement index.rst s'il existe + autoOpenIndexRst(contents.files); } function createParentRow(parentPath) { @@ -360,7 +367,7 @@ function createFileRow(file) { row.innerHTML = ` - ${file.name} + ${file.name} ${formatFileSize(file.size)} ${formatDate(file.modified)} @@ -369,6 +376,12 @@ function createFileRow(file) { `; + const fileLink = row.querySelector('.file-link'); + fileLink.addEventListener('click', (e) => { + e.preventDefault(); + showPreview(fileUrl, file.name); + }); + const copyBtn = row.querySelector('.copy-btn'); copyBtn.addEventListener('click', () => copyToClipboard(fileUrl)); @@ -419,4 +432,399 @@ async function copyToClipboard(text) { document.execCommand('copy'); document.body.removeChild(textArea); } +} + +// Variables globales pour la prévisualisation +let currentPreviewFile = { + url: '', + name: '' +}; + +function detectFileType(fileName) { + const extension = fileName.toLowerCase().split('.').pop(); + + const fileTypes = { + images: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp'], + text: ['txt', 'json', 'xml', 'csv', 'log'], + code: ['js', 'css', 'html', 'htm', 'py', 'java', 'cpp', 'c', 'php', 'rb', 'go', 'rs', 'ts', 'jsx', 'tsx', 'vue', 'svelte', 'tex', 'latex'], + markdown: ['md', 'markdown'], + rst: ['rst', 'rest'], + pdf: ['pdf'], + video: ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv'], + audio: ['mp3', 'wav', 'ogg', 'aac', 'flac', 'm4a'], + archive: ['zip', 'rar', '7z', 'tar', 'gz', 'bz2'] + }; + + for (const [type, extensions] of Object.entries(fileTypes)) { + if (extensions.includes(extension)) { + return type; + } + } + + return 'unknown'; +} + +function showPreview(fileUrl, fileName) { + currentPreviewFile = { url: fileUrl, name: fileName }; + + const previewSection = document.getElementById('preview-section'); + const previewTitle = document.getElementById('preview-title'); + const previewContent = document.getElementById('preview-content'); + + previewTitle.textContent = `Prévisualisation: ${fileName}`; + previewContent.innerHTML = '
Chargement...
'; + + previewSection.style.display = 'flex'; + + const fileType = detectFileType(fileName); + + switch (fileType) { + case 'images': + showImagePreview(fileUrl, previewContent); + break; + case 'text': + case 'code': + showTextPreview(fileUrl, previewContent); + break; + case 'markdown': + showMarkdownPreview(fileUrl, previewContent); + break; + case 'rst': + showRstPreview(fileUrl, previewContent); + break; + case 'pdf': + showPdfPreview(fileUrl, previewContent); + break; + case 'video': + showVideoPreview(fileUrl, previewContent); + break; + case 'audio': + showAudioPreview(fileUrl, previewContent); + break; + default: + showUnsupportedPreview(fileName, previewContent); + } +} + +function showImagePreview(fileUrl, container) { + const img = document.createElement('img'); + img.src = fileUrl; + img.alt = 'Prévisualisation image'; + + img.onload = () => { + container.innerHTML = ''; + container.appendChild(img); + }; + + img.onerror = () => { + container.innerHTML = '
Erreur: Impossible de charger l\'image
'; + }; +} + +function showTextPreview(fileUrl, container) { + fetch(fileUrl) + .then(response => { + if (!response.ok) { + throw new Error(`Erreur HTTP: ${response.status}`); + } + return response.text(); + }) + .then(text => { + const pre = document.createElement('pre'); + pre.textContent = text; + container.innerHTML = ''; + container.appendChild(pre); + }) + .catch(error => { + console.error('Erreur chargement texte:', error); + container.innerHTML = '
Erreur: Impossible de charger le fichier texte
'; + }); +} + +function showPdfPreview(fileUrl, container) { + const iframe = document.createElement('iframe'); + iframe.src = fileUrl; + iframe.style.width = '100%'; + iframe.style.height = '500px'; + + container.innerHTML = ''; + container.appendChild(iframe); +} + +function showVideoPreview(fileUrl, container) { + const video = document.createElement('video'); + video.src = fileUrl; + video.controls = true; + video.style.maxWidth = '100%'; + + container.innerHTML = ''; + container.appendChild(video); +} + +function showAudioPreview(fileUrl, container) { + const audio = document.createElement('audio'); + audio.src = fileUrl; + audio.controls = true; + audio.style.width = '100%'; + + container.innerHTML = ''; + container.appendChild(audio); +} + +function showUnsupportedPreview(fileName, container) { + const extension = fileName.toLowerCase().split('.').pop(); + container.innerHTML = ` +
+

Prévisualisation non disponible pour ce type de fichier (.${extension})

+

Utilisez le bouton "Télécharger" ci-dessous pour obtenir le fichier.

+
+ `; +} + +function hidePreview() { + const previewSection = document.getElementById('preview-section'); + previewSection.style.display = 'none'; + + currentPreviewFile = { url: '', name: '' }; +} + +function downloadCurrentFile() { + if (currentPreviewFile.url) { + const link = document.createElement('a'); + link.href = currentPreviewFile.url; + link.download = currentPreviewFile.name; + link.target = '_blank'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } +} + +// Fonction pour ouvrir automatiquement index.rst s'il existe +function autoOpenIndexRst(files) { + // Chercher un fichier index.rst dans la liste + const indexRstFile = files.find(file => + file.name.toLowerCase() === 'index.rst' + ); + + if (indexRstFile) { + // Construire l'URL complète du fichier + const fileUrl = `${config.baseUrl}/${indexRstFile.fullKey}`; + + // Ouvrir automatiquement la prévisualisation + console.log('Auto-ouverture de index.rst trouvé:', indexRstFile.name); + showPreview(fileUrl, indexRstFile.name); + } else { + // Pas d'index.rst trouvé, fermer le preview s'il est ouvert + console.log('Aucun index.rst trouvé, fermeture du preview'); + hidePreview(); + } +} + +// Fonction simple de parsing Markdown vers HTML +function parseMarkdown(text) { + let html = text; + + // Headers + html = html.replace(/^### (.*$)/gim, '

$1

'); + html = html.replace(/^## (.*$)/gim, '

$1

'); + html = html.replace(/^# (.*$)/gim, '

$1

'); + + // Bold + html = html.replace(/\*\*(.*?)\*\*/g, '$1'); + html = html.replace(/__(.*?)__/g, '$1'); + + // Italic + html = html.replace(/\*(.*?)\*/g, '$1'); + html = html.replace(/_(.*?)_/g, '$1'); + + // Code inline + html = html.replace(/`(.*?)`/g, '$1'); + + // Code blocks + html = html.replace(/```([\s\S]*?)```/g, '
$1
'); + + // Links + html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); + + // Images + html = html.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '$1'); + + // Lists + html = html.replace(/^\* (.*$)/gim, '
  • $1
  • '); + html = html.replace(/^- (.*$)/gim, '
  • $1
  • '); + html = html.replace(/^\d+\. (.*$)/gim, '
  • $1
  • '); + + // Wrap consecutive
  • items in