fix: resolve macOS build race condition and update download button unresponsive
CI 修复 (electron-builder.yml): - 移除 mac target 的 arch: [arm64, x64],改由 CI matrix 的 --arch flag 控制 - 根因:两个 macOS job 各自构建两个架构的 DMG,产生两个 draft release, 导致 release job 只发布了没有 DMG 的那个,macOS 产物丢失 下载按钮无响应修复: - electron/updater.ts: downloadUpdate IPC handler 加 try-catch, 失败时通过 sendStatus 发送 error 事件给前端,避免静默失败 - AppShell.tsx: downloadUpdate 回调点击后立即设置 downloadProgress=0 提供即时 UI 反馈;加 await + catch 处理下载失败并重置状态 - AppShell.tsx: error 事件处理中重置 downloadProgress 为 null, 使下载按钮在失败后重新出现 - UpdateDialog.tsx / GeneralSection.tsx: isDownloading 判断移除 > 0 条件, downloadProgress === 0 时也显示下载中状态,消除点击后无反馈的间隙 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
40a78ea0fc
commit
09908cfcb7
5 files changed
+22
-6
No files matched your search
@@ -49,7 +49,6 @@ mac:
|
||||
artifactName: "${productName}-${version}-${arch}.${ext}"
|
||||
target:
|
||||
- target: dmg
|
||||
arch: [arm64, x64]
|
||||
win:
|
||||
icon: build/icon.ico
|
||||
target:
|
||||
|
||||
+8
-1
@@ -98,7 +98,14 @@ export function initAutoUpdater(win: BrowserWindow) {
|
||||
});
|
||||
|
||||
ipcMain.handle('updater:download', async () => {
|
||||
return autoUpdater.downloadUpdate();
|
||||
try {
|
||||
return await autoUpdater.downloadUpdate();
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
console.error('[updater] Download failed:', message);
|
||||
sendStatus({ status: 'error', error: message });
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('updater:quit-and-install', () => {
|
||||
|
||||
@@ -280,6 +280,8 @@ export function AppShell({ children }: { children: React.ReactNode }) {
|
||||
|
||||
case 'error':
|
||||
setChecking(false);
|
||||
// Reset download progress so the download button re-appears
|
||||
setUpdateInfo((prev) => prev ? { ...prev, downloadProgress: null } : prev);
|
||||
console.warn('[updater] Error:', event.error);
|
||||
break;
|
||||
}
|
||||
@@ -300,8 +302,16 @@ export function AppShell({ children }: { children: React.ReactNode }) {
|
||||
setShowDialog(false);
|
||||
}, []);
|
||||
|
||||
const downloadUpdate = useCallback(() => {
|
||||
window.electronAPI?.updater?.downloadUpdate();
|
||||
const downloadUpdate = useCallback(async () => {
|
||||
// Immediately show downloading state so user gets feedback
|
||||
setUpdateInfo((prev) => prev ? { ...prev, downloadProgress: 0 } : prev);
|
||||
try {
|
||||
await window.electronAPI?.updater?.downloadUpdate();
|
||||
} catch (err) {
|
||||
console.warn('[updater] Download failed:', err);
|
||||
// Reset progress so the download button re-appears
|
||||
setUpdateInfo((prev) => prev ? { ...prev, downloadProgress: null } : prev);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const quitAndInstall = useCallback(() => {
|
||||
|
||||
@@ -20,7 +20,7 @@ export function UpdateDialog() {
|
||||
if (!updateInfo?.updateAvailable) return null;
|
||||
|
||||
const { isNativeUpdate, readyToInstall, downloadProgress } = updateInfo;
|
||||
const isDownloading = isNativeUpdate && !readyToInstall && downloadProgress != null && downloadProgress > 0;
|
||||
const isDownloading = isNativeUpdate && !readyToInstall && downloadProgress != null;
|
||||
|
||||
return (
|
||||
<Dialog open={showDialog} onOpenChange={(open) => {
|
||||
|
||||
@@ -26,7 +26,7 @@ function UpdateCard() {
|
||||
const currentVersion = process.env.NEXT_PUBLIC_APP_VERSION || "0.0.0";
|
||||
|
||||
const isDownloading = updateInfo?.isNativeUpdate && !updateInfo.readyToInstall
|
||||
&& updateInfo.downloadProgress != null && updateInfo.downloadProgress > 0;
|
||||
&& updateInfo.downloadProgress != null;
|
||||
|
||||
return (
|
||||
<div className="rounded-lg border border-border/50 p-4 transition-shadow hover:shadow-sm">
|
||||
|
||||
Reference in new issue
Block a user