Files
DemonGatanjieu-Anomalous_Mo…/web/modules/model_location.js
T
DemonGatanjieuandClaude Opus 5.5 e0abbd277a Folder column: the current type's folders, with 📂 to open one in Explorer
The list column showed every type's tree (raw folder names, [Root] rows with 0, nothing marking
where you are), repeating the type chips above it. Now (ui_folder_list.js) it follows the chips:
the type's heading with "📂 Open", All, its subfolders as a tree whose numbers count their
subfolders (empty ones dimmed, folding per session in owner.collapsedFolders), and "In the top
folder" for models directly in the type's folder; the listed one is marked.

A Bilibili comment asked for quick ways to open model folders: POST /anomalous/open_model_folder
without a file name now opens the folder itself (type root or subfolder; still by type, index
and subfolder, never a path, local only). Tests in tests/test_model_folder.py.

Gone: the every-type tree, Expand / Collapse all, expandedFolders and their locale keys.

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

56 lines
2.2 KiB
JavaScript

/**
* Where a model's file is: the details' path line (the full path, or the file name, with Copy),
* and the file manager (only on the computer ComfyUI runs on): showInFolder for the details'
* Folder button (Explorer / Finder with the file selected), openModelFolder for the folder
* column's 📂 (a type's folder or a subfolder).
*/
import { translate as t } from './locales.js';
import { anomalousAlert } from './ui_dialog.js';
import { showWorkbenchToast } from './ui_prompt_toast.js';
/** `where`: { type, path_idx, subfolder } as the browser lists it; no `filename`: the folder itself. */
export async function openModelFolder(where, filename = '') {
try {
const response = await fetch('/anomalous/open_model_folder', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...where, 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 function showInFolder(model, where) {
return openModelFolder(where, model.filename);
}
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;
}