diff --git a/locales/de.json b/locales/de.json index eadb5d06..2a1eca36 100644 --- a/locales/de.json +++ b/locales/de.json @@ -545,6 +545,15 @@ "defaultClipVisionRootHelp": "[TODO: Translate] Set default CLIP vision root directory for downloads, imports and moves", "defaultControlnetRoot": "[TODO: Translate] ControlNet Root", "defaultControlnetRootHelp": "[TODO: Translate] Set default ControlNet root directory for downloads, imports and moves", + "enableOtherModels": "[TODO: Translate] Other Models Management", + "enableOtherModelsHelp": "[TODO: Translate] When off, VAE / upscaler / text encoder / CLIP folders are not scanned, the Other Models page stays disabled, and these model types cannot be downloaded.", + "otherSubTypes": "[TODO: Translate] Managed Types", + "otherSubTypesHelp": "[TODO: Translate] Choose which other-model categories are scanned and shown on the Other Models page.", + "subTypeVae": "[TODO: Translate] VAE", + "subTypeUpscaler": "[TODO: Translate] Upscaler", + "subTypeTextEncoder": "[TODO: Translate] Text Encoder", + "subTypeClipVision": "[TODO: Translate] CLIP Vision", + "subTypeControlnet": "[TODO: Translate] ControlNet", "recipesPath": "Rezepte-Speicherpfad", "recipesPathHelp": "Optionales benutzerdefiniertes Verzeichnis für gespeicherte Rezepte. Leer lassen, um den recipes-Ordner im ersten LoRA-Stammverzeichnis zu verwenden.", "recipesPathPlaceholder": "/path/to/recipes", @@ -1214,7 +1223,16 @@ "title": "Embedding-Modelle" }, "other": { - "title": "[TODO: Translate] Other Models" + "title": "[TODO: Translate] Other Models", + "disabled": { + "title": "[TODO: Translate] Other Models management is off", + "description": "[TODO: Translate] Enable it to scan and manage VAE, upscaler, text encoder and CLIP vision files, and to download them from CivitAI.", + "enableButton": "[TODO: Translate] Enable Other Models", + "hint": "[TODO: Translate] You can change the managed model types later in Settings > Library.", + "enableFailed": "[TODO: Translate] Failed to enable Other Models", + "downloadBlocked": "[TODO: Translate] Other Models management is disabled for this model type. Enable it in Settings > Library to download this file.", + "enableAction": "[TODO: Translate] Enable Other Models" + } }, "sidebar": { "modelRoot": "Stammverzeichnis", @@ -2615,6 +2633,12 @@ "rebuilding": "Cache wird neu aufgebaut...", "rebuildFailed": "Fehler beim Neuaufbau des Caches: {error}", "retry": "Wiederholen" + }, + "otherModels": { + "title": "[TODO: Translate] Other Models Management is available", + "content": "[TODO: Translate] Scan and manage VAE, upscaler, text encoder and CLIP vision files — and download them from CivitAI — from one dedicated page.", + "enable": "[TODO: Translate] Enable Other Models", + "openSettings": "[TODO: Translate] Open Settings" } } } diff --git a/locales/en.json b/locales/en.json index 1f32af8f..0fe2394d 100644 --- a/locales/en.json +++ b/locales/en.json @@ -545,6 +545,15 @@ "defaultClipVisionRootHelp": "Set default CLIP vision root directory for downloads, imports and moves", "defaultControlnetRoot": "ControlNet Root", "defaultControlnetRootHelp": "Set default ControlNet root directory for downloads, imports and moves", + "enableOtherModels": "Other Models Management", + "enableOtherModelsHelp": "When off, VAE / upscaler / text encoder / CLIP folders are not scanned, the Other Models page stays disabled, and these model types cannot be downloaded.", + "otherSubTypes": "Managed Types", + "otherSubTypesHelp": "Choose which other-model categories are scanned and shown on the Other Models page.", + "subTypeVae": "VAE", + "subTypeUpscaler": "Upscaler", + "subTypeTextEncoder": "Text Encoder", + "subTypeClipVision": "CLIP Vision", + "subTypeControlnet": "ControlNet", "recipesPath": "Recipes Storage Path", "recipesPathHelp": "Optional custom directory for stored recipes. Leave empty to use the first LoRA root's recipes folder.", "recipesPathPlaceholder": "/path/to/recipes", @@ -1214,7 +1223,16 @@ "title": "Embedding Models" }, "other": { - "title": "Other Models" + "title": "Other Models", + "disabled": { + "title": "Other Models management is off", + "description": "Enable it to scan and manage VAE, upscaler, text encoder and CLIP vision files, and to download them from CivitAI.", + "enableButton": "Enable Other Models", + "hint": "You can change the managed model types later in Settings > Library.", + "enableFailed": "Failed to enable Other Models", + "downloadBlocked": "Other Models management is disabled for this model type. Enable it in Settings > Library to download this file.", + "enableAction": "Enable Other Models" + } }, "sidebar": { "modelRoot": "Root", @@ -2615,6 +2633,12 @@ "rebuilding": "Rebuilding cache...", "rebuildFailed": "Failed to rebuild cache: {error}", "retry": "Retry" + }, + "otherModels": { + "title": "Other Models Management is available", + "content": "Scan and manage VAE, upscaler, text encoder and CLIP vision files — and download them from CivitAI — from one dedicated page.", + "enable": "Enable Other Models", + "openSettings": "Open Settings" } } } diff --git a/locales/es.json b/locales/es.json index fe83b1f9..7f517162 100644 --- a/locales/es.json +++ b/locales/es.json @@ -545,6 +545,15 @@ "defaultClipVisionRootHelp": "[TODO: Translate] Set default CLIP vision root directory for downloads, imports and moves", "defaultControlnetRoot": "[TODO: Translate] ControlNet Root", "defaultControlnetRootHelp": "[TODO: Translate] Set default ControlNet root directory for downloads, imports and moves", + "enableOtherModels": "[TODO: Translate] Other Models Management", + "enableOtherModelsHelp": "[TODO: Translate] When off, VAE / upscaler / text encoder / CLIP folders are not scanned, the Other Models page stays disabled, and these model types cannot be downloaded.", + "otherSubTypes": "[TODO: Translate] Managed Types", + "otherSubTypesHelp": "[TODO: Translate] Choose which other-model categories are scanned and shown on the Other Models page.", + "subTypeVae": "[TODO: Translate] VAE", + "subTypeUpscaler": "[TODO: Translate] Upscaler", + "subTypeTextEncoder": "[TODO: Translate] Text Encoder", + "subTypeClipVision": "[TODO: Translate] CLIP Vision", + "subTypeControlnet": "[TODO: Translate] ControlNet", "recipesPath": "Ruta de almacenamiento de recetas", "recipesPathHelp": "Directorio personalizado opcional para las recetas guardadas. Déjalo vacío para usar la carpeta recipes del primer directorio raíz de LoRA.", "recipesPathPlaceholder": "/path/to/recipes", @@ -1214,7 +1223,16 @@ "title": "Modelos embedding" }, "other": { - "title": "[TODO: Translate] Other Models" + "title": "[TODO: Translate] Other Models", + "disabled": { + "title": "[TODO: Translate] Other Models management is off", + "description": "[TODO: Translate] Enable it to scan and manage VAE, upscaler, text encoder and CLIP vision files, and to download them from CivitAI.", + "enableButton": "[TODO: Translate] Enable Other Models", + "hint": "[TODO: Translate] You can change the managed model types later in Settings > Library.", + "enableFailed": "[TODO: Translate] Failed to enable Other Models", + "downloadBlocked": "[TODO: Translate] Other Models management is disabled for this model type. Enable it in Settings > Library to download this file.", + "enableAction": "[TODO: Translate] Enable Other Models" + } }, "sidebar": { "modelRoot": "Raíz", @@ -2615,6 +2633,12 @@ "rebuilding": "Reconstruyendo caché...", "rebuildFailed": "Error al reconstruir la caché: {error}", "retry": "Reintentar" + }, + "otherModels": { + "title": "[TODO: Translate] Other Models Management is available", + "content": "[TODO: Translate] Scan and manage VAE, upscaler, text encoder and CLIP vision files — and download them from CivitAI — from one dedicated page.", + "enable": "[TODO: Translate] Enable Other Models", + "openSettings": "[TODO: Translate] Open Settings" } } } diff --git a/locales/fr.json b/locales/fr.json index dc69d10c..d0bc7a13 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -545,6 +545,15 @@ "defaultClipVisionRootHelp": "[TODO: Translate] Set default CLIP vision root directory for downloads, imports and moves", "defaultControlnetRoot": "[TODO: Translate] ControlNet Root", "defaultControlnetRootHelp": "[TODO: Translate] Set default ControlNet root directory for downloads, imports and moves", + "enableOtherModels": "[TODO: Translate] Other Models Management", + "enableOtherModelsHelp": "[TODO: Translate] When off, VAE / upscaler / text encoder / CLIP folders are not scanned, the Other Models page stays disabled, and these model types cannot be downloaded.", + "otherSubTypes": "[TODO: Translate] Managed Types", + "otherSubTypesHelp": "[TODO: Translate] Choose which other-model categories are scanned and shown on the Other Models page.", + "subTypeVae": "[TODO: Translate] VAE", + "subTypeUpscaler": "[TODO: Translate] Upscaler", + "subTypeTextEncoder": "[TODO: Translate] Text Encoder", + "subTypeClipVision": "[TODO: Translate] CLIP Vision", + "subTypeControlnet": "[TODO: Translate] ControlNet", "recipesPath": "Chemin de stockage des Recipes", "recipesPathHelp": "Dossier personnalisé facultatif pour les Recipes enregistrées. Laissez vide pour utiliser le dossier recipes de la première racine LoRA.", "recipesPathPlaceholder": "/path/to/recipes", @@ -1214,7 +1223,16 @@ "title": "Modèles Embedding" }, "other": { - "title": "[TODO: Translate] Other Models" + "title": "[TODO: Translate] Other Models", + "disabled": { + "title": "[TODO: Translate] Other Models management is off", + "description": "[TODO: Translate] Enable it to scan and manage VAE, upscaler, text encoder and CLIP vision files, and to download them from CivitAI.", + "enableButton": "[TODO: Translate] Enable Other Models", + "hint": "[TODO: Translate] You can change the managed model types later in Settings > Library.", + "enableFailed": "[TODO: Translate] Failed to enable Other Models", + "downloadBlocked": "[TODO: Translate] Other Models management is disabled for this model type. Enable it in Settings > Library to download this file.", + "enableAction": "[TODO: Translate] Enable Other Models" + } }, "sidebar": { "modelRoot": "Racine", @@ -2615,6 +2633,12 @@ "rebuilding": "Reconstruction du cache...", "rebuildFailed": "Échec de la reconstruction du cache : {error}", "retry": "Réessayer" + }, + "otherModels": { + "title": "[TODO: Translate] Other Models Management is available", + "content": "[TODO: Translate] Scan and manage VAE, upscaler, text encoder and CLIP vision files — and download them from CivitAI — from one dedicated page.", + "enable": "[TODO: Translate] Enable Other Models", + "openSettings": "[TODO: Translate] Open Settings" } } } diff --git a/locales/he.json b/locales/he.json index cb91c56a..c5a92f2a 100644 --- a/locales/he.json +++ b/locales/he.json @@ -545,6 +545,15 @@ "defaultClipVisionRootHelp": "[TODO: Translate] Set default CLIP vision root directory for downloads, imports and moves", "defaultControlnetRoot": "[TODO: Translate] ControlNet Root", "defaultControlnetRootHelp": "[TODO: Translate] Set default ControlNet root directory for downloads, imports and moves", + "enableOtherModels": "[TODO: Translate] Other Models Management", + "enableOtherModelsHelp": "[TODO: Translate] When off, VAE / upscaler / text encoder / CLIP folders are not scanned, the Other Models page stays disabled, and these model types cannot be downloaded.", + "otherSubTypes": "[TODO: Translate] Managed Types", + "otherSubTypesHelp": "[TODO: Translate] Choose which other-model categories are scanned and shown on the Other Models page.", + "subTypeVae": "[TODO: Translate] VAE", + "subTypeUpscaler": "[TODO: Translate] Upscaler", + "subTypeTextEncoder": "[TODO: Translate] Text Encoder", + "subTypeClipVision": "[TODO: Translate] CLIP Vision", + "subTypeControlnet": "[TODO: Translate] ControlNet", "recipesPath": "נתיב אחסון מתכונים", "recipesPathHelp": "ספרייה מותאמת אישית אופציונלית למתכונים שנשמרו. השאר ריק כדי להשתמש בתיקיית recipes של שורש LoRA הראשון.", "recipesPathPlaceholder": "/path/to/recipes", @@ -1214,7 +1223,16 @@ "title": "מודלי Embedding" }, "other": { - "title": "[TODO: Translate] Other Models" + "title": "[TODO: Translate] Other Models", + "disabled": { + "title": "[TODO: Translate] Other Models management is off", + "description": "[TODO: Translate] Enable it to scan and manage VAE, upscaler, text encoder and CLIP vision files, and to download them from CivitAI.", + "enableButton": "[TODO: Translate] Enable Other Models", + "hint": "[TODO: Translate] You can change the managed model types later in Settings > Library.", + "enableFailed": "[TODO: Translate] Failed to enable Other Models", + "downloadBlocked": "[TODO: Translate] Other Models management is disabled for this model type. Enable it in Settings > Library to download this file.", + "enableAction": "[TODO: Translate] Enable Other Models" + } }, "sidebar": { "modelRoot": "שורש", @@ -2615,6 +2633,12 @@ "rebuilding": "בונה מחדש את המטמון...", "rebuildFailed": "נכשלה בניית המטמון מחדש: {error}", "retry": "נסה שוב" + }, + "otherModels": { + "title": "[TODO: Translate] Other Models Management is available", + "content": "[TODO: Translate] Scan and manage VAE, upscaler, text encoder and CLIP vision files — and download them from CivitAI — from one dedicated page.", + "enable": "[TODO: Translate] Enable Other Models", + "openSettings": "[TODO: Translate] Open Settings" } } } diff --git a/locales/ja.json b/locales/ja.json index 69339323..17c1814b 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -545,6 +545,15 @@ "defaultClipVisionRootHelp": "[TODO: Translate] Set default CLIP vision root directory for downloads, imports and moves", "defaultControlnetRoot": "[TODO: Translate] ControlNet Root", "defaultControlnetRootHelp": "[TODO: Translate] Set default ControlNet root directory for downloads, imports and moves", + "enableOtherModels": "[TODO: Translate] Other Models Management", + "enableOtherModelsHelp": "[TODO: Translate] When off, VAE / upscaler / text encoder / CLIP folders are not scanned, the Other Models page stays disabled, and these model types cannot be downloaded.", + "otherSubTypes": "[TODO: Translate] Managed Types", + "otherSubTypesHelp": "[TODO: Translate] Choose which other-model categories are scanned and shown on the Other Models page.", + "subTypeVae": "[TODO: Translate] VAE", + "subTypeUpscaler": "[TODO: Translate] Upscaler", + "subTypeTextEncoder": "[TODO: Translate] Text Encoder", + "subTypeClipVision": "[TODO: Translate] CLIP Vision", + "subTypeControlnet": "[TODO: Translate] ControlNet", "recipesPath": "レシピ保存先", "recipesPathHelp": "保存済みレシピ用の任意のカスタムディレクトリです。空欄にすると最初のLoRAルートのrecipesフォルダーを使用します。", "recipesPathPlaceholder": "/path/to/recipes", @@ -1214,7 +1223,16 @@ "title": "Embeddingモデル" }, "other": { - "title": "[TODO: Translate] Other Models" + "title": "[TODO: Translate] Other Models", + "disabled": { + "title": "[TODO: Translate] Other Models management is off", + "description": "[TODO: Translate] Enable it to scan and manage VAE, upscaler, text encoder and CLIP vision files, and to download them from CivitAI.", + "enableButton": "[TODO: Translate] Enable Other Models", + "hint": "[TODO: Translate] You can change the managed model types later in Settings > Library.", + "enableFailed": "[TODO: Translate] Failed to enable Other Models", + "downloadBlocked": "[TODO: Translate] Other Models management is disabled for this model type. Enable it in Settings > Library to download this file.", + "enableAction": "[TODO: Translate] Enable Other Models" + } }, "sidebar": { "modelRoot": "ルート", @@ -2615,6 +2633,12 @@ "rebuilding": "キャッシュを再構築中...", "rebuildFailed": "キャッシュの再構築に失敗しました: {error}", "retry": "再試行" + }, + "otherModels": { + "title": "[TODO: Translate] Other Models Management is available", + "content": "[TODO: Translate] Scan and manage VAE, upscaler, text encoder and CLIP vision files — and download them from CivitAI — from one dedicated page.", + "enable": "[TODO: Translate] Enable Other Models", + "openSettings": "[TODO: Translate] Open Settings" } } } diff --git a/locales/ko.json b/locales/ko.json index 4215737e..cfb44fcc 100644 --- a/locales/ko.json +++ b/locales/ko.json @@ -545,6 +545,15 @@ "defaultClipVisionRootHelp": "[TODO: Translate] Set default CLIP vision root directory for downloads, imports and moves", "defaultControlnetRoot": "[TODO: Translate] ControlNet Root", "defaultControlnetRootHelp": "[TODO: Translate] Set default ControlNet root directory for downloads, imports and moves", + "enableOtherModels": "[TODO: Translate] Other Models Management", + "enableOtherModelsHelp": "[TODO: Translate] When off, VAE / upscaler / text encoder / CLIP folders are not scanned, the Other Models page stays disabled, and these model types cannot be downloaded.", + "otherSubTypes": "[TODO: Translate] Managed Types", + "otherSubTypesHelp": "[TODO: Translate] Choose which other-model categories are scanned and shown on the Other Models page.", + "subTypeVae": "[TODO: Translate] VAE", + "subTypeUpscaler": "[TODO: Translate] Upscaler", + "subTypeTextEncoder": "[TODO: Translate] Text Encoder", + "subTypeClipVision": "[TODO: Translate] CLIP Vision", + "subTypeControlnet": "[TODO: Translate] ControlNet", "recipesPath": "레시피 저장 경로", "recipesPathHelp": "저장된 레시피를 위한 선택적 사용자 지정 디렉터리입니다. 비워 두면 첫 번째 LoRA 루트의 recipes 폴더를 사용합니다.", "recipesPathPlaceholder": "/path/to/recipes", @@ -1214,7 +1223,16 @@ "title": "Embedding 모델" }, "other": { - "title": "[TODO: Translate] Other Models" + "title": "[TODO: Translate] Other Models", + "disabled": { + "title": "[TODO: Translate] Other Models management is off", + "description": "[TODO: Translate] Enable it to scan and manage VAE, upscaler, text encoder and CLIP vision files, and to download them from CivitAI.", + "enableButton": "[TODO: Translate] Enable Other Models", + "hint": "[TODO: Translate] You can change the managed model types later in Settings > Library.", + "enableFailed": "[TODO: Translate] Failed to enable Other Models", + "downloadBlocked": "[TODO: Translate] Other Models management is disabled for this model type. Enable it in Settings > Library to download this file.", + "enableAction": "[TODO: Translate] Enable Other Models" + } }, "sidebar": { "modelRoot": "루트", @@ -2615,6 +2633,12 @@ "rebuilding": "캐시 재구축 중...", "rebuildFailed": "캐시 재구축 실패: {error}", "retry": "다시 시도" + }, + "otherModels": { + "title": "[TODO: Translate] Other Models Management is available", + "content": "[TODO: Translate] Scan and manage VAE, upscaler, text encoder and CLIP vision files — and download them from CivitAI — from one dedicated page.", + "enable": "[TODO: Translate] Enable Other Models", + "openSettings": "[TODO: Translate] Open Settings" } } } diff --git a/locales/ru.json b/locales/ru.json index 6bf627b4..dd9e7728 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -545,6 +545,15 @@ "defaultClipVisionRootHelp": "[TODO: Translate] Set default CLIP vision root directory for downloads, imports and moves", "defaultControlnetRoot": "[TODO: Translate] ControlNet Root", "defaultControlnetRootHelp": "[TODO: Translate] Set default ControlNet root directory for downloads, imports and moves", + "enableOtherModels": "[TODO: Translate] Other Models Management", + "enableOtherModelsHelp": "[TODO: Translate] When off, VAE / upscaler / text encoder / CLIP folders are not scanned, the Other Models page stays disabled, and these model types cannot be downloaded.", + "otherSubTypes": "[TODO: Translate] Managed Types", + "otherSubTypesHelp": "[TODO: Translate] Choose which other-model categories are scanned and shown on the Other Models page.", + "subTypeVae": "[TODO: Translate] VAE", + "subTypeUpscaler": "[TODO: Translate] Upscaler", + "subTypeTextEncoder": "[TODO: Translate] Text Encoder", + "subTypeClipVision": "[TODO: Translate] CLIP Vision", + "subTypeControlnet": "[TODO: Translate] ControlNet", "recipesPath": "Путь хранения рецептов", "recipesPathHelp": "Дополнительный пользовательский каталог для сохранённых рецептов. Оставьте пустым, чтобы использовать папку recipes в первом корне LoRA.", "recipesPathPlaceholder": "/path/to/recipes", @@ -1214,7 +1223,16 @@ "title": "Модели Embedding" }, "other": { - "title": "[TODO: Translate] Other Models" + "title": "[TODO: Translate] Other Models", + "disabled": { + "title": "[TODO: Translate] Other Models management is off", + "description": "[TODO: Translate] Enable it to scan and manage VAE, upscaler, text encoder and CLIP vision files, and to download them from CivitAI.", + "enableButton": "[TODO: Translate] Enable Other Models", + "hint": "[TODO: Translate] You can change the managed model types later in Settings > Library.", + "enableFailed": "[TODO: Translate] Failed to enable Other Models", + "downloadBlocked": "[TODO: Translate] Other Models management is disabled for this model type. Enable it in Settings > Library to download this file.", + "enableAction": "[TODO: Translate] Enable Other Models" + } }, "sidebar": { "modelRoot": "Корень", @@ -2615,6 +2633,12 @@ "rebuilding": "Перестроение кэша...", "rebuildFailed": "Не удалось перестроить кэш: {error}", "retry": "Повторить" + }, + "otherModels": { + "title": "[TODO: Translate] Other Models Management is available", + "content": "[TODO: Translate] Scan and manage VAE, upscaler, text encoder and CLIP vision files — and download them from CivitAI — from one dedicated page.", + "enable": "[TODO: Translate] Enable Other Models", + "openSettings": "[TODO: Translate] Open Settings" } } } diff --git a/locales/zh-CN.json b/locales/zh-CN.json index c3f19342..35f60c41 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -545,6 +545,15 @@ "defaultClipVisionRootHelp": "[TODO: Translate] Set default CLIP vision root directory for downloads, imports and moves", "defaultControlnetRoot": "[TODO: Translate] ControlNet Root", "defaultControlnetRootHelp": "[TODO: Translate] Set default ControlNet root directory for downloads, imports and moves", + "enableOtherModels": "[TODO: Translate] Other Models Management", + "enableOtherModelsHelp": "[TODO: Translate] When off, VAE / upscaler / text encoder / CLIP folders are not scanned, the Other Models page stays disabled, and these model types cannot be downloaded.", + "otherSubTypes": "[TODO: Translate] Managed Types", + "otherSubTypesHelp": "[TODO: Translate] Choose which other-model categories are scanned and shown on the Other Models page.", + "subTypeVae": "[TODO: Translate] VAE", + "subTypeUpscaler": "[TODO: Translate] Upscaler", + "subTypeTextEncoder": "[TODO: Translate] Text Encoder", + "subTypeClipVision": "[TODO: Translate] CLIP Vision", + "subTypeControlnet": "[TODO: Translate] ControlNet", "recipesPath": "配方存储路径", "recipesPathHelp": "已保存配方的可选自定义目录。留空则使用第一个 LoRA 根目录下的 recipes 文件夹。", "recipesPathPlaceholder": "/path/to/recipes", @@ -1214,7 +1223,16 @@ "title": "Embedding 模型" }, "other": { - "title": "[TODO: Translate] Other Models" + "title": "[TODO: Translate] Other Models", + "disabled": { + "title": "[TODO: Translate] Other Models management is off", + "description": "[TODO: Translate] Enable it to scan and manage VAE, upscaler, text encoder and CLIP vision files, and to download them from CivitAI.", + "enableButton": "[TODO: Translate] Enable Other Models", + "hint": "[TODO: Translate] You can change the managed model types later in Settings > Library.", + "enableFailed": "[TODO: Translate] Failed to enable Other Models", + "downloadBlocked": "[TODO: Translate] Other Models management is disabled for this model type. Enable it in Settings > Library to download this file.", + "enableAction": "[TODO: Translate] Enable Other Models" + } }, "sidebar": { "modelRoot": "根目录", @@ -2615,6 +2633,12 @@ "rebuilding": "正在重建缓存...", "rebuildFailed": "重建缓存失败:{error}", "retry": "重试" + }, + "otherModels": { + "title": "[TODO: Translate] Other Models Management is available", + "content": "[TODO: Translate] Scan and manage VAE, upscaler, text encoder and CLIP vision files — and download them from CivitAI — from one dedicated page.", + "enable": "[TODO: Translate] Enable Other Models", + "openSettings": "[TODO: Translate] Open Settings" } } } diff --git a/locales/zh-TW.json b/locales/zh-TW.json index 2b917517..ecac6a66 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -545,6 +545,15 @@ "defaultClipVisionRootHelp": "[TODO: Translate] Set default CLIP vision root directory for downloads, imports and moves", "defaultControlnetRoot": "[TODO: Translate] ControlNet Root", "defaultControlnetRootHelp": "[TODO: Translate] Set default ControlNet root directory for downloads, imports and moves", + "enableOtherModels": "[TODO: Translate] Other Models Management", + "enableOtherModelsHelp": "[TODO: Translate] When off, VAE / upscaler / text encoder / CLIP folders are not scanned, the Other Models page stays disabled, and these model types cannot be downloaded.", + "otherSubTypes": "[TODO: Translate] Managed Types", + "otherSubTypesHelp": "[TODO: Translate] Choose which other-model categories are scanned and shown on the Other Models page.", + "subTypeVae": "[TODO: Translate] VAE", + "subTypeUpscaler": "[TODO: Translate] Upscaler", + "subTypeTextEncoder": "[TODO: Translate] Text Encoder", + "subTypeClipVision": "[TODO: Translate] CLIP Vision", + "subTypeControlnet": "[TODO: Translate] ControlNet", "recipesPath": "配方儲存路徑", "recipesPathHelp": "已儲存配方的可選自訂目錄。留空則使用第一個 LoRA 根目錄下的 recipes 資料夾。", "recipesPathPlaceholder": "/path/to/recipes", @@ -1214,7 +1223,16 @@ "title": "Embedding 模型" }, "other": { - "title": "[TODO: Translate] Other Models" + "title": "[TODO: Translate] Other Models", + "disabled": { + "title": "[TODO: Translate] Other Models management is off", + "description": "[TODO: Translate] Enable it to scan and manage VAE, upscaler, text encoder and CLIP vision files, and to download them from CivitAI.", + "enableButton": "[TODO: Translate] Enable Other Models", + "hint": "[TODO: Translate] You can change the managed model types later in Settings > Library.", + "enableFailed": "[TODO: Translate] Failed to enable Other Models", + "downloadBlocked": "[TODO: Translate] Other Models management is disabled for this model type. Enable it in Settings > Library to download this file.", + "enableAction": "[TODO: Translate] Enable Other Models" + } }, "sidebar": { "modelRoot": "根目錄", @@ -2615,6 +2633,12 @@ "rebuilding": "重建快取中...", "rebuildFailed": "重建快取失敗:{error}", "retry": "重試" + }, + "otherModels": { + "title": "[TODO: Translate] Other Models Management is available", + "content": "[TODO: Translate] Scan and manage VAE, upscaler, text encoder and CLIP vision files — and download them from CivitAI — from one dedicated page.", + "enable": "[TODO: Translate] Enable Other Models", + "openSettings": "[TODO: Translate] Open Settings" } } } diff --git a/static/css/components/header.css b/static/css/components/header.css index fc5f2665..800fc05d 100644 --- a/static/css/components/header.css +++ b/static/css/components/header.css @@ -83,6 +83,12 @@ white-space: nowrap; } +/* Opt-in pages (e.g. Other Models) hide their nav entry until enabled. + A class is used instead of [hidden] because .nav-item sets display: flex. */ +.nav-item--hidden { + display: none; +} + .nav-item:hover, .nav-item:focus-visible { background-color: var(--lora-surface-hover, oklch(95% 0.02 256)); diff --git a/static/css/components/modal/settings-modal.css b/static/css/components/modal/settings-modal.css index 887cff88..52e63304 100644 --- a/static/css/components/modal/settings-modal.css +++ b/static/css/components/modal/settings-modal.css @@ -1744,3 +1744,39 @@ input:checked + .toggle-slider:before { font-style: italic; user-select: none; } + +/* Other Models opt-in: sub_type checkbox row */ +.other-subtype-checkboxes { + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + gap: 6px 14px; +} + +.other-subtype-checkbox { + display: inline-flex; + align-items: center; + gap: 6px; + font-size: 0.9em; + color: var(--text-color); + cursor: pointer; + white-space: nowrap; +} + +.other-subtype-checkbox input[type="checkbox"] { + cursor: pointer; +} + +.other-subtype-toggles.is-disabled { + opacity: 0.5; +} + +.other-subtype-toggles.is-disabled .other-subtype-checkbox { + cursor: default; +} + +/* Disabled default-root selects for switched-off sub_types / feature */ +.select-control select:disabled { + opacity: 0.5; + cursor: not-allowed; +} diff --git a/static/js/managers/BannerService.js b/static/js/managers/BannerService.js index 5b4b4a34..37f187a1 100644 --- a/static/js/managers/BannerService.js +++ b/static/js/managers/BannerService.js @@ -6,9 +6,11 @@ import { import { translate } from '../utils/i18nHelpers.js'; import { state } from '../state/index.js'; import { getModelApiClient } from '../api/modelApiFactory.js'; +import { enableOtherModels, openOtherModelsSettings } from '../utils/otherModels.js'; const COMMUNITY_SUPPORT_BANNER_ID = 'community-support'; const CACHE_HEALTH_BANNER_ID = 'cache-health-warning'; +const OTHER_MODELS_BANNER_ID = 'other-models-announcement'; const COMMUNITY_SUPPORT_BANNER_DELAY_MS = 5 * 24 * 60 * 60 * 1000; // 5 days const COMMUNITY_SUPPORT_FIRST_SEEN_AT_KEY = 'community_support_banner_first_seen_at'; const COMMUNITY_SUPPORT_VERSION_KEY = 'community_support_banner_state_version'; @@ -80,6 +82,7 @@ class BannerService { }); this.prepareCommunitySupportBanner(); + this.prepareOtherModelsBanner(); await this.showActiveBanners(); this.initialized = true; @@ -541,6 +544,92 @@ class BannerService { this.updateContainerVisibility(); } + /** + * Announce the opt-in Other Models management to users who have not turned + * it on yet. Dismissal is persisted through the shared dismissed_banners + * setting, so users who are not interested are not nagged again. + */ + prepareOtherModelsBanner() { + if (state.global.settings.enable_other_models) { + return; + } + if (this.isBannerDismissed(OTHER_MODELS_BANNER_ID)) { + return; + } + + this.registerBanner(OTHER_MODELS_BANNER_ID, { + id: OTHER_MODELS_BANNER_ID, + title: translate( + 'banners.otherModels.title', + {}, + 'Other Models Management is available' + ), + content: translate( + 'banners.otherModels.content', + {}, + 'Scan and manage VAE, upscaler, text encoder and CLIP vision files — and download them from CivitAI — from one dedicated page.' + ), + actions: [ + { + text: translate( + 'banners.otherModels.enable', + {}, + 'Enable Other Models' + ), + icon: 'fas fa-shapes', + type: 'primary', + action: 'enable-other-models' + }, + { + text: translate( + 'banners.otherModels.openSettings', + {}, + 'Open Settings' + ), + icon: 'fas fa-cog', + type: 'secondary', + action: 'open-other-models-settings' + } + ], + dismissible: true, + priority: 0, + onRegister: (bannerElement) => { + const enableButton = bannerElement.querySelector( + '.banner-action[data-action="enable-other-models"]' + ); + if (enableButton) { + enableButton.addEventListener('click', (event) => { + event.preventDefault(); + enableOtherModels().catch((error) => { + console.error('Failed to enable Other Models:', error); + }); + }); + } + + const settingsButton = bannerElement.querySelector( + '.banner-action[data-action="open-other-models-settings"]' + ); + if (settingsButton) { + settingsButton.addEventListener('click', (event) => { + event.preventDefault(); + openOtherModelsSettings(); + }); + } + } + }); + + this.updateContainerVisibility(); + } + + /** + * Drop the Other Models announcement once the feature is enabled. + * Dismissal is deliberately NOT persisted, so the announcement can come + * back if the user switches the feature off again. + */ + removeOtherModelsAnnouncement() { + this.removeBannerElement(OTHER_MODELS_BANNER_ID); + } + initializeCommunitySupportState() { const storedVersion = getStorageItem(COMMUNITY_SUPPORT_VERSION_KEY, null); diff --git a/static/js/managers/DownloadManager.js b/static/js/managers/DownloadManager.js index 885becef..a4acc43a 100644 --- a/static/js/managers/DownloadManager.js +++ b/static/js/managers/DownloadManager.js @@ -1,5 +1,5 @@ import { modalManager } from './ModalManager.js'; -import { showToast, setupAutoNewlineOnPaste } from '../utils/uiHelpers.js'; +import { showToast, showActionToast, setupAutoNewlineOnPaste } from '../utils/uiHelpers.js'; import { state } from '../state/index.js'; import { LoadingManager } from './LoadingManager.js'; import { getModelApiClient, resetAndReload } from '../api/modelApiFactory.js'; @@ -12,6 +12,7 @@ import { MODEL_SUBTYPE_DISPLAY_NAMES } from '../utils/constants.js'; import { buildCivitaiUrl, extractCivitaiModelUrlParts, normalizeCivitaiPageHost } from '../utils/civitaiUtils.js'; import { formatFileSize } from '../utils/formatters.js'; import { showDownloadBatchSummary } from '../components/DownloadBatchSummaryModal.js'; +import { openOtherModelsSettings } from '../utils/otherModels.js'; export class DownloadManager { constructor() { @@ -1118,6 +1119,16 @@ export class DownloadManager { throw new Error(`routing endpoint returned ${response.status}`); } const data = await response.json(); + if (data.disabled) { + // The matching sub_type (or the whole Other Models feature) is + // switched off: auto-routing is refused, so offer the settings + // shortcut while the user's intent is clear. + showActionToast('other.disabled.downloadBlocked', {}, 'warning', { + actionText: translate('other.disabled.enableAction', {}, 'Enable Other Models'), + onAction: () => openOtherModelsSettings(), + }); + return null; + } return data.sub_type || null; } catch (error) { console.warn('[download] other routing endpoint unavailable, ' diff --git a/static/js/managers/SettingsManager.js b/static/js/managers/SettingsManager.js index 5c4ba1f0..be43e380 100644 --- a/static/js/managers/SettingsManager.js +++ b/static/js/managers/SettingsManager.js @@ -1155,6 +1155,7 @@ export class SettingsManager { // Load default other-model roots (per sub_type) await this.loadOtherRoots(); + this.updateOtherModelsControls(); // Load extra folder paths this.loadExtraFolderPaths(); @@ -2304,6 +2305,16 @@ export class SettingsManager { await this.updateBackupStatus(); } + if (settingKey === 'enable_other_models') { + // Roots only exist while the feature is on, so re-fetch them + // after the backend rebuilt the other-model root set. + this.updateOtherModelsControls(); + await this.loadOtherRoots(); + this.updateOtherModelsControls(); + this.updateOtherModelsNavVisibility(value); + this.removeOtherModelsAnnouncement(value); + } + showToast('toast.settings.settingsUpdated', { setting: settingKey.replace(/_/g, ' ') }, 'success'); // Apply frontend settings immediately @@ -2408,6 +2419,82 @@ export class SettingsManager { } } + /** + * Reflect the opt-in Other Models state in the settings UI: the master + * toggle gates every sub_type checkbox, and a switched-off sub_type has + * its default-root select disabled. Never force-enables a select (the + * no-roots placeholder owns that state). + */ + updateOtherModelsControls() { + const enableOtherModels = !!state.global.settings.enable_other_models; + const enabledSubTypes = new Set( + state.global.settings.enabled_other_sub_types + || ['vae', 'upscaler', 'text_encoder', 'clip_vision'] + ); + + document.querySelectorAll('[data-other-subtype-toggle]').forEach((input) => { + input.checked = enabledSubTypes.has(input.value); + input.disabled = !enableOtherModels; + }); + + const container = document.getElementById('otherSubTypeToggles'); + if (container) { + container.classList.toggle('is-disabled', !enableOtherModels); + } + + document.querySelectorAll('select[data-other-root-subtype]').forEach((select) => { + const subType = select.dataset.otherRootSubtype; + if (!enableOtherModels || !enabledSubTypes.has(subType)) { + select.disabled = true; + } + }); + } + + /** + * Persist the whole enabled_other_sub_types list (the backend stores an + * allow-list) and refresh the per-sub_type default-root selects. + */ + async saveEnabledOtherSubTypes() { + const values = Array.from( + document.querySelectorAll('[data-other-subtype-toggle]') + ) + .filter((input) => input.checked) + .map((input) => input.value); + + try { + await this.saveSetting('enabled_other_sub_types', values); + this.updateOtherModelsControls(); + await this.loadOtherRoots(); + this.updateOtherModelsControls(); + + showToast('toast.settings.settingsUpdated', { setting: 'other model types' }, 'success'); + } catch (error) { + showToast('toast.settings.settingSaveFailed', { message: error.message }, 'error'); + } + } + + /** + * Show or hide the Other Models nav entry. The nav is server-rendered, so + * toggling the class here keeps it in sync when the switch is flipped from + * the settings modal (no reload needed). + */ + updateOtherModelsNavVisibility(enabled) { + const navItem = document.getElementById('otherNavItem'); + if (navItem) { + navItem.classList.toggle('nav-item--hidden', !enabled); + } + } + + /** + * Drop the Other Models announcement banner once the feature is on. + */ + removeOtherModelsAnnouncement(enabled) { + if (!enabled) { + return; + } + bannerService.removeOtherModelsAnnouncement(); + } + /** * Save the recipes page layout (grid | masonry) and rebuild the scroller. * Shared entry point for the settings modal segmented control and the diff --git a/static/js/other_disabled.js b/static/js/other_disabled.js new file mode 100644 index 00000000..7ae5462a --- /dev/null +++ b/static/js/other_disabled.js @@ -0,0 +1,36 @@ +import { appCore } from './core.js'; +import { showToast } from './utils/uiHelpers.js'; +import { enableOtherModels } from './utils/otherModels.js'; + +/** + * Other Models is an opt-in feature. While it is disabled this page renders an + * empty state whose button turns the feature on; the backend then rebuilds the + * other-model roots and starts scanning, so a reload lands on the real page. + */ +async function handleEnableClick() { + const button = document.getElementById('enableOtherModelsBtn'); + if (!button || button.disabled) return; + + button.disabled = true; + try { + await enableOtherModels(); + } catch (error) { + button.disabled = false; + showToast('other.disabled.enableFailed', { message: error.message }, 'error'); + } +} + +async function initializeOtherDisabledPage() { + // appCore.initialize() wires the shared header (theme, settings modal, + // language) so this page is not a dead end. + await appCore.initialize(); + + const button = document.getElementById('enableOtherModelsBtn'); + if (button) { + button.addEventListener('click', handleEnableClick); + } +} + +document.addEventListener('DOMContentLoaded', initializeOtherDisabledPage); + +export { handleEnableClick as enableOtherModels, initializeOtherDisabledPage }; diff --git a/static/js/state/index.js b/static/js/state/index.js index f54858f3..9fc6c2c3 100644 --- a/static/js/state/index.js +++ b/static/js/state/index.js @@ -25,6 +25,8 @@ const DEFAULT_SETTINGS_BASE = Object.freeze({ default_checkpoint_root: '', default_embedding_root: '', default_other_roots: {}, + enable_other_models: false, + enabled_other_sub_types: ['vae', 'upscaler', 'text_encoder', 'clip_vision'], recipes_path: '', base_model_path_mappings: {}, download_path_templates: {}, @@ -74,6 +76,7 @@ export function createDefaultSettings() { download_path_templates: { ...DEFAULT_PATH_TEMPLATES }, priority_tags: { ...DEFAULT_PRIORITY_TAG_CONFIG }, default_other_roots: {}, + enabled_other_sub_types: ['vae', 'upscaler', 'text_encoder', 'clip_vision'], }; } diff --git a/static/js/utils/otherModels.js b/static/js/utils/otherModels.js new file mode 100644 index 00000000..40477eef --- /dev/null +++ b/static/js/utils/otherModels.js @@ -0,0 +1,52 @@ +/** + * Shared helpers for the opt-in Other Models feature. + * + * Used by the disabled page, the announcement banner and the download modal so + * that enabling the feature always goes through the same settings API call and + * lands on the same settings section. + */ + +/** + * Turn on Other Models management and reload so the server-rendered nav and + * the scanner state pick up the change. + */ +export async function enableOtherModels() { + const response = await fetch('/api/lm/settings', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ enable_other_models: true }), + }); + const data = await response.json().catch(() => ({})); + if (!response.ok || data.success === false) { + throw new Error(data.error || `HTTP ${response.status}`); + } + window.location.reload(); +} + +/** + * Open the settings modal on the Library section and scroll the Other Models + * toggle into view. Mirrors DoctorManager's open-settings-syntax-format flow. + */ +export function openOtherModelsSettings() { + const modalManager = window.modalManager; + if (modalManager && typeof modalManager.showModal === 'function') { + modalManager.showModal('settingsModal'); + } + + window.setTimeout(() => { + document.querySelectorAll('.settings-section').forEach((section) => { + section.classList.remove('active'); + }); + document.getElementById('section-library')?.classList.add('active'); + + document.querySelectorAll('.settings-nav-item').forEach((item) => { + item.classList.remove('active'); + }); + document.querySelector('.settings-nav-item[data-section="library"]')?.classList.add('active'); + + document.getElementById('enableOtherModels')?.scrollIntoView({ + behavior: 'smooth', + block: 'center', + }); + }, 100); +} diff --git a/templates/components/header.html b/templates/components/header.html index d55f328c..23bc15e3 100644 --- a/templates/components/header.html +++ b/templates/components/header.html @@ -38,9 +38,9 @@ id="embeddingsNavItem"> {{ t('header.navigation.embeddings') }} - - {{ t('header.navigation.other') }} + {{ t('header.navigation.other') }} diff --git a/templates/components/modals/settings/library.html b/templates/components/modals/settings/library.html index b639d859..b39992d2 100644 --- a/templates/components/modals/settings/library.html +++ b/templates/components/modals/settings/library.html @@ -39,17 +39,44 @@ {{ sm.setting_select('defaultEmbeddingRoot', 'default_embedding_root', 'settings.folderSettings.defaultEmbeddingRoot', [], 'settings.folderSettings.defaultEmbeddingRootHelp') }} + {{ sm.setting_toggle('enableOtherModels', 'enable_other_models', 'settings.folderSettings.enableOtherModels', 'settings.folderSettings.enableOtherModelsHelp') }} + + {% set enabled_other_sub_types = settings.get('enabled_other_sub_types') or ['vae', 'upscaler', 'text_encoder', 'clip_vision'] %} +
+
+
+ +
+
+ {% for sub_type, label_key in [ + ('vae', 'settings.folderSettings.subTypeVae'), + ('upscaler', 'settings.folderSettings.subTypeUpscaler'), + ('text_encoder', 'settings.folderSettings.subTypeTextEncoder'), + ('clip_vision', 'settings.folderSettings.subTypeClipVision'), + ('controlnet', 'settings.folderSettings.subTypeControlnet'), + ] %} + + {% endfor %} +
+
+
+ {% set other_root_selects = [ ('vae', 'defaultOtherRootVae', 'settings.folderSettings.defaultVaeRoot', 'settings.folderSettings.defaultVaeRootHelp'), ('upscaler', 'defaultOtherRootUpscaler', 'settings.folderSettings.defaultUpscalerRoot', 'settings.folderSettings.defaultUpscalerRootHelp'), ('text_encoder', 'defaultOtherRootTextEncoder', 'settings.folderSettings.defaultTextEncoderRoot', 'settings.folderSettings.defaultTextEncoderRootHelp'), ('clip_vision', 'defaultOtherRootClipVision', 'settings.folderSettings.defaultClipVisionRoot', 'settings.folderSettings.defaultClipVisionRootHelp'), + ('controlnet', 'defaultOtherRootControlnet', 'settings.folderSettings.defaultControlnetRoot', 'settings.folderSettings.defaultControlnetRootHelp'), ] %} - {% if 'controlnet' in (settings.get('enabled_other_folders') or []) %} - {% set other_root_selects = other_root_selects + [ - ('controlnet', 'defaultOtherRootControlnet', 'settings.folderSettings.defaultControlnetRoot', 'settings.folderSettings.defaultControlnetRootHelp'), - ] %} - {% endif %} {% for sub_type, select_id, label_key, help_key in other_root_selects %}
@@ -60,7 +87,7 @@
-
diff --git a/templates/other.html b/templates/other.html index 46f25668..fc16aa9a 100644 --- a/templates/other.html +++ b/templates/other.html @@ -7,6 +7,53 @@ {% block init_message %}{{ t('initialization.other.message') }}{% endblock %} {% block init_check_url %}/api/other/list?page=1&page_size=1{% endblock %} +{% block page_css %} + +{% endblock %} + {% block additional_components %}