Files
DemonGatanjieu-Anomalous_Mo…/web/modules/model_detail_head.js
T
DemonGatanjieuandClaude Opus 5.5 fba4de0f11 Details: path, Copy and Delete at the foot, no ⋯; the folder drawer no longer squeezes the page
The ⋯ menu opened over the path line and the description, and two of its three entries
(copy path, copy file name) were rarely needed. The path bar sat between the buttons and the
description. Now the file's path, Copy and Delete model are the quiet foot of the details, and
Folder's tooltip shows the path.

In a narrow window the folder drawer went back into the page's layout the moment it closed and
shrank from 270px, squeezing the page as it slid; it now stays positioned over the page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:58:07 +08:00

86 lines
4.0 KiB
JavaScript

/**
* The top of a model's details, beside its cover: back (a crumb, "Models / LoRA", or back to
* Model Check, the assistant or the model before; Esc presses it), the name, the size / base /
* source line with the source links, and one row of actions: Add node (the one blue button),
* Edit, Folder (its tooltip shows the path) and Outputs. The path, Copy and Delete are at the
* foot of the details (model_location.js). Where the page is too narrow for the cover column,
* a small cover sits beside the name instead.
*/
import { translate as t } from './locales.js';
import { renderDetailLinks, renderSourceLine } from './model_source.js';
import { showInFolder } from './model_location.js';
import { cardPosterUrl, cardPreviewUrl } from './ui_grid.js';
import { typeLabel } from './ui_model_types.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, title = '') {
const node = el('button', className, label);
node.type = 'button';
if (title) node.title = title;
node.onclick = onClick;
return node;
}
/** Where back leads, as the crumb says it; true second when it leads off the models page. */
function backLabel(owner) {
const last = owner.historyStack.at(-1);
if (last?.type === 'doctor') return [t('detailBackDoctor'), true];
if (last?.type === 'assistant') return [t('detailBackAssistant'), true];
if (owner.historyStack.length) return [t('detailBackPrevModel'), false];
if (typeof owner.recipeModelReturn === 'function') return [t('detailBack'), true];
const group = (owner.foldersData || []).find(item => item.type === owner.currentType && item.path_idx === owner.currentPathIdx);
return [t('detailBackModels', { type: group ? typeLabel(group) : owner.currentType }), false];
}
function smallCover(owner, model) {
if (!model.preview_url) return null;
const cover = el('img', 'anomalous-detail-head-cover');
cover.alt = '';
cover.src = /\.(mp4|webm)(?:&|$)/i.test(model.preview_url)
? cardPosterUrl(model.preview_url) : cardPreviewUrl(model.preview_url, owner.cardThumbnailMode);
return cover;
}
/** `onBack()` leads back (ui_detail.js owns where to). */
export function createDetailHead(owner, model, onBack) {
const meta = model.metadata || {};
const where = { type: owner.currentType, path_idx: owner.currentPathIdx, subfolder: owner.currentSubfolder };
const head = el('div', 'anomalous-detail-head');
const [crumbText, leavesPage] = backLabel(owner);
const crumb = button('anomalous-detail-back', crumbText, onBack, t('detailBackHint'));
crumb.classList.toggle('is-leaving', leavesPage);
const named = el('div', 'anomalous-detail-named');
const cover = smallCover(owner, model);
if (cover) named.append(cover);
const title = el('div', 'anomalous-detail-title');
const name = el('h2', 'anomalous-detail-name', meta.custom_name || meta.name || model.filename);
name.title = model.filename;
const facts = el('div', 'anomalous-detail-facts');
const line = el('span', 'anomalous-detail-source');
renderSourceLine(line, model, meta);
facts.append(line, renderDetailLinks(meta));
title.append(name, facts);
named.append(title);
const actions = el('div', 'anomalous-detail-actions');
actions.append(
button('anomalous-detail-action is-primary', t('applyToCanvas'), () => owner.applyModelToCanvas(owner.currentType, owner.currentSubfolder, model)),
button('anomalous-detail-action', t('detailEdit'), () => owner.showEditModal(model)),
button('anomalous-detail-action', t('detailFolder'), () => showInFolder(model, where),
`${t('detailOpenFolder')}\n${model.file_path || model.filename}`),
button('anomalous-detail-action', t('detailOutputs'), () => owner.showGeneratedGallery(model), t('detailGeneratedGallery')),
);
head.append(crumb, named, actions);
return head;
}