11import type { RemovableRef } from '@vueuse/core'
22import { useLocalStorage } from '@vueuse/core'
33import { ACCENT_COLORS } from '#shared/utils/constants'
4- import type { LocaleObject } from '@nuxtjs/i18n'
54import { BACKGROUND_THEMES } from '#shared/utils/constants'
6-
7- type BackgroundThemeId = keyof typeof BACKGROUND_THEMES
8-
9- type AccentColorId = keyof typeof ACCENT_COLORS . light
10-
11- /**
12- * Application settings stored in localStorage
13- */
14- export interface AppSettings {
15- /** Display dates as relative (e.g., "3 days ago") instead of absolute */
16- relativeDates : boolean
17- /** Include @types/* package in install command for packages without built-in types */
18- includeTypesInInstall : boolean
19- /** Accent color theme */
20- accentColorId : AccentColorId | null
21- /** Preferred background shade */
22- preferredBackgroundTheme : BackgroundThemeId | null
23- /** Hide platform-specific packages (e.g., @scope/pkg-linux-x64) from search results */
24- hidePlatformPackages : boolean
25- /** User-selected locale */
26- selectedLocale : LocaleObject [ 'code' ] | null
27- sidebar : {
28- collapsed : string [ ]
29- }
30- }
31-
32- const DEFAULT_SETTINGS : AppSettings = {
33- relativeDates : false ,
34- includeTypesInInstall : true ,
35- accentColorId : null ,
36- hidePlatformPackages : true ,
37- selectedLocale : null ,
38- preferredBackgroundTheme : null ,
39- sidebar : {
40- collapsed : [ ] ,
41- } ,
42- }
5+ import {
6+ DEFAULT_USER_PREFERENCES ,
7+ type AccentColorId ,
8+ type BackgroundThemeId ,
9+ type UserPreferences ,
10+ } from '#shared/schemas/userPreferences'
4311
4412const STORAGE_KEY = 'npmx-settings'
4513
46- // Shared settings instance (singleton per app)
47- let settingsRef : RemovableRef < AppSettings > | null = null
14+ let settingsRef : RemovableRef < UserPreferences > | null = null
15+ let syncInitialized = false
4816
49- /**
50- * Composable for managing application settings with localStorage persistence.
51- * Settings are shared across all components that use this composable.
52- */
17+ // TODO: After discussion with the team, this will be replaced with a proper persistent solution (LS + server sync)
5318export function useSettings ( ) {
5419 if ( ! settingsRef ) {
55- settingsRef = useLocalStorage < AppSettings > ( STORAGE_KEY , DEFAULT_SETTINGS , {
20+ settingsRef = useLocalStorage < UserPreferences > ( STORAGE_KEY , DEFAULT_USER_PREFERENCES , {
5621 mergeDefaults : true ,
5722 } )
5823 }
@@ -62,18 +27,72 @@ export function useSettings() {
6227 }
6328}
6429
65- /**
66- * Composable for accessing just the relative dates setting.
67- * Useful for components that only need to read this specific setting.
68- */
30+ // TODO: Name to be changed
31+ export function useSettingsSync ( ) {
32+ const { settings } = useSettings ( )
33+ const {
34+ isAuthenticated,
35+ status,
36+ lastSyncedAt,
37+ error,
38+ loadFromServer,
39+ scheduleSync,
40+ setupRouteGuard,
41+ setupBeforeUnload,
42+ } = useUserPreferencesSync ( )
43+
44+ const isSyncing = computed ( ( ) => status . value === 'syncing' )
45+ const isSynced = computed ( ( ) => status . value === 'synced' )
46+ const hasError = computed ( ( ) => status . value === 'error' )
47+
48+ async function initializeSync ( ) : Promise < void > {
49+ if ( syncInitialized || import . meta. server ) return
50+
51+ setupRouteGuard ( ( ) => settings . value )
52+ setupBeforeUnload ( ( ) => settings . value )
53+
54+ if ( isAuthenticated . value ) {
55+ const serverPrefs = await loadFromServer ( )
56+ Object . assign ( settings . value , serverPrefs )
57+ }
58+
59+ watch (
60+ settings ,
61+ newSettings => {
62+ if ( isAuthenticated . value ) {
63+ scheduleSync ( newSettings )
64+ }
65+ } ,
66+ { deep : true } ,
67+ )
68+
69+ watch ( isAuthenticated , async newIsAuth => {
70+ if ( newIsAuth ) {
71+ const serverPrefs = await loadFromServer ( )
72+ Object . assign ( settings . value , serverPrefs )
73+ }
74+ } )
75+
76+ syncInitialized = true
77+ }
78+
79+ return {
80+ settings,
81+ isAuthenticated,
82+ isSyncing,
83+ isSynced,
84+ hasError,
85+ syncError : error ,
86+ lastSyncedAt,
87+ initializeSync,
88+ }
89+ }
90+
6991export function useRelativeDates ( ) {
7092 const { settings } = useSettings ( )
7193 return computed ( ( ) => settings . value . relativeDates )
7294}
7395
74- /**
75- * Composable for managing accent color.
76- */
7796export function useAccentColor ( ) {
7897 const { settings } = useSettings ( )
7998 const colorMode = useColorMode ( )
0 commit comments