A task the AI never names (mostly one asked for in the AI app's own chat, with no begin_task) took the summary of its first step that did something as its title, so the list read "run_workflow" or "new_workflow: anima test". ai_task_title.js shows such a title (title_from "auto", now in the list's summaries and the task links) with the tool in the page's words, "新建了工作流:anima test"; a title the user or the AI gave stays as written, and every page naming a task uses it. Renaming starts from that name. The short set's note said "drawing in the AI app's own chat", which the user read as the picture being drawn in the AI app. It now says it is for telling the AI to draw right in the app's chat, the picture still drawn by ComfyUI, and that a task started with New task cannot use it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
2.5 KiB
JavaScript
55 lines
2.5 KiB
JavaScript
/**
|
|
* The home page's "What the AI did lately" (ui_home.js through ui_ai_workbench.js): the last few
|
|
* tasks with their cover and counts, put above the recent activity; nothing when there are none.
|
|
* `fetchTasks()` gives the summaries, `open(summary, newestId)` opens one on the AI workbench.
|
|
*/
|
|
|
|
import { translate as t } from './locales.js';
|
|
import { timeLabel } from './activity_log.js';
|
|
import { picturePreview, taskCounts, taskState } from './ai_task_view.js';
|
|
import { taskTitle } from './ai_task_title.js';
|
|
|
|
function el(tag, className, text) {
|
|
const node = document.createElement(tag);
|
|
if (className) node.className = className;
|
|
if (text !== undefined) node.textContent = text;
|
|
return node;
|
|
}
|
|
|
|
function button(className, label, onClick) {
|
|
const node = el('button', className, label);
|
|
node.type = 'button';
|
|
node.onclick = onClick;
|
|
return node;
|
|
}
|
|
|
|
export function drawRecentAiTasks(owner, container, { fetchTasks, open }) {
|
|
fetchTasks().then((tasks) => {
|
|
if (!tasks.length || !container.isConnected) return;
|
|
const section = el('section', 'anomalous-home-recent anomalous-ai-recent');
|
|
const head = el('div', 'anomalous-home-recent-head');
|
|
head.append(el('span', 'anomalous-home-recent-title', t('aiRecent')), button('anomalous-home-link', t('activityViewAll'), () => owner.goTo('ai')));
|
|
const list = el('div', 'anomalous-ai-recent-list');
|
|
for (const summary of tasks) {
|
|
const row = button(`anomalous-ai-recent-row is-${taskState(summary)}`, '', () => open(summary, tasks[0].id));
|
|
if (summary.cover) {
|
|
const image = el('img', 'anomalous-ai-recent-cover');
|
|
image.loading = 'lazy';
|
|
image.src = picturePreview(summary.cover);
|
|
image.alt = '';
|
|
row.append(image);
|
|
}
|
|
const text = el('span', 'anomalous-ai-recent-text');
|
|
const counts = taskCounts(summary).map(item => t(item.key, item.values));
|
|
text.append(el('span', 'anomalous-ai-recent-title', taskTitle(summary)),
|
|
el('span', 'anomalous-ai-recent-meta', [summary.client, timeLabel(summary.updated), ...counts].join(' · ')));
|
|
row.append(text);
|
|
list.append(row);
|
|
}
|
|
section.append(head, list);
|
|
const recent = container.querySelector('.anomalous-home-recent');
|
|
if (recent) recent.before(section);
|
|
else container.append(section);
|
|
}).catch(() => { /* the home page works without it */ });
|
|
}
|