Enhance localization and UI for model management features

- Added new localization keys for usage statistics, collection analysis, storage efficiency, and insights in English and Chinese.
- Updated modal templates to utilize localization for delete, exclude, and bulk delete confirmations.
- Improved download modal with localized labels and placeholders.
- Enhanced example access modal with localized titles and descriptions.
- Updated help modal to include localized content for update vlogs and documentation sections.
- Refactored move modal to use localization for labels and buttons.
- Implemented localization in relink Civitai modal for warnings and help text.
- Updated update modal to reflect localized text for actions and progress messages.
- Enhanced statistics template with localized titles for charts and lists.
This commit is contained in:
Will Miao
2025-08-30 23:20:13 +08:00
parent b36fea002e
commit 36d3cd93d5
10 changed files with 360 additions and 110 deletions

View File

@@ -1,12 +1,12 @@
<!-- Delete Confirmation Modal -->
<div id="deleteModal" class="modal delete-modal">
<div class="modal-content delete-modal-content">
<h2>Delete Model</h2>
<p class="delete-message">Are you sure you want to delete this model and all associated files?</p>
<h2>{{ t('modals.deleteModel.title') }}</h2>
<p class="delete-message">{{ t('modals.deleteModel.message') }}</p>
<div class="delete-model-info"></div>
<div class="modal-actions">
<button class="cancel-btn" onclick="closeDeleteModal()">Cancel</button>
<button class="delete-btn" onclick="confirmDelete()">Delete</button>
<button class="cancel-btn" onclick="closeDeleteModal()">{{ t('common.actions.cancel') }}</button>
<button class="delete-btn" onclick="confirmDelete()">{{ t('common.actions.delete') }}</button>
</div>
</div>
</div>
@@ -14,12 +14,12 @@
<!-- Exclude Confirmation Modal -->
<div id="excludeModal" class="modal delete-modal">
<div class="modal-content delete-modal-content">
<h2>Exclude Model</h2>
<p class="delete-message">Are you sure you want to exclude this model? Excluded models won't appear in searches or model lists.</p>
<h2>{{ t('modals.excludeModel.title') }}</h2>
<p class="delete-message">{{ t('modals.excludeModel.message') }}</p>
<div class="exclude-model-info"></div>
<div class="modal-actions">
<button class="cancel-btn" onclick="closeExcludeModal()">Cancel</button>
<button class="exclude-btn" onclick="confirmExclude()">Exclude</button>
<button class="cancel-btn" onclick="closeExcludeModal()">{{ t('common.actions.cancel') }}</button>
<button class="exclude-btn" onclick="confirmExclude()">{{ t('modals.exclude.confirm') }}</button>
</div>
</div>
</div>
@@ -27,14 +27,14 @@
<!-- Recipes Duplicate Delete Confirmation Modal -->
<div id="duplicateDeleteModal" class="modal delete-modal">
<div class="modal-content delete-modal-content">
<h2>Delete Duplicate Recipes</h2>
<p class="delete-message">Are you sure you want to delete the selected duplicate recipes?</p>
<h2>{{ t('modals.deleteDuplicateRecipes.title') }}</h2>
<p class="delete-message">{{ t('modals.deleteDuplicateRecipes.message') }}</p>
<div class="delete-model-info">
<p><span id="duplicateDeleteCount">0</span> recipes will be permanently deleted.</p>
<p><span id="duplicateDeleteCount">0</span> {{ t('modals.deleteDuplicateRecipes.countMessage') }}</p>
</div>
<div class="modal-actions">
<button class="cancel-btn" onclick="modalManager.closeModal('duplicateDeleteModal')">Cancel</button>
<button class="delete-btn" onclick="recipeManager.confirmDeleteDuplicates()">Delete</button>
<button class="cancel-btn" onclick="modalManager.closeModal('duplicateDeleteModal')">{{ t('common.actions.cancel') }}</button>
<button class="delete-btn" onclick="recipeManager.confirmDeleteDuplicates()">{{ t('common.actions.delete') }}</button>
</div>
</div>
</div>
@@ -42,14 +42,14 @@
<!-- Models Duplicate Delete Confirmation Modal -->
<div id="modelDuplicateDeleteModal" class="modal delete-modal">
<div class="modal-content delete-modal-content">
<h2>Delete Duplicate Models</h2>
<p class="delete-message">Are you sure you want to delete the selected duplicate models?</p>
<h2>{{ t('modals.deleteDuplicateModels.title') }}</h2>
<p class="delete-message">{{ t('modals.deleteDuplicateModels.message') }}</p>
<div class="delete-model-info">
<p><span id="modelDuplicateDeleteCount">0</span> models will be permanently deleted.</p>
<p><span id="modelDuplicateDeleteCount">0</span> {{ t('modals.deleteDuplicateModels.countMessage') }}</p>
</div>
<div class="modal-actions">
<button class="cancel-btn" onclick="modalManager.closeModal('modelDuplicateDeleteModal')">Cancel</button>
<button class="delete-btn" onclick="modelDuplicatesManager.confirmDeleteDuplicates()">Delete</button>
<button class="cancel-btn" onclick="modalManager.closeModal('modelDuplicateDeleteModal')">{{ t('common.actions.cancel') }}</button>
<button class="delete-btn" onclick="modelDuplicatesManager.confirmDeleteDuplicates()">{{ t('common.actions.delete') }}</button>
</div>
</div>
</div>
@@ -57,14 +57,14 @@
<!-- Cache Clear Confirmation Modal -->
<div id="clearCacheModal" class="modal delete-modal">
<div class="modal-content delete-modal-content">
<h2>Clear Cache Files</h2>
<p class="delete-message">Are you sure you want to clear all cache files?</p>
<h2>{{ t('modals.clearCache.title') }}</h2>
<p class="delete-message">{{ t('modals.clearCache.message') }}</p>
<div class="delete-model-info">
<p>This will remove all cached model data. The system will need to rebuild the cache on next startup, which may take some time depending on your model collection size.</p>
<p>{{ t('modals.clearCache.description') }}</p>
</div>
<div class="modal-actions">
<button class="cancel-btn" onclick="modalManager.closeModal('clearCacheModal')">Cancel</button>
<button class="delete-btn" onclick="settingsManager.executeClearCache()">Clear Cache</button>
<button class="cancel-btn" onclick="modalManager.closeModal('clearCacheModal')">{{ t('common.actions.cancel') }}</button>
<button class="delete-btn" onclick="settingsManager.executeClearCache()">{{ t('modals.clearCache.action') }}</button>
</div>
</div>
</div>
@@ -72,14 +72,14 @@
<!-- Bulk Delete Confirmation Modal -->
<div id="bulkDeleteModal" class="modal delete-modal">
<div class="modal-content delete-modal-content">
<h2>Delete Multiple Models</h2>
<p class="delete-message">Are you sure you want to delete all selected models and their associated files?</p>
<h2>{{ t('modals.bulkDelete.title') }}</h2>
<p class="delete-message">{{ t('modals.bulkDelete.message') }}</p>
<div class="delete-model-info">
<p><span id="bulkDeleteCount">0</span> models will be permanently deleted.</p>
<p><span id="bulkDeleteCount">0</span> {{ t('modals.bulkDelete.countMessage') }}</p>
</div>
<div class="modal-actions">
<button class="cancel-btn" onclick="modalManager.closeModal('bulkDeleteModal')">Cancel</button>
<button class="delete-btn" onclick="bulkManager.confirmBulkDelete()">Delete All</button>
<button class="cancel-btn" onclick="modalManager.closeModal('bulkDeleteModal')">{{ t('common.actions.cancel') }}</button>
<button class="delete-btn" onclick="bulkManager.confirmBulkDelete()">{{ t('modals.bulkDelete.action') }}</button>
</div>
</div>
</div>

