# Рефакторинг отправки сообщений ## Проблема До рефакторинга существовало **три разных модуля**, пытающихся управлять отправкой сообщений: 1. **chatWebSocket.js** - WebSocket соединение и submit handler 2. **chat-detail-enhanced.js** - дублирующий WebSocket и рендеринг 3. **chatComposer.js** - файловые вложения + submit handler Это приводило к: - Дублированию сообщений (отправка через WebSocket + HTTP одновременно) - Конфликтам обработчиков submit - Дублированию кода рендеринга - Устаревшим inline onclick handlers в HTML ## Новая архитектура ### Разделение ответственности ``` ┌─────────────────────────────────────────────────────────────┐ │ ОТПРАВКА СООБЩЕНИЙ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌────────────────────┐ ┌────────────────────┐ │ │ │ Текстовое │ │ Сообщение с │ │ │ │ сообщение │ │ вложениями │ │ │ │ (без файлов) │ │ (файлы) │ │ │ └────────┬───────────┘ └────────┬───────────┘ │ │ │ │ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────┐ ┌──────────────────────┐ │ │ │ chatWebSocket.js │ │ chatComposer.js │ │ │ │ ───────────────── │ │ ──────────────── │ │ │ │ • WebSocket │ │ • HTTP API │ │ │ │ • Realtime │ │ • FormData upload │ │ │ │ • bindFormSubmit │ │ • Preview файлов │ │ │ │ • Instant delivery │ │ • Drag & drop │ │ │ └─────────────────────┘ └──────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ UI КОМПОНЕНТЫ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ chat-detail-enhanced.js (упрощен) │ │ ────────────────────────────────────── │ │ • MessageReactions - эмодзи реакции │ │ • MessageContextMenu - правая кнопка мыши │ │ • MessageSelection - выделение и пересылка │ │ • Наблюдатель за новыми сообщениями │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ## Файлы ### 1. chatWebSocket.js (base.html) **Ответственность**: WebSocket для текстовых сообщений ```javascript // Инициализация в base.html const chatWebSocket = initChatWebSocket({ chatId: {{ chat.id }}, meId: {{ user.id }}, bindFormSubmit: true, // ✅ Обрабатывает submit для текста // ... другие опции }); window.chatWebSocketApi = chatWebSocket; ``` **Обрабатывает**: - ✅ Текстовые сообщения без файлов → WebSocket (мгновенно) - ✅ Индикация "печатает..." - ✅ Получение входящих сообщений - ✅ Рендеринг новых сообщений через chatMessageTemplates.js - ✅ Разделители дней - ✅ Переподключение при обрыве ### 2. chatComposer.js (chat_detail.html) **Ответственность**: HTTP API для вложений ```javascript async handleSubmit(event) { const content = this.textarea.value.trim(); // Если нет файлов - НЕ перехватываем событие if (this.selectedFiles.length === 0) { // event.preventDefault() НЕ вызывается return; // Пропускаем к chatWebSocket } // Есть файлы - обрабатываем сами event.preventDefault(); await this.sendViaHTTP(content, this.selectedFiles); } ``` **Обрабатывает**: - ✅ Сообщения с вложениями → HTTP API `/api/v1/communications/upload-message/` - ✅ Drag & drop файлов - ✅ Preview прикрепленных файлов - ✅ Emoji picker - ✅ Кнопки прикрепления (документ, фото, камера, аудио) ### 3. chat-detail-enhanced.js **Ответственность**: UI компоненты (упрощен) **УДАЛЕНО** (вынесено в chatWebSocket.js): - ❌ WebSocket соединение - ❌ handleWebSocketMessage - ❌ renderMessage - ❌ submit handler - ❌ Typing индикация - ❌ inline onclick="addReaction()" кнопки **ОСТАВЛЕНО**: - ✅ MessageReactions - система реакций - ✅ MessageContextMenu - контекстное меню - ✅ MessageSelection - выделение сообщений - ✅ Наблюдатель MutationObserver для новых сообщений - ✅ Инициализация компонентов на существующих сообщениях ## Порядок выполнения ### Отправка текстового сообщения (без файлов) ``` 1. User: нажимает Enter или кнопку "Отправить" 2. Event: submit на форме #chatForm 3. chatComposer.handleSubmit(): - Проверяет: selectedFiles.length === 0 - НЕ вызывает event.preventDefault() - return (пропускает событие дальше) 4. chatWebSocket.handleFormSubmit(): - event.preventDefault() - ws.send(JSON.stringify({ content: text })) - Очищает textarea 5. Backend: ChatConsumer.receive_json() - Создает Message в БД - Отправляет в группу chat_{id} 6. Frontend: chatWebSocket получает WebSocket message - Рендерит через createMessageElement() - Добавляет в DOM 7. chat-detail-enhanced.js: MutationObserver - Обнаруживает новое сообщение - Инициализирует реакции и контекстное меню ``` ### Отправка сообщения с файлами ``` 1. User: прикрепляет файл + пишет текст 2. Event: submit на форме #chatForm 3. chatComposer.handleSubmit(): - Проверяет: selectedFiles.length > 0 - event.preventDefault() ✅ - Создает FormData с файлами - POST /api/v1/communications/upload-message/ 4. Backend: upload_message view - Создает Message в БД - Сохраняет Attachment - Отправляет через WebSocket в группу 5. Frontend: chatWebSocket получает WebSocket message - Рендерит сообщение с вложениями 6. chat-detail-enhanced.js: инициализирует UI компоненты ``` ## Удаленные дубликаты ### Из chat-detail-enhanced.js удалено: 1. **WebSocket соединение** (580 строк) ```javascript // БЫЛО: let ws = null; function connectWebSocket() { ... } function handleWebSocketMessage(data) { ... } // ТЕПЕРЬ: используется chatWebSocket.js из base.html ``` 2. **Рендеринг сообщений** (200+ строк) ```javascript // БЫЛО: function renderMessage(msg, isMe) { let html = `