Files
club-launcher/electron/preload.ts
T
houseassassin 35c61c2496 feat: v1.2.0 — Apps tab, light/dark theme, visual overhaul, animations
- Apps tab: new AppEntry type (source: 'app'), apps.json storage, IPC handlers
  (apps:add/remove/update), square tile layout in grid, blue APP badge
- Light/dark theme: CSS variables in :root/.light, ThemeToggle (Sun/Moon),
  persisted in localStorage, smooth 0.2s transition
- Visual overhaul: gradient logo, pill badges, glassmorphism header,
  gradient play button, modern AdminPanel as slide-in drawer from right
- Animations: 3D tilt + glow on hover, bounce on favorite star, ripple on play,
  slide indicator in CategoryFilter, per-category grid re-animation
- AdminPanel: ESC to close, slide-in/out animation, Game/App toggle in add form,
  separate sections for games and apps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 12:59:37 +00:00

38 lines
1.6 KiB
TypeScript

import { contextBridge, ipcRenderer } from 'electron'
import type { CustomGame, AppEntry } from './config'
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>,
// 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