fix(ui): 附件显示在用户气泡下方(独立行、右对齐)而非气泡内与文字同排

This commit is contained in:
lhl
2026-09-13 01:00:26 +08:00
parent 72b7ffb8f1
commit 3a43799577
4 changed files with 47 additions and 5 deletions
+3
View File
@@ -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%; }
+20 -3
View File
@@ -57,16 +57,33 @@ function renderPendingAttachment(): void {
}
function attachmentChipHtml(att: AttachmentRef): string {
return '<div class="attach-line"><button class="attach-chip" type="button"'
+ ' data-ft="' + esc(att.file_type) + '" data-name="' + esc(att.name) + '">📄 ' + esc(att.name) + '</button></div>';
return '<button class="attach-chip" type="button"'
+ ' data-ft="' + esc(att.file_type) + '" data-name="' + esc(att.name) + '">📄 ' + esc(att.name) + '</button>';
}
function bindAttachChips(root: HTMLElement): void {
root.querySelectorAll<HTMLElement>('.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);
}
+6
View File
@@ -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%;
}
+18 -2
View File
@@ -26948,7 +26948,7 @@ function renderPendingAttachment() {
};
}
function attachmentChipHtml(att) {
return '<div class="attach-line"><button class="attach-chip" type="button" data-ft="' + esc(att.file_type) + '" data-name="' + esc(att.name) + '">\u{1F4C4} ' + esc(att.name) + "</button></div>";
return '<button class="attach-chip" type="button" data-ft="' + esc(att.file_type) + '" data-name="' + esc(att.name) + '">\u{1F4C4} ' + esc(att.name) + "</button>";
}
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");