View File

@@ -51,7 +51,7 @@
<!-- Model Root Selection (always visible) -->
<div class="input-group">
<label for="modelRoot" id="modelRootLabel">Select Model Root:</label>
<label for="modelRoot" id="modelRootLabel">{{ t('modals.download.selectModelRoot') }}</label>
<select id="modelRoot"></select>
</div>
@@ -59,10 +59,10 @@
<div class="manual-path-selection" id="manualPathSelection">
<!-- Path input with autocomplete -->
<div class="input-group">
<label for="folderPath">Target Folder Path:</label>
<label for="folderPath">{{ t('modals.download.targetFolderPath') }}</label>
<div class="path-input-container">
<input type="text" id="folderPath" placeholder="Type folder path or select from tree below..." autocomplete="off" />
<button type="button" id="createFolderBtn" class="create-folder-btn" title="Create new folder">
<input type="text" id="folderPath" placeholder="{{ t('modals.download.pathPlaceholder') }}" autocomplete="off" />
<button type="button" id="createFolderBtn" class="create-folder-btn" title="{{ t('modals.download.createNewFolder') }}">
<i class="fas fa-plus"></i>
</button>
</div>
@@ -72,13 +72,13 @@
<!-- Breadcrumb navigation -->
<div class="breadcrumb-nav" id="breadcrumbNav">
<span class="breadcrumb-item root" data-path="">
<i class="fas fa-home"></i> Root
<i class="fas fa-home"></i> {{ t('modals.download.root') }}
</span>
</div>
<!-- Hierarchical folder tree -->
<div class="input-group">
<label>Browse Folders:</label>
<label>{{ t('modals.download.browseFolders') }}</label>
<div class="folder-tree-container">
<div class="folder-tree" id="folderTree">
<!-- Tree will be loaded dynamically -->
@@ -88,8 +88,8 @@
</div>
</div>
<div class="modal-actions">
<button class="secondary-btn" id="backToVersionsBtn">Back</button>
<button class="primary-btn" id="startDownloadBtn">Download</button>
<button class="secondary-btn" id="backToVersionsBtn">{{ t('common.actions.back') }}</button>
<button class="primary-btn" id="startDownloadBtn">{{ t('modals.download.download') }}</button>
</div>
</div>
</div>

