(function () { if (window.GIAComposePanel) { window.GIAComposePanel.initAll(document); return; } const core = window.GIAComposePanelCore; const threadModule = window.GIAComposePanelThread; const sendModule = window.GIAComposePanelSend; if (!core || !threadModule || !sendModule) { return; } const destroyPanelState = function (state) { if (!state) { return; } if (state.pollTimer) { clearInterval(state.pollTimer); } if (state.pendingCommandPoll) { clearInterval(state.pendingCommandPoll); } if (state.socket) { try { state.socket.close(); } catch (_err) { // Ignore socket close failures. } } if (state.eventHandler) { document.body.removeEventListener("composeMessageSent", state.eventHandler); } if (state.sendResultHandler) { document.body.removeEventListener( "composeSendResult", state.sendResultHandler ); } if (state.commandIdHandler) { document.body.removeEventListener( "composeSendCommandId", state.commandIdHandler ); } delete window.giaComposePanels[state.panelId]; }; const initPanel = function (panel) { if (!panel) { return; } const panelId = String(panel.id || "").trim(); if (!panelId) { return; } if (panel.dataset.composeInitialized === "1" && window.giaComposePanels[panelId]) { return; } destroyPanelState(window.giaComposePanels[panelId]); const thread = document.getElementById(panelId + "-thread"); const form = document.getElementById(panelId + "-form"); const textarea = document.getElementById(panelId + "-textarea"); if (!thread || !form || !textarea) { return; } const state = { panelId: panelId, pollTimer: null, polling: false, socket: null, websocketReady: false, pendingCommandPoll: null, pendingCommandId: "", pendingCommandAttempts: 0, pendingCommandStartedAt: 0, pendingCommandInFlight: false, eventHandler: null, sendResultHandler: null, commandIdHandler: null, }; window.giaComposePanels[panelId] = state; panel.dataset.composeInitialized = "1"; const statusBox = document.getElementById(panelId + "-status"); const setStatus = function (message, level) { if (!statusBox) { return; } statusBox.innerHTML = ""; if (!message) { return; } statusBox.appendChild( core.createNode( "p", "compose-status-line is-" + String(level || "info"), String(message) ) ); }; const flashCompose = function (className) { panel.classList.remove("is-send-success", "is-send-fail"); void panel.offsetWidth; panel.classList.add(className); window.setTimeout(function () { panel.classList.remove(className); }, 420); }; const autosize = function () { textarea.style.height = "auto"; textarea.style.height = Math.min(Math.max(textarea.scrollHeight, 44), 128) + "px"; }; const threadController = threadModule.createController({ contactSelect: document.getElementById(panelId + "-contact-select"), hiddenIdentifier: document.getElementById(panelId + "-input-identifier"), hiddenPerson: document.getElementById(panelId + "-input-person"), hiddenReplyTo: form.querySelector('input[name="reply_to_message_id"]'), hiddenService: document.getElementById(panelId + "-input-service"), metaLine: document.getElementById(panelId + "-meta-line"), panel: panel, panelId: panelId, platformSelect: document.getElementById(panelId + "-platform-select"), renderMode: String(panel.dataset.renderMode || "page"), replyBanner: document.getElementById(panelId + "-reply-banner"), replyBannerText: document.getElementById(panelId + "-reply-text"), replyClearBtn: document.getElementById(panelId + "-reply-clear"), state: state, textarea: textarea, thread: thread, typingNode: document.getElementById(panelId + "-typing"), }); const sendController = sendModule.createController({ armInput: form.querySelector('input[name="failsafe_arm"]'), autosize: autosize, clearReplyTarget: threadController.clearReplyTarget, confirmInput: form.querySelector('input[name="failsafe_confirm"]'), csrfToken: String(panel.dataset.csrfToken || ""), flashCompose: flashCompose, form: form, manualConfirm: form.querySelector(".manual-confirm"), panel: panel, panelId: panelId, poll: threadController.poll, queryParams: threadController.queryParams, sendButton: form.querySelector(".compose-send-btn"), sendCapable: String(panel.dataset.capabilitySend || "").toLowerCase() === "true", setStatus: setStatus, state: state, statusBox: statusBox, textarea: textarea, thread: thread, }); threadController.setBeforeContextReset(sendController.resetForContextSwitch); autosize(); textarea.addEventListener("input", autosize); threadController.init(); sendController.init(); }; const initAll = function (root) { core.collectPanels(root).forEach(function (panel) { initPanel(panel); }); }; window.GIAComposePanel = { destroyPanel: function (panelId) { destroyPanelState(window.giaComposePanels[panelId]); }, initAll: initAll, initPanel: initPanel, }; document.addEventListener("DOMContentLoaded", function () { initAll(document); }); if (document.body) { document.body.addEventListener("htmx:afterSwap", function (event) { initAll((event && event.target) || document); }); } initAll(document); })();