feat(localization): enhance download modal with new labels and error messages for improved user experience

This commit is contained in:
Will Miao
2025-08-31 22:06:59 +08:00
parent 63562240c4
commit 4956d6781f
3 changed files with 63 additions and 22 deletions

View File

@@ -376,19 +376,39 @@
}, },
"download": { "download": {
"title": "Download Model from URL", "title": "Download Model from URL",
"titleWithType": "Download {type} from URL",
"url": "Civitai URL", "url": "Civitai URL",
"civitaiUrl": "Civitai URL:",
"placeholder": "https://civitai.com/models/...", "placeholder": "https://civitai.com/models/...",
"locationPreview": "Download Location Preview", "locationPreview": "Download Location Preview",
"useDefaultPath": "Use Default Path", "useDefaultPath": "Use Default Path",
"useDefaultPathTooltip": "When enabled, files are automatically organized using configured path templates", "useDefaultPathTooltip": "When enabled, files are automatically organized using configured path templates",
"selectRootDirectory": "Select a root directory", "selectRootDirectory": "Select a root directory",
"selectModelRoot": "Select Model Root:", "selectModelRoot": "Select Model Root:",
"selectTypeRoot": "Select {type} Root:",
"targetFolderPath": "Target Folder Path:", "targetFolderPath": "Target Folder Path:",
"browseFolders": "Browse Folders:", "browseFolders": "Browse Folders:",
"createNewFolder": "Create new folder", "createNewFolder": "Create new folder",
"pathPlaceholder": "Type folder path or select from tree below...", "pathPlaceholder": "Type folder path or select from tree below...",
"root": "Root", "root": "Root",
"download": "Download" "download": "Download",
"fetchingVersions": "Fetching model versions...",
"versionPreview": "Version preview",
"earlyAccess": "Early Access",
"earlyAccessTooltip": "Early access required",
"inLibrary": "In Library",
"alreadyInLibrary": "Already in Library",
"autoOrganizedPath": "[Auto-organized by path template]",
"errors": {
"invalidUrl": "Invalid Civitai URL format",
"noVersions": "No versions available for this model"
},
"status": {
"preparing": "Preparing download...",
"downloadedPreview": "Downloaded preview image",
"downloadingFile": "Downloading {type} file",
"finalizing": "Finalizing download..."
}
}, },
"move": { "move": {
"title": "Move Models" "title": "Move Models"

View File

@@ -376,19 +376,39 @@
}, },
"download": { "download": {
"title": "从 URL 下载模型", "title": "从 URL 下载模型",
"titleWithType": "从 URL 下载 {type}",
"url": "Civitai URL", "url": "Civitai URL",
"civitaiUrl": "Civitai URL:",
"placeholder": "https://civitai.com/models/...", "placeholder": "https://civitai.com/models/...",
"locationPreview": "下载位置预览", "locationPreview": "下载位置预览",
"useDefaultPath": "使用默认路径", "useDefaultPath": "使用默认路径",
"useDefaultPathTooltip": "启用后,文件将自动按配置的路径模板进行整理", "useDefaultPathTooltip": "启用后,文件将自动按配置的路径模板进行整理",
"selectRootDirectory": "选择根目录", "selectRootDirectory": "选择根目录",
"selectModelRoot": "选择模型根目录:", "selectModelRoot": "选择模型根目录:",
"selectTypeRoot": "选择 {type} 根目录:",
"targetFolderPath": "目标文件夹路径:", "targetFolderPath": "目标文件夹路径:",
"browseFolders": "浏览文件夹:", "browseFolders": "浏览文件夹:",
"createNewFolder": "新建文件夹", "createNewFolder": "新建文件夹",
"pathPlaceholder": "输入文件夹路径或从下方树中选择...", "pathPlaceholder": "输入文件夹路径或从下方树中选择...",
"root": "根目录", "root": "根目录",
"download": "下载" "download": "下载",
"fetchingVersions": "正在获取模型版本...",
"versionPreview": "版本预览",
"earlyAccess": "早期访问",
"earlyAccessTooltip": "需要早期访问权限",
"inLibrary": "已在库中",
"alreadyInLibrary": "已存在于库中",
"autoOrganizedPath": "【已按路径模板自动整理】",
"errors": {
"invalidUrl": "无效的 Civitai URL 格式",
"noVersions": "此模型没有可用版本"
},
"status": {
"preparing": "正在准备下载...",
"downloadedPreview": "预览图片已下载",
"downloadingFile": "正在下载 {type} 文件",
"finalizing": "正在完成下载..."
}
}, },
"move": { "move": {
"title": "移动模型" "title": "移动模型"

View File

@@ -5,6 +5,7 @@ import { LoadingManager } from './LoadingManager.js';
import { getModelApiClient, resetAndReload } from '../api/modelApiFactory.js'; import { getModelApiClient, resetAndReload } from '../api/modelApiFactory.js';
import { getStorageItem, setStorageItem } from '../utils/storageHelpers.js'; import { getStorageItem, setStorageItem } from '../utils/storageHelpers.js';
import { FolderTreeManager } from '../components/FolderTreeManager.js'; import { FolderTreeManager } from '../components/FolderTreeManager.js';
import { translate } from '../utils/i18nHelpers.js';
export class DownloadManager { export class DownloadManager {
constructor() { constructor() {
@@ -85,26 +86,26 @@ export class DownloadManager {
const config = this.apiClient.apiConfig.config; const config = this.apiClient.apiConfig.config;
// Update modal title // Update modal title
document.getElementById('downloadModalTitle').textContent = `Download ${config.displayName} from URL`; document.getElementById('downloadModalTitle').textContent = translate('modals.download.titleWithType', { type: config.displayName });
// Update URL label // Update URL label
document.getElementById('modelUrlLabel').textContent = 'Civitai URL:'; document.getElementById('modelUrlLabel').textContent = translate('modals.download.civitaiUrl');
// Update root selection label // Update root selection label
document.getElementById('modelRootLabel').textContent = `Select ${config.displayName} Root:`; document.getElementById('modelRootLabel').textContent = translate('modals.download.selectTypeRoot', { type: config.displayName });
// Update path preview labels // Update path preview labels
const pathLabels = document.querySelectorAll('.path-preview label'); const pathLabels = document.querySelectorAll('.path-preview label');
pathLabels.forEach(label => { pathLabels.forEach(label => {
if (label.textContent.includes('Location Preview')) { if (label.textContent.includes('Location Preview')) {
label.textContent = 'Download Location Preview:'; label.textContent = translate('modals.download.locationPreview') + ':';
} }
}); });
// Update initial path text // Update initial path text
const pathText = document.querySelector('#targetPathDisplay .path-text'); const pathText = document.querySelector('#targetPathDisplay .path-text');
if (pathText) { if (pathText) {
pathText.textContent = `Select a ${config.displayName} root directory`; pathText.textContent = translate('modals.download.selectTypeRoot', { type: config.displayName });
} }
} }
@@ -142,17 +143,17 @@ export class DownloadManager {
const errorElement = document.getElementById('urlError'); const errorElement = document.getElementById('urlError');
try { try {
this.loadingManager.showSimpleLoading('Fetching model versions...'); this.loadingManager.showSimpleLoading(translate('modals.download.fetchingVersions'));
this.modelId = this.extractModelId(url); this.modelId = this.extractModelId(url);
if (!this.modelId) { if (!this.modelId) {
throw new Error('Invalid Civitai URL format'); throw new Error(translate('modals.download.errors.invalidUrl'));
} }
this.versions = await this.apiClient.fetchCivitaiVersions(this.modelId); this.versions = await this.apiClient.fetchCivitaiVersions(this.modelId);
if (!this.versions.length) { if (!this.versions.length) {
throw new Error('No versions available for this model'); throw new Error(translate('modals.download.errors.noVersions'));
} }
// If we have a version ID from URL, pre-select it // If we have a version ID from URL, pre-select it
@@ -199,15 +200,15 @@ export class DownloadManager {
let earlyAccessBadge = ''; let earlyAccessBadge = '';
if (isEarlyAccess) { if (isEarlyAccess) {
earlyAccessBadge = ` earlyAccessBadge = `
<div class="early-access-badge" title="Early access required"> <div class="early-access-badge" title="${translate('modals.download.earlyAccessTooltip')}">
<i class="fas fa-clock"></i> Early Access <i class="fas fa-clock"></i> ${translate('modals.download.earlyAccess')}
</div> </div>
`; `;
} }
const localStatus = existsLocally ? const localStatus = existsLocally ?
`<div class="local-badge"> `<div class="local-badge">
<i class="fas fa-check"></i> In Library <i class="fas fa-check"></i> ${translate('modals.download.inLibrary')}
<div class="local-path">${localPath || ''}</div> <div class="local-path">${localPath || ''}</div>
</div>` : ''; </div>` : '';
@@ -217,7 +218,7 @@ export class DownloadManager {
${isEarlyAccess ? 'is-early-access' : ''}" ${isEarlyAccess ? 'is-early-access' : ''}"
data-version-id="${version.id}"> data-version-id="${version.id}">
<div class="version-thumbnail"> <div class="version-thumbnail">
<img src="${thumbnailUrl}" alt="Version preview"> <img src="${thumbnailUrl}" alt="${translate('modals.download.versionPreview')}">
</div> </div>
<div class="version-content"> <div class="version-content">
<div class="version-header"> <div class="version-header">
@@ -273,11 +274,11 @@ export class DownloadManager {
if (existsLocally) { if (existsLocally) {
nextButton.disabled = true; nextButton.disabled = true;
nextButton.classList.add('disabled'); nextButton.classList.add('disabled');
nextButton.textContent = 'Already in Library'; nextButton.textContent = translate('modals.download.alreadyInLibrary');
} else { } else {
nextButton.disabled = false; nextButton.disabled = false;
nextButton.classList.remove('disabled'); nextButton.classList.remove('disabled');
nextButton.textContent = 'Next'; nextButton.textContent = translate('common.actions.next');
} }
} }
@@ -455,13 +456,13 @@ export class DownloadManager {
updateProgress(data.progress, 0, this.currentVersion.name); updateProgress(data.progress, 0, this.currentVersion.name);
if (data.progress < 3) { if (data.progress < 3) {
this.loadingManager.setStatus(`Preparing download...`); this.loadingManager.setStatus(translate('modals.download.status.preparing'));
} else if (data.progress === 3) { } else if (data.progress === 3) {
this.loadingManager.setStatus(`Downloaded preview image`); this.loadingManager.setStatus(translate('modals.download.status.downloadedPreview'));
} else if (data.progress > 3 && data.progress < 100) { } else if (data.progress > 3 && data.progress < 100) {
this.loadingManager.setStatus(`Downloading ${config.singularName} file`); this.loadingManager.setStatus(translate('modals.download.status.downloadingFile', { type: config.singularName }));
} else { } else {
this.loadingManager.setStatus(`Finalizing download...`); this.loadingManager.setStatus(translate('modals.download.status.finalizing'));
} }
} }
}; };
@@ -586,7 +587,7 @@ export class DownloadManager {
const modelRoot = document.getElementById('modelRoot').value; const modelRoot = document.getElementById('modelRoot').value;
const config = this.apiClient.apiConfig.config; const config = this.apiClient.apiConfig.config;
let fullPath = modelRoot || `Select a ${config.displayName} root directory`; let fullPath = modelRoot || translate('modals.download.selectTypeRoot', { type: config.displayName });
if (modelRoot) { if (modelRoot) {
if (this.useDefaultPath) { if (this.useDefaultPath) {
@@ -598,7 +599,7 @@ export class DownloadManager {
fullPath += `/${template}`; fullPath += `/${template}`;
} catch (error) { } catch (error) {
console.error('Failed to fetch template:', error); console.error('Failed to fetch template:', error);
fullPath += '/[Auto-organized by path template]'; fullPath += '/' + translate('modals.download.autoOrganizedPath');
} }
} else { } else {
// Show manual path selection // Show manual path selection