View File

@@ -2,26 +2,26 @@
<div id="exampleAccessModal" class="modal">
<div class="modal-content example-access-modal">
<button class="close" onclick="modalManager.closeModal('exampleAccessModal')">&times;</button>
<h2>Local Example Images</h2>
<p>No local example images found for this model. View options:</p>
<h2>{{ t('modals.exampleAccess.title') }}</h2>
<p>{{ t('modals.exampleAccess.message') }}</p>
<div class="example-access-options">
<button id="downloadExamplesBtn" class="example-option-btn">
<i class="fas fa-cloud-download-alt"></i>
<span class="option-title">Download from Civitai</span>
<span class="option-desc">Save remote examples locally for offline use and faster loading</span>
<span class="option-title">{{ t('modals.exampleAccess.downloadOption.title') }}</span>
<span class="option-desc">{{ t('modals.exampleAccess.downloadOption.description') }}</span>
</button>
<button id="importExamplesBtn" class="example-option-btn">
<i class="fas fa-file-import"></i>
<span class="option-title">Import Your Own</span>
<span class="option-desc">Add your own custom examples for this model</span>
<span class="option-title">{{ t('modals.exampleAccess.importOption.title') }}</span>
<span class="option-desc">{{ t('modals.exampleAccess.importOption.description') }}</span>
</button>
</div>
<div class="modal-footer-note">
<i class="fas fa-info-circle"></i>
<span>Remote examples are still viewable in the model details even without local copies</span>
<span>{{ t('modals.exampleAccess.footerNote') }}</span>
</div>
</div>
</div>

View File

