155 lines
4.5 KiB
JavaScript
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 };
|