@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.39",
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",
@@ -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
- * Get media type from MIME type for CardMedia
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: any
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[] | MediaAttachment[]
59
- ): ("image" | "audio" | "video")[] => {
60
- const types: Set<string> = new Set();
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) as ("image" | "audio" | "video")[];
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[] | MediaAttachment[]
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 + " " + sizes[i];
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
  };