2026-09-21 10:54:42 -04:00
|
|
|
import { load, Store } from '@tauri-apps/plugin-store';
|
|
|
|
|
import type { CookieSource } from '$lib/bindings/dependencies';
|
|
|
|
|
|
|
|
|
|
export type { CookieSource };
|
|
|
|
|
|
2026-09-22 10:29:22 -04:00
|
|
|
export interface CaptionSettings {
|
|
|
|
|
fontFamily: string;
|
|
|
|
|
fontSize: number;
|
|
|
|
|
textColor: string;
|
|
|
|
|
bold: boolean;
|
|
|
|
|
outlineColor: string;
|
|
|
|
|
backgroundEnabled: boolean;
|
|
|
|
|
backgroundOpacity: number;
|
|
|
|
|
backgroundColor: string;
|
|
|
|
|
textOutline: boolean;
|
|
|
|
|
shadowEnabled: boolean;
|
|
|
|
|
shadowDepth: number;
|
|
|
|
|
shadowColor: string;
|
|
|
|
|
dimmedColorMode: 'auto' | 'custom';
|
|
|
|
|
dimmedOpacity: number;
|
|
|
|
|
dimmedColor: string;
|
|
|
|
|
position: 'bottom' | 'top';
|
|
|
|
|
wordHighlight: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const DEFAULT_CAPTION_SETTINGS: CaptionSettings = {
|
|
|
|
|
fontFamily: 'Arial',
|
|
|
|
|
fontSize: 18,
|
|
|
|
|
textColor: '#ffffff',
|
|
|
|
|
bold: true,
|
|
|
|
|
outlineColor: '#000000',
|
|
|
|
|
backgroundEnabled: true,
|
|
|
|
|
backgroundOpacity: 0.75,
|
|
|
|
|
backgroundColor: '#000000',
|
|
|
|
|
textOutline: true,
|
|
|
|
|
shadowEnabled: false,
|
|
|
|
|
shadowDepth: 2,
|
|
|
|
|
shadowColor: '#000000',
|
|
|
|
|
dimmedColorMode: 'auto',
|
|
|
|
|
dimmedOpacity: 0.4,
|
|
|
|
|
dimmedColor: '#999999',
|
|
|
|
|
position: 'bottom',
|
|
|
|
|
wordHighlight: true,
|
|
|
|
|
};
|
|
|
|
|
|
2026-09-21 10:54:42 -04:00
|
|
|
export interface Preferences {
|
|
|
|
|
outputDirectory: string;
|
|
|
|
|
cookieSource: CookieSource;
|
2026-09-22 10:29:22 -04:00
|
|
|
captionSettings: CaptionSettings;
|
2026-09-22 16:49:35 -04:00
|
|
|
clipListPosition: 'bottom' | 'left';
|
|
|
|
|
clipListWidth: number;
|
2026-09-21 10:54:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const DEFAULT_PREFERENCES: Preferences = {
|
|
|
|
|
outputDirectory: '~/',
|
|
|
|
|
cookieSource: { type: 'browser', browser: 'firefox' },
|
2026-09-22 10:29:22 -04:00
|
|
|
captionSettings: { ...DEFAULT_CAPTION_SETTINGS },
|
2026-09-22 16:49:35 -04:00
|
|
|
clipListPosition: 'bottom',
|
|
|
|
|
clipListWidth: 220,
|
2026-09-21 10:54:42 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let store: Store | null = null;
|
2026-09-21 10:56:08 -04:00
|
|
|
let loadPromise: Promise<void> | null = null;
|
2026-09-21 10:54:42 -04:00
|
|
|
|
|
|
|
|
export const preferences = $state<Preferences>({ ...DEFAULT_PREFERENCES });
|
|
|
|
|
|
|
|
|
|
export async function loadPreferences(): Promise<void> {
|
2026-09-21 10:56:08 -04:00
|
|
|
if (loadPromise) {
|
|
|
|
|
await loadPromise;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
loadPromise = (async () => {
|
|
|
|
|
store = await load('preferences.json', { autoSave: true });
|
|
|
|
|
const savedDir = await store.get<string>('outputDirectory');
|
|
|
|
|
const savedCookie = await store.get<CookieSource>('cookieSource');
|
2026-09-22 10:29:22 -04:00
|
|
|
const savedCaptions = await store.get<CaptionSettings>('captionSettings');
|
2026-09-21 10:56:08 -04:00
|
|
|
if (savedDir) preferences.outputDirectory = savedDir;
|
|
|
|
|
if (savedCookie) preferences.cookieSource = savedCookie;
|
2026-09-22 10:29:22 -04:00
|
|
|
if (savedCaptions) preferences.captionSettings = { ...DEFAULT_CAPTION_SETTINGS, ...savedCaptions };
|
2026-09-22 16:49:35 -04:00
|
|
|
const savedClipListPosition = await store.get<'bottom' | 'left'>('clipListPosition');
|
|
|
|
|
const savedClipListWidth = await store.get<number>('clipListWidth');
|
|
|
|
|
if (savedClipListPosition) preferences.clipListPosition = savedClipListPosition;
|
2026-09-22 16:50:57 -04:00
|
|
|
if (savedClipListWidth != null) preferences.clipListWidth = savedClipListWidth;
|
2026-09-21 10:56:08 -04:00
|
|
|
})();
|
|
|
|
|
await loadPromise;
|
2026-09-21 10:54:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function savePreferences(): Promise<void> {
|
2026-09-21 10:56:08 -04:00
|
|
|
if (!store) {
|
|
|
|
|
await loadPreferences();
|
|
|
|
|
}
|
2026-09-21 10:54:42 -04:00
|
|
|
if (!store) return;
|
|
|
|
|
await store.set('outputDirectory', preferences.outputDirectory);
|
|
|
|
|
await store.set('cookieSource', preferences.cookieSource);
|
2026-09-22 10:29:22 -04:00
|
|
|
await store.set('captionSettings', preferences.captionSettings);
|
2026-09-22 16:49:35 -04:00
|
|
|
await store.set('clipListPosition', preferences.clipListPosition);
|
|
|
|
|
await store.set('clipListWidth', preferences.clipListWidth);
|
2026-09-21 10:54:42 -04:00
|
|
|
await store.save();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function setOutputDirectory(dir: string): Promise<void> {
|
|
|
|
|
preferences.outputDirectory = dir;
|
|
|
|
|
await savePreferences();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function setCookieSource(source: CookieSource): Promise<void> {
|
|
|
|
|
preferences.cookieSource = source;
|
|
|
|
|
await savePreferences();
|
|
|
|
|
}
|
2026-09-22 10:29:22 -04:00
|
|
|
|
|
|
|
|
export async function setCaptionSettings(settings: Partial<CaptionSettings>): Promise<void> {
|
|
|
|
|
Object.assign(preferences.captionSettings, settings);
|
|
|
|
|
await savePreferences();
|
|
|
|
|
}
|
2026-09-22 16:49:35 -04:00
|
|
|
|
|
|
|
|
export async function setClipListPosition(position: 'bottom' | 'left'): Promise<void> {
|
|
|
|
|
preferences.clipListPosition = position;
|
|
|
|
|
await savePreferences();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function setClipListWidth(width: number): Promise<void> {
|
|
|
|
|
preferences.clipListWidth = width;
|
|
|
|
|
await savePreferences();
|
|
|
|
|
}
|