@umituz/react-native-design-system 4.23.102 → 4.23.103
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/package.json +1 -1
- package/src/media/index.ts +4 -36
- package/src/media/infrastructure/services/MediaPickerService.ts +157 -0
- package/src/media/infrastructure/services/MediaSaveService.ts +97 -0
- package/src/media/infrastructure/utils/media-collection-utils.ts +20 -6
- package/src/media/presentation/hooks/useMedia.ts +190 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-design-system",
|
|
3
|
-
"version": "4.23.
|
|
3
|
+
"version": "4.23.103",
|
|
4
4
|
"description": "Universal design system for React Native apps - Consolidated package with atoms, molecules, organisms, theme, typography, responsive, safe area, exception, infinite scroll, UUID, image, timezone, offline, onboarding, and loading utilities",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
package/src/media/index.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @umituz/react-native-media -
|
|
2
|
+
* @umituz/react-native-media - Public API
|
|
3
3
|
*
|
|
4
4
|
* Media picking capabilities for React Native apps
|
|
5
|
-
* Includes multimedia flashcard support
|
|
6
5
|
*
|
|
7
6
|
* Usage:
|
|
8
7
|
* import {
|
|
9
8
|
* useMedia,
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* type
|
|
13
|
-
* type MultimediaFlashcard,
|
|
9
|
+
* MediaPickerService,
|
|
10
|
+
* type MediaAsset,
|
|
11
|
+
* type MediaPickerResult,
|
|
14
12
|
* } from '@umituz/react-native-media';
|
|
15
13
|
*/
|
|
16
14
|
|
|
@@ -90,33 +88,3 @@ export {
|
|
|
90
88
|
saveVideoToGallery,
|
|
91
89
|
type SaveToGalleryResult,
|
|
92
90
|
} from "./infrastructure/utils/file-media-utils";
|
|
93
|
-
|
|
94
|
-
// Media Attachment Types (Clean, no aliases)
|
|
95
|
-
export type {
|
|
96
|
-
MediaAttachmentType,
|
|
97
|
-
MediaPosition,
|
|
98
|
-
MediaAttachment,
|
|
99
|
-
MultimediaFlashcard,
|
|
100
|
-
MediaGenerationRequest,
|
|
101
|
-
MediaGenerationResult,
|
|
102
|
-
MediaUploadProgress,
|
|
103
|
-
MediaCompressionOptions,
|
|
104
|
-
MediaValidation,
|
|
105
|
-
MediaFile,
|
|
106
|
-
CreateMultimediaCardData,
|
|
107
|
-
} from "./domain/entities/MediaAttachments";
|
|
108
|
-
|
|
109
|
-
// Media Attachment Hooks
|
|
110
|
-
export { useMediaUpload } from "./presentation/hooks/useMediaUpload";
|
|
111
|
-
export { useMediaGeneration } from "./presentation/hooks/useMediaGeneration";
|
|
112
|
-
export { useMediaValidation } from "./presentation/hooks/useMediaValidation";
|
|
113
|
-
export { useMultimediaFlashcard } from "./presentation/hooks/useMultimediaFlashcard";
|
|
114
|
-
export type {
|
|
115
|
-
UseMediaUploadResult,
|
|
116
|
-
UseMediaGenerationResult,
|
|
117
|
-
UseMediaValidationResult,
|
|
118
|
-
UseMultimediaFlashcardResult,
|
|
119
|
-
} from "./presentation/hooks/multimedia.types";
|
|
120
|
-
|
|
121
|
-
// Media Attachment Services
|
|
122
|
-
export { MultimediaFlashcardService } from "./infrastructure/services/MultimediaFlashcardService";
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media Domain - Media Picker Service
|
|
3
|
+
*
|
|
4
|
+
* Service for picking images/videos using expo-image-picker.
|
|
5
|
+
* Handles camera, gallery, and media library permissions.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as ImagePicker from "expo-image-picker";
|
|
9
|
+
import type {
|
|
10
|
+
MediaPickerOptions,
|
|
11
|
+
MediaPickerResult,
|
|
12
|
+
CameraOptions,
|
|
13
|
+
} from "../../domain/entities/Media";
|
|
14
|
+
import {
|
|
15
|
+
MediaType,
|
|
16
|
+
MediaValidationError,
|
|
17
|
+
MEDIA_CONSTANTS,
|
|
18
|
+
} from "../../domain/entities/Media";
|
|
19
|
+
import {
|
|
20
|
+
mapMediaType,
|
|
21
|
+
mapPickerResult,
|
|
22
|
+
} from "../utils/mediaPickerMappers";
|
|
23
|
+
import { PermissionManager } from "../utils/PermissionManager";
|
|
24
|
+
import { FileValidator } from "../../domain/utils/FileValidator";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Media picker service for selecting images/videos
|
|
28
|
+
*/
|
|
29
|
+
export class MediaPickerService {
|
|
30
|
+
static async launchCamera(
|
|
31
|
+
options?: CameraOptions
|
|
32
|
+
): Promise<MediaPickerResult> {
|
|
33
|
+
try {
|
|
34
|
+
const permission = await PermissionManager.requestCameraPermission();
|
|
35
|
+
if (!PermissionManager.isPermissionGranted(permission)) {
|
|
36
|
+
return { canceled: true };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const result = await ImagePicker.launchCameraAsync({
|
|
40
|
+
mediaTypes: ["images"],
|
|
41
|
+
allowsEditing: options?.allowsEditing ?? false,
|
|
42
|
+
aspect: options?.aspect,
|
|
43
|
+
quality: options?.quality ?? MEDIA_CONSTANTS.DEFAULT_QUALITY,
|
|
44
|
+
base64: options?.base64 ?? false,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return mapPickerResult(result);
|
|
48
|
+
} catch {
|
|
49
|
+
return { canceled: true };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static async launchCameraForVideo(
|
|
54
|
+
options?: CameraOptions
|
|
55
|
+
): Promise<MediaPickerResult> {
|
|
56
|
+
try {
|
|
57
|
+
const permission = await PermissionManager.requestCameraPermission();
|
|
58
|
+
if (!PermissionManager.isPermissionGranted(permission)) {
|
|
59
|
+
return { canceled: true };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const result = await ImagePicker.launchCameraAsync({
|
|
63
|
+
mediaTypes: ["videos"],
|
|
64
|
+
allowsEditing: options?.allowsEditing ?? false,
|
|
65
|
+
quality: options?.quality ?? MEDIA_CONSTANTS.DEFAULT_QUALITY,
|
|
66
|
+
videoMaxDuration: options?.videoMaxDuration,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return mapPickerResult(result);
|
|
70
|
+
} catch {
|
|
71
|
+
return { canceled: true };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static async pickImage(
|
|
76
|
+
options?: MediaPickerOptions
|
|
77
|
+
): Promise<MediaPickerResult> {
|
|
78
|
+
try {
|
|
79
|
+
const permission = await PermissionManager.requestMediaLibraryPermission();
|
|
80
|
+
if (!PermissionManager.isPermissionGranted(permission)) {
|
|
81
|
+
return {
|
|
82
|
+
canceled: true,
|
|
83
|
+
error: MediaValidationError.PERMISSION_DENIED,
|
|
84
|
+
errorMessage: "Permission to access media library was denied",
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const result = await ImagePicker.launchImageLibraryAsync({
|
|
89
|
+
mediaTypes: mapMediaType(options?.mediaTypes),
|
|
90
|
+
allowsEditing: options?.allowsEditing ?? false,
|
|
91
|
+
allowsMultipleSelection: options?.allowsMultipleSelection ?? false,
|
|
92
|
+
aspect: options?.aspect,
|
|
93
|
+
quality: options?.quality ?? MEDIA_CONSTANTS.DEFAULT_QUALITY,
|
|
94
|
+
selectionLimit:
|
|
95
|
+
options?.selectionLimit ?? MEDIA_CONSTANTS.DEFAULT_SELECTION_LIMIT,
|
|
96
|
+
base64: options?.base64 ?? false,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const mappedResult = mapPickerResult(result);
|
|
100
|
+
|
|
101
|
+
// Validate file size if not canceled and has assets
|
|
102
|
+
if (!mappedResult.canceled && mappedResult.assets && mappedResult.assets.length > 0) {
|
|
103
|
+
const validation = FileValidator.validateAssets(mappedResult.assets, {
|
|
104
|
+
maxFileSizeMB: options?.maxFileSizeMB,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
if (!validation.valid) {
|
|
108
|
+
return {
|
|
109
|
+
canceled: true,
|
|
110
|
+
error: validation.error,
|
|
111
|
+
errorMessage: validation.errorMessage,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return mappedResult;
|
|
117
|
+
} catch {
|
|
118
|
+
return { canceled: true };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static async pickSingleImage(
|
|
123
|
+
options?: Omit<MediaPickerOptions, "allowsMultipleSelection">
|
|
124
|
+
): Promise<MediaPickerResult> {
|
|
125
|
+
return MediaPickerService.pickImage({
|
|
126
|
+
...options,
|
|
127
|
+
allowsMultipleSelection: false,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
static async pickMultipleImages(
|
|
132
|
+
options?: Omit<MediaPickerOptions, "allowsMultipleSelection">
|
|
133
|
+
): Promise<MediaPickerResult> {
|
|
134
|
+
return MediaPickerService.pickImage({
|
|
135
|
+
...options,
|
|
136
|
+
allowsMultipleSelection: true,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static async pickVideo(
|
|
141
|
+
options?: Omit<MediaPickerOptions, "mediaTypes">
|
|
142
|
+
): Promise<MediaPickerResult> {
|
|
143
|
+
return MediaPickerService.pickImage({
|
|
144
|
+
...options,
|
|
145
|
+
mediaTypes: MediaType.VIDEO,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static async pickMedia(
|
|
150
|
+
options?: MediaPickerOptions
|
|
151
|
+
): Promise<MediaPickerResult> {
|
|
152
|
+
return MediaPickerService.pickImage({
|
|
153
|
+
...options,
|
|
154
|
+
mediaTypes: MediaType.ALL,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media Save Service
|
|
3
|
+
* Saves media to device storage using expo-file-system
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as FileSystem from "expo-file-system";
|
|
7
|
+
import { MediaLibraryPermission } from "../../domain/entities/Media";
|
|
8
|
+
|
|
9
|
+
export interface SaveResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
path?: string;
|
|
12
|
+
error?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SaveOptions {
|
|
16
|
+
album?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Service for saving media to gallery
|
|
21
|
+
*/
|
|
22
|
+
export class MediaSaveService {
|
|
23
|
+
/**
|
|
24
|
+
* Request media library write permission
|
|
25
|
+
*/
|
|
26
|
+
static async requestPermission(): Promise<MediaLibraryPermission> {
|
|
27
|
+
return MediaLibraryPermission.GRANTED;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get current permission status
|
|
32
|
+
*/
|
|
33
|
+
static async getPermissionStatus(): Promise<MediaLibraryPermission> {
|
|
34
|
+
return MediaLibraryPermission.GRANTED;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Save image to gallery
|
|
39
|
+
*/
|
|
40
|
+
static async saveImage(
|
|
41
|
+
uri: string,
|
|
42
|
+
options?: SaveOptions,
|
|
43
|
+
): Promise<SaveResult> {
|
|
44
|
+
return MediaSaveService.saveToStorage(uri, "image", options);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Save video to gallery
|
|
49
|
+
*/
|
|
50
|
+
static async saveVideo(
|
|
51
|
+
uri: string,
|
|
52
|
+
options?: SaveOptions,
|
|
53
|
+
): Promise<SaveResult> {
|
|
54
|
+
return MediaSaveService.saveToStorage(uri, "video", options);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Save media (image or video) to storage
|
|
59
|
+
*/
|
|
60
|
+
private static async saveToStorage(
|
|
61
|
+
uri: string,
|
|
62
|
+
mediaType: "image" | "video",
|
|
63
|
+
_options?: SaveOptions,
|
|
64
|
+
): Promise<SaveResult> {
|
|
65
|
+
try {
|
|
66
|
+
const timestamp = Date.now();
|
|
67
|
+
const extension = mediaType === "image" ? "jpg" : "mp4";
|
|
68
|
+
const filename = `${mediaType}_${timestamp}.${extension}`;
|
|
69
|
+
|
|
70
|
+
const directory = (FileSystem as { documentDirectory?: string | null }).documentDirectory;
|
|
71
|
+
if (!directory) {
|
|
72
|
+
return {
|
|
73
|
+
success: false,
|
|
74
|
+
error: "Document directory not available",
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const destination = `${directory}${filename}`;
|
|
79
|
+
|
|
80
|
+
await FileSystem.copyAsync({
|
|
81
|
+
from: uri,
|
|
82
|
+
to: destination,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
success: true,
|
|
87
|
+
path: destination,
|
|
88
|
+
};
|
|
89
|
+
} catch (error) {
|
|
90
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
91
|
+
return {
|
|
92
|
+
success: false,
|
|
93
|
+
error: `Failed to save media: ${message}`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Media Collection Utilities
|
|
3
|
+
* Generic utilities for working with media collections
|
|
4
|
+
*/
|
|
5
5
|
|
|
6
6
|
type MediaType = "image" | "audio" | "video";
|
|
7
7
|
|
|
8
8
|
const FILE_SIZE_UNITS = ["Bytes", "KB", "MB", "GB"] as const;
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Interface for media items with type property
|
|
12
|
+
*/
|
|
13
|
+
interface MediaWithType {
|
|
14
|
+
type: MediaType;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Interface for media items with file size
|
|
19
|
+
*/
|
|
20
|
+
interface MediaWithSize {
|
|
21
|
+
fileSize: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
10
24
|
export function extractMediaTypes(
|
|
11
|
-
media: readonly
|
|
25
|
+
media: readonly MediaWithType[]
|
|
12
26
|
): MediaType[] {
|
|
13
27
|
const types = new Set<MediaType>();
|
|
14
28
|
media.forEach((m) => types.add(m.type));
|
|
@@ -16,7 +30,7 @@ export function extractMediaTypes(
|
|
|
16
30
|
}
|
|
17
31
|
|
|
18
32
|
export function calculateTotalSize(
|
|
19
|
-
media: readonly
|
|
33
|
+
media: readonly MediaWithSize[]
|
|
20
34
|
): number {
|
|
21
35
|
return media.reduce((total, m) => total + m.fileSize, 0);
|
|
22
36
|
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media Domain - useMedia Hook
|
|
3
|
+
*
|
|
4
|
+
* React hook for media picking operations (images, videos).
|
|
5
|
+
* Provides camera, gallery picking functionality.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { useState, useCallback } from "react";
|
|
9
|
+
import { MediaPickerService } from "../../infrastructure/services/MediaPickerService";
|
|
10
|
+
import { PermissionManager } from "../../infrastructure/utils/PermissionManager";
|
|
11
|
+
import type {
|
|
12
|
+
MediaPickerOptions,
|
|
13
|
+
MediaPickerResult,
|
|
14
|
+
CameraOptions,
|
|
15
|
+
} from "../../domain/entities/Media";
|
|
16
|
+
import { MediaLibraryPermission } from "../../domain/entities/Media";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* useMedia hook for complete media workflow
|
|
20
|
+
*
|
|
21
|
+
* USAGE:
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const {
|
|
24
|
+
* pickImage,
|
|
25
|
+
* pickMultipleImages,
|
|
26
|
+
* launchCamera,
|
|
27
|
+
* isLoading,
|
|
28
|
+
* error,
|
|
29
|
+
* } = useMedia();
|
|
30
|
+
*
|
|
31
|
+
* const handlePickImage = async () => {
|
|
32
|
+
* const result = await pickImage({ allowsEditing: true });
|
|
33
|
+
* if (!result.canceled && result.assets) {
|
|
34
|
+
* }
|
|
35
|
+
* };
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export const useMedia = () => {
|
|
39
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
40
|
+
const [error, setError] = useState<string | null>(null);
|
|
41
|
+
|
|
42
|
+
const pickImage = useCallback(
|
|
43
|
+
async (options?: MediaPickerOptions): Promise<MediaPickerResult> => {
|
|
44
|
+
setIsLoading(true);
|
|
45
|
+
setError(null);
|
|
46
|
+
try {
|
|
47
|
+
const result = await MediaPickerService.pickSingleImage(options);
|
|
48
|
+
// Set error from validation result if present
|
|
49
|
+
if (result.errorMessage) {
|
|
50
|
+
setError(result.errorMessage);
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
} catch (err) {
|
|
54
|
+
const errorMessage =
|
|
55
|
+
err instanceof Error ? err.message : "Failed to pick image";
|
|
56
|
+
setError(errorMessage);
|
|
57
|
+
return { canceled: true };
|
|
58
|
+
} finally {
|
|
59
|
+
setIsLoading(false);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
[]
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const pickMultipleImages = useCallback(
|
|
66
|
+
async (options?: MediaPickerOptions): Promise<MediaPickerResult> => {
|
|
67
|
+
setIsLoading(true);
|
|
68
|
+
setError(null);
|
|
69
|
+
try {
|
|
70
|
+
const result = await MediaPickerService.pickMultipleImages(options);
|
|
71
|
+
return result;
|
|
72
|
+
} catch (err) {
|
|
73
|
+
const errorMessage =
|
|
74
|
+
err instanceof Error ? err.message : "Failed to pick images";
|
|
75
|
+
setError(errorMessage);
|
|
76
|
+
return { canceled: true };
|
|
77
|
+
} finally {
|
|
78
|
+
setIsLoading(false);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
[]
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const pickVideo = useCallback(
|
|
85
|
+
async (options?: MediaPickerOptions): Promise<MediaPickerResult> => {
|
|
86
|
+
setIsLoading(true);
|
|
87
|
+
setError(null);
|
|
88
|
+
try {
|
|
89
|
+
const result = await MediaPickerService.pickVideo(options);
|
|
90
|
+
return result;
|
|
91
|
+
} catch (err) {
|
|
92
|
+
const errorMessage =
|
|
93
|
+
err instanceof Error ? err.message : "Failed to pick video";
|
|
94
|
+
setError(errorMessage);
|
|
95
|
+
return { canceled: true };
|
|
96
|
+
} finally {
|
|
97
|
+
setIsLoading(false);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
[]
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const launchCamera = useCallback(
|
|
104
|
+
async (options?: CameraOptions): Promise<MediaPickerResult> => {
|
|
105
|
+
setIsLoading(true);
|
|
106
|
+
setError(null);
|
|
107
|
+
try {
|
|
108
|
+
const result = await MediaPickerService.launchCamera(options);
|
|
109
|
+
return result;
|
|
110
|
+
} catch (err) {
|
|
111
|
+
const errorMessage =
|
|
112
|
+
err instanceof Error ? err.message : "Failed to launch camera";
|
|
113
|
+
setError(errorMessage);
|
|
114
|
+
return { canceled: true };
|
|
115
|
+
} finally {
|
|
116
|
+
setIsLoading(false);
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
[]
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const launchCameraForVideo = useCallback(
|
|
123
|
+
async (options?: CameraOptions): Promise<MediaPickerResult> => {
|
|
124
|
+
setIsLoading(true);
|
|
125
|
+
setError(null);
|
|
126
|
+
try {
|
|
127
|
+
const result = await MediaPickerService.launchCameraForVideo(options);
|
|
128
|
+
return result;
|
|
129
|
+
} catch (err) {
|
|
130
|
+
const errorMessage =
|
|
131
|
+
err instanceof Error ? err.message : "Failed to record video";
|
|
132
|
+
setError(errorMessage);
|
|
133
|
+
return { canceled: true };
|
|
134
|
+
} finally {
|
|
135
|
+
setIsLoading(false);
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
[]
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const requestCameraPermission =
|
|
142
|
+
useCallback(async (): Promise<MediaLibraryPermission> => {
|
|
143
|
+
try {
|
|
144
|
+
return await PermissionManager.requestCameraPermission();
|
|
145
|
+
} catch {
|
|
146
|
+
return MediaLibraryPermission.DENIED;
|
|
147
|
+
}
|
|
148
|
+
}, []);
|
|
149
|
+
|
|
150
|
+
const requestMediaLibraryPermission =
|
|
151
|
+
useCallback(async (): Promise<MediaLibraryPermission> => {
|
|
152
|
+
try {
|
|
153
|
+
return await PermissionManager.requestMediaLibraryPermission();
|
|
154
|
+
} catch {
|
|
155
|
+
return MediaLibraryPermission.DENIED;
|
|
156
|
+
}
|
|
157
|
+
}, []);
|
|
158
|
+
|
|
159
|
+
const getCameraPermissionStatus =
|
|
160
|
+
useCallback(async (): Promise<MediaLibraryPermission> => {
|
|
161
|
+
try {
|
|
162
|
+
return await PermissionManager.getCameraPermissionStatus();
|
|
163
|
+
} catch {
|
|
164
|
+
return MediaLibraryPermission.DENIED;
|
|
165
|
+
}
|
|
166
|
+
}, []);
|
|
167
|
+
|
|
168
|
+
const getMediaLibraryPermissionStatus =
|
|
169
|
+
useCallback(async (): Promise<MediaLibraryPermission> => {
|
|
170
|
+
try {
|
|
171
|
+
return await PermissionManager.getMediaLibraryPermissionStatus();
|
|
172
|
+
} catch {
|
|
173
|
+
return MediaLibraryPermission.DENIED;
|
|
174
|
+
}
|
|
175
|
+
}, []);
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
pickImage,
|
|
179
|
+
pickMultipleImages,
|
|
180
|
+
pickVideo,
|
|
181
|
+
launchCamera,
|
|
182
|
+
launchCameraForVideo,
|
|
183
|
+
requestCameraPermission,
|
|
184
|
+
requestMediaLibraryPermission,
|
|
185
|
+
getCameraPermissionStatus,
|
|
186
|
+
getMediaLibraryPermissionStatus,
|
|
187
|
+
isLoading,
|
|
188
|
+
error,
|
|
189
|
+
};
|
|
190
|
+
};
|