diff --git a/src/lib/stores/preferences.ts b/src/lib/stores/preferences.ts index d75cfcad19..b1be575c13 100644 --- a/src/lib/stores/preferences.ts +++ b/src/lib/stores/preferences.ts @@ -6,6 +6,7 @@ import { get, writable } from 'svelte/store'; import { sdk } from './sdk'; import type { Models } from '@appwrite.io/console'; import { organization } from './organization'; +import { user } from '$lib/stores/user'; type Preferences = { limit?: number; @@ -29,12 +30,39 @@ type PreferencesStore = { }; } & { hideAiDisclaimer?: boolean }; +async function updateConsolePreferences(store: PreferencesStore): Promise { + const currentPreferences = get(user).prefs ?? (await sdk.forConsole.account.getPrefs()); + if (!currentPreferences?.console || Array.isArray(currentPreferences.console)) { + currentPreferences.console = {}; + } + + currentPreferences.console = { + ...currentPreferences.console, + ...store + }; + + await sdk.forConsole.account.updatePrefs(currentPreferences); +} + function createPreferences() { const { subscribe, set, update } = writable({}); let preferences: PreferencesStore = {}; if (browser) { - set(JSON.parse(globalThis.localStorage.getItem('preferences') ?? '{}')); + // fresh fetch. + sdk.forConsole.account + .getPrefs() + .then((userPreferences) => { + if (!userPreferences?.console || Array.isArray(userPreferences.console)) { + userPreferences.console = {}; + } + + set(userPreferences.console); + }) + .catch(() => { + // exception is thrown if there's no session; in that case - fallback! + set(JSON.parse(globalThis.localStorage.getItem('preferences') ?? '{}')); + }); } subscribe((v) => { @@ -44,6 +72,30 @@ function createPreferences() { } }); + /** + * Update the local store and then synchronizes them on user prefs. + */ + function updateAndSync(callback: (prefs: PreferencesStore) => void) { + let oldPrefsSnapshot: string; + let newPrefsSnapshot: PreferencesStore; + + update((currentPrefs) => { + oldPrefsSnapshot = JSON.stringify(currentPrefs); + callback(currentPrefs); + newPrefsSnapshot = currentPrefs; + return currentPrefs; + }); + + // Skip API if no changes (sufficient for simple objects). + // The key order seemed to be maintained during local tests. + if (oldPrefsSnapshot === JSON.stringify(newPrefsSnapshot)) { + return; + } + + // sync the preferences. + updateConsolePreferences(newPrefsSnapshot).then(); + } + return { subscribe, set, @@ -65,7 +117,7 @@ function createPreferences() { ); }, setLimit: (limit: Preferences['limit']) => - update((n) => { + updateAndSync((n) => { const path = get(page).route.id; const project = sdk.forProject.client.config.project; if (!n[project]?.[path]) { @@ -78,7 +130,7 @@ function createPreferences() { return n; }), setView: (view: Preferences['view']) => - update((n) => { + updateAndSync((n) => { const path = get(page).route.id; const project = sdk.forProject.client.config.project; if (!n[project]?.[path]) { @@ -91,7 +143,7 @@ function createPreferences() { return n; }), setColumns: (columns: Preferences['columns']) => - update((n) => { + updateAndSync((n) => { const path = get(page).route.id; const project = sdk.forProject.client.config.project; if (!n[project]?.[path]) { @@ -104,7 +156,7 @@ function createPreferences() { return n; }), setCustomCollectionColumns: (columns: Preferences['columns']) => - update((n) => { + updateAndSync((n) => { const current = get(page); const project = sdk.forProject.client.config.project; const collection = current.params.collection; diff --git a/src/lib/stores/user.ts b/src/lib/stores/user.ts index 21f0eb6367..808dd3877d 100644 --- a/src/lib/stores/user.ts +++ b/src/lib/stores/user.ts @@ -7,6 +7,7 @@ import type { NotificationPrefItem } from '$lib/helpers/notifications'; export type Account = Models.User< { organization?: string; + console: Models.Preferences; notificationPrefs: Record; } & Record >;