|
import { browser } from "$app/environment"; |
|
import { invalidate } from "$app/navigation"; |
|
import { base } from "$app/paths"; |
|
import { UrlDependency } from "$lib/types/UrlDependency"; |
|
import type { ObjectId } from "mongodb"; |
|
import { getContext, setContext } from "svelte"; |
|
import { type Writable, writable, get } from "svelte/store"; |
|
|
|
type SettingsStore = { |
|
shareConversationsWithModelAuthors: boolean; |
|
hideEmojiOnSidebar: boolean; |
|
ethicsModalAccepted: boolean; |
|
ethicsModalAcceptedAt: Date | null; |
|
activeModel: string; |
|
customPrompts: Record<string, string>; |
|
recentlySaved: boolean; |
|
assistants: Array<ObjectId | string>; |
|
}; |
|
|
|
type SettingsStoreWritable = Writable<SettingsStore> & { |
|
instantSet: (settings: Partial<SettingsStore>) => Promise<void>; |
|
}; |
|
|
|
export function useSettingsStore() { |
|
return getContext<SettingsStoreWritable>("settings"); |
|
} |
|
|
|
export function createSettingsStore(initialValue: Omit<SettingsStore, "recentlySaved">) { |
|
const baseStore = writable({ ...initialValue, recentlySaved: false }); |
|
|
|
let timeoutId: NodeJS.Timeout; |
|
|
|
async function setSettings(settings: Partial<SettingsStore>) { |
|
baseStore.update((s) => ({ |
|
...s, |
|
...settings, |
|
})); |
|
|
|
clearTimeout(timeoutId); |
|
|
|
if (browser) { |
|
timeoutId = setTimeout(async () => { |
|
await fetch(`${base}/settings`, { |
|
method: "POST", |
|
headers: { |
|
"Content-Type": "application/json", |
|
}, |
|
body: JSON.stringify({ |
|
...get(baseStore), |
|
...settings, |
|
}), |
|
}); |
|
|
|
invalidate(UrlDependency.ConversationList); |
|
|
|
baseStore.update((s) => ({ |
|
...s, |
|
recentlySaved: true, |
|
})); |
|
setTimeout(() => { |
|
baseStore.update((s) => ({ |
|
...s, |
|
recentlySaved: false, |
|
})); |
|
}, 3000); |
|
invalidate(UrlDependency.ConversationList); |
|
}, 300); |
|
|
|
} |
|
} |
|
async function instantSet(settings: Partial<SettingsStore>) { |
|
baseStore.update((s) => ({ |
|
...s, |
|
...settings, |
|
})); |
|
|
|
if (browser) { |
|
await fetch(`${base}/settings`, { |
|
method: "POST", |
|
headers: { |
|
"Content-Type": "application/json", |
|
}, |
|
body: JSON.stringify({ |
|
...get(baseStore), |
|
...settings, |
|
}), |
|
}); |
|
invalidate(UrlDependency.ConversationList); |
|
} |
|
} |
|
|
|
const newStore = { |
|
subscribe: baseStore.subscribe, |
|
set: setSettings, |
|
instantSet, |
|
update: (fn: (s: SettingsStore) => SettingsStore) => { |
|
setSettings(fn(get(baseStore))); |
|
}, |
|
} satisfies SettingsStoreWritable; |
|
|
|
setContext("settings", newStore); |
|
|
|
return newStore; |
|
} |
|
|