Files
auto-caption/src/main/ControlWindow.ts
xuemian 051a497f3a feat(engine): 添加启动超时功能和强制终止引擎的支持
- 在 ControlWindow 中添加了 'control.engine.forceKill' 事件处理,允许强制终止引擎。
- 在 CaptionEngine 中实现了启动超时机制,若引擎启动超时,将自动强制停止并发送错误消息。
- 更新了国际化文件,添加了与启动超时相关的提示信息。
- 在 EngineControl 组件中添加了启动超时的输入选项,允许用户设置超时时间。
- 更新了相关类型定义以支持新的启动超时配置。
2025-08-28 10:24:08 +10:00

177 lines
4.7 KiB
TypeScript

import { shell, BrowserWindow, ipcMain, nativeTheme, dialog } from 'electron'
import path from 'path'
import { EngineInfo } from './types'
import pidusage from 'pidusage'
import { is } from '@electron-toolkit/utils'
import icon from '../../build/icon.png?asset'
import { captionWindow } from './CaptionWindow'
import { allConfig } from './utils/AllConfig'
import { captionEngine } from './utils/CaptionEngine'
import { Log } from './utils/Log'
class ControlWindow {
mounted: boolean = false;
window: BrowserWindow | undefined;
public createWindow(): void {
this.window = new BrowserWindow({
icon: icon,
width: 1200,
height: 800,
minWidth: 750,
minHeight: 500,
show: false,
center: true,
autoHideMenuBar: true,
webPreferences: {
preload: path.join(__dirname, '../preload/index.js'),
sandbox: false
}
})
allConfig.readConfig()
this.window.on('ready-to-show', () => {
this.window?.show()
})
this.window.on('closed', () => {
this.mounted = false
this.window = undefined
allConfig.writeConfig()
})
this.window.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url)
return { action: 'deny' }
})
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
this.window.loadURL(process.env['ELECTRON_RENDERER_URL'])
} else {
this.window.loadFile(path.join(__dirname, '../renderer/index.html'))
}
}
public handleMessage() {
nativeTheme.on('updated', () => {
if(allConfig.uiTheme === 'system'){
if(nativeTheme.shouldUseDarkColors && this.window){
this.window.webContents.send('control.nativeTheme.change', 'dark')
}
else if(!nativeTheme.shouldUseDarkColors && this.window){
this.window.webContents.send('control.nativeTheme.change', 'light')
}
}
})
ipcMain.handle('both.window.mounted', () => {
this.mounted = true
return allConfig.getFullConfig(Log.getAndClearLogQueue())
})
ipcMain.handle('control.nativeTheme.get', () => {
if(allConfig.uiTheme === 'system'){
if(nativeTheme.shouldUseDarkColors) return 'dark'
return 'light'
}
return allConfig.uiTheme
})
ipcMain.handle('control.folder.select', async () => {
const result = await dialog.showOpenDialog({
properties: ['openDirectory']
});
if (result.canceled) return "";
return result.filePaths[0];
})
ipcMain.handle('control.engine.info', async () => {
const info: EngineInfo = {
pid: 0, ppid: 0, port: 0, cpu: 0, mem: 0, elapsed: 0
}
if(captionEngine.status !== 'running') return info
const stats = await pidusage(captionEngine.process.pid)
info.pid = stats.pid
info.ppid = stats.ppid
info.port = captionEngine.port
info.cpu = stats.cpu
info.mem = stats.memory
info.elapsed = stats.elapsed
return info
})
ipcMain.on('control.uiLanguage.change', (_, args) => {
allConfig.uiLanguage = args
if(captionWindow.window){
captionWindow.window.webContents.send('control.uiLanguage.set', args)
}
})
ipcMain.on('control.uiTheme.change', (_, args) => {
allConfig.uiTheme = args
})
ipcMain.on('control.uiColor.change', (_, args) => {
allConfig.uiColor = args
})
ipcMain.on('control.leftBarWidth.change', (_, args) => {
allConfig.leftBarWidth = args
})
ipcMain.on('control.styles.change', (_, args) => {
allConfig.setStyles(args)
if(captionWindow.window){
allConfig.sendStyles(captionWindow.window)
}
})
ipcMain.on('control.styles.reset', () => {
allConfig.resetStyles()
if(this.window){
allConfig.sendStyles(this.window)
}
if(captionWindow.window){
allConfig.sendStyles(captionWindow.window)
}
})
ipcMain.on('control.captionWindow.activate', () => {
if(!captionWindow.window){
captionWindow.createWindow()
}
else {
captionWindow.window.show()
}
})
ipcMain.on('control.controls.change', (_, args) => {
allConfig.setControls(args)
})
ipcMain.on('control.engine.start', () => {
captionEngine.start()
})
ipcMain.on('control.engine.stop', () => {
captionEngine.stop()
})
ipcMain.on('control.engine.forceKill', () => {
captionEngine.forceKill()
})
ipcMain.on('control.captionLog.clear', () => {
allConfig.captionLog.splice(0)
})
}
public sendErrorMessage(message: string) {
this.window?.webContents.send('control.error.occurred', message)
}
}
export const controlWindow = new ControlWindow()