Skip to content

Commit b0f3255

Browse files
committed
feat: implement automatic application update system
- Add electron-updater dependency for auto-update support - Create UpdaterManager class with complete update workflow - Implement real-time download progress tracking - Add one-click install and restart functionality - Add comprehensive error handling and retry mechanism - Update UI with progress bar and status indicators - Add i18n support for update messages (zh-CN and en-US) - Add IPC channels and handlers for update events - Update version to 1.2.0 - Add v1.2.0 changelog entry This enables users to seamlessly update the application with automatic download, progress tracking, and one-click installation.
1 parent 4ffb09c commit b0f3255

15 files changed

Lines changed: 626 additions & 22 deletions

File tree

CODE_WIKI.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,13 @@ GNU General Public License v3.0。详见 [LICENSE](LICENSE) 文件。
324324

325325
## 13. 更新日志
326326

327+
### v1.2.0
328+
- Implemented automatic application update feature
329+
- Added real-time download progress tracking
330+
- Added one-click install and restart functionality
331+
- Improved error handling and user experience
332+
- Added multi-language support for update UI
333+
327334
### v1.1.4
328335
- 新增 Perplexity 提供商支持
329336
- 改进上下文管理功能

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</p>
66

77
<p align="center">
8-
<img src="https://img.shields.io/badge/Release-v1.1.4-blue?style=flat-square&logo=github" alt="Release">
8+
<img src="https://img.shields.io/badge/Release-v1.2.0-blue?style=flat-square&logo=github" alt="Release">
99
<img src="https://img.shields.io/badge/License-GPL--3.0-blue?style=flat-square" alt="License">
1010
<br>
1111
<a href="https://www.electronjs.org/"><img src="https://img.shields.io/badge/Electron-33+-47848F?style=flat-square&logo=electron&logoColor=white" alt="Electron"></a>

README_CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</p>
66

77
<p align="center">
8-
<img src="https://img.shields.io/badge/Release-v1.1.4-blue?style=flat-square&logo=github" alt="Release">
8+
<img src="https://img.shields.io/badge/Release-v1.2.0-blue?style=flat-square&logo=github" alt="Release">
99
<img src="https://img.shields.io/badge/License-GPL--3.0-blue?style=flat-square" alt="License">
1010
<br>
1111
<a href="https://www.electronjs.org/"><img src="https://img.shields.io/badge/Electron-33+-47848F?style=flat-square&logo=electron&logoColor=white" alt="Electron"></a>

package-lock.json

Lines changed: 98 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "chat2api",
3-
"version": "1.1.4",
3+
"version": "1.2.0",
44
"description": "Chat2API 管理器 - 统一管理多个 AI 服务提供商,提供 OpenAI 兼容 API 接口",
55
"main": "./out/main/index.js",
66
"author": {
@@ -47,6 +47,7 @@
4747
"class-variance-authority": "^0.7.0",
4848
"clsx": "^2.1.1",
4949
"electron-store": "^10.0.0",
50+
"electron-updater": "^6.3.9",
5051
"eventsource-parser": "^3.0.6",
5152
"i18next": "^25.8.11",
5253
"i18next-browser-languagedetector": "^8.2.1",

src/main/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { join } from 'path'
33
import { createWindow, getMainWindow, loadUrl, loadFile, openDevTools } from './window/manager'
44
import { createTrayManager, TrayManager } from './tray/TrayManager'
55
import { registerIpcHandlers } from './ipc/handlers'
6+
import { UpdaterManager } from './updater'
67

78
// Prevent uncaught exceptions from crashing the app
89
process.on('uncaughtException', (error) => {
@@ -124,6 +125,8 @@ async function loadAppContent(mainWindow: BrowserWindow): Promise<void> {
124125

125126
function cleanup(): void {
126127
console.log('Application is exiting, performing cleanup...')
128+
const updaterManager = UpdaterManager.getInstance()
129+
updaterManager.destroy()
127130
}
128131

129132
export function restartApp(): void {

src/main/ipc/channels.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@ export const IpcChannels = {
7878

7979
APP_GET_VERSION: 'app:getVersion',
8080
APP_CHECK_UPDATE: 'app:checkUpdate',
81+
APP_DOWNLOAD_UPDATE: 'app:downloadUpdate',
82+
APP_INSTALL_UPDATE: 'app:installUpdate',
83+
APP_UPDATE_CHECKING: 'app:updateChecking',
84+
APP_UPDATE_AVAILABLE: 'app:updateAvailable',
85+
APP_UPDATE_NOT_AVAILABLE: 'app:updateNotAvailable',
86+
APP_UPDATE_PROGRESS: 'app:updateProgress',
87+
APP_UPDATE_DOWNLOADED: 'app:updateDownloaded',
88+
APP_UPDATE_ERROR: 'app:updateError',
89+
APP_GET_UPDATE_STATUS: 'app:getUpdateStatus',
8190
APP_MINIMIZE: 'app:minimize',
8291
APP_MAXIMIZE: 'app:maximize',
8392
APP_CLOSE: 'app:close',

src/main/ipc/handlers.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import { sessionManager } from '../proxy/sessionManager'
1414
import { TrayManager } from '../tray/TrayManager'
1515
import { ConfigManager } from '../store/config'
1616
import { generateManagementSecret } from '../proxy/middleware/managementAuth'
17+
import { UpdaterManager } from '../updater'
1718
import type { Provider, Account, ProxyStatus, ProviderCheckResult, OAuthResult, AuthType, CredentialField, LogLevel, LogEntry, ProviderVendor, AppConfig } from '../../shared/types'
1819
import type { SystemPrompt, SessionConfig, SessionRecord, ManagementApiConfig } from '../store/types'
1920
import type { ProviderType } from '../oauth/types'
2021

2122
let proxyServer: ProxyServer | null = null
2223
let proxyStartTime: number | null = null
24+
const updaterManager = UpdaterManager.getInstance()
2325

2426
export async function registerIpcHandlers(mainWindow: BrowserWindow | null): Promise<void> {
2527
try {
@@ -48,6 +50,7 @@ export async function registerIpcHandlers(mainWindow: BrowserWindow | null): Pro
4850

4951
if (mainWindow) {
5052
oauthManager.setMainWindow(mainWindow)
53+
updaterManager.initialize(mainWindow)
5154
}
5255

5356
// Check if auto-start proxy is needed
@@ -827,6 +830,18 @@ export async function registerIpcHandlers(mainWindow: BrowserWindow | null): Pro
827830
}
828831
})
829832

833+
ipcMain.handle(IpcChannels.APP_DOWNLOAD_UPDATE, async (): Promise<void> => {
834+
await updaterManager.downloadUpdate()
835+
})
836+
837+
ipcMain.handle(IpcChannels.APP_INSTALL_UPDATE, async (): Promise<void> => {
838+
updaterManager.quitAndInstall()
839+
})
840+
841+
ipcMain.handle(IpcChannels.APP_GET_UPDATE_STATUS, async () => {
842+
return updaterManager.getStatus()
843+
})
844+
830845
ipcMain.handle(IpcChannels.APP_MINIMIZE, async (): Promise<void> => {
831846
mainWindow?.minimize()
832847
})

0 commit comments

Comments
 (0)