diff --git a/backend/static/js/components/chatComposer.js b/backend/static/js/components/chatComposer.js index 5d05124a..7d5e75cb 100644 --- a/backend/static/js/components/chatComposer.js +++ b/backend/static/js/components/chatComposer.js @@ -629,22 +629,46 @@ class ChatComposer { this.preview.innerHTML = ''; this.selectedFiles.forEach((entry) => { + const isImage = entry.file.type.startsWith('image/'); const iconClass = pickIcon(entry.file.type); const wrapper = document.createElement('div'); wrapper.className = 'attachment-item d-flex align-items-center gap-2 p-2 rounded mb-2'; - wrapper.innerHTML = ` - -
-
${entry.file.name}
-
${formatFileSize(entry.file.size)}
-
- - `; + + // Для изображений показываем превью + if (isImage) { + const imgUrl = URL.createObjectURL(entry.file); + wrapper.innerHTML = ` + ${entry.file.name} +
+
${entry.file.name}
+
${formatFileSize(entry.file.size)}
+
+ + `; + } else { + // Для других файлов - иконка + wrapper.innerHTML = ` + +
+
${entry.file.name}
+
${formatFileSize(entry.file.size)}
+
+ + `; + } wrapper.querySelector('button')?.addEventListener('click', () => { this.removeFile(entry.id); + // Очищаем URL.createObjectURL для изображений + if (isImage) { + const img = wrapper.querySelector('img'); + if (img) URL.revokeObjectURL(img.src); + } }); this.preview.appendChild(wrapper); diff --git a/backend/static/js/renderers/messageRendererV2.js b/backend/static/js/renderers/messageRendererV2.js index 30ef81ce..ed3f7ae5 100644 --- a/backend/static/js/renderers/messageRendererV2.js +++ b/backend/static/js/renderers/messageRendererV2.js @@ -659,24 +659,54 @@ export class MessageRendererV2 { const fileUrl = att.file_url || att.url || '#'; const fileSize = att.file_size || att.size || 0; const fileType = att.file_type || att.type || ''; + const thumbnailUrl = att.thumbnail || null; - // Форматируем размер + // Рендеринг изображений + if (fileType === 'image' || fileType.startsWith('image/')) { + const imgSrc = thumbnailUrl || fileUrl; + return ` + + ${fileName} + + `; + } + + // Рендеринг видео + if (fileType === 'video' || fileType.startsWith('video/')) { + return ` +
+ +
+ `; + } + + // Форматируем размер для файлов const sizeStr = fileSize > 0 ? `${(fileSize / 1024).toFixed(1)} KB` : ''; - // Определяем иконку по типу + // Определяем иконку для файлов let icon = 'bi-file-earmark'; - if (fileType.startsWith('image/')) { - icon = 'bi-file-image'; - } else if (fileType.startsWith('video/')) { - icon = 'bi-file-play'; - } else if (fileType.includes('pdf')) { + if (fileType.includes('pdf')) { icon = 'bi-file-pdf'; } else if (fileType.includes('word') || fileType.includes('document')) { icon = 'bi-file-word'; + } else if (fileType.startsWith('audio/')) { + icon = 'bi-file-music'; } + // Рендеринг обычных файлов (документы, аудио и т.д.) return `