@@ -44,7 +44,7 @@
<!-- Update Vlogs Tab -->
<div class="tab-pane" id="update-vlogs">
<h3>
Latest Updates
{{ t('help.updateVlogs.title') }}
<span class="update-date-badge">
<i class="fas fa-calendar-alt"></i>
Apr 28, 2025
@@ -58,14 +58,14 @@
<div class="video-play-overlay">
<a href="https://www.youtube.com/playlist?list=PLU2fMdHNl8ohz1u7Ke3ooOuMbU5Y4sgoj" target="_blank" class="external-link-btn">
<i class="fas fa-external-link-alt"></i>
<span>Watch on YouTube</span>
<span>{{ t('help.updateVlogs.watchOnYouTube') }}</span>
</a>
</div>
</div>
</div>
<div class="video-info">
<h4>LoRA Manager Updates Playlist</h4>
<p>Watch all update videos showcasing the latest features and improvements.</p>
<h4>{{ t('help.updateVlogs.playlistTitle') }}</h4>
<p>{{ t('help.updateVlogs.playlistDescription') }}</p>
</div>
</div>
</div>
@@ -73,10 +73,10 @@
<!-- Documentation Tab -->
<div class="tab-pane" id="documentation">
<h3>Documentation</h3>
<h3>{{ t('help.documentation.title') }}</h3>
<div class="docs-section">
<h4><i class="fas fa-book"></i> General</h4>
<h4><i class="fas fa-book"></i> {{ t('help.documentation.general') }}</h4>
<ul class="docs-links">
<li><a href="https://github.com/willmiao/ComfyUI-Lora-Manager/wiki" target="_blank">Wiki Home</a></li>
<li><a href="https://github.com/willmiao/ComfyUI-Lora-Manager/blob/main/README.md" target="_blank">README</a></li>
@@ -84,28 +84,28 @@
</div>
<div class="docs-section">
<h4><i class="fas fa-tools"></i> Troubleshooting</h4>
<h4><i class="fas fa-tools"></i> {{ t('help.documentation.troubleshooting') }}</h4>
<ul class="docs-links">
<li><a href="https://github.com/willmiao/ComfyUI-Lora-Manager/wiki/FAQ-(Frequently-Asked-Questions)" target="_blank">FAQ (Frequently Asked Questions)</a></li>
</ul>
</div>
<div class="docs-section">
<h4><i class="fas fa-layer-group"></i> Model Management</h4>
<h4><i class="fas fa-layer-group"></i> {{ t('help.documentation.modelManagement') }}</h4>
<ul class="docs-links">
<li><a href="https://github.com/willmiao/ComfyUI-Lora-Manager/wiki/Example-Images" target="_blank">Example Images (WIP)</a></li>
</ul>
</div>
<div class="docs-section">
<h4><i class="fas fa-book-open"></i> Recipes</h4>
<h4><i class="fas fa-book-open"></i> {{ t('help.documentation.recipes') }}</h4>
<ul class="docs-links">
<li><a href="https://github.com/willmiao/ComfyUI-Lora-Manager/wiki/Recipes-Feature-Tutorial-%E2%80%93-ComfyUI-LoRA-Manager" target="_blank">Recipes Tutorial</a></li>
</ul>
</div>
<div class="docs-section">
<h4><i class="fas fa-cog"></i> Settings & Configuration</h4>
<h4><i class="fas fa-cog"></i> {{ t('help.documentation.settings') }}</h4>
<ul class="docs-links">
<li><a href="https://github.com/willmiao/ComfyUI-Lora-Manager/wiki/Configuration" target="_blank">Configuration Options (WIP)</a></li>
</ul>
@@ -113,14 +113,14 @@
<div class="docs-section">
<h4>
<i class="fas fa-puzzle-piece"></i> Extensions
<span class="new-content-badge">NEW</span>
<i class="fas fa-puzzle-piece"></i> {{ t('help.documentation.extensions') }}
<span class="new-content-badge">{{ t('help.documentation.newBadge') }}</span>
</h4>
<ul class="docs-links">
<li>
<a href="https://github.com/willmiao/ComfyUI-Lora-Manager/wiki/LoRA-Manager-Civitai-Extension-(Chrome-Extension)" target="_blank">
LM Civitai Extension
<span class="new-content-badge inline">NEW</span>
<span class="new-content-badge inline">{{ t('help.documentation.newBadge') }}</span>
</a>
</li>
</ul>

