Files
game-marathon/desktop/src/preload/index.ts
2026-01-10 08:48:52 +07:00

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
}
}