Rebuild bundle for Agents-style chats list UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-23 06:21:23 +03:00
co-authored by Cursor
parent 9ac24a828b
commit 9d2cbca8f2
+43 -18
View File
@@ -3960,8 +3960,25 @@ ${patch.prompt}`;
if (!ts) {
return "";
}
const t = Number(ts) || 0;
if (!t) {
return "";
}
const sec = Math.max(0, Math.floor((Date.now() - t) / 1e3));
if (sec < 45) {
return "\u0441\u0435\u0439\u0447\u0430\u0441";
}
if (sec < 3600) {
return `${Math.max(1, Math.floor(sec / 60))}\u043C`;
}
if (sec < 86400) {
return `${Math.floor(sec / 3600)}\u0447`;
}
if (sec < 86400 * 14) {
return `${Math.floor(sec / 86400)}\u0434`;
}
try {
return new Date(ts).toLocaleString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" });
return new Date(t).toLocaleDateString(void 0, { month: "short", day: "numeric" });
} catch (e) {
return "";
}
@@ -3982,6 +3999,23 @@ ${patch.prompt}`;
}
return false;
}
function chatListParamsBits(params) {
if (!params || typeof params !== "object") {
return "";
}
const g = params.gen && typeof params.gen === "object" ? params.gen : params;
const bits = [];
if (g.width && g.height) {
bits.push(`${g.width}\xD7${g.height}`);
} else if (g.aspect) {
bits.push(String(g.aspect));
}
const loras = Array.isArray(g.loras) ? g.loras : [];
if (loras.length) {
bits.push(`LoRA ${loras.length}`);
}
return bits.join(" \xB7 ");
}
function renderChatsList() {
const root = $2("sa_chats_list");
if (!root) {
@@ -3998,29 +4032,20 @@ ${patch.prompt}`;
chats = local.concat(extra);
}
if (!chats.length) {
root.innerHTML = q ? '<div class="sa-chats-empty">\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0448\u043B\u043E\u0441\u044C.</div>' : '<div class="sa-chats-empty">\u041F\u043E\u043A\u0430 \u043F\u0443\u0441\u0442\u043E. \u041D\u0430\u043F\u0438\u0448\u0438 \u0447\u0442\u043E-\u043D\u0438\u0431\u0443\u0434\u044C \u0432 \u0447\u0430\u0442 \u2014 \u043E\u043D \u043F\u043E\u044F\u0432\u0438\u0442\u0441\u044F \u0437\u0434\u0435\u0441\u044C. \u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u0432\u0435\u0440\u043D\u0451\u0442 \u0438 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F, \u0438 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B Generate.</div>';
root.innerHTML = q ? '<div class="sa-chats-empty">\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0448\u043B\u043E\u0441\u044C.</div>' : '<div class="sa-chats-empty">\u041F\u043E\u043A\u0430 \u043F\u0443\u0441\u0442\u043E \u2014 \u043D\u0430\u043F\u0438\u0448\u0438 \u0432 \u0447\u0430\u0442, \u0438 \u043E\u043D \u043F\u043E\u044F\u0432\u0438\u0442\u0441\u044F \u0437\u0434\u0435\u0441\u044C.</div>';
return;
}
const ico = '<svg class="sa-chat-row-ico" width="14" height="14" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 4.5h10M3 8h10M3 11.5h7" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>';
for (const c of chats) {
const row = document.createElement("div");
row.className = "sa-chat-row" + (c.id === state.activeChatId ? " sa-chat-row-active" : "");
row.dataset.id = c.id;
const n = (c.messages || []).length || Number(c.messages_count) || 0;
const bits = [];
if (c.params?.width && c.params?.height) {
bits.push(`${c.params.width}\xD7${c.params.height}`);
}
if (c.params?.steps != null) {
bits.push(`steps ${c.params.steps}`);
}
if (c.params?.cfg != null) {
bits.push(`cfg ${c.params.cfg}`);
}
if (Array.isArray(c.params?.loras) && c.params.loras.length) {
bits.push(`LoRA ${c.params.loras.length}`);
}
const noParams = !c.params ? " \xB7 \u0431\u0435\u0437 \u0441\u043D\u0438\u043C\u043A\u0430 params" : "";
row.innerHTML = `<button type="button" class="sa-chat-row-main" data-open="1"><span class="sa-chat-row-title">${escapeHtml2(c.title || "\u0427\u0430\u0442")}</span><span class="sa-chat-row-meta">${escapeHtml2([formatChatWhen(c.updatedAt), `${n} \u0441\u043E\u043E\u0431\u0449.`, bits.join(" \xB7 ")].filter(Boolean).join(" \xB7 ") + noParams)}</span></button><button type="button" class="sa-chat-row-del" data-del="1" title="\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0447\u0430\u0442">\xD7</button>`;
row.setAttribute("role", "listitem");
const when = formatChatWhen(c.updatedAt);
const title = escapeHtml2(c.title || "\u041D\u043E\u0432\u044B\u0439 \u0447\u0430\u0442");
const tipBits = [chatListParamsBits(c.params)].filter(Boolean);
const tip = tipBits.length ? ` title="${escapeHtml2(tipBits.join(" \xB7 "))}"` : "";
row.innerHTML = `<button type="button" class="sa-chat-row-main" data-open="1"${tip}>${ico}<span class="sa-chat-row-title">${title}</span><span class="sa-chat-row-when">${escapeHtml2(when)}</span></button><button type="button" class="sa-chat-row-del" data-del="1" title="\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0447\u0430\u0442" aria-label="\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0447\u0430\u0442">\xD7</button>`;
root.appendChild(row);
}
}