184 lines
4.5 KiB
JavaScript
184 lines
4.5 KiB
JavaScript
import { app, BrowserWindow, ipcMain, dialog } from 'electron';
|
|
import { fileURLToPath } from 'url';
|
|
import { dirname, join, resolve } from 'path';
|
|
import { existsSync, readFileSync, writeFile, writeFileSync } from 'fs';
|
|
import pkg from 'electron-updater';
|
|
|
|
const { autoUpdater } = pkg;
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
|
|
function getCarOptionsPath() {
|
|
return app.isPackaged
|
|
? join(process.resourcesPath, 'carOptions.json')
|
|
: resolve(__dirname, '..', 'src', 'frontend', 'carOptions.json');
|
|
}
|
|
|
|
function getSharedCarsPath() {
|
|
return join(getDefaultCarsFolder(), 'shared-cars.json');
|
|
}
|
|
|
|
function getSettingsPath() {
|
|
return join(app.getPath('userData'), 'kenteken-settings.json');
|
|
}
|
|
|
|
function getDefaultCarsFolder() {
|
|
return app.isPackaged
|
|
? app.getPath('userData')
|
|
: resolve(__dirname, '..');
|
|
}
|
|
|
|
function normalizeCarsFolder(folder) {
|
|
if (!folder || typeof folder !== 'string') {
|
|
return '';
|
|
}
|
|
if (!existsSync(folder)) {
|
|
return '';
|
|
}
|
|
return folder;
|
|
}
|
|
|
|
function loadSettings() {
|
|
// Persist the chosen cars folder so users can keep using the same location.
|
|
try {
|
|
const raw = readFileSync(getSettingsPath(), 'utf-8');
|
|
const parsed = JSON.parse(raw);
|
|
const carsFolder = normalizeCarsFolder(parsed?.carsFolder);
|
|
return { carsFolder };
|
|
} catch {
|
|
return { carsFolder: '' };
|
|
}
|
|
}
|
|
|
|
function saveSettings(nextSettings) {
|
|
writeFileSync(getSettingsPath(), JSON.stringify(nextSettings, null, 2));
|
|
}
|
|
|
|
function getCarsFolder() {
|
|
return settings.carsFolder || getDefaultCarsFolder();
|
|
}
|
|
|
|
function setCarsFolder(folder) {
|
|
const normalized = normalizeCarsFolder(folder);
|
|
settings.carsFolder = normalized;
|
|
saveSettings(settings);
|
|
storeFile = join(getCarsFolder(), 'shared-cars.json');
|
|
}
|
|
|
|
function loadBaseCarOptions() {
|
|
const p = getCarOptionsPath();
|
|
const json = readFileSync(p, 'utf-8');
|
|
return JSON.parse(json);
|
|
}
|
|
|
|
function createWindow() {
|
|
const win = new BrowserWindow({
|
|
width: 1024,
|
|
height: 768,
|
|
webPreferences: {
|
|
contextIsolation: true,
|
|
nodeIntegration: false,
|
|
preload: join(__dirname, 'preload.cjs'),
|
|
},
|
|
});
|
|
|
|
if (app.isPackaged) {
|
|
win.loadFile(join(__dirname, '../dist/index.html'));
|
|
} else {
|
|
win.loadURL('http://localhost:5173');
|
|
win.webContents.openDevTools();
|
|
}
|
|
}
|
|
|
|
let storeFile;
|
|
let cars = [];
|
|
let saveTimer;
|
|
let settings = { carsFolder: '' };
|
|
|
|
function loadCars() {
|
|
try {
|
|
const data = JSON.parse(readFileSync(storeFile, 'utf-8'));
|
|
if (!Array.isArray(data)) throw new Error('Invalid data');
|
|
if (
|
|
!data.every(
|
|
(c) =>
|
|
typeof c.name === 'string' &&
|
|
typeof c.width === 'number' &&
|
|
typeof c.height === 'number'
|
|
)
|
|
) {
|
|
throw new Error('Invalid schema');
|
|
}
|
|
cars = data;
|
|
} catch {
|
|
cars = loadBaseCarOptions();
|
|
saveCars(cars, true);
|
|
}
|
|
return cars;
|
|
}
|
|
|
|
function saveCars(newCars, immediate = false) {
|
|
cars = newCars;
|
|
const write = () =>
|
|
writeFile(storeFile, JSON.stringify(cars, null, 2), () => {});
|
|
if (immediate) {
|
|
write();
|
|
} else {
|
|
clearTimeout(saveTimer);
|
|
saveTimer = setTimeout(write, 250);
|
|
}
|
|
}
|
|
|
|
ipcMain.handle('cars:load', () => loadCars());
|
|
ipcMain.handle('cars:save', (_e, newCars) => {
|
|
saveCars(newCars);
|
|
return cars;
|
|
});
|
|
ipcMain.handle('cars:folder:get', () => getCarsFolder());
|
|
ipcMain.handle('cars:folder:select', async () => {
|
|
const result = await dialog.showOpenDialog({
|
|
properties: ['openDirectory', 'createDirectory'],
|
|
});
|
|
if (result.canceled || !result.filePaths?.[0]) {
|
|
return { canceled: true, folder: getCarsFolder(), cars };
|
|
}
|
|
setCarsFolder(result.filePaths[0]);
|
|
const updatedCars = loadCars();
|
|
return { canceled: false, folder: getCarsFolder(), cars: updatedCars };
|
|
});
|
|
ipcMain.handle('cars:folder:reset', () => {
|
|
settings.carsFolder = '';
|
|
saveSettings(settings);
|
|
storeFile = getSharedCarsPath();
|
|
const updatedCars = loadCars();
|
|
return { folder: getCarsFolder(), cars: updatedCars };
|
|
});
|
|
|
|
app.whenReady().then(() => {
|
|
settings = loadSettings();
|
|
storeFile = settings.carsFolder
|
|
? join(getCarsFolder(), 'shared-cars.json')
|
|
: getSharedCarsPath();
|
|
loadCars();
|
|
createWindow();
|
|
|
|
try {
|
|
autoUpdater.checkForUpdatesAndNotify();
|
|
} catch (e) {
|
|
// fail silently
|
|
}
|
|
|
|
app.on('activate', () => {
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
|
createWindow();
|
|
}
|
|
});
|
|
});
|
|
|
|
app.on('window-all-closed', () => {
|
|
if (process.platform !== 'darwin') {
|
|
app.quit();
|
|
}
|
|
});
|