feat(localization): enhance toast messages for recipes and example images with improved error handling and success feedback

This commit is contained in:
Will Miao
2025-08-31 13:51:37 +08:00
parent e60a579b85
commit 987b8c8742
11 changed files with 134 additions and 65 deletions

View File

@@ -199,7 +199,7 @@ class RecipeCard {
// Get recipe ID
const recipeId = this.recipe.id;
if (!recipeId) {
showToast('Cannot send recipe: Missing recipe ID', 'error');
showToast('toast.recipes.cannotSend', {}, 'error');
return;
}
@@ -214,11 +214,11 @@ class RecipeCard {
})
.catch(err => {
console.error('Failed to send recipe to workflow: ', err);
showToast('Failed to send recipe to workflow', 'error');
showToast('toast.recipes.sendFailed', {}, 'error');
});
} catch (error) {
console.error('Error sending recipe to workflow:', error);
showToast('Error sending recipe to workflow', 'error');
showToast('toast.recipes.sendError', {}, 'error');
}
}
@@ -228,7 +228,7 @@ class RecipeCard {
const recipeId = this.recipe.id;
const filePath = this.recipe.file_path;
if (!recipeId) {
showToast('Cannot delete recipe: Missing recipe ID', 'error');
showToast('toast.recipes.cannotDelete', {}, 'error');
return;
}
@@ -278,7 +278,7 @@ class RecipeCard {
} catch (error) {
console.error('Error showing delete confirmation:', error);
showToast('Error showing delete confirmation', 'error');
showToast('toast.recipes.deleteConfirmationError', {}, 'error');
}
}
@@ -287,7 +287,7 @@ class RecipeCard {
const recipeId = deleteModal.dataset.recipeId;
if (!recipeId) {
showToast('Cannot delete recipe: Missing recipe ID', 'error');
showToast('toast.recipes.cannotDelete', {}, 'error');
modalManager.closeModal('deleteModal');
return;
}
@@ -312,7 +312,7 @@ class RecipeCard {
return response.json();
})
.then(data => {
showToast('Recipe deleted successfully', 'success');
showToast('toast.recipes.deletedSuccessfully', {}, 'success');
state.virtualScroller.removeItemByFilePath(deleteModal.dataset.filePath);
@@ -320,7 +320,7 @@ class RecipeCard {
})
.catch(error => {
console.error('Error deleting recipe:', error);
showToast('Error deleting recipe: ' + error.message, 'error');
showToast('toast.recipes.deleteFailed', { message: error.message }, 'error');
// Reset button state
deleteBtn.textContent = originalText;
@@ -333,12 +333,12 @@ class RecipeCard {
// Get recipe ID
const recipeId = this.recipe.id;
if (!recipeId) {
showToast('Cannot share recipe: Missing recipe ID', 'error');
showToast('toast.recipes.cannotShare', {}, 'error');
return;
}
// Show loading toast
showToast('Preparing recipe for sharing...', 'info');
showToast('toast.recipes.preparingForSharing', {}, 'info');
// Call the API to process the image with metadata
fetch(`/api/recipe/${recipeId}/share`)
@@ -363,15 +363,15 @@ class RecipeCard {
downloadLink.click();
document.body.removeChild(downloadLink);
showToast('Recipe download started', 'success');
showToast('toast.recipes.downloadStarted', {}, 'success');
})
.catch(error => {
console.error('Error sharing recipe:', error);
showToast('Error sharing recipe: ' + error.message, 'error');
showToast('toast.recipes.shareError', { message: error.message }, 'error');
});
} catch (error) {
console.error('Error sharing recipe:', error);
showToast('Error preparing recipe for sharing', 'error');
showToast('toast.recipes.sharePreparationError', {}, 'error');
}
}
}

View File

