@oxyhq/services 5.17.14 → 5.17.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/lib/commonjs/ui/context/OxyContext.js +34 -34
  2. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  3. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +21 -26
  4. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  5. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js +31 -28
  6. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js.map +1 -1
  7. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +9 -3
  8. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  9. package/lib/commonjs/ui/utils/avatarUtils.js +7 -8
  10. package/lib/commonjs/ui/utils/avatarUtils.js.map +1 -1
  11. package/lib/module/ui/context/OxyContext.js +39 -39
  12. package/lib/module/ui/context/OxyContext.js.map +1 -1
  13. package/lib/module/ui/hooks/mutations/useAccountMutations.js +21 -26
  14. package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  15. package/lib/module/ui/hooks/queries/useAccountQueries.js +31 -28
  16. package/lib/module/ui/hooks/queries/useAccountQueries.js.map +1 -1
  17. package/lib/module/ui/screens/AccountSettingsScreen.js +9 -3
  18. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  19. package/lib/module/ui/utils/avatarUtils.js +7 -8
  20. package/lib/module/ui/utils/avatarUtils.js.map +1 -1
  21. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  22. package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  23. package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  24. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  25. package/lib/typescript/ui/utils/avatarUtils.d.ts.map +1 -1
  26. package/package.json +1 -1
  27. package/src/ui/context/OxyContext.tsx +30 -41
  28. package/src/ui/hooks/mutations/useAccountMutations.ts +23 -34
  29. package/src/ui/hooks/queries/useAccountQueries.ts +23 -20
  30. package/src/ui/screens/AccountSettingsScreen.tsx +17 -3
  31. package/src/ui/utils/avatarUtils.ts +7 -8
@@ -5,6 +5,7 @@ import { queryKeys, invalidateAccountQueries, invalidateUserQueries } from '../q
5
5
  import { useOxy } from '../../context/OxyContext';
6
6
  import { toast } from '../../../lib/sonner';
7
7
  import { refreshAccountInStore } from '../../utils/avatarUtils';
8
+ import { logger } from '../../../utils/loggerUtils';
8
9
 
9
10
  const getDeviceIdForSession = (sessions: ClientSession[] = [], sessionId: string | null) =>
10
11
  sessionId ? sessions.find((s) => s.sessionId === sessionId)?.deviceId : undefined;
@@ -79,43 +80,29 @@ export const useUpdateProfile = () => {
79
80
  }
80
81
  toast.error(error instanceof Error ? error.message : 'Failed to update profile');
81
82
  },
82
- // On success, invalidate and refetch
83
+ // On success, update cache and sync to store
83
84
  onSuccess: async (data, updates) => {
84
- if (__DEV__) {
85
- console.log('[useUpdateProfile] Profile update successful:', data);
86
- console.log('[useUpdateProfile] Updated fields:', Object.keys(updates));
87
- }
88
-
85
+ logger.debug('Profile update successful', {
86
+ component: 'useUpdateProfile',
87
+ username: data.username,
88
+ updatedFields: Object.keys(updates)
89
+ });
90
+
89
91
  // Update cache with server response
90
92
  queryClient.setQueryData(queryKeys.accounts.current(), data);
91
93
  if (activeSessionId) {
92
94
  queryClient.setQueryData(queryKeys.users.profile(activeSessionId), data);
93
95
  }
94
-
95
- // Refresh accountStore with all updated profile data (not just avatar)
96
+
97
+ // Refresh accountStore with all updated profile data (synchronizes immediately)
96
98
  if (activeSessionId && oxyServices) {
97
99
  refreshAccountInStore(activeSessionId, data, oxyServices);
98
100
  }
99
-
100
- // Invalidate all related queries to refresh everywhere
101
- await Promise.all([
102
- invalidateUserQueries(queryClient),
103
- invalidateAccountQueries(queryClient),
104
- ]);
105
-
106
- // Force immediate refetch to update UI - refetch ALL active queries
107
- await queryClient.refetchQueries({
108
- queryKey: queryKeys.accounts.current(),
109
- type: 'active',
110
- exact: false // Also refetch derived queries
111
- });
112
-
113
- if (__DEV__) {
114
- console.log('[useUpdateProfile] Profile update complete - cache invalidated and refetched');
115
- // Log current cache state
116
- const currentUser = queryClient.getQueryData(queryKeys.accounts.current());
117
- console.log('[useUpdateProfile] Current cached user:', currentUser);
118
- }
101
+
102
+ // Only invalidate specific queries that need refresh (not everything)
103
+ invalidateAccountQueries(queryClient);
104
+
105
+ logger.debug('Profile update complete', { component: 'useUpdateProfile' });
119
106
  },
120
107
  });
121
108
  };
@@ -190,9 +177,10 @@ export const useUploadAvatar = () => {
190
177
  toast.error(error instanceof Error ? error.message : 'Failed to upload avatar');
191
178
  },
