feat(localization): enhance English and Chinese translations for update notifications and support modal

This commit is contained in:
Will Miao
2025-08-31 21:54:54 +08:00
parent 84d801cf14
commit 63562240c4
6 changed files with 162 additions and 50 deletions

View File

@@ -14,7 +14,9 @@
},
"status": {
"loading": "Loading...",
"unknown": "Unknown"
"unknown": "Unknown",
"date": "Date",
"version": "Version"
},
"language": {
"select": "Select Language",
@@ -696,6 +698,8 @@
},
"update": {
"title": "Check for Updates",
"updateAvailable": "Update Available",
"noChangelogAvailable": "No detailed changelog available. Check GitHub for more information.",
"currentVersion": "Current Version",
"newVersion": "New Version",
"commit": "Commit",
@@ -705,7 +709,27 @@
"changelog": "Changelog",
"checkingUpdates": "Checking for updates...",
"checkingMessage": "Please wait while we check for the latest version.",
"showNotifications": "Show update notifications"
"showNotifications": "Show update notifications",
"updateProgress": {
"preparing": "Preparing update...",
"installing": "Installing update...",
"completed": "Update completed successfully!",
"failed": "Update failed: {error}"
},
"status": {
"updating": "Updating...",
"updated": "Updated!",
"updateFailed": "Update Failed"
},
"completion": {
"successMessage": "Successfully updated to {version}!",
"restartMessage": "Please restart ComfyUI or LoRA Manager to apply update.",
"reloadMessage": "Make sure to reload your browser for both LoRA Manager and ComfyUI."
},
"nightly": {
"warning": "Warning: Nightly builds may contain experimental features and could be unstable.",
"enable": "Enable Nightly Updates"
}
},
"support": {
"title": "Support the Project",
@@ -713,7 +737,27 @@
"feedback": {
"title": "Provide Feedback",
"description": "Your feedback helps shape future updates! Share your thoughts:"
}
},
"links": {
"submitGithubIssue": "Submit GitHub Issue",
"joinDiscord": "Join Discord",
"youtubeChannel": "YouTube Channel",
"civitaiProfile": "Civitai Profile",
"supportKofi": "Support on Ko-fi",
"supportPatreon": "Support on Patreon"
},
"sections": {
"followUpdates": "Follow for Updates",
"buyMeCoffee": "Buy me a coffee",
"coffeeDescription": "If you'd like to support my work directly:",
"becomePatron": "Become a Patron",
"patronDescription": "Support ongoing development with monthly contributions:",
"wechatSupport": "WeChat Support",
"wechatDescription": "For users in China, you can support via WeChat:",
"showWechatQR": "Show WeChat QR Code",
"hideWechatQR": "Hide WeChat QR Code"
},
"footer": "Thank you for using LoRA Manager! ❤️"
},
"toast": {
"general": {
@@ -924,5 +968,14 @@
"exampleImagesDownloadSuccess": "Successfully downloaded example images!",
"exampleImagesDownloadFailed": "Failed to download example images: {message}"
}
},
"banners": {
"versionMismatch": {
"title": "Application Update Detected",
"content": "Your browser is running an outdated version of LoRA Manager ({storedVersion}). The server has been updated to version {currentVersion}. Please refresh to ensure proper functionality.",
"refreshNow": "Refresh Now",
"refreshingIn": "Refreshing in",
"seconds": "seconds"
}
}
}

View File