@@ -526,7 +526,7 @@ class RecipeModal {
updateRecipeMetadata(this.filePath, { title: newTitle })
.then(data => {
// Show success toast
showToast('Recipe name updated successfully', 'success');
showToast('toast.recipes.nameUpdated', {}, 'success');
// Update the current recipe object
this.currentRecipe.title = newTitle;
@@ -596,7 +596,7 @@ class RecipeModal {
updateRecipeMetadata(this.filePath, { tags: newTags })
.then(data => {
// Show success toast
showToast('Recipe tags updated successfully', 'success');
showToast('toast.recipes.tagsUpdated', {}, 'success');
// Update the current recipe object
this.currentRecipe.tags = newTags;
@@ -717,7 +717,7 @@ class RecipeModal {
updateRecipeMetadata(this.filePath, { source_path: newSourceUrl })
.then(data => {
// Show success toast
showToast('Source URL updated successfully', 'success');
showToast('toast.recipes.sourceUrlUpdated', {}, 'success');
// Update source URL in the UI
sourceUrlText.textContent = newSourceUrl || 'No source URL';
@@ -778,7 +778,7 @@ class RecipeModal {
// Fetch recipe syntax from backend and copy to clipboard
async fetchAndCopyRecipeSyntax() {
if (!this.recipeId) {
showToast('No recipe ID available', 'error');
showToast('toast.recipes.noRecipeId', {}, 'error');
return;
}
@@ -800,7 +800,7 @@ class RecipeModal {
}
} catch (error) {
console.error('Error fetching recipe syntax:', error);
showToast(`Error copying recipe syntax: ${error.message}`, 'error');
showToast('toast.recipes.copyFailed', { message: error.message }, 'error');
}
}
@@ -817,7 +817,7 @@ class RecipeModal {
console.log("missingLoras", missingLoras);
if (missingLoras.length === 0) {
showToast('No missing LoRAs to download', 'info');
showToast('toast.recipes.noMissingLoras', {}, 'info');
return;
}
@@ -856,7 +856,7 @@ class RecipeModal {
const validLoras = lorasWithVersionInfo.filter(lora => lora !== null);
if (validLoras.length === 0) {
showToast('Failed to get information for missing LoRAs', 'error');
showToast('toast.recipes.missingLorasInfoFailed', {}, 'error');
return;
}
@@ -902,7 +902,7 @@ class RecipeModal {
window.importManager.downloadMissingLoras(recipeData, this.currentRecipe.id);
} catch (error) {
console.error("Error downloading missing LoRAs:", error);
showToast('Error preparing LoRAs for download', 'error');
showToast('toast.recipes.preparingForDownloadFailed', {}, 'error');
} finally {
state.loadingManager.hide();
}
@@ -988,7 +988,7 @@ class RecipeModal {
async reconnectLora(loraIndex, inputValue) {
if (!inputValue || !inputValue.trim()) {
showToast('Please enter a LoRA name or syntax', 'error');
showToast('toast.recipes.enterLoraName', {}, 'error');
return;
}
@@ -1026,7 +1026,7 @@ class RecipeModal {
this.currentRecipe.loras[loraIndex] = result.updated_lora;
// Show success message
showToast('LoRA reconnected successfully', 'success');
showToast('toast.recipes.reconnectedSuccessfully', {}, 'success');
// Refresh modal to show updated content
setTimeout(() => {
@@ -1037,11 +1037,11 @@ class RecipeModal {
loras: this.currentRecipe.loras
});
} else {
showToast(`Error: ${result.error}`, 'error');
showToast('toast.recipes.reconnectFailed', { message: result.error }, 'error');
}
} catch (error) {
console.error('Error reconnecting LoRA:', error);
showToast(`Error reconnecting LoRA: ${error.message}`, 'error');
showToast('toast.recipes.reconnectFailed', { message: error.message }, 'error');
} finally {
state.loadingManager.hide();
}

View File

@@ -278,7 +278,7 @@ export function initMetadataPanelHandlers(container) {
await copyToClipboard(promptElement.textContent, 'Prompt copied to clipboard');
} catch (err) {
console.error('Copy failed:', err);
showToast('Copy failed', 'error');
showToast('toast.triggerWords.copyFailed', {}, 'error');
}
});
});
@@ -432,7 +432,7 @@ export function initMediaControlHandlers(container) {
}, 600);
// Show success toast
showToast('Example image deleted', 'success');
showToast('toast.exampleImages.deleted', {}, 'success');
// Create an update object with only the necessary properties
const updateData = {
@@ -456,7 +456,7 @@ export function initMediaControlHandlers(container) {
}
} catch (error) {
console.error('Error deleting example image:', error);
showToast('Failed to delete example image', 'error');
showToast('toast.exampleImages.deleteFailed', {}, 'error');
// Reset button state
this.disabled = false;
@@ -536,7 +536,7 @@ function initSetPreviewHandlers(container) {
}
} catch (error) {
console.error('Error setting preview:', error);
showToast('Failed to set preview image', 'error');
showToast('toast.exampleImages.setPreviewFailed', {}, 'error');
} finally {
// Restore button state
this.innerHTML = '<i class="fas fa-image"></i>';

View File

@@ -412,7 +412,7 @@ async function handleImportFiles(files, modelHash, importContainer) {
// Initialize the import UI for the new content
initExampleImport(modelHash, showcaseTab);
showToast('Example images imported successfully', 'success');
showToast('toast.import.imagesImported', {}, 'success');
// Update VirtualScroller if available
if (state.virtualScroller && result.model_file_path) {