Files
DemonGatanjieu-Anomalous_Mo…/web/modules/model_location.js
T
DemonGatanjieuandClaude Opus 5.5 983e9b1166 Model details, layout B: name and actions beside the cover
From a Bilibili comment (buttons small and in five places, the file name twice, a title bar
of little use), layout B chosen by the user from three mockups:
- The title bar goes. The head (new model_detail_head.js) tops the right column: a crumb
  back (Models / LoRA, or where history leads; still .anomalous-detail-back, so Esc presses
  it), the name, the source line with the source links, and one action row: Add node (the
  one accent button), Edit, Folder, Outputs, and ... with Copy path, Copy file name, Delete.
- Delete asks in AMB's dialog instead of window.confirm, and is no longer beside Add node.
- model_location.js: one path line with Copy; Show in folder is exported for Folder.
- action_menu.js: the small menu the gallery card's right-click had, shared with the ...
- Narrow (no cover column), a 64 px cover sits beside the name.
- Gone: the jump-to-bottom button, the full-width Outputs button, the location card's file
  name row, and their locale keys (back, backToPrev, detailJumpToBottom,
  detailPhysicalFilename, detailFullPath).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:45:44 +08:00

51 lines
2.0 KiB
JavaScript

/**
* Where a model's file is: the details' path line (the full path, or the file name, with Copy)
* and Show in folder (Explorer / Finder opens with the file selected; only on the computer
* ComfyUI runs on), which the details' Folder button calls.
*/
import { translate as t } from './locales.js';
import { anomalousAlert } from './ui_dialog.js';
import { showWorkbenchToast } from './ui_prompt_toast.js';
/** `where`: the model's { type, path_idx, subfolder } in the browser. */
export async function showInFolder(model, where) {
try {
const response = await fetch('/anomalous/open_model_folder', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...where, filename: model.filename }),
});
const data = await response.json().catch(() => ({}));
if (data.status !== 'success') throw new Error(data.message || `HTTP ${response.status}`);
} catch (error) {
await anomalousAlert(t('detailOpenFolderFailed', { error: error.message }));
}
}
export async function copyToClipboard(text, doneKey) {
try {
await navigator.clipboard.writeText(text);
showWorkbenchToast(t(doneKey));
} catch {
showWorkbenchToast(t('detailPathCopyFailed'));
}
}
/** The path line: the only place the file name shows (the heading shows the model's name). */
export function createModelLocationCard(model) {
const card = document.createElement('div');
card.className = 'anomalous-model-location';
const path = document.createElement('code');
path.textContent = model.file_path || model.filename;
path.title = path.textContent;
const copy = document.createElement('button');
copy.type = 'button';
copy.className = 'anomalous-model-location-copy';
copy.textContent = t('detailCopy');
copy.title = t('detailCopyPath');
copy.onclick = () => copyToClipboard(path.textContent, 'detailPathCopied');
card.append(path, copy);
return card;
}