From fe8113e8d1705752c99d0716a00b529026c44ce3 Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 8 Feb 2025 19:08:53 +0530 Subject: [PATCH 1/8] update: sync preferences from local to users. --- src/lib/stores/preferences.ts | 55 +++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/src/lib/stores/preferences.ts b/src/lib/stores/preferences.ts index d75cfcad1..931d95f4c 100644 --- a/src/lib/stores/preferences.ts +++ b/src/lib/stores/preferences.ts @@ -29,12 +29,33 @@ type PreferencesStore = { }; } & { hideAiDisclaimer?: boolean }; +async function updateConsolePreferences(store: PreferencesStore): Promise { + const currentPreferences = 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); + }); } subscribe((v) => { @@ -44,6 +65,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 +110,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 +123,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 +136,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 +149,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; From 23911a8e8dc9e732d1619d107cc8d6e4a563f46d Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 8 Feb 2025 19:28:39 +0530 Subject: [PATCH 2/8] update: use `user` store prefs if available. --- src/lib/stores/preferences.ts | 3 ++- src/lib/stores/user.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/stores/preferences.ts b/src/lib/stores/preferences.ts index 931d95f4c..b1b7ed15e 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; @@ -30,7 +31,7 @@ type PreferencesStore = { } & { hideAiDisclaimer?: boolean }; async function updateConsolePreferences(store: PreferencesStore): Promise { - const currentPreferences = await sdk.forConsole.account.getPrefs(); + const currentPreferences = get(user).prefs ?? (await sdk.forConsole.account.getPrefs()); if (!currentPreferences?.console || Array.isArray(currentPreferences.console)) { currentPreferences.console = {}; } diff --git a/src/lib/stores/user.ts b/src/lib/stores/user.ts index 21f0eb636..046551fe9 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: Record; notificationPrefs: Record; } & Record >; From cb0ad218f49df3ff3da8eba8a4843d8ce7ddae5d Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 8 Feb 2025 19:48:57 +0530 Subject: [PATCH 3/8] fix: tests ^_^. --- src/lib/stores/preferences.ts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/lib/stores/preferences.ts b/src/lib/stores/preferences.ts index b1b7ed15e..34c30bc11 100644 --- a/src/lib/stores/preferences.ts +++ b/src/lib/stores/preferences.ts @@ -37,7 +37,7 @@ async function updateConsolePreferences(store: PreferencesStore): Promise } currentPreferences.console = { - ...(currentPreferences['console'] ?? {}), + ...(currentPreferences.console ?? {}), ...store }; @@ -50,13 +50,19 @@ function createPreferences() { if (browser) { // fresh fetch. - sdk.forConsole.account.getPrefs().then((userPreferences) => { - if (!userPreferences?.console || Array.isArray(userPreferences.console)) { - userPreferences.console = {}; - } + sdk.forConsole.account + .getPrefs() + .then((userPreferences) => { + if (!userPreferences?.console || Array.isArray(userPreferences.console)) { + userPreferences.console = {}; + } - set(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) => { From fbc75f39a6d05acf565c2bff3168c6c91d34ab68 Mon Sep 17 00:00:00 2001 From: Darshan Date: Mon, 10 Feb 2025 13:31:49 +0530 Subject: [PATCH 4/8] fix: the `console` pref type. --- src/lib/stores/user.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/stores/user.ts b/src/lib/stores/user.ts index 046551fe9..808dd3877 100644 --- a/src/lib/stores/user.ts +++ b/src/lib/stores/user.ts @@ -7,7 +7,7 @@ import type { NotificationPrefItem } from '$lib/helpers/notifications'; export type Account = Models.User< { organization?: string; - console: Record; + console: Models.Preferences; notificationPrefs: Record; } & Record >; From fa0c76e6a344625d42557bd1c9151e68edefc46b Mon Sep 17 00:00:00 2001 From: Darshan Date: Thu, 6 Mar 2025 17:37:22 +0530 Subject: [PATCH 5/8] address comment. --- src/lib/stores/preferences.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/stores/preferences.ts b/src/lib/stores/preferences.ts index 34c30bc11..b1be575c1 100644 --- a/src/lib/stores/preferences.ts +++ b/src/lib/stores/preferences.ts @@ -37,7 +37,7 @@ async function updateConsolePreferences(store: PreferencesStore): Promise } currentPreferences.console = { - ...(currentPreferences.console ?? {}), + ...currentPreferences.console, ...store }; From 8fd8aa530815e0c957c0d8819dddb4eb1f55482b Mon Sep 17 00:00:00 2001 From: Darshan Date: Tue, 3 Jun 2025 17:10:55 +0530 Subject: [PATCH 6/8] lint. --- src/lib/stores/preferences.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/stores/preferences.ts b/src/lib/stores/preferences.ts index 375e85ce9..b75208949 100644 --- a/src/lib/stores/preferences.ts +++ b/src/lib/stores/preferences.ts @@ -153,7 +153,6 @@ function createPreferences() { }), setCustomCollectionColumns: (columns: Preferences['columns']) => updateAndSync((n) => { - const collection = page.params.collection; if (!n?.collections?.[collection]) { n ??= {}; From 15078626bab6bab09aed12f95dd68d5a0a971025 Mon Sep 17 00:00:00 2001 From: Darshan Date: Tue, 3 Jun 2025 18:55:12 +0530 Subject: [PATCH 7/8] address comments. --- src/lib/stores/preferences.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lib/stores/preferences.ts b/src/lib/stores/preferences.ts index b75208949..c144c24bc 100644 --- a/src/lib/stores/preferences.ts +++ b/src/lib/stores/preferences.ts @@ -7,6 +7,7 @@ import type { Models } from '@appwrite.io/console'; import { organization } from './organization'; import { page } from '$app/state'; import { user } from '$lib/stores/user'; +import deepEqual from 'deep-equal'; type Preferences = { limit?: number; @@ -74,19 +75,17 @@ function createPreferences() { * Update the local store and then synchronizes them on user prefs. */ function updateAndSync(callback: (prefs: PreferencesStore) => void) { - let oldPrefsSnapshot: string; + let oldPrefsSnapshot: PreferencesStore; let newPrefsSnapshot: PreferencesStore; update((currentPrefs) => { - oldPrefsSnapshot = JSON.stringify(currentPrefs); + oldPrefsSnapshot = 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)) { + if (deepEqual(oldPrefsSnapshot, newPrefsSnapshot)) { return; } From c6bd014f560262ced1fda5c5edb17699b2056555 Mon Sep 17 00:00:00 2001 From: Darshan Date: Tue, 3 Jun 2025 18:57:08 +0530 Subject: [PATCH 8/8] add: return, to feel better about the linter. --- src/lib/stores/preferences.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/stores/preferences.ts b/src/lib/stores/preferences.ts index c144c24bc..0dd009cd7 100644 --- a/src/lib/stores/preferences.ts +++ b/src/lib/stores/preferences.ts @@ -74,7 +74,7 @@ function createPreferences() { /** * Update the local store and then synchronizes them on user prefs. */ - function updateAndSync(callback: (prefs: PreferencesStore) => void) { + function updateAndSync(callback: (prefs: PreferencesStore) => void): Promise { let oldPrefsSnapshot: PreferencesStore; let newPrefsSnapshot: PreferencesStore; @@ -90,7 +90,7 @@ function createPreferences() { } // sync the preferences. - updateConsolePreferences(newPrefsSnapshot); + return updateConsolePreferences(newPrefsSnapshot); } return {