@oxyhq/services 5.16.4 → 5.16.8
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.
- package/lib/commonjs/core/OxyServices.base.js +3 -1
- package/lib/commonjs/core/OxyServices.base.js.map +1 -1
- package/lib/commonjs/core/mixins/OxyServices.assets.js +20 -330
- package/lib/commonjs/core/mixins/OxyServices.assets.js.map +1 -1
- package/lib/commonjs/index.js +156 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +95 -9
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/hooks/mutations/index.js +60 -20
- package/lib/commonjs/ui/hooks/mutations/index.js.map +1 -1
- package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +230 -1
- package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/index.js +96 -30
- package/lib/commonjs/ui/hooks/queries/index.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/queryKeys.js +5 -0
- package/lib/commonjs/ui/hooks/queries/queryKeys.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/useAccountQueries.js +75 -1
- package/lib/commonjs/ui/hooks/queries/useAccountQueries.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/useServicesQueries.js +50 -2
- package/lib/commonjs/ui/hooks/queries/useServicesQueries.js.map +1 -1
- package/lib/commonjs/ui/hooks/useAssets.js +8 -29
- package/lib/commonjs/ui/hooks/useAssets.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js +6 -6
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +3 -3
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +14 -10
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/utils/fileManagement.js +88 -0
- package/lib/commonjs/ui/utils/fileManagement.js.map +1 -1
- package/lib/module/core/OxyServices.base.js +3 -1
- package/lib/module/core/OxyServices.base.js.map +1 -1
- package/lib/module/core/mixins/OxyServices.assets.js +20 -331
- package/lib/module/core/mixins/OxyServices.assets.js.map +1 -1
- package/lib/module/index.js +17 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +95 -9
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/mutations/index.js +12 -3
- package/lib/module/ui/hooks/mutations/index.js.map +1 -1
- package/lib/module/ui/hooks/mutations/useAccountMutations.js +227 -0
- package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
- package/lib/module/ui/hooks/queries/index.js +15 -4
- package/lib/module/ui/hooks/queries/index.js.map +1 -1
- package/lib/module/ui/hooks/queries/queryKeys.js +5 -0
- package/lib/module/ui/hooks/queries/queryKeys.js.map +1 -1
- package/lib/module/ui/hooks/queries/useAccountQueries.js +73 -0
- package/lib/module/ui/hooks/queries/useAccountQueries.js.map +1 -1
- package/lib/module/ui/hooks/queries/useServicesQueries.js +50 -2
- package/lib/module/ui/hooks/queries/useServicesQueries.js.map +1 -1
- package/lib/module/ui/hooks/useAssets.js +8 -29
- package/lib/module/ui/hooks/useAssets.js.map +1 -1
- package/lib/module/ui/screens/AccountOverviewScreen.js +6 -6
- package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +3 -3
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +12 -10
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/utils/fileManagement.js +87 -0
- package/lib/module/ui/utils/fileManagement.js.map +1 -1
- package/lib/typescript/core/OxyServices.base.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.assets.d.ts +1 -70
- package/lib/typescript/core/mixins/OxyServices.assets.d.ts.map +1 -1
- package/lib/typescript/core/mixins/index.d.ts +4 -14
- package/lib/typescript/core/mixins/index.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts +1 -0
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/mutations/index.d.ts +8 -2
- package/lib/typescript/ui/hooks/mutations/index.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts +19 -0
- package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/queries/index.d.ts +9 -3
- package/lib/typescript/ui/hooks/queries/index.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/queries/queryKeys.d.ts +4 -0
- package/lib/typescript/ui/hooks/queries/queryKeys.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts +6 -0
- package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/queries/useServicesQueries.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useAssets.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/ui/utils/fileManagement.d.ts +48 -0
- package/lib/typescript/ui/utils/fileManagement.d.ts.map +1 -1
- package/package.json +6 -2
- package/src/core/OxyServices.base.ts +5 -1
- package/src/core/mixins/OxyServices.assets.ts +21 -338
- package/src/index.ts +49 -2
- package/src/ui/context/OxyContext.tsx +98 -7
- package/src/ui/hooks/mutations/index.ts +24 -3
- package/src/ui/hooks/mutations/useAccountMutations.ts +205 -0
- package/src/ui/hooks/queries/index.ts +29 -4
- package/src/ui/hooks/queries/queryKeys.ts +6 -0
- package/src/ui/hooks/queries/useAccountQueries.ts +69 -0
- package/src/ui/hooks/queries/useServicesQueries.ts +49 -2
- package/src/ui/hooks/useAssets.ts +8 -28
- package/src/ui/screens/AccountOverviewScreen.tsx +4 -3
- package/src/ui/screens/AccountSettingsScreen.tsx +3 -5
- package/src/ui/screens/FileManagementScreen.tsx +10 -11
- package/src/ui/utils/fileManagement.ts +105 -0
|
@@ -75,12 +75,12 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
|
|
|
75
75
|
} = useOxy();
|
|
76
76
|
const { t } = useI18n();
|
|
77
77
|
const normalizedTheme = normalizeTheme(theme);
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
// Use TanStack Query for user data
|
|
80
80
|
const { data: user, isLoading: userLoading } = useCurrentUser({ enabled: isAuthenticated });
|
|
81
81
|
const updateProfileMutation = useUpdateProfile();
|
|
82
82
|
const uploadAvatarMutation = useUploadAvatar();
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
// Fallback to store for backward compatibility
|
|
85
85
|
const userFromStore = useAuthStore((state) => state.user);
|
|
86
86
|
const finalUser = user || userFromStore;
|
|
@@ -503,9 +503,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
|
|
|
503
503
|
});
|
|
504
504
|
};
|
|
505
505
|
|
|
506
|
-
const openAvatarPicker =
|
|
507
|
-
toast.info?.(t('editProfile.toasts.avatarPickerUnavailable') || 'Avatar picker is not available in this build.');
|
|
508
|
-
}, [t]);
|
|
506
|
+
const { openAvatarPicker } = useOxy();
|
|
509
507
|
|
|
510
508
|
// Handlers to open modals
|
|
511
509
|
const handleOpenDisplayNameModal = useCallback(() => setShowEditDisplayNameModal(true), []);
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
Alert,
|
|
15
15
|
} from 'react-native';
|
|
16
16
|
import { Image as ExpoImage } from 'expo-image';
|
|
17
|
+
import * as DocumentPicker from 'expo-document-picker';
|
|
17
18
|
import type { FileManagementScreenProps } from '../types/fileManagement';
|
|
18
19
|
import { toast } from '../../lib/sonner';
|
|
19
20
|
import { Ionicons } from '@expo/vector-icons';
|
|
@@ -28,13 +29,13 @@ import { useThemeStyles } from '../hooks/useThemeStyles';
|
|
|
28
29
|
import { useColorScheme } from '../hooks/use-color-scheme';
|
|
29
30
|
import { normalizeTheme } from '../utils/themeUtils';
|
|
30
31
|
import { useOxy } from '../context/OxyContext';
|
|
32
|
+
import { useUploadFile } from '../hooks/mutations/useAccountMutations';
|
|
31
33
|
import {
|
|
32
34
|
confirmAction,
|
|
33
35
|
convertDocumentPickerAssetToFile,
|
|
34
36
|
formatFileSize,
|
|
35
37
|
getFileIcon,
|
|
36
38
|
getSafeDownloadUrl,
|
|
37
|
-
uploadFileRaw
|
|
38
39
|
} from '../utils/fileManagement';
|
|
39
40
|
import { FileViewer } from '../components/fileManagement/FileViewer';
|
|
40
41
|
import { FileDetailsModal } from '../components/fileManagement/FileDetailsModal';
|
|
@@ -115,6 +116,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
115
116
|
}) => {
|
|
116
117
|
// Use useOxy() hook for OxyContext values
|
|
117
118
|
const { user, oxyServices } = useOxy();
|
|
119
|
+
const uploadFileMutation = useUploadFile();
|
|
118
120
|
const files = useFiles();
|
|
119
121
|
// Ensure containerWidth is a number (TypeScript guard)
|
|
120
122
|
const safeContainerWidth: number = typeof containerWidth === 'number' ? containerWidth : 400;
|
|
@@ -528,7 +530,11 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
528
530
|
};
|
|
529
531
|
useFileStore.getState().addFile(optimisticFile, { prepend: true });
|
|
530
532
|
|
|
531
|
-
|
|
533
|
+
// Use the mutation hook with authentication handling
|
|
534
|
+
const result = await uploadFileMutation.mutateAsync({
|
|
535
|
+
file: raw,
|
|
536
|
+
visibility: defaultVisibility,
|
|
537
|
+
});
|
|
532
538
|
|
|
533
539
|
// Attempt to refresh file list incrementally – fetch single file metadata if API allows
|
|
534
540
|
if (result?.file || result?.files?.[0]) {
|
|
@@ -763,16 +769,9 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
763
769
|
|
|
764
770
|
try {
|
|
765
771
|
setIsPickingDocument(true);
|
|
766
|
-
|
|
767
|
-
// Dynamically import expo-document-picker (Expo 54 supports it on all platforms)
|
|
768
|
-
const DocumentPicker = await import('expo-document-picker').catch(() => null);
|
|
769
|
-
|
|
770
|
-
if (!DocumentPicker || !DocumentPicker.getDocumentAsync) {
|
|
771
|
-
toast.error('File picker not available. Please install expo-document-picker');
|
|
772
|
-
return;
|
|
773
|
-
}
|
|
774
772
|
|
|
775
|
-
// Use
|
|
773
|
+
// Use expo-document-picker (works on all platforms including web)
|
|
774
|
+
// On web, it uses the native file input and provides File objects directly
|
|
776
775
|
const result = await DocumentPicker.getDocumentAsync({
|
|
777
776
|
type: '*/*',
|
|
778
777
|
multiple: true,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Alert } from 'react-native';
|
|
2
2
|
import type { FileMetadata } from '../../models/interfaces';
|
|
3
3
|
import { File as ExpoFile } from 'expo-file-system';
|
|
4
|
+
import { toast } from '../../lib/sonner';
|
|
5
|
+
import type { RouteName } from '../navigation/routes';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Format file size in bytes to human-readable string
|
|
@@ -188,3 +190,106 @@ export async function uploadFileRaw(
|
|
|
188
190
|
return await oxyServices.uploadRawFile(file, visibility);
|
|
189
191
|
}
|
|
190
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Configuration for creating an avatar picker handler
|
|
195
|
+
*/
|
|
196
|
+
export interface AvatarPickerConfig {
|
|
197
|
+
/** Navigation function from BaseScreenProps */
|
|
198
|
+
navigate?: (screen: RouteName, props?: Record<string, unknown>) => void;
|
|
199
|
+
/** OxyServices instance */
|
|
200
|
+
oxyServices: any;
|
|
201
|
+
/** TanStack Query mutation for updating profile */
|
|
202
|
+
updateProfileMutation: {
|
|
203
|
+
mutateAsync: (updates: { avatar: string }) => Promise<any>;
|
|
204
|
+
};
|
|
205
|
+
/** Callback to update local avatar state */
|
|
206
|
+
onAvatarSelected?: (fileId: string) => void;
|
|
207
|
+
/** i18n translation function */
|
|
208
|
+
t: (key: string) => string | undefined;
|
|
209
|
+
/** Optional context name for logging (e.g., 'AccountSettings', 'WelcomeNewUser') */
|
|
210
|
+
contextName?: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Creates a reusable avatar picker handler function.
|
|
215
|
+
*
|
|
216
|
+
* This function navigates to the FileManagement screen and handles:
|
|
217
|
+
* - Image file validation
|
|
218
|
+
* - File visibility update to public
|
|
219
|
+
* - Profile avatar update via mutation
|
|
220
|
+
* - Success/error toast notifications
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```tsx
|
|
224
|
+
* const openAvatarPicker = createAvatarPickerHandler({
|
|
225
|
+
* navigate,
|
|
226
|
+
* oxyServices,
|
|
227
|
+
* updateProfileMutation,
|
|
228
|
+
* onAvatarSelected: setAvatarFileId,
|
|
229
|
+
* t,
|
|
230
|
+
* contextName: 'AccountSettings'
|
|
231
|
+
* });
|
|
232
|
+
*
|
|
233
|
+
* <TouchableOpacity onPress={openAvatarPicker}>
|
|
234
|
+
* <Text>Change Avatar</Text>
|
|
235
|
+
* </TouchableOpacity>
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
export function createAvatarPickerHandler(config: AvatarPickerConfig): () => void {
|
|
239
|
+
const {
|
|
240
|
+
navigate,
|
|
241
|
+
oxyServices,
|
|
242
|
+
updateProfileMutation,
|
|
243
|
+
onAvatarSelected,
|
|
244
|
+
t,
|
|
245
|
+
contextName = 'AvatarPicker'
|
|
246
|
+
} = config;
|
|
247
|
+
|
|
248
|
+
return () => {
|
|
249
|
+
if (!navigate) {
|
|
250
|
+
console.warn(`[${contextName}] navigate function is not available`);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
navigate('FileManagement', {
|
|
255
|
+
selectMode: true,
|
|
256
|
+
multiSelect: false,
|
|
257
|
+
disabledMimeTypes: ['video/', 'audio/', 'application/pdf'],
|
|
258
|
+
afterSelect: 'none', // Don't navigate away - stay on current screen
|
|
259
|
+
onSelect: async (file: any) => {
|
|
260
|
+
if (!file.contentType.startsWith('image/')) {
|
|
261
|
+
toast.error(t('editProfile.toasts.selectImage') || 'Please select an image file');
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
try {
|
|
266
|
+
// Update file visibility to public for avatar (skip if temporary asset ID)
|
|
267
|
+
if (file.id && !file.id.startsWith('temp-')) {
|
|
268
|
+
try {
|
|
269
|
+
await oxyServices.assetUpdateVisibility(file.id, 'public');
|
|
270
|
+
console.log(`[${contextName}] Avatar visibility updated to public`);
|
|
271
|
+
} catch (visError: any) {
|
|
272
|
+
// Only log non-404 errors (404 means asset doesn't exist yet, which is OK)
|
|
273
|
+
if (visError?.response?.status !== 404) {
|
|
274
|
+
console.warn(`[${contextName}] Failed to update avatar visibility, continuing anyway:`, visError);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Update local state if callback provided
|
|
280
|
+
if (onAvatarSelected) {
|
|
281
|
+
onAvatarSelected(file.id);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Update user using TanStack Query mutation
|
|
285
|
+
await updateProfileMutation.mutateAsync({ avatar: file.id });
|
|
286
|
+
|
|
287
|
+
toast.success(t('editProfile.toasts.avatarUpdated') || 'Avatar updated');
|
|
288
|
+
} catch (e: any) {
|
|
289
|
+
toast.error(e.message || t('editProfile.toasts.updateAvatarFailed') || 'Failed to update avatar');
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|