97 lines
4.1 KiB
TypeScript
97 lines
4.1 KiB
TypeScript
|
|
import { contextBridge, ipcRenderer } from 'electron'
|
||
|
|
import type { AppSettings, TrackedProcess, SteamGame, TrackedGame, TrackingStats, User, LoginResponse } from '../shared/types'
|
||
|
|
|
||
|
|
interface ApiResult<T> {
|
||
|
|
success: boolean
|
||
|
|
data?: T
|
||
|
|
error?: string
|
||
|
|
status?: number
|
||
|
|
}
|
||
|
|
|
||
|
|
// Expose protected methods that allow the renderer process to use
|
||
|
|
// ipcRenderer without exposing the entire object
|
||
|
|
const electronAPI = {
|
||
|
|
// Settings
|
||
|
|
getSettings: (): Promise<AppSettings> => ipcRenderer.invoke('get-settings'),
|
||
|
|
saveSettings: (settings: Partial<AppSettings>): Promise<void> =>
|
||
|
|
ipcRenderer.invoke('save-settings', settings),
|
||
|
|
|
||
|
|
// Auth (local storage)
|
||
|
|
getToken: (): Promise<string | null> => ipcRenderer.invoke('get-token'),
|
||
|
|
saveToken: (token: string): Promise<void> => ipcRenderer.invoke('save-token', token),
|
||
|
|
clearToken: (): Promise<void> => ipcRenderer.invoke('clear-token'),
|
||
|
|
|
||
|
|
// API calls (through main process - no CORS)
|
||
|
|
apiLogin: (login: string, password: string): Promise<ApiResult<LoginResponse>> =>
|
||
|
|
ipcRenderer.invoke('api-login', login, password),
|
||
|
|
api2faVerify: (sessionId: number, code: string): Promise<ApiResult<LoginResponse>> =>
|
||
|
|
ipcRenderer.invoke('api-2fa-verify', sessionId, code),
|
||
|
|
apiGetMe: (): Promise<ApiResult<User>> =>
|
||
|
|
ipcRenderer.invoke('api-get-me'),
|
||
|
|
apiRequest: <T>(method: string, endpoint: string, data?: unknown): Promise<ApiResult<T>> =>
|
||
|
|
ipcRenderer.invoke('api-request', method, endpoint, data),
|
||
|
|
|
||
|
|
// Process tracking
|
||
|
|
getRunningProcesses: (): Promise<TrackedProcess[]> =>
|
||
|
|
ipcRenderer.invoke('get-running-processes'),
|
||
|
|
getForegroundWindow: (): Promise<string | null> =>
|
||
|
|
ipcRenderer.invoke('get-foreground-window'),
|
||
|
|
getTrackingStats: (): Promise<TrackingStats> =>
|
||
|
|
ipcRenderer.invoke('get-tracking-stats'),
|
||
|
|
|
||
|
|
// Steam
|
||
|
|
getSteamGames: (): Promise<SteamGame[]> => ipcRenderer.invoke('get-steam-games'),
|
||
|
|
getSteamPath: (): Promise<string | null> => ipcRenderer.invoke('get-steam-path'),
|
||
|
|
|
||
|
|
// Tracked games
|
||
|
|
getTrackedGames: (): Promise<TrackedGame[]> => ipcRenderer.invoke('get-tracked-games'),
|
||
|
|
addTrackedGame: (game: Omit<TrackedGame, 'totalTime' | 'lastPlayed'>): Promise<TrackedGame> =>
|
||
|
|
ipcRenderer.invoke('add-tracked-game', game),
|
||
|
|
removeTrackedGame: (gameId: string): Promise<void> =>
|
||
|
|
ipcRenderer.invoke('remove-tracked-game', gameId),
|
||
|
|
|
||
|
|
// Window controls
|
||
|
|
minimizeToTray: (): void => ipcRenderer.send('minimize-to-tray'),
|
||
|
|
quitApp: (): void => ipcRenderer.send('quit-app'),
|
||
|
|
|
||
|
|
// Monitoring control
|
||
|
|
startMonitoring: (): Promise<boolean> => ipcRenderer.invoke('start-monitoring'),
|
||
|
|
stopMonitoring: (): Promise<boolean> => ipcRenderer.invoke('stop-monitoring'),
|
||
|
|
getMonitoringStatus: (): Promise<boolean> => ipcRenderer.invoke('get-monitoring-status'),
|
||
|
|
|
||
|
|
// Updates
|
||
|
|
getAppVersion: (): Promise<string> => ipcRenderer.invoke('get-app-version'),
|
||
|
|
checkForUpdates: (): Promise<{ available: boolean; version?: string; error?: string }> =>
|
||
|
|
ipcRenderer.invoke('check-for-updates'),
|
||
|
|
installUpdate: (): Promise<void> => ipcRenderer.invoke('install-update'),
|
||
|
|
|
||
|
|
// Events
|
||
|
|
onTrackingUpdate: (callback: (stats: TrackingStats) => void) => {
|
||
|
|
const subscription = (_event: Electron.IpcRendererEvent, stats: TrackingStats) => callback(stats)
|
||
|
|
ipcRenderer.on('tracking-update', subscription)
|
||
|
|
return () => ipcRenderer.removeListener('tracking-update', subscription)
|
||
|
|
},
|
||
|
|
|
||
|
|
onGameStarted: (callback: (gameName: string, gameId: string) => void) => {
|
||
|
|
const subscription = (_event: Electron.IpcRendererEvent, gameName: string, gameId: string) => callback(gameName, gameId)
|
||
|
|
ipcRenderer.on('game-started', subscription)
|
||
|
|
return () => ipcRenderer.removeListener('game-started', subscription)
|
||
|
|
},
|
||
|
|
|
||
|
|
onGameStopped: (callback: (gameName: string, duration: number) => void) => {
|
||
|
|
const subscription = (_event: Electron.IpcRendererEvent, gameName: string, duration: number) =>
|
||
|
|
callback(gameName, duration)
|
||
|
|
ipcRenderer.on('game-stopped', subscription)
|
||
|
|
return () => ipcRenderer.removeListener('game-stopped', subscription)
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
contextBridge.exposeInMainWorld('electronAPI', electronAPI)
|
||
|
|
|
||
|
|
// Type declaration for renderer process
|
||
|
|
declare global {
|
||
|
|
interface Window {
|
||
|
|
electronAPI: typeof electronAPI
|
||
|
|
}
|
||
|
|
}
|