diff options
| author | haoyuren <13851610112@163.com> | 2026-03-11 18:16:45 -0500 |
|---|---|---|
| committer | haoyuren <13851610112@163.com> | 2026-03-11 18:16:45 -0500 |
| commit | ebec1a1073f9cc5b69e125d5b284669545ea3d9f (patch) | |
| tree | 731ae664b9966b6fbd269c55be2ba5c01ee3341f /src/preload | |
Initial commit: ClaudeTeX - LaTeX editor with Overleaf sync
Features:
- Electron + React + TypeScript app with Cosmic Latte theme
- CodeMirror 6 editor with LaTeX syntax highlighting
- PDF preview with pdf.js, zoom controls, SyncTeX double-click jump
- File tree with context menu (new/rename/delete/reveal)
- Overleaf Git clone with token auth + macOS Keychain storage
- Git pull/push sync for Overleaf projects
- Embedded terminal (xterm.js + node-pty) with Claude CLI integration
- LaTeX compilation via latexmk with auto package install detection
- Structured compile log (errors/warnings) with click-to-navigate
- Main document setting (auto-detect or right-click to set)
- Custom modal system (input/confirm/alert)
- Resizable panel layout (file tree | editor | PDF + terminal)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'src/preload')
| -rw-r--r-- | src/preload/index.d.ts | 7 | ||||
| -rw-r--r-- | src/preload/index.ts | 78 |
2 files changed, 85 insertions, 0 deletions
diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts new file mode 100644 index 0000000..ccfa000 --- /dev/null +++ b/src/preload/index.d.ts @@ -0,0 +1,7 @@ +import type { ElectronAPI } from './index' + +declare global { + interface Window { + api: ElectronAPI + } +} diff --git a/src/preload/index.ts b/src/preload/index.ts new file mode 100644 index 0000000..ab360c0 --- /dev/null +++ b/src/preload/index.ts @@ -0,0 +1,78 @@ +import { contextBridge, ipcRenderer } from 'electron' + +const api = { + // File system + openProject: () => ipcRenderer.invoke('dialog:openProject'), + selectSaveDir: () => ipcRenderer.invoke('dialog:selectSaveDir'), + readDir: (path: string) => ipcRenderer.invoke('fs:readDir', path), + readFile: (path: string) => ipcRenderer.invoke('fs:readFile', path), + findMainTex: (dir: string) => ipcRenderer.invoke('fs:findMainTex', dir) as Promise<string | null>, + readBinary: (path: string) => ipcRenderer.invoke('fs:readBinary', path) as Promise<ArrayBuffer>, + writeFile: (path: string, content: string) => ipcRenderer.invoke('fs:writeFile', path, content), + createFile: (dir: string, name: string) => ipcRenderer.invoke('fs:createFile', dir, name), + createDir: (dir: string, name: string) => ipcRenderer.invoke('fs:createDir', dir, name), + renameFile: (oldPath: string, newPath: string) => ipcRenderer.invoke('fs:rename', oldPath, newPath), + deleteFile: (path: string) => ipcRenderer.invoke('fs:delete', path), + fileStat: (path: string) => ipcRenderer.invoke('fs:stat', path), + + // File watcher + watchStart: (path: string) => ipcRenderer.invoke('watcher:start', path), + watchStop: () => ipcRenderer.invoke('watcher:stop'), + onWatchChange: (cb: (data: { event: string; path: string }) => void) => { + const handler = (_e: Electron.IpcRendererEvent, data: { event: string; path: string }) => cb(data) + ipcRenderer.on('watcher:change', handler) + return () => ipcRenderer.removeListener('watcher:change', handler) + }, + + // LaTeX + compile: (path: string) => ipcRenderer.invoke('latex:compile', path), + getPdfPath: (texPath: string) => ipcRenderer.invoke('latex:getPdfPath', texPath), + onCompileLog: (cb: (log: string) => void) => { + const handler = (_e: Electron.IpcRendererEvent, log: string) => cb(log) + ipcRenderer.on('latex:log', handler) + return () => ipcRenderer.removeListener('latex:log', handler) + }, + + // Terminal + ptySpawn: (cwd: string) => ipcRenderer.invoke('pty:spawn', cwd), + ptyWrite: (data: string) => ipcRenderer.invoke('pty:write', data), + ptyResize: (cols: number, rows: number) => ipcRenderer.invoke('pty:resize', cols, rows), + ptyKill: () => ipcRenderer.invoke('pty:kill'), + onPtyData: (cb: (data: string) => void) => { + const handler = (_e: Electron.IpcRendererEvent, data: string) => cb(data) + ipcRenderer.on('pty:data', handler) + return () => ipcRenderer.removeListener('pty:data', handler) + }, + onPtyExit: (cb: () => void) => { + const handler = () => cb() + ipcRenderer.on('pty:exit', handler) + return () => ipcRenderer.removeListener('pty:exit', handler) + }, + + // Overleaf + overleafCloneWithAuth: (projectId: string, dest: string, token: string, remember: boolean) => + ipcRenderer.invoke('overleaf:cloneWithAuth', projectId, dest, token, remember) as Promise<{ success: boolean; message: string; detail: string }>, + overleafCheck: () => ipcRenderer.invoke('overleaf:check') as Promise<{ loggedIn: boolean; email: string }>, + overleafLogout: () => ipcRenderer.invoke('overleaf:logout'), + gitPull: (cwd: string) => ipcRenderer.invoke('git:pull', cwd), + gitPush: (cwd: string) => ipcRenderer.invoke('git:push', cwd), + gitStatus: (cwd: string) => ipcRenderer.invoke('git:status', cwd), + + // SyncTeX + synctexEdit: (pdfPath: string, page: number, x: number, y: number) => + ipcRenderer.invoke('synctex:editFromPdf', pdfPath, page, x, y) as Promise<{ file: string; line: number } | null>, + synctexView: (texPath: string, line: number, pdfPath: string) => + ipcRenderer.invoke('synctex:viewFromSource', texPath, line, pdfPath) as Promise<{ page: number; x: number; y: number } | null>, + + // LaTeX package management + installTexPackages: (packages: string[]) => + ipcRenderer.invoke('latex:installPackages', packages) as Promise<{ success: boolean; message: string; packages?: string[] }>, + + // Shell + openExternal: (url: string) => ipcRenderer.invoke('shell:openExternal', url), + showInFinder: (path: string) => ipcRenderer.invoke('shell:showInFinder', path) +} + +contextBridge.exposeInMainWorld('api', api) + +export type ElectronAPI = typeof api |
