sync-event toasts, image pull ordering, stale banner field diff

- replace chat-bot sync notifications with a dedicated relay_sync_events
  queue: POST/GET /api/sync-events, drained by /api/relay/poll and
  surfaced as stacking toasts via caldav.js. Old /api/chat/bot removed,
  bot=1 rows purged on bootstrap, orange bot rendering dropped from
  relay UI. Chat thread stays clean.
- collab pull: fetch attachments BEFORE applying the body so the moment
  state.cards reflects the new reference the file is on disk. Fixes the
  "preview shows broken/missing image, editor shows it" race where the
  browser cached the 404 between attachment landing and user re-render.
- detail stale banner now compares title/body/color/tags in addition to
  updated_at — robust against second-granularity timestamp collisions
  and any other case where updated_at doesn't tick but content differs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.6 committed 2026-04-14 23:00:30 +02:00
1 parent 26f95ba079
commit 1966f8f4c0
10 files changed
+170 -75

No files matched your search

+3 -11
View File
@@ -719,20 +719,12 @@ async function loadChatHistory(peer, quiet = false) {
return;
}
container.innerHTML = messages.map(m => {
if (m.bot) {
return `
<div class="chat-msg bot">
<div><i class="ph ph-robot"></i> ${escapeHtml(m.body)}</div>
<div class="msg-time">${formatChatTime(m.created_at)}</div>
</div>`;
}
return `
container.innerHTML = messages.map(m => `
<div class="chat-msg ${m.mine ? 'mine' : 'theirs'}">
<div>${escapeHtml(m.body)}</div>
<div class="msg-time">${formatChatTime(m.created_at)}${m.mine && m.seen ? ' <i class="ph ph-checks"></i>' : ''}</div>
</div>`;
}).join('');
</div>
`).join('');
if (wasAtBottom || !quiet) {
container.scrollTop = container.scrollHeight;