smoothie/src/lib/settings.js
2026-03-09 20:15:49 +01:00

155 lines
4.5 KiB
JavaScript

import { LazyStore } from '@tauri-apps/plugin-store';
import { writable, get } from 'svelte/store';
import { platform, arch } from '@tauri-apps/plugin-os';
import { appDataDir } from '@tauri-apps/api/path';
import { ensureLibraryStructure, selectDirectory } from './file_utils.js';
// Define the settings structure
/** @typedef {Object} Settings
* @property {string} [libraryDir] - Path to library directory
* @property {string} [defaultPlatform] - Default platform ('auto', 'windows', 'linux', 'macos')
* @property {string} [defaultArch] - Default architecture ('x86_64', 'arm64', etc.)
* @property {string} [theme] - Theme ('light', 'dark')
* @property {boolean} [autoCreateShortcuts] - should smoothie create a shortcut to newly installed blender versions
* @property {boolean} [keepDownloadedArchives] - Whether to keep downloaded archives after extraction
*/
// Settings lazy store
const settingsStore = new LazyStore('settings.json');
export const currentSettings = writable(/** @type {Settings} */ ({}));
export const BASE_LIBRARY_DIR = 'smoothie-library';
let DEFAULT_SETTINGS = null;
export async function initSettings() {
const detectedPlatform = await detectPlatform();
const detectedArch = await detectArch();
const defaultLibraryDir = await appDataDir();
DEFAULT_SETTINGS = {
libraryDir: defaultLibraryDir, // Will be filled with default library directory
defaultPlatform: detectedPlatform, //Automatic
defaultArch: detectedArch,
keepDownloadedArchives: false,
autoCreateShortcuts: true,
theme: 'light' //
};
}
/**
* Get the current settings, filling with defaults if missing.
* @returns {Promise<Settings>}
*/
export async function getSettings() {
if (DEFAULT_SETTINGS === null) {
await initSettings();
}
try {
// Get all stored values
const storeEntries = await settingsStore.entries();
// Store empty, load defaults
if (storeEntries.length === 0) {
await resetSettings();
}
//load settings object and patch with defaults for missing fields
const settings = Object.fromEntries(storeEntries);
const filledSettings = { ...DEFAULT_SETTINGS, ...settings };
currentSettings.set(filledSettings);
await ensureLibraryStructure(filledSettings.libraryDir);
return filledSettings;
} catch (error) {
console.error('Error loading settings:', error);
currentSettings.set(DEFAULT_SETTINGS);
return DEFAULT_SETTINGS;
}
}
/**
* @typedef {Partial<Settings>} PartialSettings
*/
export async function saveSettings(newSettings) {
try {
for (const [key, value] of Object.entries(newSettings)) {
await settingsStore.set(key, value);
}
if (newSettings.libraryDir) {
//if new library dir check it
await ensureLibraryStructure(newSettings.libraryDir);
}
await settingsStore.save();
let completeSettings = { ...get(currentSettings), ...newSettings };
currentSettings.set(completeSettings);
} catch (error) {
console.error('Error saving settings:', error);
throw error;
}
}
/**
* Clear store and reset all settings to defaults.
* @returns {Promise<Settings>}
*/
export async function resetSettings() {
try {
await settingsStore.clear();
await saveSettings(DEFAULT_SETTINGS);
return DEFAULT_SETTINGS;
} catch (error) {
console.error('Error resetting settings:', error);
throw error;
}
}
/**
* Detect the current platform, mapping to our supported values.
* @returns {Promise<string>} 'windows', 'linux', or 'macos'
*/
async function detectPlatform() {
try {
const currentPlatform = platform();
// Map from OS plugin values to our settings values (desktop only)
const platformMap = {
linux: 'linux',
windows: 'windows',
darwin: 'macos',
macos: 'macos'
};
// Only desktop platforms are supported
if (currentPlatform in platformMap) {
return currentPlatform;
}
console.warn(`Platform "${currentPlatform}" is not supported, defaulting to linux`);
return 'linux';
} catch (error) {
console.error('Error detecting platform:', error);
return 'linux'; // fallback
}
}
/**
* Detect the current platform, mapping to our supported values.
* @returns {Promise<string>} 'windows', 'linux', or 'macos'
*/
async function detectArch() {
try {
const currentArch = arch();
const archmap = {
x86_64: 'x64',
arm: 'arm64',
aarch64: 'arm64'
};
if (currentArch in archmap) {
return currentArch;
}
console.warn(`Architecture "${currentArch}" is not supported, defaulting to x64`);
return 'x64';
} catch (error) {
console.error('Error detecting platform:', error);
return 'linux'; // fallback
}
}
export { selectDirectory };