Files
DemonGatanjieu-Anomalous_Mo…/web/modules/model_location.js
T
DemonGatanjieuandClaude Opus 5.5 e0129eaa2f Esc and the shortcut close the browser; Show in folder; insert a picture as a node
From a Bilibili comment (2026-10-13):
- Esc closes the top layer: a dialog or menu (the plugin's alert and confirm
  now close on Esc, as OK / Cancel), else the Workflows / Combos workspace,
  else the browser. One capture listener decides before the layers act, so a
  dialog closing on the same Esc still counts as above. The shortcut and the
  Extensions entry toggle the browser.
- A model's file card has Show in folder: POST /anomalous/open_model_folder
  (api/model_folder.py) takes type, folder index, subfolder and file name,
  never a path, and opens Explorer / Finder with the file selected; a POST,
  so local_guard keeps it to this computer. The card moves out of
  ui_detail.js into model_location.js.
- A gallery card's right-click menu (gallery_card_menu.js): Insert as a Load
  Image node reads the output file in place ("name.png [output]"), and View
  Parameters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 01:09:29 +08:00

71 lines
2.7 KiB
JavaScript

/**
* The model details' location card: the file name and full path, Copy path, and Show in
* folder (Explorer / Finder opens with the file selected; only on the computer ComfyUI runs on).
*/
import { translate as t } from './locales.js';
import { anomalousAlert } from './ui_dialog.js';
function actionButton(label) {
const button = document.createElement('button');
button.type = 'button';
button.className = 'anomalous-model-location-copy';
button.textContent = label;
return button;
}
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 }));
}
}
/** `where`: the model's { type, path_idx, subfolder } in the browser. */
export function createModelLocationCard(model, where) {
const card = document.createElement('div');
card.className = 'anomalous-model-location';
const appendValue = (labelKey, value) => {
const row = document.createElement('div');
row.className = 'anomalous-model-location-row';
const label = document.createElement('span');
label.className = 'anomalous-model-location-label';
label.textContent = t(labelKey);
const content = document.createElement('code');
content.textContent = value;
content.title = value;
row.append(label, content);
card.appendChild(row);
};
appendValue('detailPhysicalFilename', model.filename);
if (model.file_path) {
appendValue('detailFullPath', model.file_path);
const actions = document.createElement('div');
actions.className = 'anomalous-model-location-actions';
const copyButton = actionButton(t('detailCopyPath'));
copyButton.onclick = async () => {
try {
await navigator.clipboard.writeText(model.file_path);
copyButton.textContent = t('detailPathCopied');
} catch (error) {
copyButton.textContent = t('detailPathCopyFailed');
}
setTimeout(() => { copyButton.textContent = t('detailCopyPath'); }, 1400);
};
const folderButton = actionButton(t('detailOpenFolder'));
folderButton.onclick = () => showInFolder(model, where);
actions.append(copyButton, folderButton);
card.appendChild(actions);
}
return card;
}