diff --git a/frontend/src/chat.css b/frontend/src/chat.css index 79b79d2..1a5f9d5 100644 --- a/frontend/src/chat.css +++ b/frontend/src/chat.css @@ -473,3 +473,6 @@ header h1 { font-size: 16px; font-weight: 700; letter-spacing: -.02em; margin: 0 .viewer-body { flex: 1; overflow: auto; padding: 12px; background: #fff; color: #111; } .viewer-body table { border-collapse: collapse; font-size: 12px; } .viewer-body td, .viewer-body th { border: 1px solid #ccc; padding: 3px 8px; white-space: nowrap; } + +/* === 用户消息:气泡 + 下方附件(同列右对齐) === */ +.msg-stack { display: flex; flex-direction: column; align-items: flex-end; max-width: 100%; } diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 1818975..e1ff874 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -57,16 +57,33 @@ function renderPendingAttachment(): void { } function attachmentChipHtml(att: AttachmentRef): string { - return '
'; + return ''; } function bindAttachChips(root: HTMLElement): void { root.querySelectorAll('.attach-chip').forEach((btn) => { btn.onclick = () => { void openAttachmentViewer(btn.dataset.ft || 'requirements', btn.dataset.name || ''); }; }); } +// 用户消息:文字在气泡内,附件在气泡**下方**(同一列、右对齐) function addUserMsg(text: string, att: AttachmentRef | null): void { - const m = addMsg('user', esc(text) + (att ? attachmentChipHtml(att) : '')); + const m = document.createElement('div'); + m.className = 'msg user'; + const stack = document.createElement('div'); + stack.className = 'msg-stack'; + const bubble = document.createElement('div'); + bubble.className = 'bubble'; + bubble.innerHTML = esc(text); + stack.appendChild(bubble); + if (att) { + const line = document.createElement('div'); + line.className = 'attach-line'; + line.innerHTML = attachmentChipHtml(att); + stack.appendChild(line); + } + m.appendChild(stack); + chatEl.appendChild(m); + chatEl.scrollTop = chatEl.scrollHeight; bindAttachChips(m); } diff --git a/src/genesis/server/static/chat.css b/src/genesis/server/static/chat.css index a85cc7f..c70a817 100644 --- a/src/genesis/server/static/chat.css +++ b/src/genesis/server/static/chat.css @@ -1295,3 +1295,9 @@ header h1 { padding: 3px 8px; white-space: nowrap; } +.msg-stack { + display: flex; + flex-direction: column; + align-items: flex-end; + max-width: 100%; +} diff --git a/src/genesis/server/static/chat.js b/src/genesis/server/static/chat.js index 756c5f1..135a1fc 100644 --- a/src/genesis/server/static/chat.js +++ b/src/genesis/server/static/chat.js @@ -26948,7 +26948,7 @@ function renderPendingAttachment() { }; } function attachmentChipHtml(att) { - return '
"; + return '"; } function bindAttachChips(root) { root.querySelectorAll(".attach-chip").forEach((btn) => { @@ -26958,7 +26958,23 @@ function bindAttachChips(root) { }); } function addUserMsg(text, att) { - const m = addMsg("user", esc(text) + (att ? attachmentChipHtml(att) : "")); + const m = document.createElement("div"); + m.className = "msg user"; + const stack = document.createElement("div"); + stack.className = "msg-stack"; + const bubble = document.createElement("div"); + bubble.className = "bubble"; + bubble.innerHTML = esc(text); + stack.appendChild(bubble); + if (att) { + const line = document.createElement("div"); + line.className = "attach-line"; + line.innerHTML = attachmentChipHtml(att); + stack.appendChild(line); + } + m.appendChild(stack); + chatEl.appendChild(m); + chatEl.scrollTop = chatEl.scrollHeight; bindAttachChips(m); } var pfName = must("pf-name");