From 4acd9e7669df06e4c87e37f788b61553d3f5eabb Mon Sep 17 00:00:00 2001 From: zmdyy0318 Date: Tue, 1 Sep 2026 20:49:24 +0800 Subject: [PATCH 1/3] =?UTF-8?q?perf:=20=E4=B8=8B=E8=BD=BD=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E5=A2=9E=E5=8A=A0=E8=B7=B3=E8=BD=AC=E5=88=B0cdk?= =?UTF-8?q?=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/InstallConfirmModal.tsx | 10 +++- src/components/SettingsPage.tsx | 17 +++++++ src/components/UpdateInfoCard.tsx | 61 ++++++++++++++++++++++- src/components/UpdatePanel.tsx | 10 +++- src/components/settings/UpdateSection.tsx | 14 +++++- src/i18n/locales/en-US.ts | 1 + src/i18n/locales/ja-JP.ts | 1 + src/i18n/locales/ko-KR.ts | 1 + src/i18n/locales/zh-CN.ts | 1 + src/i18n/locales/zh-TW.ts | 1 + src/stores/appStore.ts | 23 ++++++++- src/stores/types.ts | 6 +++ 12 files changed, 139 insertions(+), 7 deletions(-) diff --git a/src/components/InstallConfirmModal.tsx b/src/components/InstallConfirmModal.tsx index 005cb019..bb99bbc1 100644 --- a/src/components/InstallConfirmModal.tsx +++ b/src/components/InstallConfirmModal.tsx @@ -18,7 +18,7 @@ import { FallbackUpdateError, isExecutableInstaller, } from '@/services/updateService'; -import { ReleaseNotes, DownloadProgressBar } from './UpdateInfoCard'; +import { ReleaseNotes, DownloadProgressBar, useOpenUpdateSettings } from './UpdateInfoCard'; import { loggers } from '@/utils/logger'; export function InstallConfirmModal() { @@ -134,6 +134,13 @@ export function InstallConfirmModal() { setJustUpdatedInfo, ]); + // 跳转到设置页的更新分区去配置 CDK + const openUpdateSettings = useOpenUpdateSettings(); + const handleOpenUpdateSettings = useCallback(() => { + openUpdateSettings(); + setShowInstallConfirmModal(false); // 否则弹窗会盖住设置页 + }, [openUpdateSettings, setShowInstallConfirmModal]); + // 用于追踪是否已触发自动安装,避免重复执行 const autoInstallTriggered = useRef(false); // 用于追踪是否已触发自动重启,避免重复执行 @@ -398,6 +405,7 @@ export function InstallConfirmModal() { fileSize={updateInfo.fileSize} downloadSource={updateInfo.downloadSource} showActions={false} + onSlowDownloadHintClick={handleOpenUpdateSettings} /> )} diff --git a/src/components/SettingsPage.tsx b/src/components/SettingsPage.tsx index e2e48e9a..8be0f48c 100644 --- a/src/components/SettingsPage.tsx +++ b/src/components/SettingsPage.tsx @@ -155,6 +155,8 @@ export function SettingsPage({ onClose }: SettingsPageProps) { confirmBeforeDelete, interfaceTranslations, language, + settingsTargetSection, + setSettingsTargetSection, } = useAppStore(); // 自定义强调色编辑状态 @@ -299,6 +301,21 @@ export function SettingsPage({ onClose }: SettingsPageProps) { setDrawerOpen(false); }, []); + // 由外部(如更新气泡里的加速下载入口)指定的目标分区,进入设置页后自动滚过去 + useEffect(() => { + if (!settingsTargetSection) return; + + const target = settingsTargetSection; + setActiveSection(target); + // 等一帧让页面切换后的布局稳定,否则 offsetTop 可能还没到位。 + // 清空必须放在回调里:若提前清空,依赖变化会让 cleanup 在这一帧结束前取消掉 rAF。 + const raf = requestAnimationFrame(() => { + scrollToSection(target); + setSettingsTargetSection(null); + }); + return () => cancelAnimationFrame(raf); + }, [settingsTargetSection, setSettingsTargetSection, scrollToSection]); + // 监听滚动,更新当前高亮的 section useEffect(() => { const container = scrollContainerRef.current; diff --git a/src/components/UpdateInfoCard.tsx b/src/components/UpdateInfoCard.tsx index a60bc404..ceb483d8 100644 --- a/src/components/UpdateInfoCard.tsx +++ b/src/components/UpdateInfoCard.tsx @@ -1,6 +1,12 @@ +import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { ChevronRight, RefreshCw, PackageCheck } from 'lucide-react'; -import type { DownloadProgress, DownloadStatus } from '@/stores/appStore'; +import { ChevronRight, RefreshCw, PackageCheck, Zap } from 'lucide-react'; +import { + useAppStore, + SLOW_DOWNLOAD_DURATION_MS, + type DownloadProgress, + type DownloadStatus, +} from '@/stores/appStore'; import { simpleMarkdownToHtml } from '@/services/contentResolver'; import clsx from 'clsx'; @@ -137,6 +143,51 @@ export function ReleaseNotes({ ); } +/** + * 跳转到设置页的更新分区。 + * 调用方通常还需要自行关闭当前的气泡/弹窗,否则会盖住设置页。 + */ +export function useOpenUpdateSettings() { + const setSettingsTargetSection = useAppStore((s) => s.setSettingsTargetSection); + const setCurrentPage = useAppStore((s) => s.setCurrentPage); + + return useCallback(() => { + setSettingsTargetSection('update'); + setCurrentPage('settings'); + }, [setSettingsTargetSection, setCurrentPage]); +} + +/** + * 慢速下载引导入口。仅在「下载中 + 未填 CDK + 速度持续偏低」时出现, + * 其余情况自行返回 null,因此调用方无需再做条件判断。 + */ +function SlowDownloadHint({ onClick }: { onClick: () => void }) { + const { t } = useTranslation(); + const mirrorChyanRid = useAppStore((s) => s.projectInterface?.mirrorchyan_rid); + const cdk = useAppStore((s) => s.mirrorChyanSettings.cdk); + const downloadStatus = useAppStore((s) => s.downloadStatus); + const slowDownloadSince = useAppStore((s) => s.slowDownloadSince); + + const hasCdk = !!cdk && cdk.trim() !== ''; + + // 没有 mirrorchyan_rid 时设置页不存在更新分区,跳过去是空的 + if (!mirrorChyanRid || downloadStatus !== 'downloading' || hasCdk) return null; + if (slowDownloadSince === null || Date.now() - slowDownloadSince < SLOW_DOWNLOAD_DURATION_MS) { + return null; + } + + return ( + + ); +} + interface DownloadProgressBarProps { downloadStatus: DownloadStatus; downloadProgress: DownloadProgress | null; @@ -150,6 +201,8 @@ interface DownloadProgressBarProps { showActions?: boolean; /** 进度条背景色类名 */ progressBgClass?: string; + /** 慢速下载引导入口的点击行为;不传则不显示该入口 */ + onSlowDownloadHintClick?: () => void; } /** 下载进度组件 */ @@ -162,6 +215,7 @@ export function DownloadProgressBar({ onRetryClick, showActions = true, progressBgClass = 'bg-bg-tertiary', + onSlowDownloadHintClick, }: DownloadProgressBarProps) { const { t } = useTranslation(); @@ -231,6 +285,9 @@ export function DownloadProgressBar({ : t('mirrorChyan.downloadFromMirrorChyan')} )} + + {/* 慢速下载引导 */} + {onSlowDownloadHintClick && } ); } diff --git a/src/components/UpdatePanel.tsx b/src/components/UpdatePanel.tsx index daaf3b58..d6929cff 100644 --- a/src/components/UpdatePanel.tsx +++ b/src/components/UpdatePanel.tsx @@ -18,7 +18,7 @@ import { savePendingUpdateInfo, } from '@/services/updateService'; import { proxySettingsForUpdateDownload } from '@/services/proxyService'; -import { DownloadProgressBar } from './UpdateInfoCard'; +import { DownloadProgressBar, useOpenUpdateSettings } from './UpdateInfoCard'; import clsx from 'clsx'; import { loggers } from '@/utils/logger'; @@ -124,6 +124,13 @@ export function UpdatePanel({ onClose, anchorRef }: UpdatePanelProps) { useAppStore.getState().setInstallStatus('installing'); }, [setShowInstallConfirmModal, onClose]); + // 跳转到设置页的更新分区去配置 CDK + const openUpdateSettings = useOpenUpdateSettings(); + const handleOpenUpdateSettings = useCallback(() => { + openUpdateSettings(); + onClose(); // 关闭气泡 + }, [openUpdateSettings, onClose]); + // 计算面板位置 useEffect(() => { if (anchorRef.current) { @@ -351,6 +358,7 @@ export function UpdatePanel({ onClose, anchorRef }: UpdatePanelProps) { resetDownloadState(); startDownload(); }} + onSlowDownloadHintClick={handleOpenUpdateSettings} /> )} diff --git a/src/components/settings/UpdateSection.tsx b/src/components/settings/UpdateSection.tsx index 493ff1a6..db20755d 100644 --- a/src/components/settings/UpdateSection.tsx +++ b/src/components/settings/UpdateSection.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback, useMemo } from 'react'; +import { useState, useEffect, useCallback, useMemo, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { Download, @@ -61,6 +61,7 @@ export function UpdateSection() { } = useAppStore(); const [showCdk, setShowCdk] = useState(false); + const cdkInputRef = useRef(null); const [proxyInput, setProxyInput] = useState(proxySettings?.url || ''); const [proxyError, setProxyError] = useState(false); const [checkFailed, setCheckFailed] = useState(false); @@ -268,6 +269,15 @@ export function UpdateSection() { setInstallStatus('installing'); }, [setShowInstallConfirmModal, setInstallStatus]); + // 慢速下载引导:本身已在更新分区内,直接把 CDK 输入框滚进视野并聚焦 + const handleFocusCdkInput = useCallback(() => { + const input = cdkInputRef.current; + if (!input) return; + input.scrollIntoView({ behavior: 'smooth', block: 'center' }); + // preventScroll 避免 focus 的瞬时滚动与上面的平滑滚动打架 + input.focus({ preventScroll: true }); + }, []); + // 获取错误码对应的翻译文本 const errorText = useMemo(() => { if (!updateInfo?.errorCode) return null; @@ -424,6 +434,7 @@ export function UpdateSection() {
handleCdkChange(e.target.value)} @@ -607,6 +618,7 @@ export function UpdateSection() { startDownload(); }} progressBgClass="bg-bg-secondary" + onSlowDownloadHintClick={handleFocusCdkInput} /> )} diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index c652b261..08c37bc7 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -690,6 +690,7 @@ export default { ' is an independent third-party accelerated download service that requires a paid subscription, not a fee charged by "{{projectName}}". Its operating costs are covered by subscription revenue, with a portion supporting project developers. Subscribe for high-speed downloads while supporting ongoing development. Without a CDK, downloads will fall back to GitHub. If that fails, please configure a network proxy.', getCdk: 'No CDKey? Subscribe Now', cdkHint: 'Please check if your CDK is correct or has expired', + slowDownloadHint: 'Speed up', checkUpdate: 'Check for Updates', checking: 'Checking...', upToDate: 'You are up to date ({{version}})', diff --git a/src/i18n/locales/ja-JP.ts b/src/i18n/locales/ja-JP.ts index 71541523..4cb59c1a 100644 --- a/src/i18n/locales/ja-JP.ts +++ b/src/i18n/locales/ja-JP.ts @@ -689,6 +689,7 @@ export default { ' は独立したサードパーティの高速ダウンロードサービスで、有料サブスクリプションが必要です。これは「{{projectName}}」の料金ではありません。運営費はサブスクリプション収入で賄われ、一部は開発者に還元されます。CDK を購読して高速ダウンロードをお楽しみください。CDK を入力しない場合、GitHub からダウンロードします。失敗した場合は、ネットワークプロキシを設定してください。', getCdk: 'CDKをお持ちでない方はこちら', cdkHint: 'CDK が正しいか、または有効期限が切れていないか確認してください', + slowDownloadHint: '高速化', checkUpdate: '更新を確認', checking: '確認中...', upToDate: '最新バージョンです ({{version}})', diff --git a/src/i18n/locales/ko-KR.ts b/src/i18n/locales/ko-KR.ts index f1d3c891..9c781a12 100644 --- a/src/i18n/locales/ko-KR.ts +++ b/src/i18n/locales/ko-KR.ts @@ -678,6 +678,7 @@ export default { '는 독립적인 서드파티 고속 다운로드 서비스이며 유료 구독이 필요합니다. 이것은 "{{projectName}}"의 요금이 아닙니다. 운영비는 구독 수익으로 충당되며 일부는 개발자에게 환원됩니다. CDK를 구독하여 고속 다운로드를 즐기세요. CDK가 없으면 GitHub에서 다운로드됩니다. 실패하면 네트워크 프록시를 설정하세요.', getCdk: 'CDK가 없으신가요? 지금 구독하세요', cdkHint: 'CDK가 올바른지 또는 만료되지 않았는지 확인하세요', + slowDownloadHint: '다운로드 가속', checkUpdate: '업데이트 확인', checking: '확인 중...', upToDate: '최신 버전입니다 ({{version}})', diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index 18bd1d33..5783cc24 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -666,6 +666,7 @@ export default { ' 是独立的第三方加速下载服务,需要付费使用,并非「{{projectName}}」收费。其运营成本由订阅收入支撑,部分收益将回馈项目开发者。欢迎订阅 CDK 享受高速下载,同时支持项目持续开发。未填写 CDK 时将自动通过 GitHub 下载,若失败请尝试配置网络代理。', getCdk: '没有CDK?立即订阅', cdkHint: '请检查您的 CDK 是否正确或已过期', + slowDownloadHint: '加速下载', checkUpdate: '检查更新', checking: '正在检查...', upToDate: '当前已是最新版本 ({{version}})', diff --git a/src/i18n/locales/zh-TW.ts b/src/i18n/locales/zh-TW.ts index dd33d810..74db900c 100644 --- a/src/i18n/locales/zh-TW.ts +++ b/src/i18n/locales/zh-TW.ts @@ -662,6 +662,7 @@ export default { ' 是獨立的第三方加速下載服務,需要付費使用,並非「{{projectName}}」收費。其營運成本由訂閱收入支撐,部分收益將回饋專案開發者。歡迎訂閱 CDK 享受高速下載,同時支援專案持續開發。未填寫 CDK 時將自動透過 GitHub 下載,若失敗請嘗試設定網路代理。', getCdk: '沒有CDK?立即訂閱', cdkHint: '請檢查您的 CDK 是否正確或已過期', + slowDownloadHint: '加速下載', checkUpdate: '檢查更新', checking: '正在檢查...', upToDate: '目前已是最新版本 ({{version}})', diff --git a/src/stores/appStore.ts b/src/stores/appStore.ts index ad88b722..0a44c006 100644 --- a/src/stores/appStore.ts +++ b/src/stores/appStore.ts @@ -79,6 +79,12 @@ import { cacheTaskEnabledForController } from '@/utils/taskControllerCache'; // 从独立模块导入类型和辅助函数 import type { AppState, LogEntry, TaskRunStatus } from './types'; +/** 低于该速度(字节/秒)视为慢速下载 */ +const SLOW_DOWNLOAD_SPEED_BPS = 1024 * 1024; + +/** 慢速需要持续这么久才认定为「确实慢」,避免下载刚开始时误报 */ +export const SLOW_DOWNLOAD_DURATION_MS = 5000; + /** * 规范化定时策略:仅保留 times(分钟精度)字段,丢弃旧版整点 hours 字段。 * 不做新旧数据迁移——旧配置中基于 hours 的时间点不会被转换为 times,加载后时间点为空,需用户重新配置。 @@ -351,6 +357,9 @@ export const useAppStore = create()( currentPage: 'main', setCurrentPage: (page) => set({ currentPage: page }), + settingsTargetSection: null, + setSettingsTargetSection: (section) => set({ settingsTargetSection: section }), + // 调试选项(不落盘,每次启动默认关闭) saveDraw: false, setSaveDraw: async (enabled) => { @@ -2036,14 +2045,24 @@ export const useAppStore = create()( downloadStatus: 'idle', downloadProgress: null, downloadSavePath: null, - setDownloadStatus: (status) => set({ downloadStatus: status }), - setDownloadProgress: (progress) => set({ downloadProgress: progress }), + slowDownloadSince: null, + // 每次状态变化都重置慢速计时:'downloading' 表示新一轮下载开始,其余状态表示下载已结束 + setDownloadStatus: (status) => set({ downloadStatus: status, slowDownloadSince: null }), + setDownloadProgress: (progress) => + set((state) => ({ + downloadProgress: progress, + slowDownloadSince: + progress && progress.speed < SLOW_DOWNLOAD_SPEED_BPS + ? (state.slowDownloadSince ?? Date.now()) + : null, + })), setDownloadSavePath: (path) => set({ downloadSavePath: path }), resetDownloadState: () => set({ downloadStatus: 'idle', downloadProgress: null, downloadSavePath: null, + slowDownloadSince: null, }), // 安装状态 diff --git a/src/stores/types.ts b/src/stores/types.ts index 2805883f..42c3fda0 100644 --- a/src/stores/types.ts +++ b/src/stores/types.ts @@ -136,6 +136,10 @@ export interface AppState { currentPage: PageView; setCurrentPage: (page: PageView) => void; + /** 进入设置页后需要自动滚动到的分区 id(如 'update'),由 SettingsPage 消费后清空 */ + settingsTargetSection: string | null; + setSettingsTargetSection: (section: string | null) => void; + // 调试选项(不落盘,每次启动默认关闭) saveDraw: boolean; setSaveDraw: (enabled: boolean) => void; @@ -456,6 +460,8 @@ export interface AppState { downloadStatus: DownloadStatus; downloadProgress: DownloadProgress | null; downloadSavePath: string | null; + /** 下载速度持续低于阈值的起始时间戳,速度回升或下载结束时置为 null */ + slowDownloadSince: number | null; setDownloadStatus: (status: DownloadStatus) => void; setDownloadProgress: (progress: DownloadProgress | null) => void; setDownloadSavePath: (path: string | null) => void; From 487ea86edb8ce29368d624a20bc55ebdc17ba8df Mon Sep 17 00:00:00 2001 From: zmdyy0318 Date: Tue, 1 Sep 2026 20:58:29 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dai=E5=BB=BA=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stores/appStore.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stores/appStore.ts b/src/stores/appStore.ts index 0a44c006..f9c05ddb 100644 --- a/src/stores/appStore.ts +++ b/src/stores/appStore.ts @@ -2048,11 +2048,13 @@ export const useAppStore = create()( slowDownloadSince: null, // 每次状态变化都重置慢速计时:'downloading' 表示新一轮下载开始,其余状态表示下载已结束 setDownloadStatus: (status) => set({ downloadStatus: status, slowDownloadSince: null }), + // 要求 downloadedSize > 0 才起算:下载开始前先写入的那条 speed 为 0 的占位进度, + // 以及 Rust 建连/重定向期间(进度事件还没开始推送)都不应计入慢速时长 setDownloadProgress: (progress) => set((state) => ({ downloadProgress: progress, slowDownloadSince: - progress && progress.speed < SLOW_DOWNLOAD_SPEED_BPS + progress && progress.downloadedSize > 0 && progress.speed < SLOW_DOWNLOAD_SPEED_BPS ? (state.slowDownloadSince ?? Date.now()) : null, })), From 632668aa56cf1d02ac1c37796b73e93e0916fc40 Mon Sep 17 00:00:00 2001 From: zmdyy0318 Date: Thu, 3 Sep 2026 22:38:06 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=94=B9=E6=88=90=E5=85=B6=E4=BB=96?= =?UTF-8?q?=E6=B8=A0=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/UpdateInfoCard.tsx | 4 ++-- src/components/settings/UpdateSection.tsx | 12 ++++-------- src/i18n/locales/en-US.ts | 2 +- src/i18n/locales/ja-JP.ts | 2 +- src/i18n/locales/ko-KR.ts | 2 +- src/i18n/locales/zh-CN.ts | 2 +- src/i18n/locales/zh-TW.ts | 2 +- src/services/updateService.ts | 13 +++++++++---- 8 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/components/UpdateInfoCard.tsx b/src/components/UpdateInfoCard.tsx index ceb483d8..8350acc3 100644 --- a/src/components/UpdateInfoCard.tsx +++ b/src/components/UpdateInfoCard.tsx @@ -1,6 +1,6 @@ import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { ChevronRight, RefreshCw, PackageCheck, Zap } from 'lucide-react'; +import { ChevronRight, RefreshCw, PackageCheck, Globe } from 'lucide-react'; import { useAppStore, SLOW_DOWNLOAD_DURATION_MS, @@ -181,7 +181,7 @@ function SlowDownloadHint({ onClick }: { onClick: () => void }) { onClick={onClick} className="w-full flex items-center gap-2 px-2.5 py-2 rounded-lg bg-accent/10 text-accent text-xs hover:bg-accent/15 transition-colors" > - + {t('mirrorChyan.slowDownloadHint')} diff --git a/src/components/settings/UpdateSection.tsx b/src/components/settings/UpdateSection.tsx index db20755d..bd9aaf3e 100644 --- a/src/components/settings/UpdateSection.tsx +++ b/src/components/settings/UpdateSection.tsx @@ -269,13 +269,9 @@ export function UpdateSection() { setInstallStatus('installing'); }, [setShowInstallConfirmModal, setInstallStatus]); - // 慢速下载引导:本身已在更新分区内,直接把 CDK 输入框滚进视野并聚焦 - const handleFocusCdkInput = useCallback(() => { - const input = cdkInputRef.current; - if (!input) return; - input.scrollIntoView({ behavior: 'smooth', block: 'center' }); - // preventScroll 避免 focus 的瞬时滚动与上面的平滑滚动打架 - input.focus({ preventScroll: true }); + // 慢速下载引导:本身已在更新分区内,把 CDK 输入框滚进视野即可,不抢焦点 + const handleScrollToCdkInput = useCallback(() => { + cdkInputRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' }); }, []); // 获取错误码对应的翻译文本 @@ -618,7 +614,7 @@ export function UpdateSection() { startDownload(); }} progressBgClass="bg-bg-secondary" - onSlowDownloadHintClick={handleFocusCdkInput} + onSlowDownloadHintClick={handleScrollToCdkInput} /> )} diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index 08c37bc7..188dbb37 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -690,7 +690,7 @@ export default { ' is an independent third-party accelerated download service that requires a paid subscription, not a fee charged by "{{projectName}}". Its operating costs are covered by subscription revenue, with a portion supporting project developers. Subscribe for high-speed downloads while supporting ongoing development. Without a CDK, downloads will fall back to GitHub. If that fails, please configure a network proxy.', getCdk: 'No CDKey? Subscribe Now', cdkHint: 'Please check if your CDK is correct or has expired', - slowDownloadHint: 'Speed up', + slowDownloadHint: 'Other channels', checkUpdate: 'Check for Updates', checking: 'Checking...', upToDate: 'You are up to date ({{version}})', diff --git a/src/i18n/locales/ja-JP.ts b/src/i18n/locales/ja-JP.ts index 4cb59c1a..f6c0d3f8 100644 --- a/src/i18n/locales/ja-JP.ts +++ b/src/i18n/locales/ja-JP.ts @@ -689,7 +689,7 @@ export default { ' は独立したサードパーティの高速ダウンロードサービスで、有料サブスクリプションが必要です。これは「{{projectName}}」の料金ではありません。運営費はサブスクリプション収入で賄われ、一部は開発者に還元されます。CDK を購読して高速ダウンロードをお楽しみください。CDK を入力しない場合、GitHub からダウンロードします。失敗した場合は、ネットワークプロキシを設定してください。', getCdk: 'CDKをお持ちでない方はこちら', cdkHint: 'CDK が正しいか、または有効期限が切れていないか確認してください', - slowDownloadHint: '高速化', + slowDownloadHint: '他の入手先', checkUpdate: '更新を確認', checking: '確認中...', upToDate: '最新バージョンです ({{version}})', diff --git a/src/i18n/locales/ko-KR.ts b/src/i18n/locales/ko-KR.ts index 9c781a12..c36f6381 100644 --- a/src/i18n/locales/ko-KR.ts +++ b/src/i18n/locales/ko-KR.ts @@ -678,7 +678,7 @@ export default { '는 독립적인 서드파티 고속 다운로드 서비스이며 유료 구독이 필요합니다. 이것은 "{{projectName}}"의 요금이 아닙니다. 운영비는 구독 수익으로 충당되며 일부는 개발자에게 환원됩니다. CDK를 구독하여 고속 다운로드를 즐기세요. CDK가 없으면 GitHub에서 다운로드됩니다. 실패하면 네트워크 프록시를 설정하세요.', getCdk: 'CDK가 없으신가요? 지금 구독하세요', cdkHint: 'CDK가 올바른지 또는 만료되지 않았는지 확인하세요', - slowDownloadHint: '다운로드 가속', + slowDownloadHint: '다른 채널', checkUpdate: '업데이트 확인', checking: '확인 중...', upToDate: '최신 버전입니다 ({{version}})', diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index 5783cc24..032dfce7 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -666,7 +666,7 @@ export default { ' 是独立的第三方加速下载服务,需要付费使用,并非「{{projectName}}」收费。其运营成本由订阅收入支撑,部分收益将回馈项目开发者。欢迎订阅 CDK 享受高速下载,同时支持项目持续开发。未填写 CDK 时将自动通过 GitHub 下载,若失败请尝试配置网络代理。', getCdk: '没有CDK?立即订阅', cdkHint: '请检查您的 CDK 是否正确或已过期', - slowDownloadHint: '加速下载', + slowDownloadHint: '其他渠道', checkUpdate: '检查更新', checking: '正在检查...', upToDate: '当前已是最新版本 ({{version}})', diff --git a/src/i18n/locales/zh-TW.ts b/src/i18n/locales/zh-TW.ts index 74db900c..028a461b 100644 --- a/src/i18n/locales/zh-TW.ts +++ b/src/i18n/locales/zh-TW.ts @@ -662,7 +662,7 @@ export default { ' 是獨立的第三方加速下載服務,需要付費使用,並非「{{projectName}}」收費。其營運成本由訂閱收入支撐,部分收益將回饋專案開發者。歡迎訂閱 CDK 享受高速下載,同時支援專案持續開發。未填寫 CDK 時將自動透過 GitHub 下載,若失敗請嘗試設定網路代理。', getCdk: '沒有CDK?立即訂閱', cdkHint: '請檢查您的 CDK 是否正確或已過期', - slowDownloadHint: '加速下載', + slowDownloadHint: '其他管道', checkUpdate: '檢查更新', checking: '正在檢查...', upToDate: '目前已是最新版本 ({{version}})', diff --git a/src/services/updateService.ts b/src/services/updateService.ts index 473da55a..b98f5552 100644 --- a/src/services/updateService.ts +++ b/src/services/updateService.ts @@ -733,9 +733,14 @@ interface DownloadUpdateOptions { // 当前下载的保存路径,用于取消时清理临时文件 let currentDownloadPath: string | null = null; -// 进度事件数据(包含 session_id 用于区分不同下载任务) -interface DownloadProgressEventPayload extends DownloadProgress { +// 进度事件数据。Rust 侧 DownloadProgressEvent 走 serde 默认命名, +// 字段是 snake_case,不能直接套用前端 camelCase 的 DownloadProgress +interface DownloadProgressEventPayload { session_id: number; + downloaded_size: number; + total_size: number; + speed: number; + progress: number; } /** @@ -809,8 +814,8 @@ export async function downloadUpdate( // 如果已被取消,忽略进度更新 if (downloadCancelled) return; onProgress({ - downloadedSize: event.payload.downloadedSize, - totalSize: event.payload.totalSize, + downloadedSize: event.payload.downloaded_size, + totalSize: event.payload.total_size, speed: event.payload.speed, progress: event.payload.progress, });