function app(socket) { return { wysiwyg: null, socket: socket, typingTimeout: null, init: function (el) { this.wysiwyg = el; this.setupWysiwyg(); }, setupWysiwyg: function () { this.updateTextarea(); this.wysiwyg.contentDocument.body.addEventListener('input', this.onInput.bind(this)); this.wysiwyg.contentDocument.querySelector('head').innerHTML += ``; this.wysiwyg.contentDocument.body.innerHTML = ''; this.wysiwyg.contentDocument.designMode = "on"; }, onInput: function () { this.updateTextarea(); this.sendTypingEvent(); }, updateTextarea: function () { var wrapperDiv = document.createElement('div'); wrapperDiv.className = this.wysiwyg.classList.contains('rtl') ? 'rtl' : 'ltr'; wrapperDiv.innerHTML = this.wysiwyg.contentDocument.body.innerHTML; document.getElementById('textEditor').value = wrapperDiv.outerHTML; }, sendTypingEvent: function () { if (this.socket && this.socket.readyState === WebSocket.OPEN) { clearTimeout(this.typingTimeout); const data = { event_type: 'typing' }; this.socket.send(JSON.stringify(data)); this.typingTimeout = setTimeout(() => { const stopTypingData = { event_type: 'stop_typing' }; this.socket.send(JSON.stringify(stopTypingData)); }, 1500); } }, format: function (cmd, param) { this.wysiwyg.contentDocument.execCommand(cmd, false, param || null); this.updateTextarea(); }, setDirection: function (direction) { this.wysiwyg.classList.remove('rtl', 'ltr'); this.wysiwyg.contentDocument.body.classList.remove('rtl', 'ltr'); document.getElementById('textEditor').classList.remove('rtl', 'ltr'); this.wysiwyg.classList.add(direction); this.wysiwyg.contentDocument.body.classList.add(direction); document.getElementById('textEditor').classList.add(direction); this.wysiwyg.contentDocument.body.style.direction = direction; this.updateTextarea(); } } } function initializeWebSocket() { const ticketId = document.getElementById('ticketId').textContent.trim(); const wsUrl = `wss://${window.location.host}/ws/ticketroom/${ticketId}/`; const socket = new WebSocket(wsUrl); socket.onopen = () => { console.log('WebSocket connection established'); const appInstance = app(socket); const wysiwygElement = document.querySelector('iframe'); appInstance.init(wysiwygElement); }; let typingTimeout; socket.onmessage = (event) => { const data = JSON.parse(event.data); const typingDiv = document.getElementById('typing-notification'); const messagesDiv = document.getElementById('messages'); if (data.event_type === 'typing') { clearTimeout(typingTimeout); if (!typingDiv.classList.contains('fade-in-up')) { typingDiv.innerHTML = data.html; typingDiv.classList.remove('fade-out'); typingDiv.classList.add('fade-in-up'); } } else if (data.event_type === 'stop_typing') { if (!typingDiv.classList.contains('fade-out')) { typingDiv.classList.remove('fade-in-up'); typingDiv.classList.add('fade-out'); typingTimeout = setTimeout(() => { typingDiv.innerHTML = ''; typingDiv.classList.remove('fade-out'); }, 600); } } else if (data.event_type === 'reaction') { const updateElement = document.getElementById(`update-${data.update_id}`); updateElement.querySelectorAll('.reaction-button').forEach(button => { button.classList.remove('border-2', 'border-secondosiblue'); if (button.dataset.reaction === data.reaction) { button.classList.add('border-2', 'border-secondosiblue'); } }); const submittedReactions = updateElement.querySelector('#submitted-reactions'); submittedReactions.classList.remove('w-full', 'border-t', 'border-gray-200', 'pt-5', 'flex', 'justify-start', 'items-center', 'gap-3', 'p-5'); updateElement.querySelectorAll('.submittedreaction-button').forEach(button => { button.classList.add('hidden'); if (button.dataset.reaction === data.reaction) { submittedReactions.classList.add('w-full', 'border-t', 'border-gray-200', 'pt-5', 'flex', 'justify-start', 'items-center', 'gap-3', 'p-5'); button.classList.remove('hidden'); } }); } else if (data.event_type === 'user_status') { const toponlineUsersDiv = document.getElementById('top-online-users'); const fixedonlineUsersDiv = document.getElementById('fixed-online-users'); toponlineUsersDiv.innerHTML = data.html; fixedonlineUsersDiv.innerHTML = data.html; } else { messagesDiv.insertAdjacentHTML('beforeend', data.html); typingDiv.innerHTML = ''; typingDiv.classList.remove('fade-in-up', 'fade-out'); } }; socket.onclose = () => { console.log('WebSocket connection closed'); }; socket.onerror = (error) => { console.log('WebSocket error:', error); }; const form = document.getElementById('ticketForm'); const textEditor = document.getElementById('textEditor'); const wysiwygElement = document.querySelector('iframe'); form.addEventListener('submit', (event) => { event.preventDefault(); const formData = new FormData(form); const description = formData.get('description'); const filePath = formData.getAll('filePath'); const data = { event_type: 'update', description: description, filePath: filePath }; socket.send(JSON.stringify(data)); form.reset(); textEditor.value = ''; wysiwygElement.contentDocument.body.innerHTML = ''; // Clear the WYSIWYG content }); document.addEventListener('click', (event) => { if (event.target.classList.contains('reaction-button')) { const updateId = event.target.dataset.updateId; const reaction = event.target.dataset.reaction; const data = { event_type: 'update_reaction', update_id: updateId, reaction: reaction }; socket.send(JSON.stringify(data)); } }); } document.addEventListener('DOMContentLoaded', () => { initializeWebSocket(); });