From eb92e617559b9d8f9f03e403910d830ca64991f7 Mon Sep 17 00:00:00 2001 From: Patrick Buckley Date: Wed, 6 May 2026 22:15:45 -0700 Subject: [PATCH] fix(ui): wrap interactive reminder spans in .msg-body + exclude system-nudge from anchor lookup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes round-1 review findings q-3 + q-4 (minor, merged) and bug-3 + bug-4 (nit, merged). * **q-3 + q-4:** The new ``.msg.user-reminder .msg-body { white-space: pre-wrap }`` rule was a no-op on the interactive UI because that frontend's ``_buildDefaultReminderBubble`` appended label + text spans directly to the outer ``.msg.user-reminder`` element with no ``.msg-body`` wrapper. Coord rendered the same shape with a wrapper. The two implementations diverging on DOM structure also meant a shared-helper extraction was harder than necessary. Reconciled by wrapping interactive's spans in ``.msg-body`` to match coord; the CSS rule now applies to both UIs and the shared-extraction follow-up to ``shared_static/cards.js`` is mechanical (deferred per the review report — out of scope for this commit). * **bug-3 + bug-4:** The reminder anchor lookup ``.msg.user`` also matched ``.msg.user.system-nudge`` markers because the marker carries both classes. A non-wake reminder fired between a wake marker and the next real user message would anchor below the wake marker rather than the previous real user message. Edge case (``/history`` reload corrects), but the fix is mechanical: change the selector to ``.msg.user:not(.system-nudge)`` in both files. (cherry picked from commit 869135d97ad9015ba6f78fe5895caa98dbabfaf4) --- turnstone/console/static/coordinator/coordinator.js | 4 +++- turnstone/ui/static/app.js | 11 ++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/turnstone/console/static/coordinator/coordinator.js b/turnstone/console/static/coordinator/coordinator.js index 3e7b337b..c3207b15 100644 --- a/turnstone/console/static/coordinator/coordinator.js +++ b/turnstone/console/static/coordinator/coordinator.js @@ -492,7 +492,9 @@ appendReminderBubble(reminders, marker); return; } - const userMsgs = messagesEl.querySelectorAll(".msg.user"); + const userMsgs = messagesEl.querySelectorAll( + ".msg.user:not(.system-nudge)", + ); const anchor = userMsgs.length ? userMsgs[userMsgs.length - 1] : null; appendReminderBubble(reminders, anchor); } diff --git a/turnstone/ui/static/app.js b/turnstone/ui/static/app.js index b5d457af..6088474d 100644 --- a/turnstone/ui/static/app.js +++ b/turnstone/ui/static/app.js @@ -753,6 +753,8 @@ function _buildWatchResultBubble(r) { function _buildDefaultReminderBubble(r) { var el = document.createElement("div"); el.className = "msg user-reminder"; + var body = document.createElement("div"); + body.className = "msg-body"; var labelEl = document.createElement("span"); labelEl.className = "msg-user-reminder-label"; labelEl.textContent = @@ -760,8 +762,9 @@ function _buildDefaultReminderBubble(r) { var textEl = document.createElement("span"); textEl.className = "msg-user-reminder-text"; textEl.textContent = r.text || ""; - el.appendChild(labelEl); - el.appendChild(textEl); + body.appendChild(labelEl); + body.appendChild(textEl); + el.appendChild(body); return el; } @@ -803,7 +806,9 @@ Pane.prototype.addUserReminder = function (reminders, source) { if (source === "system_nudge") { anchor = this.addSystemNudgeMarker(); } else { - var userBubbles = this.messagesEl.querySelectorAll(".msg.user"); + var userBubbles = this.messagesEl.querySelectorAll( + ".msg.user:not(.system-nudge)", + ); anchor = userBubbles.length ? userBubbles[userBubbles.length - 1] : null; } for (var i = 0; i < reminders.length; i++) {