View File

@@ -2,29 +2,29 @@
<div id="moveModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h2 id="moveModalTitle">Move Model</h2>
<h2 id="moveModalTitle">{{ t('modals.move.title') }}</h2>
<span class="close" onclick="modalManager.closeModal('moveModal')">&times;</span>
</div>
<div class="location-selection">
<!-- Path preview -->
<div class="path-preview">
<label>Target Location Preview:</label>
<label>{{ t('modals.moveModel.targetLocationPreview') }}</label>
<div class="path-display" id="moveTargetPathDisplay">
<span class="path-text">Select a model root directory</span>
<span class="path-text">{{ t('modals.download.selectRootDirectory') }}</span>
</div>
</div>
<div class="input-group">
<label for="moveModelRoot" id="moveRootLabel">Select Model Root:</label>
<label for="moveModelRoot" id="moveRootLabel">{{ t('modals.moveModel.selectModelRoot') }}</label>
<select id="moveModelRoot"></select>
</div>
<!-- Path input with autocomplete -->
<div class="input-group">
<label for="moveFolderPath">Target Folder Path:</label>
<label for="moveFolderPath">{{ t('modals.moveModel.targetFolderPath') }}</label>
<div class="path-input-container">
<input type="text" id="moveFolderPath" placeholder="Type folder path or select from tree below..." autocomplete="off" />
<button type="button" id="moveCreateFolderBtn" class="create-folder-btn" title="Create new folder">
<input type="text" id="moveFolderPath" placeholder="{{ t('modals.moveModel.pathPlaceholder') }}" autocomplete="off" />
<button type="button" id="moveCreateFolderBtn" class="create-folder-btn" title="{{ t('modals.moveModel.createNewFolder') }}">
<i class="fas fa-plus"></i>
</button>
</div>
@@ -34,13 +34,13 @@
<!-- Breadcrumb navigation -->
<div class="breadcrumb-nav" id="moveBreadcrumbNav">
<span class="breadcrumb-item root" data-path="">
<i class="fas fa-home"></i> Root
<i class="fas fa-home"></i> {{ t('modals.moveModel.root') }}
</span>
</div>
<!-- Hierarchical folder tree -->
<div class="input-group">
<label>Browse Folders:</label>
<label>{{ t('modals.moveModel.browseFolders') }}</label>
<div class="folder-tree-container">
<div class="folder-tree" id="moveFolderTree">
<!-- Tree will be loaded dynamically -->
@@ -49,8 +49,8 @@
</div>
</div>
<div class="modal-actions">
<button class="cancel-btn" onclick="modalManager.closeModal('moveModal')">Cancel</button>
<button class="primary-btn" onclick="moveManager.moveModel()">Move</button>
<button class="cancel-btn" onclick="modalManager.closeModal('moveModal')">{{ t('common.actions.cancel') }}</button>
<button class="primary-btn" onclick="moveManager.moveModel()">{{ t('common.actions.move') }}</button>
</div>
</div>
</div>

View File

