refactor: use singleton pattern for screenshot service

- Export screenshotService singleton instance instead of class
- Remove redundant instantiation in IPC handlers
- Align with project patterns (mcpService, searchService, etc.)
- Simplify IPC handler code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
suyao 2025-12-15 03:29:21 +08:00
parent 0534585fa9
commit 76ecc7376f
No known key found for this signature in database
2 changed files with 12 additions and 20 deletions

View File

@ -54,7 +54,7 @@ import powerMonitorService from './services/PowerMonitorService'
import { proxyManager } from './services/ProxyManager'
import { pythonService } from './services/PythonService'
import { FileServiceManager } from './services/remotefile/FileServiceManager'
import { Screenshot } from './services/ScreenshotService'
import { screenshotService } from './services/ScreenshotService'
import { searchService } from './services/SearchService'
import { SelectionService } from './services/SelectionService'
import { registerShortcuts, unregisterAllShortcuts } from './services/ShortcutService'
@ -612,34 +612,24 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
}
})
// Screenshot service singleton for selection flow
let screenshotService: Screenshot | null = null
// Screenshot
ipcMain.handle(IpcChannel.Screenshot_Capture, async (_event, fileName: string) => {
const service = new Screenshot()
return await service.capture(fileName)
return await screenshotService.capture(fileName)
})
ipcMain.handle(IpcChannel.Screenshot_CaptureWithSelection, async (_event, fileName: string) => {
if (!screenshotService) {
screenshotService = new Screenshot()
}
return await screenshotService.captureWithSelection(fileName)
})
ipcMain.handle(
IpcChannel.Screenshot_SelectionConfirm,
async (_event, selection: { x: number; y: number; width: number; height: number }) => {
if (screenshotService) {
screenshotService.confirmSelection(selection)
}
}
)
ipcMain.handle(IpcChannel.Screenshot_SelectionCancel, async () => {
if (screenshotService) {
screenshotService.cancelSelection()
}
})
ipcMain.handle(IpcChannel.File_BinaryImage, fileManager.binaryImage.bind(fileManager))

View File

@ -29,7 +29,7 @@ interface Rectangle {
height: number
}
export class ScreenshotService {
class ScreenshotService {
private selectionWindow: BrowserWindow | null = null
private screenshotBuffer: Buffer | null = null
private screenshotData: string | null = null
@ -176,7 +176,7 @@ export class ScreenshotService {
}
}
public confirmSelection(selection: Rectangle): void {
public async confirmSelection(selection: Rectangle): Promise<void> {
if (!this.selectionPromise) {
logger.warn('No active selection to confirm')
return
@ -189,7 +189,7 @@ export class ScreenshotService {
status: 'error',
message: 'Selection too small (minimum 10×10 pixels)'
})
void this.cleanupSelection()
await this.cleanupSelection()
return
}
@ -197,7 +197,7 @@ export class ScreenshotService {
this.processSelection(selection)
}
public cancelSelection(): void {
public async cancelSelection(): Promise<void> {
if (!this.selectionPromise) {
logger.warn('No active selection to cancel')
return
@ -208,7 +208,7 @@ export class ScreenshotService {
status: 'cancelled',
message: 'User cancelled selection'
})
void this.cleanupSelection()
await this.cleanupSelection()
}
private async processSelection(selection: Rectangle): Promise<void> {
@ -349,3 +349,5 @@ export class ScreenshotService {
}
}
}
export const screenshotService = new ScreenshotService()