diff --git a/locales/de.json b/locales/de.json index 6e62c58b..8675f123 100644 --- a/locales/de.json +++ b/locales/de.json @@ -853,7 +853,8 @@ "recipes": { "title": "LoRA-Rezepte", "actions": { - "sendCheckpoint": "Send to ComfyUI" + "sendCheckpoint": "Send to ComfyUI", + "sendRecipe": "Send to ComfyUI" }, "controls": { "import": { diff --git a/locales/en.json b/locales/en.json index f5271973..ff334dd9 100644 --- a/locales/en.json +++ b/locales/en.json @@ -853,7 +853,8 @@ "recipes": { "title": "LoRA Recipes", "actions": { - "sendCheckpoint": "Send to ComfyUI" + "sendCheckpoint": "Send to ComfyUI", + "sendRecipe": "Send to ComfyUI" }, "controls": { "import": { diff --git a/locales/es.json b/locales/es.json index 6610b289..bf25d159 100644 --- a/locales/es.json +++ b/locales/es.json @@ -853,7 +853,8 @@ "recipes": { "title": "Recetas de LoRA", "actions": { - "sendCheckpoint": "Enviar a ComfyUI" + "sendCheckpoint": "Enviar a ComfyUI", + "sendRecipe": "Enviar a ComfyUI" }, "controls": { "import": { diff --git a/locales/fr.json b/locales/fr.json index 12b306df..9eb4b85a 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -853,7 +853,8 @@ "recipes": { "title": "LoRA Recipes", "actions": { - "sendCheckpoint": "Envoyer vers ComfyUI" + "sendCheckpoint": "Envoyer vers ComfyUI", + "sendRecipe": "Envoyer vers ComfyUI" }, "controls": { "import": { diff --git a/locales/he.json b/locales/he.json index 7e5e4f9c..43c924e3 100644 --- a/locales/he.json +++ b/locales/he.json @@ -853,7 +853,8 @@ "recipes": { "title": "מתכוני LoRA", "actions": { - "sendCheckpoint": "שלח ל-ComfyUI" + "sendCheckpoint": "שלח ל-ComfyUI", + "sendRecipe": "שלח ל-ComfyUI" }, "controls": { "import": { diff --git a/locales/ja.json b/locales/ja.json index 3f565d7e..3896d63f 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -853,7 +853,8 @@ "recipes": { "title": "LoRAレシピ", "actions": { - "sendCheckpoint": "ComfyUIへ送信" + "sendCheckpoint": "ComfyUIへ送信", + "sendRecipe": "ComfyUIへ送信" }, "controls": { "import": { diff --git a/locales/ko.json b/locales/ko.json index ac29ec85..6cae7c6a 100644 --- a/locales/ko.json +++ b/locales/ko.json @@ -853,7 +853,8 @@ "recipes": { "title": "LoRA 레시피", "actions": { - "sendCheckpoint": "ComfyUI로 보내기" + "sendCheckpoint": "ComfyUI로 보내기", + "sendRecipe": "ComfyUI로 보내기" }, "controls": { "import": { diff --git a/locales/ru.json b/locales/ru.json index fd9fce54..6bf71861 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -853,7 +853,8 @@ "recipes": { "title": "Рецепты LoRA", "actions": { - "sendCheckpoint": "Отправить в ComfyUI" + "sendCheckpoint": "Отправить в ComfyUI", + "sendRecipe": "Отправить в ComfyUI" }, "controls": { "import": { diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 497874f9..59bb51f3 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -853,7 +853,8 @@ "recipes": { "title": "LoRA 配方", "actions": { - "sendCheckpoint": "发送到 ComfyUI" + "sendCheckpoint": "发送到 ComfyUI", + "sendRecipe": "发送到 ComfyUI" }, "controls": { "import": { diff --git a/locales/zh-TW.json b/locales/zh-TW.json index 007a74cd..7c80ba3a 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -853,7 +853,8 @@ "recipes": { "title": "LoRA 配方", "actions": { - "sendCheckpoint": "傳送到 ComfyUI" + "sendCheckpoint": "傳送到 ComfyUI", + "sendRecipe": "傳送到 ComfyUI" }, "controls": { "import": { diff --git a/static/css/components/recipe-modal.css b/static/css/components/recipe-modal.css index 3445dc18..5edd5368 100644 --- a/static/css/components/recipe-modal.css +++ b/static/css/components/recipe-modal.css @@ -104,15 +104,29 @@ display: none; } +/* Darker, blurred backdrop keeps the busy page behind the modal from bleeding through */ +#recipeModal { + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(6px); + -webkit-backdrop-filter: blur(6px); +} + #recipeModal .modal-content { display: flex; flex-direction: column; + /* Content-sized shell: grows with content up to the viewport limit, inner panes scroll past it */ + box-sizing: border-box; /* Include padding/border so the shell never exceeds the viewport */ + width: min(1600px, 94vw); + max-width: min(1600px, 94vw); + height: auto; + max-height: calc(100vh - var(--header-height, 48px) - 2rem); + overflow: hidden; } #recipeModal .modal-body { - display: flex; - flex-direction: column; - gap: var(--space-2); + display: grid; + grid-template-columns: 320px minmax(0, 1fr) 420px; + gap: var(--space-3); flex: 1 1 auto; min-height: 0; overflow: hidden; @@ -174,19 +188,22 @@ } } -/* Top Section: Preview and Gen Params */ -.recipe-top-section { - display: grid; - grid-template-columns: 280px 1fr; +/* Left Column: Preview */ +.recipe-media-column { + display: flex; + flex-direction: column; gap: var(--space-2); - flex-shrink: 0; - margin-bottom: var(--space-2); + min-height: 0; + overflow-y: auto; + overflow-x: hidden; /* Guard against sub-pixel overflow from bordered children */ } /* Recipe Preview */ .recipe-preview-container { width: 100%; - height: 360px; + box-sizing: border-box; /* Keep the 1px border inside the column width */ + height: auto; + max-height: 42vh; border-radius: var(--border-radius-sm); overflow: hidden; background: var(--lora-surface); @@ -196,18 +213,19 @@ align-items: center; justify-content: center; position: relative; + flex-shrink: 0; } .recipe-preview-container img, .recipe-preview-container video { max-width: 100%; - max-height: 100%; + max-height: 42vh; object-fit: contain; } .recipe-preview-media { max-width: 100%; - max-height: 100%; + max-height: 42vh; object-fit: contain; } @@ -340,9 +358,10 @@ /* Generation Parameters */ .recipe-gen-params { - height: 360px; display: flex; flex-direction: column; + min-height: 0; + overflow-y: auto; } .gen-params-header-row { @@ -399,8 +418,6 @@ display: flex; flex-direction: column; gap: var(--space-2); - overflow-y: auto; - flex: 1; } .param-group { @@ -453,8 +470,6 @@ color: var(--text-color); font-size: 0.9em; line-height: 1.5; - max-height: 150px; - overflow-y: auto; white-space: pre-wrap; word-break: break-word; } @@ -526,14 +541,12 @@ opacity: 0.8; } -/* Bottom Section: Resources */ +/* Right Column: Resources */ .recipe-bottom-section { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; - border-top: 1px solid var(--border-color); - padding-top: var(--space-2); } .recipe-section-header { @@ -1010,18 +1023,43 @@ } /* Responsive adjustments */ -@media (max-width: 768px) { - .recipe-top-section { - grid-template-columns: 1fr; +@media (max-width: 1500px) { + #recipeModal .modal-body { + grid-template-columns: 300px minmax(0, 1fr) 380px; } - - .recipe-preview-container { - height: 200px; +} + +@media (max-width: 1000px) { + #recipeModal .modal-body { + display: flex; + flex-direction: column; + gap: var(--space-2); + overflow-y: auto; } - + + .recipe-media-column { + overflow-y: visible; + flex-shrink: 0; + } + + .recipe-preview-container, + .recipe-preview-container img, + .recipe-preview-container video, + .recipe-preview-media { + max-height: 40vh; + } + .recipe-gen-params { - height: auto; - max-height: 300px; + overflow-y: visible; + flex-shrink: 0; + } + + .recipe-bottom-section { + flex: none; + } + + .recipe-loras-list { + max-height: 45vh; } } @@ -1045,19 +1083,11 @@ margin-bottom: 6px; } - .recipe-top-section { - grid-template-columns: 1fr; - gap: var(--space-1); - margin-bottom: var(--space-1); - } - - .recipe-preview-container { - display: none; - } - - .recipe-gen-params { - height: auto; - max-height: 210px; + .recipe-preview-container, + .recipe-preview-container img, + .recipe-preview-container video, + .recipe-preview-media { + max-height: 32vh; } .recipe-gen-params h3 { @@ -1070,7 +1100,6 @@ } .param-content { - max-height: 90px; padding: 10px; } @@ -1083,10 +1112,6 @@ gap: 6px; } - .recipe-bottom-section { - padding-top: var(--space-1); - } - .recipe-section-header { margin-bottom: var(--space-1); } diff --git a/static/js/components/RecipeModal.js b/static/js/components/RecipeModal.js index f90c7d65..477b765c 100644 --- a/static/js/components/RecipeModal.js +++ b/static/js/components/RecipeModal.js @@ -515,7 +515,7 @@ class RecipeModal { return; } - actionsContainer.innerHTML = ''; + actionsContainer.querySelectorAll('.recipe-source-url-btn').forEach(btn => btn.remove()); const sourcePath = this.currentRecipe?.source_path || ''; const isValidUrl = sourcePath.startsWith('http://') || sourcePath.startsWith('https://'); @@ -719,7 +719,7 @@ class RecipeModal { } } - lorasCountElement.innerHTML = ` ${totalCount} LoRAs ${statusHTML}`; + lorasCountElement.innerHTML = ` ${totalCount} ${totalCount === 1 ? 'LoRA' : 'LoRAs'} ${statusHTML}`; setTimeout(() => { const viewRecipeLorasBtn = document.getElementById('viewRecipeLorasBtn'); @@ -1180,11 +1180,10 @@ class RecipeModal { }); } - // Setup copy buttons for prompts and recipe syntax + // Setup copy buttons for prompts and send recipe button setupCopyButtons() { const copyPromptBtn = document.getElementById('copyPromptBtn'); const copyNegativePromptBtn = document.getElementById('copyNegativePromptBtn'); - const copyRecipeSyntaxBtn = document.getElementById('copyRecipeSyntaxBtn'); const sendRecipeBtn = document.getElementById('sendRecipeBtn'); if (copyPromptBtn) { @@ -1207,13 +1206,6 @@ class RecipeModal { }); } - if (copyRecipeSyntaxBtn) { - copyRecipeSyntaxBtn.addEventListener('click', () => { - // Use backend API to get recipe syntax - this.fetchAndCopyRecipeSyntax(); - }); - } - if (sendRecipeBtn) { sendRecipeBtn.addEventListener('click', () => { // Send recipe to ComfyUI workflow @@ -1299,35 +1291,6 @@ class RecipeModal { }); } - // Fetch recipe syntax from backend and copy to clipboard - async fetchAndCopyRecipeSyntax() { - if (!this.recipeId) { - showToast('toast.recipes.noRecipeId', {}, 'error'); - return; - } - - try { - // Fetch recipe syntax from backend - const response = await fetch(`/api/lm/recipe/${this.recipeId}/syntax`); - - if (!response.ok) { - throw new Error(`Failed to get recipe syntax: ${response.statusText}`); - } - - const data = await response.json(); - - if (data.success && data.syntax) { - // Use the centralized copyToClipboard utility function - await copyToClipboard(data.syntax, 'Recipe syntax copied to clipboard'); - } else { - throw new Error(data.error || 'No syntax returned from server'); - } - } catch (error) { - console.error('Error fetching recipe syntax:', error); - showToast('toast.recipes.copyFailed', { message: error.message }, 'error'); - } - } - // Helper method to copy text to clipboard copyToClipboard(text, successMessage) { copyToClipboard(text, successMessage); @@ -1632,7 +1595,7 @@ class RecipeModal { let headerAction = ''; if (existsLocally && localPath) { headerAction = ` - diff --git a/templates/components/recipe_modal.html b/templates/components/recipe_modal.html index e7a9f65e..269988a4 100644 --- a/templates/components/recipe_modal.html +++ b/templates/components/recipe_modal.html @@ -4,21 +4,27 @@

Recipe Details

- -
+ +
+ +