fix(example-images): support importing for Other models and pending hashes

Two gaps kept 'import example images' from working on the Other page:

- import_images/delete_custom_image/set_example_image_nsfw_level only
  searched the lora/checkpoint/embedding scanners, so Other-category
  models were never found ('Model with hash ... not found in cache').
  All three now go through a shared scanner list that includes the
  Other scanner.
- Other models (and fresh checkpoints) carry hash_status=pending with
  an empty sha256, so the frontend sent an empty model_hash and the
  import was rejected with 'Missing model_hash parameter'. The modal
  now also sends the model's file path, and the import use case
  resolves the hash on demand via the scanner's lazy-hash calculation.
  The resolved hash is returned to the UI and persisted on the
  showcase element so follow-up operations target the same
  hash-keyed folder.
This commit is contained in:
Will Miao
2026-10-01 10:16:34 +08:00
parent eeb9270827
commit 2193ec8f38
5 changed files with 248 additions and 23 deletions
@@ -1162,10 +1162,20 @@ async function handleImportFiles(files, modelHash, importContainer) {
let successCount = 0;
const errors = [];
// The showcase section carries the freshest hash (an import may have
// resolved a deferred hash) plus the file path the backend needs to
// locate models whose hash is still pending.
const showcaseSection = document.querySelector('.showcase-section');
const modelPath = showcaseSection?.dataset.filepath || '';
const currentHash = showcaseSection?.dataset.modelHash || modelHash;
for (const file of validFiles) {
try {
const formData = new FormData();
formData.append('model_hash', modelHash);
formData.append('model_hash', currentHash);
if (modelPath) {
formData.append('model_path', modelPath);
}
formData.append('files', file);
const response = await fetch('/api/lm/import-example-images', {
@@ -1192,8 +1202,17 @@ async function handleImportFiles(files, modelHash, importContainer) {
const result = lastSuccessResult;
// A model with a deferred hash (checkpoint / Other) is imported via
// model_path; the backend resolves and returns the real hash. Persist
// it so every follow-up (file list, NSFW toggle, delete, re-render)
// targets the hash-keyed example folder.
const effectiveHash = result.model_hash || currentHash;
if (showcaseSection && effectiveHash) {
showcaseSection.dataset.modelHash = effectiveHash;
}
// Get updated local files
const updatedFilesResponse = await fetch(`/api/lm/example-image-files?model_hash=${modelHash}`);
const updatedFilesResponse = await fetch(`/api/lm/example-image-files?model_hash=${effectiveHash}`);
const updatedFilesResult = await updatedFilesResponse.json();
if (!updatedFilesResult.success) {
@@ -1221,7 +1240,7 @@ async function handleImportFiles(files, modelHash, importContainer) {
}
// Initialize the import UI for the new content
initExampleImport(modelHash, showcaseTab);
initExampleImport(effectiveHash, showcaseTab);
if (errors.length > 0) {
showToast('toast.import.imagesPartial', { success: successCount, failed: errors.length }, 'warning');