219 lines
6.4 KiB
TypeScript
219 lines
6.4 KiB
TypeScript
import { app } from 'electron';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
export type AutoUpdateMode = 'auto' | 'off' | 'version';
|
|
|
|
export interface LocalApiSettings {
|
|
enabled: boolean;
|
|
port: number;
|
|
exposeOnLan: boolean;
|
|
scalarEnabled: boolean;
|
|
allowedSignalingServers: string[];
|
|
}
|
|
|
|
export interface DesktopSettings {
|
|
autoUpdateMode: AutoUpdateMode;
|
|
autoStart: boolean;
|
|
closeToTray: boolean;
|
|
hardwareAcceleration: boolean;
|
|
localApi: LocalApiSettings;
|
|
manifestUrls: string[];
|
|
preferredVersion: string | null;
|
|
vaapiVideoEncode: boolean;
|
|
}
|
|
|
|
export interface DesktopSettingsSnapshot extends DesktopSettings {
|
|
runtimeHardwareAcceleration: boolean;
|
|
restartRequired: boolean;
|
|
}
|
|
|
|
const DEFAULT_LOCAL_API_SETTINGS: LocalApiSettings = {
|
|
enabled: false,
|
|
port: 17878,
|
|
exposeOnLan: false,
|
|
scalarEnabled: false,
|
|
allowedSignalingServers: []
|
|
};
|
|
|
|
const DEFAULT_DESKTOP_SETTINGS: DesktopSettings = {
|
|
autoUpdateMode: 'auto',
|
|
autoStart: true,
|
|
closeToTray: true,
|
|
hardwareAcceleration: true,
|
|
localApi: { ...DEFAULT_LOCAL_API_SETTINGS },
|
|
manifestUrls: [],
|
|
preferredVersion: null,
|
|
vaapiVideoEncode: false
|
|
};
|
|
|
|
function normalizeAutoUpdateMode(value: unknown): AutoUpdateMode {
|
|
return value === 'off' || value === 'version' ? value : 'auto';
|
|
}
|
|
|
|
function normalizePreferredVersion(value: unknown): string | null {
|
|
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null;
|
|
}
|
|
|
|
function normalizeManifestUrls(value: unknown): string[] {
|
|
if (!Array.isArray(value)) {
|
|
return [];
|
|
}
|
|
|
|
const manifestUrls: string[] = [];
|
|
|
|
for (const entry of value) {
|
|
if (typeof entry !== 'string') {
|
|
continue;
|
|
}
|
|
|
|
const nextUrl = entry.trim();
|
|
|
|
if (!nextUrl || manifestUrls.includes(nextUrl)) {
|
|
continue;
|
|
}
|
|
|
|
manifestUrls.push(nextUrl);
|
|
}
|
|
|
|
return manifestUrls;
|
|
}
|
|
|
|
function normalizePort(value: unknown, fallback: number): number {
|
|
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
return fallback;
|
|
}
|
|
|
|
const port = Math.floor(value);
|
|
|
|
if (port < 1 || port > 65535) {
|
|
return fallback;
|
|
}
|
|
|
|
return port;
|
|
}
|
|
|
|
function normalizeAllowedSignalingServers(value: unknown): string[] {
|
|
if (!Array.isArray(value)) {
|
|
return [];
|
|
}
|
|
|
|
const urls: string[] = [];
|
|
|
|
for (const entry of value) {
|
|
if (typeof entry !== 'string') {
|
|
continue;
|
|
}
|
|
|
|
const trimmed = entry.trim().replace(/\/+$/u, '');
|
|
|
|
if (!trimmed || urls.includes(trimmed)) {
|
|
continue;
|
|
}
|
|
|
|
if (!/^https?:\/\//iu.test(trimmed)) {
|
|
continue;
|
|
}
|
|
|
|
urls.push(trimmed);
|
|
}
|
|
|
|
return urls;
|
|
}
|
|
|
|
function normalizeLocalApiSettings(value: unknown): LocalApiSettings {
|
|
const source = (value && typeof value === 'object') ? value as Partial<LocalApiSettings> : {};
|
|
|
|
return {
|
|
enabled: typeof source.enabled === 'boolean' ? source.enabled : DEFAULT_LOCAL_API_SETTINGS.enabled,
|
|
port: normalizePort(source.port, DEFAULT_LOCAL_API_SETTINGS.port),
|
|
exposeOnLan: typeof source.exposeOnLan === 'boolean' ? source.exposeOnLan : DEFAULT_LOCAL_API_SETTINGS.exposeOnLan,
|
|
scalarEnabled: typeof source.scalarEnabled === 'boolean' ? source.scalarEnabled : DEFAULT_LOCAL_API_SETTINGS.scalarEnabled,
|
|
allowedSignalingServers: normalizeAllowedSignalingServers(source.allowedSignalingServers)
|
|
};
|
|
}
|
|
|
|
export function getDesktopSettingsSnapshot(): DesktopSettingsSnapshot {
|
|
const storedSettings = readDesktopSettings();
|
|
const runtimeHardwareAcceleration = app.isHardwareAccelerationEnabled();
|
|
|
|
return {
|
|
...storedSettings,
|
|
runtimeHardwareAcceleration,
|
|
restartRequired: storedSettings.hardwareAcceleration !== runtimeHardwareAcceleration
|
|
};
|
|
}
|
|
|
|
export function readDesktopSettings(): DesktopSettings {
|
|
const filePath = getDesktopSettingsPath();
|
|
|
|
try {
|
|
if (!fs.existsSync(filePath)) {
|
|
return { ...DEFAULT_DESKTOP_SETTINGS };
|
|
}
|
|
|
|
const raw = fs.readFileSync(filePath, 'utf8');
|
|
const parsed = JSON.parse(raw) as Partial<DesktopSettings>;
|
|
|
|
return {
|
|
autoUpdateMode: normalizeAutoUpdateMode(parsed.autoUpdateMode),
|
|
autoStart: typeof parsed.autoStart === 'boolean'
|
|
? parsed.autoStart
|
|
: DEFAULT_DESKTOP_SETTINGS.autoStart,
|
|
closeToTray: typeof parsed.closeToTray === 'boolean'
|
|
? parsed.closeToTray
|
|
: DEFAULT_DESKTOP_SETTINGS.closeToTray,
|
|
vaapiVideoEncode: typeof parsed.vaapiVideoEncode === 'boolean'
|
|
? parsed.vaapiVideoEncode
|
|
: DEFAULT_DESKTOP_SETTINGS.vaapiVideoEncode,
|
|
hardwareAcceleration: typeof parsed.hardwareAcceleration === 'boolean'
|
|
? parsed.hardwareAcceleration
|
|
: DEFAULT_DESKTOP_SETTINGS.hardwareAcceleration,
|
|
localApi: normalizeLocalApiSettings(parsed.localApi),
|
|
manifestUrls: normalizeManifestUrls(parsed.manifestUrls),
|
|
preferredVersion: normalizePreferredVersion(parsed.preferredVersion)
|
|
};
|
|
} catch {
|
|
return { ...DEFAULT_DESKTOP_SETTINGS };
|
|
}
|
|
}
|
|
|
|
export function updateDesktopSettings(patch: Partial<DesktopSettings>): DesktopSettingsSnapshot {
|
|
const previousSettings = readDesktopSettings();
|
|
const mergedSettings = {
|
|
...previousSettings,
|
|
...patch,
|
|
localApi: patch.localApi
|
|
? { ...previousSettings.localApi, ...patch.localApi }
|
|
: previousSettings.localApi
|
|
};
|
|
const nextSettings: DesktopSettings = {
|
|
autoUpdateMode: normalizeAutoUpdateMode(mergedSettings.autoUpdateMode),
|
|
autoStart: typeof mergedSettings.autoStart === 'boolean'
|
|
? mergedSettings.autoStart
|
|
: DEFAULT_DESKTOP_SETTINGS.autoStart,
|
|
closeToTray: typeof mergedSettings.closeToTray === 'boolean'
|
|
? mergedSettings.closeToTray
|
|
: DEFAULT_DESKTOP_SETTINGS.closeToTray,
|
|
hardwareAcceleration: typeof mergedSettings.hardwareAcceleration === 'boolean'
|
|
? mergedSettings.hardwareAcceleration
|
|
: DEFAULT_DESKTOP_SETTINGS.hardwareAcceleration,
|
|
localApi: normalizeLocalApiSettings(mergedSettings.localApi),
|
|
manifestUrls: normalizeManifestUrls(mergedSettings.manifestUrls),
|
|
preferredVersion: normalizePreferredVersion(mergedSettings.preferredVersion),
|
|
vaapiVideoEncode: typeof mergedSettings.vaapiVideoEncode === 'boolean'
|
|
? mergedSettings.vaapiVideoEncode
|
|
: DEFAULT_DESKTOP_SETTINGS.vaapiVideoEncode
|
|
};
|
|
const filePath = getDesktopSettingsPath();
|
|
|
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
fs.writeFileSync(filePath, JSON.stringify(nextSettings, null, 2), 'utf8');
|
|
|
|
return getDesktopSettingsSnapshot();
|
|
}
|
|
|
|
function getDesktopSettingsPath(): string {
|
|
return path.join(app.getPath('userData'), 'desktop-settings.json');
|
|
}
|