From f827b870c3f0f95738d3423b1738236c9ae6ac45 Mon Sep 17 00:00:00 2001 From: Innei Date: Thu, 19 Mar 2026 14:24:03 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(version):=20display=20actual?= =?UTF-8?q?=20desktop=20app=20version=20with=20canary=20suffix=20(#13110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ feat(version): display actual desktop app version with canary suffix Add support for fetching and displaying the desktop application's actual version number in the About section. When running on desktop, the version now displays the desktop app's version (including canary suffix if applicable), falling back to the web version if unavailable. - Add getAppVersion IPC method in SystemController - Create versionDisplay utility module with comprehensive tests - Integrate desktop version fetching in Version component * ♻️ refactor(desktop): inject about version at build time --- apps/desktop/electron.vite.config.ts | 25 ++++++++++++------- .../settings/about/features/Version.tsx | 4 ++- .../about/features/appVersion.desktop.ts | 1 + .../settings/about/features/appVersion.ts | 3 +++ src/types/global.d.ts | 3 +++ 5 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 src/routes/(main)/settings/about/features/appVersion.desktop.ts create mode 100644 src/routes/(main)/settings/about/features/appVersion.ts diff --git a/apps/desktop/electron.vite.config.ts b/apps/desktop/electron.vite.config.ts index e2d84ab740..2e186c7dc0 100644 --- a/apps/desktop/electron.vite.config.ts +++ b/apps/desktop/electron.vite.config.ts @@ -1,4 +1,5 @@ -import { resolve } from 'node:path'; +import { readFileSync } from 'node:fs'; +import path from 'node:path'; import dotenv from 'dotenv'; import { defineConfig } from 'electron-vite'; @@ -34,11 +35,14 @@ function electronDesktopHtmlPlugin(): PluginOption { dotenv.config(); const isDev = process.env.NODE_ENV === 'development'; -const ROOT_DIR = resolve(__dirname, '../..'); +const ROOT_DIR = path.resolve(__dirname, '../..'); const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development'; Object.assign(process.env, loadEnv(mode, ROOT_DIR, '')); const updateChannel = process.env.UPDATE_CHANNEL; +const desktopPackageJson = JSON.parse( + readFileSync(path.resolve(__dirname, 'package.json'), 'utf8'), +) as { version: string }; console.info(`[electron-vite.config.ts] Detected UPDATE_CHANNEL: ${updateChannel}`); @@ -74,8 +78,8 @@ export default defineConfig({ }, resolve: { alias: { - '@': resolve(__dirname, 'src/main'), - '~common': resolve(__dirname, 'src/common'), + '@': path.resolve(__dirname, 'src/main'), + '~common': path.resolve(__dirname, 'src/common'), }, }, }, @@ -88,21 +92,24 @@ export default defineConfig({ resolve: { alias: { - '@': resolve(__dirname, 'src/main'), - '~common': resolve(__dirname, 'src/common'), + '@': path.resolve(__dirname, 'src/main'), + '~common': path.resolve(__dirname, 'src/common'), }, }, }, renderer: { root: ROOT_DIR, build: { - outDir: resolve(__dirname, 'dist/renderer'), + outDir: path.resolve(__dirname, 'dist/renderer'), rollupOptions: { - input: resolve(__dirname, 'index.html'), + input: path.resolve(__dirname, 'index.html'), output: sharedRollupOutput, }, }, - define: sharedRendererDefine({ isMobile: false, isElectron: true }), + define: { + ...sharedRendererDefine({ isMobile: false, isElectron: true }), + __MAIN_VERSION__: JSON.stringify(desktopPackageJson.version), + }, optimizeDeps: sharedOptimizeDeps, plugins: [ electronDesktopHtmlPlugin(), diff --git a/src/routes/(main)/settings/about/features/Version.tsx b/src/routes/(main)/settings/about/features/Version.tsx index 2db9c7d506..89f0f281b5 100644 --- a/src/routes/(main)/settings/about/features/Version.tsx +++ b/src/routes/(main)/settings/about/features/Version.tsx @@ -16,6 +16,8 @@ import { useNewVersion } from '@/features/User/UserPanel/useNewVersion'; import { autoUpdateService } from '@/services/electron/autoUpdate'; import { useGlobalStore } from '@/store/global'; +import { APP_VERSION } from './appVersion'; + const styles = createStaticStyles(({ css, cssVar }) => ({ logo: css` border-radius: calc(${cssVar.borderRadiusLG} * 2); @@ -133,7 +135,7 @@ const Version = memo<{ mobile?: boolean }>(({ mobile }) => {
{BRANDING_NAME}
- v{CURRENT_VERSION} + v{APP_VERSION} {buildChannel && buildChannel !== 'stable' && ( diff --git a/src/routes/(main)/settings/about/features/appVersion.desktop.ts b/src/routes/(main)/settings/about/features/appVersion.desktop.ts new file mode 100644 index 0000000000..4233d85d3e --- /dev/null +++ b/src/routes/(main)/settings/about/features/appVersion.desktop.ts @@ -0,0 +1 @@ +export const APP_VERSION = __MAIN_VERSION__; diff --git a/src/routes/(main)/settings/about/features/appVersion.ts b/src/routes/(main)/settings/about/features/appVersion.ts new file mode 100644 index 0000000000..25f54ea41b --- /dev/null +++ b/src/routes/(main)/settings/about/features/appVersion.ts @@ -0,0 +1,3 @@ +import { CURRENT_VERSION } from '@/const/version'; + +export const APP_VERSION = CURRENT_VERSION; diff --git a/src/types/global.d.ts b/src/types/global.d.ts index 26fe5db0ce..adea4467d5 100644 --- a/src/types/global.d.ts +++ b/src/types/global.d.ts @@ -40,4 +40,7 @@ declare global { /** Vite define: current bundle is Electron desktop variant */ const __ELECTRON__: boolean | undefined; + + /** Vite define: desktop app version injected by electron-vite renderer build */ + const __MAIN_VERSION__: string; }