mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-08-29 17:01:26 -03:00
fix(recipes): resolve stale LoRA hash on import and add hashInvalid state
- import: prefer A1111 Lora hashes (12-char AutoV3) over conflicting Hashes JSON values; recover the quote-wrapped AutoV3 from CivitAI image API meta; merge EXIF-parsed LoRAs when the API-only parse yields none (meta=null) - rematch: treat entries whose hash failed CivitAI resolution (hashInvalid) as unresolved candidates; clear the flag on rematch/reconnect write-back - download: persist hashInvalid and show a distinct toast when hash lookup returns "Model not found", so unresolvable entries become recoverable - ui: add Unresolvable Hash badge styling and reconnect affordance - i18n: translate the new keys across all 10 locales
This commit is contained in:
@@ -897,6 +897,11 @@ class RecipeModal {
|
||||
<div class="deleted-badge" title="${escapeHtml(translate('recipes.resources.deletedTooltip', {}, 'This LoRA was deleted from the source and is no longer available for download'))}">
|
||||
<i class="fas fa-trash-alt" aria-hidden="true"></i> ${escapeHtml(translate('recipes.resources.deleted', {}, 'Deleted'))}
|
||||
</div>`;
|
||||
} else if (lora.hashInvalid) {
|
||||
statusBadge = `
|
||||
<div class="invalid-hash-badge" title="${escapeHtml(translate('recipes.resources.hashInvalidTooltip', {}, 'This LoRA hash cannot be resolved on CivitAI - the model may have been updated'))}">
|
||||
<i class="fas fa-question-circle" aria-hidden="true"></i> ${escapeHtml(translate('recipes.resources.hashInvalid', {}, 'Unresolvable Hash'))}
|
||||
</div>`;
|
||||
} else {
|
||||
statusBadge = `
|
||||
<div class="missing-badge" title="${escapeHtml(translate('recipes.resources.notInLibraryTooltip', {}, 'This model is not in your library'))}">
|
||||
@@ -1982,7 +1987,7 @@ class RecipeModal {
|
||||
}
|
||||
|
||||
const controls = [];
|
||||
if (isDeleted) {
|
||||
if (isDeleted || lora.hashInvalid) {
|
||||
const reconnectLabel = translate('recipes.resources.reconnect', {}, 'Reconnect');
|
||||
const reconnectTooltip = translate('recipes.resources.reconnectTooltip', {}, 'Reconnect with a local LoRA');
|
||||
controls.push(`
|
||||
@@ -2032,7 +2037,7 @@ class RecipeModal {
|
||||
const loraIndex = parseInt(button.dataset.loraIndex, 10);
|
||||
const lora = this.currentRecipe?.loras?.[loraIndex];
|
||||
if (lora) {
|
||||
this.downloadRecipeLora(lora, button);
|
||||
this.downloadRecipeLora(lora, button, loraIndex);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -2112,7 +2117,7 @@ class RecipeModal {
|
||||
}
|
||||
}
|
||||
|
||||
async downloadRecipeLora(lora, button) {
|
||||
async downloadRecipeLora(lora, button, loraIndex) {
|
||||
if (!this.canDownloadLora(lora)) {
|
||||
showToast('toast.recipes.missingLoraDownloadInfo', {}, 'error');
|
||||
return;
|
||||
@@ -2141,7 +2146,12 @@ class RecipeModal {
|
||||
state.loadingManager.hide();
|
||||
}
|
||||
if (!identifiers) {
|
||||
showToast('toast.recipes.missingLoraDownloadInfo', {}, 'error');
|
||||
if (!hasDirectIds && lora.hash) {
|
||||
await this.markLoraHashInvalid(loraIndex);
|
||||
showToast('toast.recipes.hashNotFoundOnCivitai', {}, 'error');
|
||||
} else {
|
||||
showToast('toast.recipes.missingLoraDownloadInfo', {}, 'error');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2170,6 +2180,33 @@ class RecipeModal {
|
||||
}
|
||||
}
|
||||
|
||||
async markLoraHashInvalid(loraIndex) {
|
||||
const recipeId =
|
||||
this.recipeId ||
|
||||
extractRecipeId(this.listFilePath || this.currentRecipe?.file_path);
|
||||
if (!recipeId) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await fetch('/api/lm/recipe/lora/mark-hash-invalid', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
recipe_id: recipeId,
|
||||
lora_index: loraIndex,
|
||||
}),
|
||||
});
|
||||
if (this.currentRecipe?.loras?.[loraIndex]) {
|
||||
this.currentRecipe.loras[loraIndex].hashInvalid = true;
|
||||
this.syncResourcesSection(this.currentRecipe);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to mark LoRA hash invalid:', error);
|
||||
}
|
||||
}
|
||||
|
||||
navigateToCheckpointPage(checkpoint) {
|
||||
const checkpointHash = this._getCheckpointHash(checkpoint);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user