@@ -14,7 +14,9 @@
},
"status": {
"loading": "加载中...",
"unknown": "未知"
"unknown": "未知",
"date": "日期",
"version": "版本"
},
"language": {
"select": "选择语言",
@@ -697,6 +699,8 @@
"update": {
"title": "检查更新",
"currentVersion": "当前版本",
"updateAvailable": "更新可用",
"noChangelogAvailable": "没有详细的更新日志可用。请查看 GitHub 以获取更多信息。",
"newVersion": "新版本",
"commit": "提交",
"viewOnGitHub": "在 GitHub 查看",
@@ -705,7 +709,27 @@
"changelog": "更新日志",
"checkingUpdates": "正在检查更新...",
"checkingMessage": "请稍候,正在检查最新版本。",
"showNotifications": "显示更新通知"
"showNotifications": "显示更新通知",
"updateProgress": {
"preparing": "正在准备更新...",
"installing": "正在安装更新...",
"completed": "更新已成功完成!",
"failed": "更新失败:{error}"
},
"status": {
"updating": "正在更新...",
"updated": "已更新!",
"updateFailed": "更新失败"
},
"completion": {
"successMessage": "已成功更新到 {version}",
"restartMessage": "请重启 ComfyUI 或 LoRA 管理器以应用更新。",
"reloadMessage": "请确保刷新浏览器以加载最新的 LoRA 管理器和 ComfyUI。"
},
"nightly": {
"warning": "警告Nightly 版本可能包含实验性功能,可能不稳定。",
"enable": "启用 Nightly 更新"
}
},
"support": {
"title": "支持项目",
@@ -713,7 +737,27 @@
"feedback": {
"title": "反馈建议",
"description": "你的反馈有助于未来更新!欢迎分享你的想法:"
}
},
"links": {
"submitGithubIssue": "提交 GitHub 问题",
"joinDiscord": "加入 Discord",
"youtubeChannel": "YouTube 频道",
"civitaiProfile": "Civitai 个人资料",
"supportKofi": "支持 Ko-fi",
"supportPatreon": "支持 Patreon"
},
"sections": {
"followUpdates": "关注更新",
"buyMeCoffee": "请我喝杯咖啡",
"coffeeDescription": "如果你想直接支持我的工作:",
"becomePatron": "成为赞助人",
"patronDescription": "通过每月捐款支持持续开发:",
"wechatSupport": "微信支持",
"wechatDescription": "对于中国用户,你可以通过微信支持:",
"showWechatQR": "显示微信二维码",
"hideWechatQR": "隐藏微信二维码"
},
"footer": "感谢使用 LoRA 管理器!❤️"
},
"toast": {
"general": {
@@ -924,5 +968,14 @@
"exampleImagesDownloadSuccess": "示例图片下载成功!",
"exampleImagesDownloadFailed": "示例图片下载失败:{message}"
}
},
"banners": {
"versionMismatch": {
"title": "检测到应用更新",
"content": "你的浏览器正在运行过时的 LoRA 管理器版本({storedVersion})。服务器已更新到版本 {currentVersion}。请刷新以确保正常使用。",
"refreshNow": "立即刷新",
"refreshingIn": "将在",
"seconds": "秒后刷新"
}
}
}

View File

