/** * Chat Form Manager * Управляет состоянием формы отправки сообщений * - Обычная отправка * - Редактирование сообщения * - Ответ на сообщение */ export function initChatFormManager(options = {}) { const { formId = 'chatForm', textareaId = 'id_content', chatId, uploadUrl = '/api/v1/communications/upload-message/', editUrlTemplate = '/api/v1/communications/messages/{id}/edit/', } = options; const form = document.getElementById(formId); const textarea = document.getElementById(textareaId); if (!form || !textarea) { console.warn('[ChatFormManager] Form or textarea not found'); return null; } // Состояние формы const state = { mode: 'send', // 'send' | 'edit' | 'reply' editMessageId: null, replyToMessageId: null, originalAction: form.action, originalMethod: form.method, }; // ==================== API ==================== /** * Переключить форму в режим обычной отправки */ function setModeToSend() { state.mode = 'send'; state.editMessageId = null; state.replyToMessageId = null; // Восстанавливаем action form.action = uploadUrl; form.method = 'POST'; // Удаляем hidden поля removeHiddenInput('message_id'); removeHiddenInput('reply_to'); // Удаляем индикаторы removeEditIndicator(); removeReplyIndicator(); // Очищаем текст textarea.value = ''; textarea.placeholder = 'Напишите сообщение…'; textarea.focus(); console.log('[ChatFormManager] Mode: SEND'); } /** * Переключить форму в режим редактирования */ function setModeToEdit(messageId, currentContent) { if (!messageId) { console.error('[ChatFormManager] messageId required for edit mode'); return; } state.mode = 'edit'; state.editMessageId = messageId; state.replyToMessageId = null; // Меняем action на API редактирования const editUrl = editUrlTemplate.replace('{id}', messageId); form.action = editUrl; form.method = 'POST'; // Добавляем hidden input для message_id (на всякий случай) addHiddenInput('message_id', messageId); // Удаляем reply_to если был removeHiddenInput('reply_to'); // Удаляем индикатор ответа removeReplyIndicator(); // Показываем индикатор редактирования showEditIndicator(messageId, currentContent); // Заполняем textarea текущим содержимым textarea.value = currentContent || ''; textarea.placeholder = 'Редактирование сообщения…'; textarea.focus(); // Курсор в конец textarea.setSelectionRange(textarea.value.length, textarea.value.length); console.log('[ChatFormManager] Mode: EDIT', messageId); } /** * Переключить форму в режим ответа */ function setModeToReply(messageId, authorName, messagePreview) { if (!messageId) { console.error('[ChatFormManager] messageId required for reply mode'); return; } // Если было редактирование - сбрасываем if (state.mode === 'edit') { form.action = uploadUrl; form.method = 'POST'; removeHiddenInput('message_id'); removeEditIndicator(); } state.mode = 'reply'; state.editMessageId = null; state.replyToMessageId = messageId; // Action остаётся обычным (upload-message) form.action = uploadUrl; form.method = 'POST'; // Добавляем hidden input reply_to addHiddenInput('reply_to', messageId); // Показываем индикатор ответа showReplyIndicator(messageId, authorName, messagePreview); // Фокус на textarea textarea.placeholder = `Ответ на сообщение от ${authorName}…`; textarea.focus(); console.log('[ChatFormManager] Mode: REPLY', messageId); } /** * Отменить текущее действие (вернуться к обычной отправке) */ function cancel() { setModeToSend(); } /** * Получить текущий режим */ function getMode() { return state.mode; } /** * Получить данные для отправки */ function getFormData() { return { mode: state.mode, editMessageId: state.editMessageId, replyToMessageId: state.replyToMessageId, content: textarea.value.trim(), }; } // ==================== HELPER FUNCTIONS ==================== function addHiddenInput(name, value) { // Удаляем если уже есть removeHiddenInput(name); const input = document.createElement('input'); input.type = 'hidden'; input.name = name; input.value = value; input.dataset.chatFormManager = '1'; form.appendChild(input); } function removeHiddenInput(name) { const existing = form.querySelector(`input[name="${name}"][data-chat-form-manager="1"]`); if (existing) { existing.remove(); } } function showEditIndicator(messageId, content) { removeEditIndicator(); const preview = content.length > 50 ? content.substring(0, 50) + '…' : content; const indicator = document.createElement('div'); indicator.className = 'edit-indicator alert alert-warning d-flex align-items-center justify-content-between py-2 px-3 mb-2'; indicator.dataset.editIndicator = '1'; indicator.innerHTML = `