import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron'; export interface ElectronAPI { screen: { wake: () => Promise; sleep: () => Promise; setIdleTimeout: (timeout: number) => Promise; activity: () => Promise; }; presence: { start: () => Promise; stop: () => Promise; onDetected: (callback: () => void) => () => void; onCleared: (callback: () => void) => () => void; }; frigate: { startStream: (rtspUrl: string) => Promise; stopStream: () => Promise; onPersonDetected: (callback: (camera: string) => void) => () => void; }; app: { quit: () => void; toggleFullscreen: () => void; toggleDevTools: () => void; }; config: { getStoredToken: () => Promise; getJellyfinApiKey: () => Promise; }; photos: { list: () => Promise; getDir: () => Promise; getUrl: (relative: string) => Promise; }; } const electronAPI: ElectronAPI = { screen: { wake: () => ipcRenderer.invoke('screen:wake'), sleep: () => ipcRenderer.invoke('screen:sleep'), setIdleTimeout: (timeout: number) => ipcRenderer.invoke('screen:setIdleTimeout', timeout), activity: () => ipcRenderer.invoke('screen:activity'), }, presence: { start: () => ipcRenderer.invoke('presence:start'), stop: () => ipcRenderer.invoke('presence:stop'), onDetected: (callback: () => void) => { const handler = (_event: IpcRendererEvent) => callback(); ipcRenderer.on('presence:detected', handler); return () => ipcRenderer.removeListener('presence:detected', handler); }, onCleared: (callback: () => void) => { const handler = (_event: IpcRendererEvent) => callback(); ipcRenderer.on('presence:cleared', handler); return () => ipcRenderer.removeListener('presence:cleared', handler); }, }, frigate: { startStream: (rtspUrl: string) => ipcRenderer.invoke('frigate:startStream', rtspUrl), stopStream: () => ipcRenderer.invoke('frigate:stopStream'), onPersonDetected: (callback: (camera: string) => void) => { const handler = (_event: IpcRendererEvent, camera: string) => callback(camera); ipcRenderer.on('frigate:personDetected', handler); return () => ipcRenderer.removeListener('frigate:personDetected', handler); }, }, app: { quit: () => ipcRenderer.invoke('app:quit'), toggleFullscreen: () => ipcRenderer.invoke('app:toggleFullscreen'), toggleDevTools: () => ipcRenderer.invoke('app:toggleDevTools'), }, config: { getStoredToken: () => ipcRenderer.invoke('config:getStoredToken'), getJellyfinApiKey: () => ipcRenderer.invoke('config:getJellyfinApiKey'), }, photos: { list: () => ipcRenderer.invoke('photos:list'), getDir: () => ipcRenderer.invoke('photos:getDir'), getUrl: (relative: string) => ipcRenderer.invoke('photos:getUrl', relative), }, }; contextBridge.exposeInMainWorld('electronAPI', electronAPI); // Type declaration for renderer declare global { interface Window { electronAPI: ElectronAPI; } }