web: implement settings core

this was a torture
This commit is contained in:
wukko
2024-06-19 21:12:51 +06:00
parent 21e03a407c
commit 009a2cc863
6 changed files with 139 additions and 2 deletions

42
web/src/lib/settings.ts Normal file
View File

@@ -0,0 +1,42 @@
import { readable, type Updater } from 'svelte/store';
import { merge } from 'ts-deepmerge';
import type { RecursivePartial } from './types/generic';
import type { CobaltSettings } from './types/settings';
import defaultSettings from "$lib/settings/defaults";
const writeToStorage = (settings: CobaltSettings) => {
localStorage.setItem(
"settings",
JSON.stringify(settings)
);
return settings;
}
const loadFromStorage = () => {
const settings = localStorage.getItem('settings');
if (!settings) {
return writeToStorage(defaultSettings);
}
return JSON.parse(settings) as CobaltSettings;
}
let update: (_: Updater<CobaltSettings>) => void;
export default readable<CobaltSettings>(
loadFromStorage(),
(_, _update) => { update = _update }
);
// update settings from outside
export function updateSetting(settings: RecursivePartial<CobaltSettings>) {
update((current) => {
// deep merge partial type into full CobaltSettings type
current = merge(current, settings) as CobaltSettings;
return writeToStorage(current);
});
}

View File

@@ -0,0 +1,35 @@
import type { CobaltSettings } from "$lib/types/settings";
const defaultSettings: CobaltSettings = {
schemaVersion: 1,
accessibility: {
reduceAnimations: false,
reduceTransparency: false
},
appearance: {
theme: "auto"
},
general: {
customProcessingEndpoint: "",
seenOnboarding: false,
seenSafetyWarning: false
},
save: {
audioFormat: "mp3",
disableMetadata: false,
downloadMode: "auto",
downloadPopup: true,
filenameStyle: "classic",
tiktokH265: false,
tiktokFullAudio: false,
twitterGif: false,
videoQuality: "720",
youtubeVideoCodec: "h264",
youtubeDubBrowserLang: false
},
privacy: {
trafficAnalytics: true
}
}
export default defaultSettings;

View File

@@ -0,0 +1,8 @@
// more readable version of recursive partial taken from stackoverflow:
// https://stackoverflow.com/a/51365037
export type RecursivePartial<Type> = {
[Key in keyof Type]?:
Type[Key] extends (infer ElementType)[] ? RecursivePartial<ElementType>[] :
Type[Key] extends object | undefined ? RecursivePartial<Type[Key]> :
Type[Key];
};

View File

@@ -0,0 +1,41 @@
type CobaltSettingsAccessibility = {
reduceAnimations: boolean,
reduceTransparency: boolean,
};
type CobaltSettingsAppearance = {
theme: "auto" | "light" | "dark",
};
type CobaltSettingsGeneral = {
customProcessingEndpoint: string,
seenOnboarding: boolean,
seenSafetyWarning: boolean,
};
type CobaltSettingsSave = {
audioFormat: "best" | "mp3" | "ogg" | "wav" | "opus",
disableMetadata: boolean,
downloadMode: "auto" | "audio" | "mute",
downloadPopup: boolean,
filenameStyle: "classic" | "basic" | "pretty" | "nerdy",
tiktokH265: boolean,
tiktokFullAudio: boolean,
twitterGif: boolean,
videoQuality: "max" | "2160" | "1440" | "1080" | "720" | "360" | "240" | "144",
youtubeVideoCodec: "h264" | "av1" | "vp9",
youtubeDubBrowserLang: boolean,
};
type CobaltSettingsPrivacy = {
trafficAnalytics: boolean,
};
export type CobaltSettings = {
schemaVersion: number,
accessibility: CobaltSettingsAccessibility,
appearance: CobaltSettingsAppearance,
general: CobaltSettingsGeneral,
save: CobaltSettingsSave,
privacy: CobaltSettingsPrivacy,
};