Files
club-launcher/electron/preload.ts
T
houseassassin b84a7bdf29 feat: v1.3.0 — Steam path override, game folder scanner
- electron/settings.ts: persist steamPath + gameFolders in settings.json
- electron/scanner.ts: scan folders 2 levels deep for .exe files,
  filter out known non-game binaries (uninstall/setup/redist/crash handlers)
- electron/steam.ts: detectSteamGames(customPath?) — uses user path when set
- electron/main.ts: new IPC handlers — dialog:pick-folder, settings:get/set-steam-path/
  add-folder/remove-folder, scanner:scan/import
- src/components/SettingsPanel.tsx: drawer UI — Steam path picker with auto-resolved
  path display, game folders list, per-folder scan with checkbox selection,
  one-click import of selected executables
- src/App.tsx: SlidersHorizontal button opens SettingsPanel, reload on import

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 13:05:29 +00:00

51 lines
2.5 KiB
TypeScript

import { contextBridge, ipcRenderer } from 'electron'
import type { CustomGame, AppEntry } from './config'
import type { AppSettings } from './settings'
import type { ScannedExe } from './scanner'
const launcher = {
// Games
getGames: () => ipcRenderer.invoke('games:get-all'),
launchGame: (id: string) =>
ipcRenderer.invoke('games:launch', id) as Promise<{ ok: boolean; error?: string; recent?: string[] }>,
// Custom games (admin)
addCustomGame: (g: Omit<CustomGame, 'id' | 'source'>) => ipcRenderer.invoke('admin:add-game', g),
removeGame: (id: string) => ipcRenderer.invoke('admin:remove-game', id),
updateGame: (g: CustomGame) => ipcRenderer.invoke('admin:update-game', g),
// App entries (admin)
addApp: (a: Omit<AppEntry, 'id' | 'source'>) => ipcRenderer.invoke('apps:add', a),
removeApp: (id: string) => ipcRenderer.invoke('apps:remove', id),
updateApp: (a: AppEntry) => ipcRenderer.invoke('apps:update', a),
// Dialogs
pickExe: () => ipcRenderer.invoke('dialog:pick-exe') as Promise<string | null>,
pickImage: () => ipcRenderer.invoke('dialog:pick-image') as Promise<string | null>,
pickFolder: (title?: string) => ipcRenderer.invoke('dialog:pick-folder', title) as Promise<string | null>,
// Settings
getSettings: () => ipcRenderer.invoke('settings:get') as Promise<AppSettings & { resolvedSteamPath: string | null }>,
setSteamPath: (path: string | null) => ipcRenderer.invoke('settings:set-steam-path', path) as Promise<AppSettings>,
addGameFolder: (folder: string) => ipcRenderer.invoke('settings:add-folder', folder) as Promise<AppSettings>,
removeGameFolder: (folder: string) => ipcRenderer.invoke('settings:remove-folder', folder) as Promise<AppSettings>,
// Scanner
scanFolder: (folder: string) => ipcRenderer.invoke('scanner:scan', folder) as Promise<ScannedExe[]>,
importScanned: (exes: ScannedExe[]) => ipcRenderer.invoke('scanner:import', exes) as Promise<CustomGame[]>,
// Favorites / recent
getFavorites: () => ipcRenderer.invoke('favorites:get') as Promise<string[]>,
toggleFavorite: (id: string) => ipcRenderer.invoke('favorites:toggle', id) as Promise<string[]>,
getRecent: () => ipcRenderer.invoke('recent:get') as Promise<string[]>,
// Events
onAdminOpen: (cb: () => void) => {
ipcRenderer.on('admin:open', cb)
return () => ipcRenderer.removeListener('admin:open', cb)
},
}
contextBridge.exposeInMainWorld('launcher', launcher)
export type LauncherAPI = typeof launcher