fix(12-03): suppress sender duplicate discussion rows

This commit is contained in:
Arthur Belleville 2026-05-16 10:24:34 +02:00
parent d15c3748e4
commit 6f17c3016f
No known key found for this signature in database
2 changed files with 55 additions and 0 deletions

View file

@ -472,6 +472,32 @@ func TestDiscussionBrokerUnregistersOnCancel(t *testing.T) {
} }
} }
func TestDiscussionStaticScriptSuppressesDuplicateMessageSwap(t *testing.T) {
js, err := os.ReadFile("../../static/discussion-sse.js")
if err != nil {
t.Fatalf("read discussion-sse.js: %v", err)
}
script := string(js)
for _, want := range []string{"htmx:beforeSwap", "messageIdFromHTML", "preventDefault()"} {
if !strings.Contains(script, want) {
t.Fatalf("discussion script missing %q for duplicate swap suppression; script: %.1200s", want, script)
}
}
}
func TestDiscussionStaticScriptClearsComposerAfterSuccessfulPost(t *testing.T) {
js, err := os.ReadFile("../../static/discussion-sse.js")
if err != nil {
t.Fatalf("read discussion-sse.js: %v", err)
}
script := string(js)
for _, want := range []string{"htmx:afterRequest", "discussion-message-body", ".reset()"} {
if !strings.Contains(script, want) {
t.Fatalf("discussion script missing %q for composer reset; script: %.1200s", want, script)
}
}
}
func TestTablosListDiscussionUnreadBadge(t *testing.T) { func TestTablosListDiscussionUnreadBadge(t *testing.T) {
pool, cleanup := setupTestDB(t) pool, cleanup := setupTestDB(t)
defer cleanup() defer cleanup()

View file

@ -3,6 +3,18 @@
return Boolean(document.querySelector('[data-message-id="' + CSS.escape(messageId) + '"]')); return Boolean(document.querySelector('[data-message-id="' + CSS.escape(messageId) + '"]'));
} }
function isDiscussionMessageForm(element) {
return Boolean(element && element.matches && element.matches('form[action$="/discussion/messages"]'));
}
function messageIdFromHTML(html) {
if (!html) return "";
var template = document.createElement("template");
template.innerHTML = html.trim();
var message = template.content.querySelector("[data-message-id]");
return message ? message.dataset.messageId : "";
}
function ensureMessageList(container) { function ensureMessageList(container) {
var messages = container.querySelector("#discussion-messages"); var messages = container.querySelector("#discussion-messages");
if (!messages) return null; if (!messages) return null;
@ -52,4 +64,21 @@
document.addEventListener("DOMContentLoaded", connectDiscussionStreams); document.addEventListener("DOMContentLoaded", connectDiscussionStreams);
document.body.addEventListener("htmx:afterSwap", connectDiscussionStreams); document.body.addEventListener("htmx:afterSwap", connectDiscussionStreams);
document.body.addEventListener("htmx:beforeSwap", function (event) {
if (!isDiscussionMessageForm(event.detail && event.detail.elt)) return;
var messageId = messageIdFromHTML(event.detail.xhr && event.detail.xhr.responseText);
if (messageId && messageExists(messageId)) {
event.detail.shouldSwap = false;
event.preventDefault();
}
});
document.body.addEventListener("htmx:afterRequest", function (event) {
var form = event.detail && event.detail.elt;
if (!isDiscussionMessageForm(form) || !event.detail.successful) return;
form.reset();
var textarea = form.querySelector("#discussion-message-body");
if (textarea) textarea.value = "";
});
})(); })();