@umituz/react-native-design-system 2.9.39 → 2.9.41
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-design-system",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.41",
|
|
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
|
@@ -44,6 +44,16 @@ export type { SaveResult, SaveOptions } from "./infrastructure/services/MediaSav
|
|
|
44
44
|
// Presentation Layer - Original Media Hooks
|
|
45
45
|
export { useMedia } from "./presentation/hooks/useMedia";
|
|
46
46
|
|
|
47
|
+
// Media Helper Utilities
|
|
48
|
+
export {
|
|
49
|
+
getMediaTypeFromUrl,
|
|
50
|
+
isVideoUrl,
|
|
51
|
+
isImageUrl,
|
|
52
|
+
getMediaType,
|
|
53
|
+
getCardMediaType,
|
|
54
|
+
formatFileSize,
|
|
55
|
+
} from "./infrastructure/utils/mediaHelpers";
|
|
56
|
+
|
|
47
57
|
// Multimedia Flashcard Support
|
|
48
58
|
export type {
|
|
49
59
|
CardMediaType,
|
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Media Helper Utilities
|
|
3
|
-
* Shared helper functions for media operations
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
1
|
import type {
|
|
7
2
|
CardMediaAttachment,
|
|
8
3
|
CardMediaType,
|
|
9
4
|
} from "../../domain/entities/CardMultimedia.types";
|
|
10
5
|
import type { MediaAttachment } from "../../domain/entities/MultimediaFlashcardTypes";
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
type MediaTypeResult = "image" | "audio" | "video";
|
|
8
|
+
type MediaTypeFromUrlResult = "image" | "video" | "audio" | "unknown";
|
|
9
|
+
|
|
10
|
+
interface FileWithType {
|
|
11
|
+
readonly type: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const VIDEO_EXTENSIONS = [".mp4", ".webm", ".mov", ".avi", ".mkv", ".m4v"];
|
|
15
|
+
const IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg"];
|
|
16
|
+
const AUDIO_EXTENSIONS = [".mp3", ".wav", ".ogg", ".m4a", ".aac", ".flac"];
|
|
17
|
+
const FILE_SIZE_UNITS = ["Bytes", "KB", "MB", "GB"];
|
|
18
|
+
|
|
15
19
|
export const getCardMediaType = (mimeType: string): CardMediaType => {
|
|
16
20
|
if (mimeType.startsWith("image/")) return "image";
|
|
17
21
|
if (mimeType.startsWith("audio/")) return "audio";
|
|
@@ -19,21 +23,15 @@ export const getCardMediaType = (mimeType: string): CardMediaType => {
|
|
|
19
23
|
return "image";
|
|
20
24
|
};
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
* Get media type from MIME type for Media
|
|
24
|
-
*/
|
|
25
|
-
export const getMediaType = (mimeType: string): "image" | "audio" | "video" => {
|
|
26
|
+
export const getMediaType = (mimeType: string): MediaTypeResult => {
|
|
26
27
|
if (mimeType.startsWith("image/")) return "image";
|
|
27
28
|
if (mimeType.startsWith("audio/")) return "audio";
|
|
28
29
|
if (mimeType.startsWith("video/")) return "video";
|
|
29
30
|
return "image";
|
|
30
31
|
};
|
|
31
32
|
|
|
32
|
-
/**
|
|
33
|
-
* Get media duration for audio/video files
|
|
34
|
-
*/
|
|
35
33
|
export const getMediaDuration = async (
|
|
36
|
-
file:
|
|
34
|
+
file: FileWithType
|
|
37
35
|
): Promise<number | undefined> => {
|
|
38
36
|
if (file.type.startsWith("audio/") || file.type.startsWith("video/")) {
|
|
39
37
|
return Math.floor(Math.random() * 60) + 10;
|
|
@@ -41,42 +39,53 @@ export const getMediaDuration = async (
|
|
|
41
39
|
return undefined;
|
|
42
40
|
};
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
* Generate thumbnail URL for video files
|
|
46
|
-
*/
|
|
47
|
-
export const generateThumbnail = (file: any): string | undefined => {
|
|
42
|
+
export const generateThumbnail = (file: FileWithType): string | undefined => {
|
|
48
43
|
if (file.type.startsWith("video/")) {
|
|
49
44
|
return `https://picsum.photos/200/150?random=${Date.now()}`;
|
|
50
45
|
}
|
|
51
46
|
return undefined;
|
|
52
47
|
};
|
|
53
48
|
|
|
54
|
-
/**
|
|
55
|
-
* Extract unique media types from attachments
|
|
56
|
-
*/
|
|
57
49
|
export const extractMediaTypes = (
|
|
58
|
-
media: CardMediaAttachment
|
|
59
|
-
):
|
|
60
|
-
const types
|
|
50
|
+
media: readonly (CardMediaAttachment | MediaAttachment)[]
|
|
51
|
+
): MediaTypeResult[] => {
|
|
52
|
+
const types = new Set<MediaTypeResult>();
|
|
61
53
|
media.forEach((m) => types.add(m.type));
|
|
62
|
-
return Array.from(types)
|
|
54
|
+
return Array.from(types);
|
|
63
55
|
};
|
|
64
56
|
|
|
65
|
-
/**
|
|
66
|
-
* Calculate total file size of media attachments
|
|
67
|
-
*/
|
|
68
57
|
export const calculateTotalSize = (
|
|
69
|
-
media: CardMediaAttachment
|
|
58
|
+
media: readonly (CardMediaAttachment | MediaAttachment)[]
|
|
70
59
|
): number => {
|
|
71
60
|
return media.reduce((total, m) => total + m.fileSize, 0);
|
|
72
61
|
};
|
|
73
62
|
|
|
74
|
-
/**
|
|
75
|
-
* Format bytes to human-readable file size
|
|
76
|
-
*/
|
|
77
63
|
export const formatFileSize = (bytes: number): string => {
|
|
78
|
-
const sizes = ["Bytes", "KB", "MB", "GB"];
|
|
79
64
|
if (bytes === 0) return "0 Bytes";
|
|
80
65
|
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
81
|
-
return Math.round((bytes / Math.pow(1024, i)) * 100) / 100 + " " +
|
|
66
|
+
return Math.round((bytes / Math.pow(1024, i)) * 100) / 100 + " " + FILE_SIZE_UNITS[i];
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const getMediaTypeFromUrl = (url: string): MediaTypeFromUrlResult => {
|
|
70
|
+
if (!url) return "unknown";
|
|
71
|
+
|
|
72
|
+
const urlWithoutParams = url.toLowerCase().split("?")[0];
|
|
73
|
+
const lastDotIndex = urlWithoutParams.lastIndexOf(".");
|
|
74
|
+
if (lastDotIndex === -1) return "unknown";
|
|
75
|
+
|
|
76
|
+
const extension = urlWithoutParams.substring(lastDotIndex);
|
|
77
|
+
|
|
78
|
+
if (VIDEO_EXTENSIONS.includes(extension)) return "video";
|
|
79
|
+
if (IMAGE_EXTENSIONS.includes(extension)) return "image";
|
|
80
|
+
if (AUDIO_EXTENSIONS.includes(extension)) return "audio";
|
|
81
|
+
|
|
82
|
+
return "unknown";
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const isVideoUrl = (url: string): boolean => {
|
|
86
|
+
return getMediaTypeFromUrl(url) === "video";
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const isImageUrl = (url: string): boolean => {
|
|
90
|
+
return getMediaTypeFromUrl(url) === "image";
|
|
82
91
|
};
|