feat(build): add icon generation and external binary bundling

- Add scripts to generate application icons in multiple formats (ICO, ICNS, PNG)
- Implement download scripts for uv and Node.js binaries for cross-platform support
- Update build configuration to use new icon resources and bundled binaries
- Remove old loading screen and unused build configurations
- Fix application icon path resolution to use app resources directory
This commit is contained in:
duanshuwen
2026-04-08 07:25:25 +08:00
parent 49a8c0c1d6
commit eb9acae071
132 changed files with 1289 additions and 817920 deletions

View File

@@ -1,7 +1,7 @@
import type { WindowNames } from '@lib/types'
import { CONFIG_KEYS, IPC_EVENTS, WINDOW_NAMES } from '@lib/constants'
import { BrowserWindow, BrowserWindowConstructorOptions, ipcMain, IpcMainInvokeEvent, WebContentsView, type IpcMainEvent } from 'electron'
import { BrowserWindow, BrowserWindowConstructorOptions, ipcMain, IpcMainInvokeEvent, type IpcMainEvent } from 'electron'
import { debounce } from '@lib/utils'
import { createLogo } from '@electron/utils'
@@ -173,41 +173,19 @@ class WindowService {
}
private _addLoadingView(window: BrowserWindow, size: SizeOptions) {
let loadingView: WebContentsView | void = new WebContentsView();
let rendererIsReady = false;
window.contentView?.addChildView(loadingView);
loadingView.setBounds({
x: 0,
y: 0,
width: size.width,
height: size.height,
});
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
loadingView.webContents.loadURL(`${MAIN_WINDOW_VITE_DEV_SERVER_URL}/loading.html`);
} else {
loadingView.webContents.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/loading.html`));
}
const onRendererIsReady = (e: IpcMainEvent) => {
if ((e.sender !== window?.webContents) || rendererIsReady) return;
rendererIsReady = true;
window.contentView.removeChildView(loadingView as WebContentsView);
ipcMain.removeListener(IPC_EVENTS.RENDERER_IS_READY, onRendererIsReady);
loadingView = void 0;
}
ipcMain.on(IPC_EVENTS.RENDERER_IS_READY, onRendererIsReady);
return (cb: () => void) => loadingView?.webContents.once('dom-ready', () => {
loadingView?.webContents.insertCSS(`body {
background-color: ${themeManager.isDark ? '#2C2C2C' : '#FFFFFF'} !important;
--stop-color-start: ${themeManager.isDark ? '#A0A0A0' : '#7F7F7F'} !important;
--stop-color-end: ${themeManager.isDark ? '#A0A0A0' : '#7F7F7F'} !important;
}`);
return (cb: () => void) => {
// Immediately call callback since we don't have a loading view
cb();
})
}
}
private _applySizeConstraints(win: BrowserWindow, size: SizeOptions) {
@@ -223,11 +201,12 @@ class WindowService {
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
return window.loadURL(`${MAIN_WINDOW_VITE_DEV_SERVER_URL}/${pageName}.html`);
}
window.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/${pageName}.html`));
window.loadFile(path.join(app.getAppPath(), 'dist', `${pageName}.html`));
}
private _loadWindowTemplate(window: BrowserWindow, name: WindowNames) {
const page = name === WINDOW_NAMES.LOADING ? 'loading' : 'index';
// Always load index.html, loading.html has been removed
const page = 'index';
this._loadPage(window, page);
}

View File

@@ -2,6 +2,7 @@ import { CONFIG_KEYS } from '@lib/constants'
import logManager from '@electron/service/logger'
import configManager from '@electron/service/config-service'
import path from 'node:path'
import { app } from 'electron'
import en from '@locales/en.json'
import zh from '@locales/zh.json'
@@ -31,6 +32,9 @@ export function createLogo() {
if (logo != null) {
return logo;
}
logo = path.join(__dirname, '/public/logo.ico');
// Use app.getAppPath() to get the application root directory
const appPath = app.getAppPath();
const iconPath = path.join(appPath, 'resources', 'icons', 'icon.ico');
logo = iconPath;
return logo;
}