192
179
  onSuccess: async (data) => {
193
- if (__DEV__) {
194
- console.log('[useUploadAvatar] Avatar upload successful:', data);
195
- }
180
+ logger.debug(
181
+ 'Avatar upload successful',
182
+ { component: 'useUploadAvatar', method: 'onSuccess', data }
183
+ );
196
184
 
197
185
  queryClient.setQueryData(queryKeys.accounts.current(), data);
198
186
  if (activeSessionId) {
@@ -213,9 +201,10 @@ export const useUploadAvatar = () => {
213
201
 
214
202
  toast.success('Avatar updated successfully');
215
203
 
216
- if (__DEV__) {
217
- console.log('[useUploadAvatar] Avatar update complete - cache invalidated and refetched');
218
- }
204
+ logger.debug(
205
+ 'Avatar update complete - cache invalidated and refetched',
206
+ { component: 'useUploadAvatar', method: 'onSuccess' }
207
+ );
219
208
  },
220
209
  });
221
210
  };
@@ -3,6 +3,7 @@ import type { User } from '../../../models/interfaces';
3
3
  import type { OxyServices } from '../../../core';
4
4
  import { queryKeys } from './queryKeys';
5
5
  import { useOxy } from '../../context/OxyContextBase';
6
+ import { logger } from '../../../utils/loggerUtils';
6
7
 
