fe127ec3ed
Deliver schema v9, book/chapter IPC extensions, BookSettingsTab, chapter meta/tags, AI session menu, focus mode and TTS, template context enrich, and Wave 1 E2E coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
61 lines
2.1 KiB
TypeScript
61 lines
2.1 KiB
TypeScript
import { ipcMain, dialog, app } from 'electron'
|
|
import { copyFileSync, mkdirSync } from 'fs'
|
|
import { extname, join } from 'path'
|
|
import { IPC } from '../../../shared/ipc-channels'
|
|
import type { CreateBookParams, UpdateBookMetaParams } from '../../../shared/types'
|
|
import { BookRegistryService } from '../../services/book-registry'
|
|
import type { WritingSessionService } from '../../services/writing-session.service'
|
|
import { wrap } from '../result'
|
|
|
|
let previousBookId: string | null = null
|
|
|
|
export function registerBookHandlers(
|
|
registry: BookRegistryService,
|
|
writingSessions?: WritingSessionService
|
|
): void {
|
|
ipcMain.handle(IPC.BOOK_LIST, () => wrap(() => registry.list()))
|
|
|
|
ipcMain.handle(IPC.BOOK_CREATE, (_event, params: CreateBookParams) =>
|
|
wrap(() => registry.create(params))
|
|
)
|
|
|
|
ipcMain.handle(IPC.BOOK_DELETE, (_event, { bookId }: { bookId: string }) =>
|
|
wrap(() => {
|
|
registry.delete(bookId)
|
|
})
|
|
)
|
|
|
|
ipcMain.handle(IPC.BOOK_OPEN, (_event, { bookId }: { bookId: string }) =>
|
|
wrap(() => {
|
|
if (writingSessions && previousBookId && previousBookId !== bookId) {
|
|
writingSessions.endActive(previousBookId)
|
|
}
|
|
previousBookId = bookId
|
|
return registry.open(bookId)
|
|
})
|
|
)
|
|
|
|
ipcMain.handle(
|
|
IPC.BOOK_UPDATE_META,
|
|
(_event, { bookId, ...patch }: { bookId: string } & UpdateBookMetaParams) =>
|
|
wrap(() => registry.updateMeta(bookId, patch))
|
|
)
|
|
|
|
ipcMain.handle(IPC.BOOK_PICK_COVER, (_event, { bookId }: { bookId: string }) =>
|
|
wrap(async () => {
|
|
const { canceled, filePaths } = await dialog.showOpenDialog({
|
|
filters: [{ name: 'Images', extensions: ['jpg', 'jpeg', 'png', 'webp'] }],
|
|
properties: ['openFile']
|
|
})
|
|
if (canceled || !filePaths[0]) return null
|
|
const src = filePaths[0]
|
|
const ext = extname(src).toLowerCase() || '.jpg'
|
|
const coversDir = join(app.getPath('userData'), 'covers')
|
|
mkdirSync(coversDir, { recursive: true })
|
|
const dest = join(coversDir, `${bookId}${ext}`)
|
|
copyFileSync(src, dest)
|
|
return registry.updateMeta(bookId, { coverPath: dest })
|
|
})
|
|
)
|
|
}
|