195 lines
6.3 KiB
TypeScript
195 lines
6.3 KiB
TypeScript
import { contextBridge, ipcRenderer, webUtils } from 'electron'
|
|
import { electronAPI } from '@electron-toolkit/preload'
|
|
|
|
// Custom APIs for renderer
|
|
const api = {
|
|
deleteClass: (classId: string) => ipcRenderer.invoke('student:delete-class', classId),
|
|
deleteStudentProfile: (profileId: string) =>
|
|
ipcRenderer.invoke('student:delete-profile', profileId),
|
|
exportEmptyClassFolder: (payload: { className: string; classId: string; childNames: string[] }) =>
|
|
ipcRenderer.invoke('classes:export-empty-folder', payload),
|
|
loadStudentData: (payload?: { includeProfiles?: boolean; includeImages?: boolean }) =>
|
|
ipcRenderer.invoke('student:load', payload),
|
|
listStudentProfiles: (payload: {
|
|
page: number
|
|
pageSize: number
|
|
query?: string
|
|
classId?: string
|
|
}) => ipcRenderer.invoke('student:list', payload),
|
|
getStudentProfile: (profileId: string) => ipcRenderer.invoke('student:get-profile', profileId),
|
|
updateStudentProfile: (profile: {
|
|
id: string
|
|
classId: string
|
|
className: string
|
|
name: string
|
|
englishName: string
|
|
gender: string
|
|
birthday: string
|
|
zodiac: string
|
|
friends: string[]
|
|
hobbies: string[]
|
|
favoriteGames: string[]
|
|
favoriteFoods: string[]
|
|
traits: string
|
|
comment: string
|
|
commentGeneratedAt: string
|
|
reportGenerated: boolean
|
|
meImage: string
|
|
workImage1: string
|
|
workImage2: string
|
|
importedAt: string
|
|
}) => ipcRenderer.invoke('student:update-profile', profile),
|
|
generateStudentComment: (payload: { profileId: string }) =>
|
|
ipcRenderer.invoke('student:generate-comment', payload),
|
|
listModels: (payload: { baseUrl: string; apiKey: string }) =>
|
|
ipcRenderer.invoke('models:list', payload),
|
|
testModelConnection: (modelConfig: {
|
|
provider: string
|
|
baseUrl: string
|
|
apiKey: string
|
|
model: string
|
|
temperature: string
|
|
maxTokens: string
|
|
systemPrompt: string
|
|
}) => ipcRenderer.invoke('models:test-connection', modelConfig),
|
|
replaceClassProfiles: (payload: {
|
|
classItem: {
|
|
id: string
|
|
name: string
|
|
type: 'cheap' | 'noble'
|
|
teacherNames: string[]
|
|
familyPhoto?: string
|
|
}
|
|
profiles: Array<{
|
|
id: string
|
|
classId: string
|
|
className: string
|
|
name: string
|
|
englishName: string
|
|
gender: string
|
|
birthday: string
|
|
zodiac: string
|
|
friends: string[]
|
|
hobbies: string[]
|
|
favoriteGames: string[]
|
|
favoriteFoods: string[]
|
|
traits: string
|
|
comment?: string
|
|
commentGeneratedAt?: string
|
|
reportGenerated?: boolean
|
|
meImage?: string
|
|
workImage1?: string
|
|
workImage2?: string
|
|
importedAt: string
|
|
}>
|
|
}) => ipcRenderer.invoke('student:replace-class-profiles', payload),
|
|
migrateLocalStudentData: (payload: {
|
|
classes: Array<{
|
|
id: string
|
|
name: string
|
|
type: 'cheap' | 'noble'
|
|
teacherNames: string[]
|
|
familyPhoto?: string
|
|
}>
|
|
profiles: Array<{
|
|
id: string
|
|
classId: string
|
|
className: string
|
|
name: string
|
|
englishName: string
|
|
gender: string
|
|
birthday: string
|
|
zodiac: string
|
|
friends: string[]
|
|
hobbies: string[]
|
|
favoriteGames: string[]
|
|
favoriteFoods: string[]
|
|
traits: string
|
|
comment?: string
|
|
commentGeneratedAt?: string
|
|
reportGenerated?: boolean
|
|
meImage?: string
|
|
workImage1?: string
|
|
workImage2?: string
|
|
importedAt: string
|
|
}>
|
|
}) => ipcRenderer.invoke('student:migrate-local', payload),
|
|
saveClasses: (
|
|
classes: Array<{
|
|
id: string
|
|
name: string
|
|
type: 'cheap' | 'noble'
|
|
teacherNames: string[]
|
|
familyPhoto?: string
|
|
}>
|
|
) => ipcRenderer.invoke('student:save-classes', classes),
|
|
loadSettings: () => ipcRenderer.invoke('settings:load'),
|
|
saveSettings: (modelConfig: {
|
|
provider: string
|
|
baseUrl: string
|
|
apiKey: string
|
|
model: string
|
|
temperature: string
|
|
maxTokens: string
|
|
systemPrompt: string
|
|
}) => ipcRenderer.invoke('settings:save', modelConfig),
|
|
loadTemplates: () => ipcRenderer.invoke('templates:load'),
|
|
selectTemplateFile: () => ipcRenderer.invoke('templates:select-file'),
|
|
parseTemplatePlaceholders: (filePath: string) =>
|
|
ipcRenderer.invoke('templates:parse-placeholders', filePath),
|
|
getDroppedFilePath: (file: File) => webUtils.getPathForFile(file),
|
|
saveTemplate: (template: {
|
|
id?: string
|
|
name: string
|
|
grade: string
|
|
semester: 'first' | 'second'
|
|
type: 'portrait' | 'landscape'
|
|
sourceFilePath: string
|
|
}) => ipcRenderer.invoke('templates:save', template),
|
|
openTemplate: (filePath: string) => ipcRenderer.invoke('templates:open', filePath),
|
|
deleteTemplate: (id: string) => ipcRenderer.invoke('templates:delete', id),
|
|
loadReports: () => ipcRenderer.invoke('reports:load'),
|
|
generateReports: (payload: { templateId: string; classId: string; studentIds?: string[] }) =>
|
|
ipcRenderer.invoke('reports:generate', payload),
|
|
openReport: (filePath: string) => ipcRenderer.invoke('reports:open', filePath),
|
|
downloadReport: (id: string) => ipcRenderer.invoke('reports:download', id),
|
|
downloadClassReports: (payload: { classId: string }) =>
|
|
ipcRenderer.invoke('reports:download-class', payload),
|
|
onReportGenerationProgress: (callback: (progress: {
|
|
batchId: string
|
|
status: 'started' | 'student-started' | 'student-finished' | 'student-failed' | 'finished'
|
|
classId: string
|
|
className: string
|
|
studentId?: string
|
|
studentName?: string
|
|
current: number
|
|
total: number
|
|
report?: unknown
|
|
error?: string
|
|
}) => void) => {
|
|
const listener = (_: Electron.IpcRendererEvent, progress: Parameters<typeof callback>[0]) =>
|
|
callback(progress)
|
|
|
|
ipcRenderer.on('reports:generation-progress', listener)
|
|
return () => ipcRenderer.removeListener('reports:generation-progress', listener)
|
|
},
|
|
deleteReport: (id: string) => ipcRenderer.invoke('reports:delete', id)
|
|
}
|
|
|
|
// Use `contextBridge` APIs to expose Electron APIs to
|
|
// renderer only if context isolation is enabled, otherwise
|
|
// just add to the DOM global.
|
|
if (process.contextIsolated) {
|
|
try {
|
|
contextBridge.exposeInMainWorld('electron', electronAPI)
|
|
contextBridge.exposeInMainWorld('api', api)
|
|
} catch (error) {
|
|
console.error(error)
|
|
}
|
|
} else {
|
|
// @ts-ignore (define in dts)
|
|
window.electron = electronAPI
|
|
// @ts-ignore (define in dts)
|
|
window.api = api
|
|
}
|