@@ -2,32 +2,32 @@
<div id="relinkCivitaiModal" class="modal">
<div class="modal-content">
<button class="close" onclick="modalManager.closeModal('relinkCivitaiModal')">&times;</button>
<h2>Re-link to Civitai</h2>
<h2>{{ t('modals.relinkCivitai.title') }}</h2>
<div class="warning-box">
<i class="fas fa-exclamation-triangle"></i>
<p><strong>Warning:</strong> This is a potentially destructive operation. Re-linking will:</p>
<p><strong>{{ t('modals.relinkCivitai.warning') }}</strong> {{ t('modals.relinkCivitai.warningText') }}</p>
<ul>
<li>Override existing metadata</li>
<li>Potentially modify the model hash</li>
<li>May have other unintended consequences</li>
<li>{{ t('modals.relinkCivitai.warningList.overrideMetadata') }}</li>
<li>{{ t('modals.relinkCivitai.warningList.modifyHash') }}</li>
<li>{{ t('modals.relinkCivitai.warningList.unintendedConsequences') }}</li>
</ul>
<p>Only proceed if you're sure this is what you want.</p>
<p>{{ t('modals.relinkCivitai.proceedText') }}</p>
</div>
<div class="input-group">
<label for="civitaiModelUrl">Civitai Model URL:</label>
<input type="text" id="civitaiModelUrl" placeholder="https://civitai.com/models/649516/model-name?modelVersionId=726676" />
<label for="civitaiModelUrl">{{ t('modals.relinkCivitai.urlLabel') }}</label>
<input type="text" id="civitaiModelUrl" placeholder="{{ t('modals.relinkCivitai.urlPlaceholder') }}" />
<div class="input-error" id="civitaiModelUrlError"></div>
<div class="input-help">
Paste any Civitai model URL. Supported formats:<br>
https://civitai.com/models/649516<br>
https://civitai.com/models/649516?modelVersionId=726676<br>
https://civitai.com/models/649516/model-name?modelVersionId=726676<br>
<em>Note: If no modelVersionId is provided, the latest version will be used.</em>
{{ t('modals.relinkCivitai.helpText.title') }}<br>
{{ t('modals.relinkCivitai.helpText.format1') }}<br>
{{ t('modals.relinkCivitai.helpText.format2') }}<br>
{{ t('modals.relinkCivitai.helpText.format3') }}<br>
<em>{{ t('modals.relinkCivitai.helpText.note') }}</em>
</div>
</div>
<div class="modal-actions">
<button class="cancel-btn" onclick="modalManager.closeModal('relinkCivitaiModal')">Cancel</button>
<button class="confirm-btn" id="confirmRelinkBtn">Confirm Re-link</button>
<button class="cancel-btn" onclick="modalManager.closeModal('relinkCivitaiModal')">{{ t('common.actions.cancel') }}</button>
<button class="confirm-btn" id="confirmRelinkBtn">{{ t('modals.relinkCivitai.confirmAction') }}</button>
</div>
</div>
</div>

View File

@@ -22,11 +22,11 @@
<div class="update-actions">
<a href="https://github.com/willmiao/ComfyUI-Lora-Manager" target="_blank" class="update-link">
<i class="fas fa-external-link-alt"></i> View on GitHub
<i class="fas fa-external-link-alt"></i> {{ t('update.viewOnGitHub') }}
</a>
<button id="updateBtn" class="primary-btn disabled">
<i class="fas fa-download"></i>
<span id="updateBtnText">Update Now</span>
<span id="updateBtnText">{{ t('update.updateNow') }}</span>
</button>
</div>
</div>
@@ -34,7 +34,7 @@
<!-- Update Progress Section -->
<div class="update-progress" id="updateProgress" style="display: none;">
<div class="progress-info">
<div class="progress-text" id="updateProgressText">Preparing update...</div>
<div class="progress-text" id="updateProgressText">{{ t('update.preparingUpdate') }}</div>
<div class="update-progress-bar">
<div class="progress-fill" id="updateProgressFill"></div>
</div>
@@ -42,12 +42,12 @@
</div>
<div class="changelog-section">
<h3>Changelog</h3>
<h3>{{ t('update.changelog') }}</h3>
<div class="changelog-content">
<!-- Dynamic changelog content will be inserted here -->
<div class="changelog-item">
<h4>Checking for updates...</h4>
<p>Please wait while we check for the latest version.</p>
<h4>{{ t('update.checkingUpdates') }}</h4>
<p>{{ t('update.checkingMessage') }}</p>
</div>
</div>
</div>
@@ -56,7 +56,7 @@
<label class="toggle-switch">
<input type="checkbox" id="updateNotifications" checked>
<span class="toggle-slider"></span>
<span class="toggle-label">Show update notifications</span>
<span class="toggle-label">{{ t('update.showNotifications') }}</span>
</label>
</div>
</div>