fleeting-garden/src/settings.ts
2026-05-22 07:54:38 +01:00

69 lines
1.9 KiB
TypeScript

import {
appConfig,
normalizeRuntimeSettings,
type GardenRuntimeSettings,
} from './config';
import { writeBrowserStorage } from './utils/browser-storage';
import { getInitialVibe, type VibePreset } from './vibes';
const preservedRuntimeSettingKeys = [
'eraserSize',
'adaptiveCapInitial',
'adaptiveCapMin',
'internalRenderAreaMegapixels',
'maxAgentCount',
'mirrorSegmentCount',
] satisfies ReadonlyArray<keyof GardenRuntimeSettings>;
const cloneRgbColor = <T extends [number, number, number]>(color: T): T =>
[...color] as T;
const cloneVibePreset = (vibe: VibePreset): VibePreset => ({
...vibe,
colors: vibe.colors.map(cloneRgbColor) as VibePreset['colors'],
backgroundColor: cloneRgbColor(vibe.backgroundColor),
settings: { ...vibe.settings },
audio: { ...vibe.audio },
});
const buildSettings = (vibe: VibePreset): GardenRuntimeSettings =>
normalizeRuntimeSettings(
{
...appConfig.defaultSettings,
eraserSize: appConfig.toolbar.eraser.default,
mirrorSegmentCount: appConfig.toolbar.mirror.default,
...vibe.settings,
},
appConfig.runtimeSettings.controls
);
export let activeVibe = cloneVibePreset(getInitialVibe());
export const settings: GardenRuntimeSettings = {
...buildSettings(activeVibe),
};
export const rememberActiveVibeSelection = (): void => {
writeBrowserStorage(appConfig.storage.vibeKey, activeVibe.id);
};
export const applyVibeSettings = (vibe: VibePreset) => {
activeVibe = cloneVibePreset(vibe);
const nextSettings = buildSettings(activeVibe);
preservedRuntimeSettingKeys.forEach((key) => {
nextSettings[key] = settings[key];
});
nextSettings.selectedColorIndex = Math.min(
settings.selectedColorIndex,
activeVibe.colors.length - 1
);
Object.assign(
settings,
normalizeRuntimeSettings(nextSettings, appConfig.runtimeSettings.controls)
);
rememberActiveVibeSelection();
return activeVibe;
};