${escapeHtml(message.body)}
+ ${message.body ? `${escapeHtml(message.body)}
` : ""} ${renderAttachments(message.attachments)}diff --git a/public/admin.js b/public/admin.js index e224f59..94c263c 100644 --- a/public/admin.js +++ b/public/admin.js @@ -69,21 +69,28 @@ $("#settingsForm").addEventListener("submit", async (event) => { $("#replyForm").addEventListener("submit", async (event) => { event.preventDefault(); if (!state.activeId) return; + const textarea = event.currentTarget.querySelector("textarea[name='message']"); + const originalMessage = textarea.value; const form = new FormData(event.currentTarget); const payload = { message: form.get("message") || "", attachments: await Promise.all(state.replyFiles.slice(0, 3).map(fileToPayload)) }; if (!payload.message.trim() && !payload.attachments.length) return; - await api(`/api/admin/conversations/${state.activeId}/messages`, { - method: "POST", - body: payload - }); - event.currentTarget.querySelector("textarea[name='message']").value = ""; - event.currentTarget.reset(); - state.replyFiles = []; - renderReplyAttachments(); - await openConversation(state.activeId); + textarea.value = ""; + try { + await api(`/api/admin/conversations/${state.activeId}/messages`, { + method: "POST", + body: payload + }); + event.currentTarget.reset(); + state.replyFiles = []; + renderReplyAttachments(); + await openConversation(state.activeId); + } catch (error) { + textarea.value = originalMessage; + throw error; + } }); $("#replyForm textarea").addEventListener("keydown", (event) => { @@ -299,7 +306,7 @@ function renderActive() { $("#messages").innerHTML = messages.map((message) => ` `).join(""); diff --git a/public/widget.js b/public/widget.js index d32a2bf..61d5e8d 100644 --- a/public/widget.js +++ b/public/widget.js @@ -37,7 +37,7 @@