7
8
  /**
8
9
  * Get user profile by session ID
@@ -19,8 +20,8 @@ export const useUserProfile = (sessionId: string | null, options?: { enabled?: b
19
20
  return await oxyServices.getUserBySession(sessionId);
20
21
  },
21
22
  enabled: (options?.enabled !== false) && !!sessionId,
22
- staleTime: 0, // Always fetch fresh - Services never caches profile
23
- gcTime: 0, // No garbage collection time - always fetch fresh
23
+ staleTime: 30000, // 30 seconds - reasonable freshness without constant refetching
24
+ gcTime: 5 * 60 * 1000, // 5 minutes - keep in cache for quick access
24
25
  });
25
26
  };
26
27
 
@@ -38,8 +39,8 @@ export const useUserProfiles = (sessionIds: string[], options?: { enabled?: bool
38
39
  return results[0]?.user || null;
39
40
  },
40
41
  enabled: (options?.enabled !== false) && !!sessionId,
41
- staleTime: 0, // Always fetch fresh - Services never caches profile
42
- gcTime: 0, // No garbage collection time - always fetch fresh
42
+ staleTime: 30000, // 30 seconds
43
+ gcTime: 5 * 60 * 1000, // 5 minutes
43
44
  })),
44
45
  });
45
46
  };
@@ -53,21 +54,23 @@ export const useCurrentUser = (options?: { enabled?: boolean }) => {
53
54
  return useQuery({
54
55
  queryKey: queryKeys.accounts.current(),
55
56
  queryFn: async () => {
56
- if (__DEV__) {
57
- console.log('[useCurrentUser] Fetching user data for session:', activeSessionId);
58
- }
57
+ logger.debug('Fetching current user', {
58
+ component: 'useCurrentUser',
59
+ sessionId: activeSessionId ?? undefined
60
+ });
59
61
  if (!activeSessionId) {
60
62
  throw new Error('No active session');
61
63
  }
62
64
  const userData = await oxyServices.getUserBySession(activeSessionId);
63
- if (__DEV__) {
64
- console.log('[useCurrentUser] Fetched user:', userData.username, userData.name);
65
- }
65
+ logger.debug('Current user fetched', {
66
+ component: 'useCurrentUser',
67
+ username: userData.username
68
+ });
66
69
  return userData;
67
70
  },
68
71
  enabled: (options?.enabled !== false) && isAuthenticated && !!activeSessionId,
69
- staleTime: 0, // Always fetch fresh - Services never caches profile
70
- gcTime: 0, // No garbage collection time - always fetch fresh
72
+ staleTime: 30000, // 30 seconds - balances freshness with performance
73
+ gcTime: 5 * 60 * 1000, // 5 minutes
71
74
  refetchOnMount: 'always', // Always refetch on mount
72
75
  refetchOnWindowFocus: false,
73
76
  });
@@ -88,8 +91,8 @@ export const useUserById = (userId: string | null, options?: { enabled?: boolean
88
91
  return await oxyServices.getUserById(userId);
89
92
  },
90
93
  enabled: (options?.enabled !== false) && !!userId,
91
- staleTime: 0, // Always fetch fresh - Services never caches profile
92
- gcTime: 0, // No garbage collection time - always fetch fresh
94
+ staleTime: 60000, // 1 minute - other users' profiles change less frequently
95
+ gcTime: 10 * 60 * 1000, // 10 minutes
93
96
  });
94
97
  };
95
98
 
@@ -108,8 +111,8 @@ export const useUserByUsername = (username: string | null, options?: { enabled?:
108
111
  return await oxyServices.getProfileByUsername(username);
109
112
  },
110
113
  enabled: (options?.enabled !== false) && !!username,
111
- staleTime: 0, // Always fetch fresh - Services never caches profile
112
- gcTime: 0, // No garbage collection time - always fetch fresh
114
+ staleTime: 60000, // 1 minute
115
+ gcTime: 10 * 60 * 1000, // 10 minutes
113
116
  });
114
117
  };
115
118
 
@@ -128,8 +131,8 @@ export const useUsersBySessions = (sessionIds: string[], options?: { enabled?: b
128
131
  return await oxyServices.getUsersBySessions(sessionIds);
129
132
  },
130
133
  enabled: (options?.enabled !== false) && sessionIds.length > 0,
131
- staleTime: 0, // Always fetch fresh - Services never caches profile
132
- gcTime: 0, // No garbage collection time - always fetch fresh
134
+ staleTime: 30000, // 30 seconds
135
+ gcTime: 5 * 60 * 1000, // 5 minutes
133
136
  });
134
137
  };
135
138
 
@@ -176,7 +179,7 @@ export const usePrivacySettings = (userId?: string, options?: { enabled?: boolea
176
179
  }
177
180
  },
178
181
  enabled: (options?.enabled !== false) && !!targetUserId,
179
- staleTime: 0, // Always fetch fresh - Services never caches profile
180
- gcTime: 0, // No garbage collection time - always fetch fresh
182
+ staleTime: 60000, // 1 minute - privacy settings don't change frequently
183
+ gcTime: 10 * 60 * 1000, // 10 minutes
181
184
  });
182
185
  };
@@ -215,9 +215,10 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
215
215
  // Only reset all fields if it's a new user or first load
216
216
  // Skip reset if it's just an avatar update
217
217
  if (shouldInitialize && !isAvatarOnlyUpdate) {
218
+ // Prioritize name.full over name.first for display name
218
219
  const userDisplayName = typeof finalUser.name === 'string'
219
220
  ? finalUser.name
220
- : finalUser.name?.first || finalUser.name?.full || '';
221
+ : finalUser.name?.full || finalUser.name?.first || '';
221
222
  const userLastName = typeof finalUser.name === 'object' ? finalUser.name?.last || '' : '';
222
223
  setDisplayName(userDisplayName);
223
224
  setLastName(userLastName);
@@ -362,7 +363,15 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
362
363
  try {
363
364
  switch (field) {
364
365
  case 'displayName':
365
- await updateProfileMutation.mutateAsync({ name: { first: tempDisplayName, last: tempLastName } });
366
+ // Send both first/last AND full name for proper synchronization
367
+ const fullName = [tempDisplayName, tempLastName].filter(Boolean).join(' ').trim() || tempDisplayName;
368
+ await updateProfileMutation.mutateAsync({
369
+ name: {
370
+ first: tempDisplayName,
371
+ last: tempLastName,
372
+ full: fullName
373
+ }
374
+ });
366
375
  setDisplayName(tempDisplayName);
367
376
  setLastName(tempLastName);
368
377
  break;
@@ -467,7 +476,12 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
467
476
 
468
477
  // Handle name field
469
478
  if (displayName || lastName) {
470
- updates.name = { first: displayName, last: lastName };
479
+ const fullName = [displayName, lastName].filter(Boolean).join(' ').trim() || displayName;
480
+ updates.name = {
481
+ first: displayName,
482
+ last: lastName,
483
+ full: fullName
484
+ };
471
485
  }
472
486
 
473
487
  // Handle avatar
@@ -3,6 +3,7 @@ import type { User } from '../../models/interfaces';
3
3
  import { useAccountStore } from '../stores/accountStore';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  import { queryKeys, invalidateUserQueries, invalidateAccountQueries } from '../hooks/queries/queryKeys';
6
+ import { logger } from '../../utils/loggerUtils';
6
7
 
7
8
  /**
8
9
  * Updates file visibility to public for avatar use.
@@ -74,14 +75,12 @@ export function refreshAccountInStore(
74
75
  ? oxyServices.getFileDownloadUrl(userData.avatar, 'thumb') + `?t=${Date.now()}`
75
76
  : undefined;
76
77
 
77
- if (__DEV__) {
78
- console.log('[AccountStore] Refreshing account in store:', {
79
- sessionId,
80
- username: userData.username,
81
- displayName,
82
- avatar: userData.avatar,
83
- });
84
- }
78
+ logger.debug('Refreshing account in store', {
79
+ component: 'AccountStore',
80
+ sessionId,
81
+ username: userData.username,
82
+ hasAvatar: !!userData.avatar
83
+ });
85
84
 
86
85
  updateAccount(sessionId, {
87
86
  username: userData.username,