108 lines
2.6 KiB
JavaScript
108 lines
2.6 KiB
JavaScript
const { app, BrowserWindow, ipcMain } = require('electron')
|
|
const path = require('path')
|
|
const fs = require('fs')
|
|
|
|
const isDev = process.env.NODE_ENV !== 'production'
|
|
const devUrl = 'http://localhost:5173'
|
|
const API_URL_KEY = 'runtime_api_url'
|
|
const DEFAULT_API_URL = process.env.VITE_API_URL || 'http://localhost:4000/api'
|
|
let mainWindow
|
|
|
|
function normalizeApiUrl(value) {
|
|
if (!value || typeof value !== 'string') return null
|
|
const trimmed = value.trim().replace(/\/+$/, '')
|
|
if (!trimmed) return null
|
|
if (!/^https?:\/\//i.test(trimmed)) return null
|
|
return /\/api$/i.test(trimmed) ? trimmed : `${trimmed}/api`
|
|
}
|
|
|
|
function getStoragePath() {
|
|
return path.join(app.getPath('userData'), 'storage.json')
|
|
}
|
|
|
|
function readStorage() {
|
|
try {
|
|
const p = getStoragePath()
|
|
if (!fs.existsSync(p)) return {}
|
|
const raw = fs.readFileSync(p, 'utf8') || '{}'
|
|
return JSON.parse(raw)
|
|
} catch (e) {
|
|
return {}
|
|
}
|
|
}
|
|
|
|
function writeStorage(obj) {
|
|
try {
|
|
fs.mkdirSync(path.dirname(getStoragePath()), { recursive: true })
|
|
fs.writeFileSync(getStoragePath(), JSON.stringify(obj, null, 2), 'utf8')
|
|
return true
|
|
} catch (e) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
ipcMain.handle('storage-get', (event, key) => {
|
|
const s = readStorage()
|
|
if (!key) return s
|
|
if (!(key in s)) return null
|
|
return { value: s[key] }
|
|
})
|
|
|
|
ipcMain.handle('storage-set', (event, key, value) => {
|
|
const s = readStorage()
|
|
s[key] = value
|
|
writeStorage(s)
|
|
return true
|
|
})
|
|
|
|
ipcMain.handle('storage-remove', (event, key) => {
|
|
const s = readStorage()
|
|
delete s[key]
|
|
writeStorage(s)
|
|
return true
|
|
})
|
|
|
|
ipcMain.handle('get-api-url', () => {
|
|
const s = readStorage()
|
|
return normalizeApiUrl(s[API_URL_KEY]) || normalizeApiUrl(DEFAULT_API_URL) || 'http://localhost:4000/api'
|
|
})
|
|
|
|
ipcMain.handle('set-api-url', (event, value) => {
|
|
const next = normalizeApiUrl(value)
|
|
if (!next) throw new Error('API URL must be a valid http(s) URL')
|
|
|
|
const s = readStorage()
|
|
s[API_URL_KEY] = next
|
|
writeStorage(s)
|
|
return next
|
|
})
|
|
|
|
function createWindow() {
|
|
mainWindow = new BrowserWindow({
|
|
width: 1200,
|
|
height: 800,
|
|
webPreferences: {
|
|
preload: path.join(__dirname, 'preload.cjs'),
|
|
contextIsolation: true,
|
|
nodeIntegration: false
|
|
}
|
|
})
|
|
|
|
if (isDev) {
|
|
mainWindow.loadURL(devUrl)
|
|
mainWindow.webContents.openDevTools()
|
|
} else {
|
|
mainWindow.loadFile(path.join(__dirname, '..', 'dist', 'index.html'))
|
|
}
|
|
}
|
|
|
|
app.whenReady().then(createWindow)
|
|
|
|
app.on('window-all-closed', () => {
|
|
if (process.platform !== 'darwin') app.quit()
|
|
})
|
|
|
|
app.on('activate', () => {
|
|
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
|
})
|