mirror of
https://github.com/dream-pep/koring-launcher.git
synced 2026-09-12 05:45:18 +08:00
Introduce crash monitoring and an OOBE onboarding flow. Adds a crash logger (koring-crash.log), crash-monitor handler/window, preload-crash bridge, crash UI (crash.html, src/crash.tsx, pages/crash) and a debug page. Main process now sets up crash listeners, startup checks (first-launch, .minecraft), and a config reset/factory-reset that removes Koring.yml, koring-auth.json and background cache and can relaunch the app. Exposes config preloading to renderer, adds OOBE pages/layout, confirm dialog store/UI, trims Silk renderer settings, bumps version to 1.0.1 and adds motion dependency, and registers crash.html in Vite. Various related type and config updates included.
91 lines
3.2 KiB
TypeScript
91 lines
3.2 KiB
TypeScript
import electron from 'electron';
|
|
import path from 'path';
|
|
import fs from 'fs';
|
|
const { contextBridge, ipcRenderer } = electron;
|
|
|
|
const MIME_MAP: Record<string, string> = {
|
|
'.png': 'image/png',
|
|
'.jpg': 'image/jpeg',
|
|
'.jpeg': 'image/jpeg',
|
|
'.webp': 'image/webp',
|
|
'.gif': 'image/gif',
|
|
'.bmp': 'image/bmp',
|
|
};
|
|
|
|
function getFileAsDataUrl(filePath: string): string | null {
|
|
try {
|
|
const buffer = fs.readFileSync(filePath);
|
|
const ext = path.extname(filePath).toLowerCase();
|
|
const mime = MIME_MAP[ext] || 'image/png';
|
|
return `data:${mime};base64,${buffer.toString('base64')}`;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
contextBridge.exposeInMainWorld('electronAPI', {
|
|
// Generic IPC
|
|
invoke: (channel: string, ...args: unknown[]) =>
|
|
ipcRenderer.invoke(channel, ...args),
|
|
|
|
on: (channel: string, callback: (...args: unknown[]) => void) => {
|
|
const handler = (_event: Electron.IpcRendererEvent, ...args: unknown[]) => callback(...args);
|
|
ipcRenderer.on(channel, handler);
|
|
return () => ipcRenderer.removeListener(channel, handler);
|
|
},
|
|
|
|
send: (channel: string, ...args: unknown[]) =>
|
|
ipcRenderer.send(channel, ...args),
|
|
|
|
// Window controls
|
|
minimize: () => ipcRenderer.invoke('window:minimize'),
|
|
maximize: () => ipcRenderer.invoke('window:maximize'),
|
|
close: () => ipcRenderer.invoke('window:close'),
|
|
isMaximized: () => ipcRenderer.invoke('window:isMaximized'),
|
|
onResized: (callback: () => void) => {
|
|
const handler = () => callback();
|
|
ipcRenderer.on('window:resized', handler);
|
|
return () => ipcRenderer.removeListener('window:resized', handler);
|
|
},
|
|
|
|
// Theme
|
|
getTheme: () => ipcRenderer.invoke('window:getTheme'),
|
|
|
|
// Config preloading
|
|
onConfigPreload: (callback: (data: { config: unknown; isFirstLaunch: boolean }) => void) => {
|
|
const handler = (_event: Electron.IpcRendererEvent, data: { config: unknown; isFirstLaunch: boolean }) => callback(data);
|
|
ipcRenderer.on('config:preload', handler);
|
|
return () => ipcRenderer.removeListener('config:preload', handler);
|
|
},
|
|
|
|
// Background image — pick file, copy to userData, return base64 data URL
|
|
pickBackgroundImage: async (): Promise<string | null> => {
|
|
const result = await ipcRenderer.invoke('dialog:openFile', {
|
|
filters: [{ name: '图片', extensions: ['png', 'jpg', 'jpeg', 'webp', 'gif', 'bmp'] }],
|
|
});
|
|
if (!result) return null;
|
|
const { srcPath, ext } = result as { srcPath: string; ext: string };
|
|
// Copy to userData via main process
|
|
const destPath = await ipcRenderer.invoke('background:copyToUserData', srcPath, ext);
|
|
if (!destPath) return null;
|
|
return getFileAsDataUrl(destPath);
|
|
},
|
|
|
|
// Get cached background as base64 data URL
|
|
getBackgroundDataUrl: async (): Promise<string | null> => {
|
|
const filePath = await ipcRenderer.invoke('background:getCachedPath');
|
|
if (!filePath) return null;
|
|
return getFileAsDataUrl(filePath);
|
|
},
|
|
|
|
// Open external URL in system browser
|
|
openExternal: (url: string) => ipcRenderer.invoke('shell:openExternal', url),
|
|
|
|
// Crash monitoring — devtools only
|
|
simulateCrash: () => ipcRenderer.invoke('crash:simulate'),
|
|
testCrashDialog: () => ipcRenderer.invoke('crash:testDialog'),
|
|
|
|
// Config reset
|
|
resetConfig: () => ipcRenderer.invoke('config:reset'),
|
|
});
|