@@ -52,13 +52,13 @@ export class HeaderManager {
const currentTheme = getStorageItem('theme') || 'auto';
themeToggle.classList.add(`theme-${currentTheme}`);
// 使用i18nHelpers更新themeToggletitle
// Use i18nHelpers to update themeToggle's title
this.updateThemeTooltip(themeToggle, currentTheme);
themeToggle.addEventListener('click', async () => {
if (typeof toggleTheme === 'function') {
const newTheme = toggleTheme();
// 使用i18nHelpers更新themeToggletitle
// Use i18nHelpers to update themeToggle's title
this.updateThemeTooltip(themeToggle, newTheme);
}
});

View File

@@ -8,6 +8,7 @@ import {
resetDismissedBanner
} from '../utils/storageHelpers.js';
import { bannerService } from './BannerService.js';
import { translate } from '../utils/i18nHelpers.js';
export class UpdateService {
constructor() {
@@ -165,8 +166,8 @@ export class UpdateService {
if (updateToggle) {
updateToggle.title = this.updateNotificationsEnabled && this.updateAvailable
? "Update Available"
: "Check Updates";
? translate('update.updateAvailable')
: translate('update.title');
}
// Force updating badges visibility based on current state
@@ -185,7 +186,9 @@ export class UpdateService {
// Update title based on update availability
const headerTitle = modal.querySelector('.update-header h2');
if (headerTitle) {
headerTitle.textContent = this.updateAvailable ? "Update Available" : "Check for Updates";
headerTitle.textContent = this.updateAvailable ?
translate('update.updateAvailable') :
translate('update.title');
}
// Always update version information, even if updateInfo is null
@@ -209,9 +212,9 @@ export class UpdateService {
const gitInfoEl = modal.querySelector('.git-info');
if (gitInfoEl && this.gitInfo) {
if (this.gitInfo.short_hash !== 'unknown') {
let gitText = `Commit: ${this.gitInfo.short_hash}`;
let gitText = `${translate('update.commit')}: ${this.gitInfo.short_hash}`;
if (this.gitInfo.commit_date !== 'unknown') {
gitText += ` - Date: ${this.gitInfo.commit_date}`;
gitText += ` - ${translate('common.status.date', {}, 'Date')}: ${this.gitInfo.commit_date}`;
}
gitInfoEl.textContent = gitText;
gitInfoEl.style.display = 'block';
@@ -231,7 +234,7 @@ export class UpdateService {
changelogItem.className = 'changelog-item';
const versionHeader = document.createElement('h4');
versionHeader.textContent = `Version ${this.latestVersion}`;
versionHeader.textContent = `${translate('common.status.version', {}, 'Version')} ${this.latestVersion}`;
changelogItem.appendChild(versionHeader);
// Create changelog list
@@ -247,7 +250,7 @@ export class UpdateService {
} else {
// If no changelog items available
const listItem = document.createElement('li');
listItem.textContent = "No detailed changelog available. Check GitHub for more information.";
listItem.textContent = translate('update.noChangelogAvailable', {}, 'No detailed changelog available. Check GitHub for more information.');
changelogList.appendChild(listItem);
}
@@ -271,11 +274,11 @@ export class UpdateService {
try {
this.isUpdating = true;
this.updateUpdateUI('updating', 'Updating...');
this.updateUpdateUI('updating', translate('update.status.updating'));
this.showUpdateProgress(true);
// Update progress
this.updateProgress(10, 'Preparing update...');
this.updateProgress(10, translate('update.updateProgress.preparing'));
const response = await fetch('/api/perform-update', {
method: 'POST',
@@ -287,13 +290,13 @@ export class UpdateService {
})
});
this.updateProgress(50, 'Installing update...');
this.updateProgress(50, translate('update.updateProgress.installing'));
const data = await response.json();
if (data.success) {
this.updateProgress(100, 'Update completed successfully!');
this.updateUpdateUI('success', 'Updated!');
this.updateProgress(100, translate('update.updateProgress.completed'));
this.updateUpdateUI('success', translate('update.status.updated'));
// Show success message and suggest restart
setTimeout(() => {
@@ -301,13 +304,13 @@ export class UpdateService {
}, 1000);
} else {
throw new Error(data.error || 'Update failed');
throw new Error(data.error || translate('update.status.updateFailed'));
}
} catch (error) {
console.error('Update failed:', error);
this.updateUpdateUI('error', 'Update Failed');
this.updateProgress(0, `Update failed: ${error.message}`);
this.updateUpdateUI('error', translate('update.status.updateFailed'));
this.updateProgress(0, translate('update.updateProgress.failed', { error: error.message }));
// Hide progress after error
setTimeout(() => {
@@ -369,11 +372,11 @@ export class UpdateService {
progressText.innerHTML = `
<div style="text-align: center; color: var(--lora-success);">
<i class="fas fa-check-circle" style="margin-right: 8px;"></i>
Successfully updated to ${newVersion}!
${translate('update.completion.successMessage', { version: newVersion })}
<br><br>
<div style="opacity: 0.95; color: var(--lora-error); font-size: 1em;">
Please restart ComfyUI or LoRA Manager to apply update.<br>
Make sure to reload your browser for both LoRA Manager and ComfyUI.
${translate('update.completion.restartMessage')}<br>
${translate('update.completion.reloadMessage')}
</div>
</div>
`;
@@ -470,16 +473,19 @@ export class UpdateService {
registerVersionMismatchBanner() {
// Get stored and current version for display
const storedVersion = getStoredVersionInfo() || 'unknown';
const currentVersion = this.currentVersionInfo || 'unknown';
const storedVersion = getStoredVersionInfo() || translate('common.status.unknown');
const currentVersion = this.currentVersionInfo || translate('common.status.unknown');
bannerService.registerBanner('version-mismatch', {
id: 'version-mismatch',
title: 'Application Update Detected',
content: `Your browser is running an outdated version of LoRA Manager (${storedVersion}). The server has been updated to version ${currentVersion}. Please refresh to ensure proper functionality.`,
title: translate('banners.versionMismatch.title', {}, 'Application Update Detected'),
content: translate('banners.versionMismatch.content', {
storedVersion,
currentVersion
}, `Your browser is running an outdated version of LoRA Manager (${storedVersion}). The server has been updated to version ${currentVersion}. Please refresh to ensure proper functionality.`),
actions: [
{
text: 'Refresh Now',
text: translate('banners.versionMismatch.refreshNow', {}, 'Refresh Now'),
icon: 'fas fa-sync',
action: 'hardRefresh',
type: 'primary'
@@ -492,7 +498,7 @@ export class UpdateService {
// Add countdown element
const countdownEl = document.createElement('div');
countdownEl.className = 'banner-countdown';
countdownEl.innerHTML = `<span>Refreshing in <strong>15</strong> seconds...</span>`;
countdownEl.innerHTML = `<span>${translate('banners.versionMismatch.refreshingIn', {}, 'Refreshing in')} <strong>15</strong> ${translate('banners.versionMismatch.seconds', {}, 'seconds')}...</span>`;
bannerElement.querySelector('.banner-content').appendChild(countdownEl);
// Start countdown

View File

@@ -15,21 +15,21 @@
<div class="support-links">
<a href="https://github.com/willmiao/ComfyUI-Lora-Manager/issues/new" class="social-link" target="_blank">
<i class="fab fa-github"></i>
<span>Submit GitHub Issue</span>
<span>{{ t('support.links.submitGithubIssue') }}</span>
</a>
<a href="https://discord.gg/vcqNrWVFvM" class="social-link" target="_blank">
<i class="fab fa-discord"></i>
<span>Join Discord</span>
<span>{{ t('support.links.joinDiscord') }}</span>
</a>
</div>
</div>
<div class="support-section">
<h3><i class="fas fa-rss"></i> Follow for Updates</h3>
<h3><i class="fas fa-rss"></i> {{ t('support.sections.followUpdates') }}</h3>
<div class="support-links">
<a href="https://www.youtube.com/@pixelpaws-ai" class="social-link" target="_blank">
<i class="fab fa-youtube"></i>
<span>YouTube Channel</span>
<span>{{ t('support.links.youtubeChannel') }}</span>
</a>
<a href="https://civitai.com/user/PixelPawsAI" class="social-link civitai-link" target="_blank">
<svg class="civitai-icon" viewBox="0 0 225 225" width="20" height="20">
@@ -45,37 +45,37 @@
95 c91 52 167 94 169 94 2 0 78 -42 168 -92z"/>
</g>
</svg>
<span>Civitai Profile</span>
<span>{{ t('support.links.civitaiProfile') }}</span>
</a>
</div>
</div>
<div class="support-section">
<h3><i class="fas fa-coffee"></i> Buy me a coffee</h3>
<p>If you'd like to support my work directly:</p>
<h3><i class="fas fa-coffee"></i> {{ t('support.sections.buyMeCoffee') }}</h3>
<p>{{ t('support.sections.coffeeDescription') }}</p>
<a href="https://ko-fi.com/pixelpawsai" class="kofi-button" target="_blank">
<i class="fas fa-mug-hot"></i>
<span>Support on Ko-fi</span>
<span>{{ t('support.links.supportKofi') }}</span>
</a>
</div>
<!-- Patreon Support Section -->
<div class="support-section">
<h3><i class="fab fa-patreon"></i> Become a Patron</h3>
<p>Support ongoing development with monthly contributions:</p>
<h3><i class="fab fa-patreon"></i> {{ t('support.sections.becomePatron') }}</h3>
<p>{{ t('support.sections.patronDescription') }}</p>
<a href="https://patreon.com/PixelPawsAI" class="patreon-button" target="_blank">
<i class="fab fa-patreon"></i>
<span>Support on Patreon</span>
<span>{{ t('support.links.supportPatreon') }}</span>
</a>
</div>
<!-- New section for Chinese payment methods -->
<div class="support-section">
<h3><i class="fas fa-qrcode"></i> WeChat Support</h3>
<p>For users in China, you can support via WeChat:</p>
<h3><i class="fas fa-qrcode"></i> {{ t('support.sections.wechatSupport') }}</h3>
<p>{{ t('support.sections.wechatDescription') }}</p>
<button class="secondary-btn qrcode-toggle" id="toggleQRCode">
<i class="fas fa-qrcode"></i>
<span class="toggle-text">Show WeChat QR Code</span>
<span class="toggle-text">{{ t('support.sections.showWechatQR') }}</span>
<i class="fas fa-chevron-down toggle-icon"></i>
</button>
<div class="qrcode-container" id="qrCodeContainer">
@@ -84,7 +84,7 @@
</div>
<div class="support-footer">
<p>Thank you for using LoRA Manager! ❤️</p>
<p>{{ t('support.footer') }}</p>
</div>
</div>
</div>

View File

@@ -4,7 +4,7 @@
<button class="close" onclick="modalManager.closeModal('updateModal')">&times;</button>
<div class="update-header">
<i class="fas fa-bell update-icon"></i>
<h2>{{ t('update.title') }}</h2>
<h2 data-i18n="update.title">{{ t('update.title') }}</h2>
</div>
<div class="update-content">
<div class="update-info">
@@ -26,7 +26,7 @@
</a>
<button id="updateBtn" class="primary-btn disabled">
<i class="fas fa-download"></i>
<span id="updateBtnText">{{ t('update.updateNow') }}</span>
<span id="updateBtnText" data-i18n="update.updateNow">{{ 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">{{ t('update.preparingUpdate') }}</div>
<div class="progress-text" id="updateProgressText" data-i18n="update.preparingUpdate">{{ t('update.preparingUpdate') }}</div>
<div class="update-progress-bar">
<div class="progress-fill" id="updateProgressFill"></div>
</div>