diff --git a/locales/de.json b/locales/de.json index e10465e7..e2c58159 100644 --- a/locales/de.json +++ b/locales/de.json @@ -1165,7 +1165,11 @@ "exampleImages": { "opened": "Beispielbilder-Ordner geöffnet", "openingFolder": "Beispielbilder-Ordner wird geöffnet", - "failedToOpen": "Fehler beim Öffnen des Beispielbilder-Ordners" + "failedToOpen": "Fehler beim Öffnen des Beispielbilder-Ordners", + "setupRequired": "Beispielbilder-Speicher", + "setupDescription": "Um benutzerdefinierte Beispielbilder hinzuzufügen, müssen Sie zuerst einen Download-Speicherort festlegen.", + "setupUsage": "Dieser Pfad wird sowohl für heruntergeladene als auch für benutzerdefinierte Beispielbilder verwendet.", + "openSettings": "Einstellungen öffnen" } }, "help": { diff --git a/locales/en.json b/locales/en.json index 827e06a2..995ce3bd 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1165,7 +1165,11 @@ "exampleImages": { "opened": "Example images folder opened", "openingFolder": "Opening example images folder", - "failedToOpen": "Failed to open example images folder" + "failedToOpen": "Failed to open example images folder", + "setupRequired": "Example Images Storage", + "setupDescription": "To add custom example images, you need to set a download location first.", + "setupUsage": "This path is used for both downloaded and custom example images.", + "openSettings": "Open Settings" } }, "help": { diff --git a/locales/es.json b/locales/es.json index 788a2900..a7373353 100644 --- a/locales/es.json +++ b/locales/es.json @@ -1165,7 +1165,11 @@ "exampleImages": { "opened": "Carpeta de imágenes de ejemplo abierta", "openingFolder": "Abriendo carpeta de imágenes de ejemplo", - "failedToOpen": "Error al abrir carpeta de imágenes de ejemplo" + "failedToOpen": "Error al abrir carpeta de imágenes de ejemplo", + "setupRequired": "Almacenamiento de imágenes de ejemplo", + "setupDescription": "Para agregar imágenes de ejemplo personalizadas, primero necesita establecer una ubicación de descarga.", + "setupUsage": "Esta ruta se utiliza tanto para imágenes de ejemplo descargadas como personalizadas.", + "openSettings": "Abrir configuración" } }, "help": { diff --git a/locales/fr.json b/locales/fr.json index ef409f6e..931d049b 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -1165,7 +1165,11 @@ "exampleImages": { "opened": "Dossier d'images d'exemple ouvert", "openingFolder": "Ouverture du dossier d'images d'exemple", - "failedToOpen": "Échec de l'ouverture du dossier d'images d'exemple" + "failedToOpen": "Échec de l'ouverture du dossier d'images d'exemple", + "setupRequired": "Stockage d'images d'exemple", + "setupDescription": "Pour ajouter des images d'exemple personnalisées, vous devez d'abord définir un emplacement de téléchargement.", + "setupUsage": "Ce chemin est utilisé pour les images d'exemple téléchargées et personnalisées.", + "openSettings": "Ouvrir les paramètres" } }, "help": { diff --git a/locales/he.json b/locales/he.json index 2c6fde8f..ade6ec63 100644 --- a/locales/he.json +++ b/locales/he.json @@ -1165,7 +1165,11 @@ "exampleImages": { "opened": "תיקיית תמונות הדוגמה נפתחה", "openingFolder": "פותח תיקיית תמונות דוגמה", - "failedToOpen": "פתיחת תיקיית תמונות הדוגמה נכשלה" + "failedToOpen": "פתיחת תיקיית תמונות הדוגמה נכשלה", + "setupRequired": "אחסון תמונות דוגמה", + "setupDescription": "כדי להוסיף תמונות דוגמה מותאמות אישית, עליך קודם להגדיר מיקום הורדה.", + "setupUsage": "נתיב זה משמש הן עבור תמונות דוגמה שהורדו והן עבור תמונות מותאמות אישית.", + "openSettings": "פתח הגדרות" } }, "help": { diff --git a/locales/ja.json b/locales/ja.json index 401e6966..52e08474 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -1165,7 +1165,11 @@ "exampleImages": { "opened": "例画像フォルダが開かれました", "openingFolder": "例画像フォルダを開いています", - "failedToOpen": "例画像フォルダを開くのに失敗しました" + "failedToOpen": "例画像フォルダを開くのに失敗しました", + "setupRequired": "例画像ストレージ", + "setupDescription": "カスタム例画像を追加するには、まずダウンロード場所を設定する必要があります。", + "setupUsage": "このパスは、ダウンロードした例画像とカスタム画像の両方に使用されます。", + "openSettings": "設定を開く" } }, "help": { diff --git a/locales/ko.json b/locales/ko.json index d4b55e08..d468aa7b 100644 --- a/locales/ko.json +++ b/locales/ko.json @@ -1165,7 +1165,11 @@ "exampleImages": { "opened": "예시 이미지 폴더가 열렸습니다", "openingFolder": "예시 이미지 폴더를 여는 중", - "failedToOpen": "예시 이미지 폴더 열기 실패" + "failedToOpen": "예시 이미지 폴더 열기 실패", + "setupRequired": "예시 이미지 저장소", + "setupDescription": "사용자 지정 예시 이미지를 추가하려면 먼저 다운로드 위치를 설정해야 합니다.", + "setupUsage": "이 경로는 다운로드한 예시 이미지와 사용자 지정 이미지 모두에 사용됩니다.", + "openSettings": "설정 열기" } }, "help": { diff --git a/locales/ru.json b/locales/ru.json index 09f0a8a5..5db1838e 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -1165,7 +1165,11 @@ "exampleImages": { "opened": "Папка с примерами изображений открыта", "openingFolder": "Открытие папки с примерами изображений", - "failedToOpen": "Не удалось открыть папку с примерами изображений" + "failedToOpen": "Не удалось открыть папку с примерами изображений", + "setupRequired": "Хранилище примеров изображений", + "setupDescription": "Чтобы добавить собственные примеры изображений, сначала нужно установить место загрузки.", + "setupUsage": "Этот путь используется как для загруженных, так и для пользовательских примеров изображений.", + "openSettings": "Открыть настройки" } }, "help": { diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 3209f763..c9c04def 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -1165,7 +1165,11 @@ "exampleImages": { "opened": "示例图片文件夹已打开", "openingFolder": "正在打开示例图片文件夹", - "failedToOpen": "打开示例图片文件夹失败" + "failedToOpen": "打开示例图片文件夹失败", + "setupRequired": "示例图片存储", + "setupDescription": "要添加自定义示例图片,您需要先设置下载位置。", + "setupUsage": "此路径用于存储下载的示例图片和自定义图片。", + "openSettings": "打开设置" } }, "help": { diff --git a/locales/zh-TW.json b/locales/zh-TW.json index c1098099..47d9069e 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -1165,7 +1165,11 @@ "exampleImages": { "opened": "範例圖片資料夾已開啟", "openingFolder": "正在開啟範例圖片資料夾", - "failedToOpen": "開啟範例圖片資料夾失敗" + "failedToOpen": "開啟範例圖片資料夾失敗", + "setupRequired": "範例圖片儲存", + "setupDescription": "要新增自訂範例圖片,您需要先設定下載位置。", + "setupUsage": "此路徑用於儲存下載的範例圖片和自訂圖片。", + "openSettings": "開啟設定" } }, "help": { diff --git a/static/css/components/lora-modal/showcase.css b/static/css/components/lora-modal/showcase.css index dc3467fd..c49c869b 100644 --- a/static/css/components/lora-modal/showcase.css +++ b/static/css/components/lora-modal/showcase.css @@ -482,3 +482,75 @@ [data-theme="dark"] .import-container { background: rgba(255, 255, 255, 0.03); } + +/* Setup Guidance State - When example images path is not configured */ +.import-container--needs-setup { + cursor: default; + border-style: solid; + border-color: var(--border-color); + background: var(--lora-surface); +} + +.import-container--needs-setup:hover { + border-color: var(--border-color); + transform: none; +} + +.import-setup-guidance { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-2); + padding: var(--space-3) var(--space-2); + text-align: center; +} + +.setup-icon { + width: 64px; + height: 64px; + border-radius: 50%; + background: oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1); + display: flex; + align-items: center; + justify-content: center; + margin-bottom: var(--space-1); +} + +.setup-icon i { + font-size: 1.75rem; + color: var(--lora-accent); +} + +.import-setup-guidance h3 { + margin: 0; + font-size: 1.2rem; + font-weight: 600; + color: var(--text-color); +} + +.setup-description { + margin: 0; + color: var(--text-color); + opacity: 0.9; + max-width: 320px; + line-height: 1.5; +} + +.setup-usage { + margin: 0; + font-size: 0.85em; + color: var(--text-color); + opacity: 0.6; + font-style: italic; +} + +.setup-settings-btn { + margin-top: var(--space-2); + background: var(--lora-accent) !important; + color: var(--lora-text) !important; +} + +.setup-settings-btn:hover { + opacity: 0.9; + transform: translateY(-1px); +} diff --git a/static/js/components/shared/showcase/ShowcaseView.js b/static/js/components/shared/showcase/ShowcaseView.js index 9987873a..093422a9 100644 --- a/static/js/components/shared/showcase/ShowcaseView.js +++ b/static/js/components/shared/showcase/ShowcaseView.js @@ -4,6 +4,8 @@ */ import { showToast } from '../../../utils/uiHelpers.js'; import { state } from '../../../state/index.js'; +import { modalManager } from '../../../managers/ModalManager.js'; +import { translate } from '../../../utils/i18nHelpers.js'; import { NSFW_LEVELS } from '../../../utils/constants.js'; import { initLazyLoading, @@ -275,6 +277,40 @@ function findLocalFile(img, index, exampleFiles) { * @returns {string} HTML content for import interface */ function renderImportInterface(isEmpty) { + // Check if example images path is configured + const exampleImagesPath = state.global.settings.example_images_path; + const isPathConfigured = exampleImagesPath && exampleImagesPath.trim() !== ''; + + // If path is not configured, show setup guidance + if (!isPathConfigured) { + const title = translate('uiHelpers.exampleImages.setupRequired', {}, 'Example Images Storage'); + const description = translate('uiHelpers.exampleImages.setupDescription', {}, 'To add custom example images, you need to set a download location first.'); + const usage = translate('uiHelpers.exampleImages.setupUsage', {}, 'This path is used for both downloaded and custom example images.'); + const openSettings = translate('uiHelpers.exampleImages.openSettings', {}, 'Open Settings'); + + return ` +
+
+
+
+ +
+

${title}

+

+ ${description} +

+

+ ${usage} +

+ +
+
+
+ `; + } + return `
@@ -300,6 +336,33 @@ function renderImportInterface(isEmpty) { `; } +/** + * Open settings modal and scroll to example images section + */ +function openSettingsForExampleImages() { + modalManager.showModal('settingsModal'); + + // Wait for modal to be visible, then scroll to example images section + setTimeout(() => { + const exampleImagesInput = document.getElementById('exampleImagesPath'); + if (exampleImagesInput) { + // Find the parent settings-section + const section = exampleImagesInput.closest('.settings-section'); + if (section) { + section.scrollIntoView({ behavior: 'smooth', block: 'center' }); + // Add a brief highlight effect + section.style.transition = 'background-color 0.3s ease'; + section.style.backgroundColor = 'rgba(66, 153, 225, 0.1)'; + setTimeout(() => { + section.style.backgroundColor = ''; + }, 1500); + } + // Focus the input + exampleImagesInput.focus(); + } + }, 100); +} + /** * Initialize the example import functionality * @param {string} modelHash - The SHA256 hash of the model @@ -311,6 +374,14 @@ export function initExampleImport(modelHash, container) { const importContainer = container.querySelector('#exampleImportContainer'); const fileInput = container.querySelector('#exampleFilesInput'); const selectFilesBtn = container.querySelector('#selectExampleFilesBtn'); + const openSettingsBtn = container.querySelector('#openExampleSettingsBtn'); + + // Set up "Open Settings" button for setup guidance state + if (openSettingsBtn) { + openSettingsBtn.addEventListener('click', () => { + openSettingsForExampleImages(); + }); + } // Set up file selection button if (selectFilesBtn) {