@umituz/react-native-design-system 2.8.7 → 2.8.9

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 (189) hide show
  1. package/package.json +10 -6
  2. package/src/device/infrastructure/repositories/LegacyDeviceIdRepository.ts +1 -1
  3. package/src/device/infrastructure/services/DeviceFeatureService.ts +1 -1
  4. package/src/exception/infrastructure/services/ExceptionLogger.ts +1 -1
  5. package/src/exception/infrastructure/storage/ExceptionStore.ts +1 -1
  6. package/src/exports/filesystem.ts +1 -0
  7. package/src/exports/media.ts +1 -0
  8. package/src/exports/storage.ts +1 -0
  9. package/src/filesystem/domain/constants/FileConstants.ts +20 -0
  10. package/src/filesystem/domain/entities/File.ts +20 -0
  11. package/src/filesystem/domain/types/FileTypes.ts +43 -0
  12. package/src/filesystem/domain/utils/FileUtils.ts +86 -0
  13. package/src/filesystem/index.ts +23 -0
  14. package/src/filesystem/infrastructure/services/FileSystemService.ts +45 -0
  15. package/src/filesystem/infrastructure/services/cache.service.ts +48 -0
  16. package/src/filesystem/infrastructure/services/directory.service.ts +66 -0
  17. package/src/filesystem/infrastructure/services/download.constants.ts +6 -0
  18. package/src/filesystem/infrastructure/services/download.service.ts +74 -0
  19. package/src/filesystem/infrastructure/services/download.types.ts +7 -0
  20. package/src/filesystem/infrastructure/services/encoding.service.ts +25 -0
  21. package/src/filesystem/infrastructure/services/file-info.service.ts +52 -0
  22. package/src/filesystem/infrastructure/services/file-manager.service.ts +81 -0
  23. package/src/filesystem/infrastructure/services/file-path.service.ts +22 -0
  24. package/src/filesystem/infrastructure/services/file-reader.service.ts +52 -0
  25. package/src/filesystem/infrastructure/services/file-writer.service.ts +32 -0
  26. package/src/filesystem/infrastructure/utils/blob.utils.ts +20 -0
  27. package/src/image/infrastructure/services/ImageStorageService.ts +1 -1
  28. package/src/index.ts +14 -0
  29. package/src/media/domain/entities/CardMultimedia.types.README.md +129 -0
  30. package/src/media/domain/entities/CardMultimedia.types.ts +105 -0
  31. package/src/media/domain/entities/Media.README.md +80 -0
  32. package/src/media/domain/entities/Media.ts +139 -0
  33. package/src/media/domain/entities/MultimediaFlashcardTypes.README.md +144 -0
  34. package/src/media/domain/entities/MultimediaFlashcardTypes.ts +105 -0
  35. package/src/media/domain/utils/MediaUtils.README.md +178 -0
  36. package/src/media/domain/utils/MediaUtils.ts +82 -0
  37. package/src/media/index.ts +70 -0
  38. package/src/media/index.ts.README.md +191 -0
  39. package/src/media/infrastructure/services/CardMediaGenerationService.README.md +99 -0
  40. package/src/media/infrastructure/services/CardMediaGenerationService.ts +101 -0
  41. package/src/media/infrastructure/services/CardMediaOptimizerService.README.md +167 -0
  42. package/src/media/infrastructure/services/CardMediaOptimizerService.ts +36 -0
  43. package/src/media/infrastructure/services/CardMediaUploadService.README.md +123 -0
  44. package/src/media/infrastructure/services/CardMediaUploadService.ts +67 -0
  45. package/src/media/infrastructure/services/CardMediaValidationService.README.md +134 -0
  46. package/src/media/infrastructure/services/CardMediaValidationService.ts +81 -0
  47. package/src/media/infrastructure/services/CardMultimediaService.README.md +176 -0
  48. package/src/media/infrastructure/services/CardMultimediaService.ts +97 -0
  49. package/src/media/infrastructure/services/MediaGenerationService.README.md +142 -0
  50. package/src/media/infrastructure/services/MediaGenerationService.ts +80 -0
  51. package/src/media/infrastructure/services/MediaOptimizerService.README.md +145 -0
  52. package/src/media/infrastructure/services/MediaOptimizerService.ts +32 -0
  53. package/src/media/infrastructure/services/MediaPickerService.README.md +106 -0
  54. package/src/media/infrastructure/services/MediaPickerService.ts +173 -0
  55. package/src/media/infrastructure/services/MediaSaveService.README.md +120 -0
  56. package/src/media/infrastructure/services/MediaSaveService.ts +154 -0
  57. package/src/media/infrastructure/services/MediaUploadService.README.md +135 -0
  58. package/src/media/infrastructure/services/MediaUploadService.ts +62 -0
  59. package/src/media/infrastructure/services/MediaValidationService.README.md +135 -0
  60. package/src/media/infrastructure/services/MediaValidationService.ts +61 -0
  61. package/src/media/infrastructure/services/MultimediaFlashcardService.README.md +142 -0
  62. package/src/media/infrastructure/services/MultimediaFlashcardService.ts +95 -0
  63. package/src/media/infrastructure/utils/mediaHelpers.README.md +96 -0
  64. package/src/media/infrastructure/utils/mediaHelpers.ts +82 -0
  65. package/src/media/infrastructure/utils/mediaPickerMappers.README.md +129 -0
  66. package/src/media/infrastructure/utils/mediaPickerMappers.ts +76 -0
  67. package/src/media/presentation/hooks/card-multimedia.types.README.md +177 -0
  68. package/src/media/presentation/hooks/card-multimedia.types.ts +51 -0
  69. package/src/media/presentation/hooks/multimedia.types.README.md +201 -0
  70. package/src/media/presentation/hooks/multimedia.types.ts +51 -0
  71. package/src/media/presentation/hooks/useCardMediaGeneration.README.md +164 -0
  72. package/src/media/presentation/hooks/useCardMediaGeneration.ts +124 -0
  73. package/src/media/presentation/hooks/useCardMediaUpload.README.md +153 -0
  74. package/src/media/presentation/hooks/useCardMediaUpload.ts +86 -0
  75. package/src/media/presentation/hooks/useCardMediaValidation.README.md +176 -0
  76. package/src/media/presentation/hooks/useCardMediaValidation.ts +101 -0
  77. package/src/media/presentation/hooks/useCardMultimediaFlashcard.README.md +158 -0
  78. package/src/media/presentation/hooks/useCardMultimediaFlashcard.ts +104 -0
  79. package/src/media/presentation/hooks/useMedia.README.md +94 -0
  80. package/src/media/presentation/hooks/useMedia.ts +186 -0
  81. package/src/media/presentation/hooks/useMediaGeneration.README.md +118 -0
  82. package/src/media/presentation/hooks/useMediaGeneration.ts +101 -0
  83. package/src/media/presentation/hooks/useMediaUpload.README.md +108 -0
  84. package/src/media/presentation/hooks/useMediaUpload.ts +86 -0
  85. package/src/media/presentation/hooks/useMediaValidation.README.md +134 -0
  86. package/src/media/presentation/hooks/useMediaValidation.ts +93 -0
  87. package/src/media/presentation/hooks/useMultimediaFlashcard.README.md +141 -0
  88. package/src/media/presentation/hooks/useMultimediaFlashcard.ts +103 -0
  89. package/src/molecules/alerts/AlertStore.ts +1 -1
  90. package/src/molecules/calendar/infrastructure/storage/EventActions.ts +1 -1
  91. package/src/molecules/calendar/infrastructure/stores/storageAdapter.ts +1 -1
  92. package/src/offline/infrastructure/storage/OfflineStore.ts +1 -1
  93. package/src/onboarding/infrastructure/storage/OnboardingStore.ts +2 -2
  94. package/src/onboarding/infrastructure/storage/__tests__/OnboardingStore.test.ts +1 -1
  95. package/src/onboarding/infrastructure/storage/actions/answerActions.ts +1 -1
  96. package/src/onboarding/infrastructure/storage/actions/storageHelpers.ts +1 -1
  97. package/src/storage/README.md +185 -0
  98. package/src/storage/__tests__/integration.test.ts +391 -0
  99. package/src/storage/__tests__/mocks/asyncStorage.mock.ts +52 -0
  100. package/src/storage/__tests__/performance.test.tsx +352 -0
  101. package/src/storage/__tests__/setup.ts +63 -0
  102. package/src/storage/application/README.md +158 -0
  103. package/src/storage/application/ports/IStorageRepository.ts +61 -0
  104. package/src/storage/application/ports/README.md +127 -0
  105. package/src/storage/cache/README.md +154 -0
  106. package/src/storage/cache/__tests__/PerformanceAndMemory.test.ts +387 -0
  107. package/src/storage/cache/__tests__/setup.ts +19 -0
  108. package/src/storage/cache/domain/Cache.ts +146 -0
  109. package/src/storage/cache/domain/CacheManager.md +83 -0
  110. package/src/storage/cache/domain/CacheManager.ts +48 -0
  111. package/src/storage/cache/domain/CacheStatsTracker.md +169 -0
  112. package/src/storage/cache/domain/CacheStatsTracker.ts +49 -0
  113. package/src/storage/cache/domain/CachedValue.md +97 -0
  114. package/src/storage/cache/domain/ErrorHandler.md +99 -0
  115. package/src/storage/cache/domain/ErrorHandler.ts +42 -0
  116. package/src/storage/cache/domain/PatternMatcher.md +122 -0
  117. package/src/storage/cache/domain/PatternMatcher.ts +30 -0
  118. package/src/storage/cache/domain/README.md +118 -0
  119. package/src/storage/cache/domain/__tests__/Cache.test.ts +293 -0
  120. package/src/storage/cache/domain/__tests__/CacheManager.test.ts +276 -0
  121. package/src/storage/cache/domain/__tests__/ErrorHandler.test.ts +303 -0
  122. package/src/storage/cache/domain/__tests__/PatternMatcher.test.ts +261 -0
  123. package/src/storage/cache/domain/strategies/EvictionStrategy.ts +9 -0
  124. package/src/storage/cache/domain/strategies/FIFOStrategy.ts +12 -0
  125. package/src/storage/cache/domain/strategies/LFUStrategy.ts +22 -0
  126. package/src/storage/cache/domain/strategies/LRUStrategy.ts +22 -0
  127. package/src/storage/cache/domain/strategies/README.md +117 -0
  128. package/src/storage/cache/domain/strategies/TTLStrategy.ts +23 -0
  129. package/src/storage/cache/domain/strategies/__tests__/EvictionStrategies.test.ts +293 -0
  130. package/src/storage/cache/domain/types/Cache.ts +28 -0
  131. package/src/storage/cache/domain/types/README.md +107 -0
  132. package/src/storage/cache/index.ts +28 -0
  133. package/src/storage/cache/infrastructure/README.md +126 -0
  134. package/src/storage/cache/infrastructure/TTLCache.ts +103 -0
  135. package/src/storage/cache/infrastructure/__tests__/TTLCache.test.ts +303 -0
  136. package/src/storage/cache/presentation/README.md +123 -0
  137. package/src/storage/cache/presentation/__tests__/ReactHooks.test.ts +514 -0
  138. package/src/storage/cache/presentation/useCache.ts +76 -0
  139. package/src/storage/cache/presentation/useCachedValue.ts +88 -0
  140. package/src/storage/cache/types.d.ts +3 -0
  141. package/src/storage/domain/README.md +128 -0
  142. package/src/storage/domain/constants/CacheDefaults.ts +64 -0
  143. package/src/storage/domain/constants/README.md +105 -0
  144. package/src/storage/domain/entities/CachedValue.ts +86 -0
  145. package/src/storage/domain/entities/README.md +109 -0
  146. package/src/storage/domain/entities/StorageResult.ts +75 -0
  147. package/src/storage/domain/entities/__tests__/CachedValue.test.ts +149 -0
  148. package/src/storage/domain/entities/__tests__/StorageResult.test.ts +122 -0
  149. package/src/storage/domain/errors/README.md +126 -0
  150. package/src/storage/domain/errors/StorageError.ts +81 -0
  151. package/src/storage/domain/errors/__tests__/StorageError.test.ts +127 -0
  152. package/src/storage/domain/factories/README.md +138 -0
  153. package/src/storage/domain/factories/StoreFactory.ts +59 -0
  154. package/src/storage/domain/types/README.md +522 -0
  155. package/src/storage/domain/types/Store.ts +44 -0
  156. package/src/storage/domain/utils/CacheKeyGenerator.ts +66 -0
  157. package/src/storage/domain/utils/README.md +127 -0
  158. package/src/storage/domain/utils/__tests__/devUtils.test.ts +97 -0
  159. package/src/storage/domain/utils/devUtils.ts +37 -0
  160. package/src/storage/domain/value-objects/README.md +120 -0
  161. package/src/storage/domain/value-objects/StorageKey.ts +60 -0
  162. package/src/storage/index.ts +175 -0
  163. package/src/storage/infrastructure/README.md +165 -0
  164. package/src/storage/infrastructure/adapters/README.md +175 -0
  165. package/src/storage/infrastructure/adapters/StorageService.md +103 -0
  166. package/src/storage/infrastructure/adapters/StorageService.ts +49 -0
  167. package/src/storage/infrastructure/repositories/AsyncStorageRepository.ts +98 -0
  168. package/src/storage/infrastructure/repositories/BaseStorageOperations.ts +100 -0
  169. package/src/storage/infrastructure/repositories/BatchStorageOperations.ts +42 -0
  170. package/src/storage/infrastructure/repositories/README.md +121 -0
  171. package/src/storage/infrastructure/repositories/StringStorageOperations.ts +44 -0
  172. package/src/storage/infrastructure/repositories/__tests__/AsyncStorageRepository.test.ts +170 -0
  173. package/src/storage/infrastructure/repositories/__tests__/BaseStorageOperations.test.ts +201 -0
  174. package/src/storage/presentation/README.md +181 -0
  175. package/src/storage/presentation/hooks/CacheStorageOperations.ts +94 -0
  176. package/src/storage/presentation/hooks/README.md +128 -0
  177. package/src/storage/presentation/hooks/__tests__/usePersistentCache.test.ts +405 -0
  178. package/src/storage/presentation/hooks/__tests__/useStorage.test.ts +247 -0
  179. package/src/storage/presentation/hooks/__tests__/useStorageState.test.ts +293 -0
  180. package/src/storage/presentation/hooks/useCacheState.ts +53 -0
  181. package/src/storage/presentation/hooks/usePersistentCache.ts +154 -0
  182. package/src/storage/presentation/hooks/useStorage.ts +102 -0
  183. package/src/storage/presentation/hooks/useStorageState.ts +71 -0
  184. package/src/storage/presentation/hooks/useStore.ts +15 -0
  185. package/src/storage/types/README.md +103 -0
  186. package/src/theme/infrastructure/globalThemeStore.ts +1 -1
  187. package/src/theme/infrastructure/storage/ThemeStorage.ts +1 -1
  188. package/src/theme/infrastructure/stores/themeStore.ts +1 -1
  189. package/src/utilities/sharing/infrastructure/services/SharingService.ts +1 -1
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Media Generation Hook
3
+ * Hook for generating media with AI
4
+ */
5
+
6
+ import React from "react";
7
+ import type { UseMediaGenerationResult } from "./multimedia.types";
8
+ import type {
9
+ MediaAttachment,
10
+ MediaGenerationRequest,
11
+ MediaGenerationResult,
12
+ } from "../../domain/entities/MultimediaFlashcardTypes";
13
+
14
+ export const useMediaGeneration = (): UseMediaGenerationResult => {
15
+ const [isGenerating, setIsGenerating] = React.useState(false);
16
+ const [generationResult, setGenerationResult] =
17
+ React.useState<MediaGenerationResult | null>(null);
18
+ const [error, setError] = React.useState<string | null>(null);
19
+
20
+ const generateMedia = React.useCallback(
21
+ async (request: MediaGenerationRequest): Promise<MediaGenerationResult> => {
22
+ try {
23
+ setIsGenerating(true);
24
+ setError(null);
25
+
26
+ // Simulate generation
27
+ await new Promise((resolve) => setTimeout(resolve, 3000));
28
+
29
+ const attachments: MediaAttachment[] = [];
30
+
31
+ switch (request.type) {
32
+ case "text_to_image":
33
+ for (let i = 0; i < (request.options.maxResults || 1); i++) {
34
+ attachments.push({
35
+ id: `ai_img_${Date.now()}_${i}`,
36
+ type: "image",
37
+ position: "both",
38
+ url: `https://picsum.photos/400/300?random=${Date.now() + i}`,
39
+ filename: `ai_generated_${i}.jpg`,
40
+ fileSize: 150000, // 150KB
41
+ mimeType: "image/jpeg",
42
+ isDownloaded: false,
43
+ createdAt: new Date().toISOString(),
44
+ });
45
+ }
46
+ break;
47
+
48
+ case "text_to_audio":
49
+ attachments.push({
50
+ id: `ai_audio_${Date.now()}`,
51
+ type: "audio",
52
+ position: "back",
53
+ url: `https://example.com/audio_${Date.now()}.mp3`,
54
+ filename: `ai_generated_${Date.now()}.mp3`,
55
+ fileSize: 80000, // 80KB
56
+ mimeType: "audio/mp3",
57
+ duration: 10, // 10 seconds
58
+ isDownloaded: false,
59
+ createdAt: new Date().toISOString(),
60
+ });
61
+ break;
62
+ }
63
+
64
+ const result: MediaGenerationResult = {
65
+ success: true,
66
+ attachments,
67
+ creditsUsed: request.type === "text_to_image" ? 5 : 3,
68
+ processingTime: 3000,
69
+ requestId: `req_${Date.now()}`,
70
+ };
71
+
72
+ setGenerationResult(result);
73
+ return result;
74
+ } catch (err) {
75
+ const errorMessage =
76
+ err instanceof Error ? err.message : "Generation failed";
77
+ setError(errorMessage);
78
+ setIsGenerating(false);
79
+
80
+ return {
81
+ success: false,
82
+ attachments: [],
83
+ creditsUsed: 0,
84
+ processingTime: 0,
85
+ error: errorMessage,
86
+ requestId: "",
87
+ };
88
+ } finally {
89
+ setIsGenerating(false);
90
+ }
91
+ },
92
+ [],
93
+ );
94
+
95
+ return {
96
+ generateMedia,
97
+ isGenerating,
98
+ generationResult,
99
+ error,
100
+ };
101
+ };
@@ -0,0 +1,108 @@
1
+ # useMediaUpload
2
+
3
+ ## Purpose
4
+ React hook for uploading media files to server with progress tracking and compression support.
5
+
6
+ ## File Location
7
+ `src/presentation/hooks/useMediaUpload.ts`
8
+
9
+ ## Strategy
10
+ - Provide unified media upload interface with progress tracking
11
+ - Support compression options to optimize file sizes before upload
12
+ - Track upload progress with percentage and status updates
13
+ - Handle upload errors gracefully with proper error propagation
14
+ - Maintain loading state to prevent duplicate uploads
15
+ - Support various media types (image, video, audio)
16
+ - Generate automatic thumbnails for media files
17
+
18
+ ## Forbidden
19
+ - **DO NOT** start new upload while previous upload is in progress
20
+ - **DO NOT** ignore compression options - always apply before upload
21
+ - **DO NOT** upload files without validation (use useMediaValidation first)
22
+ - **DO NOT** mock upload process in production without integration
23
+ - **DO NOT** modify file during upload (compression happens before)
24
+ - **DO NOT** assume upload will succeed - always handle errors
25
+ - **DO NOT** use hardcoded API endpoints - must be configurable
26
+ - **DO NOT** bypass progress tracking for async uploads
27
+ - **DO NOT** store upload results permanently in hook state
28
+
29
+ ## Rules
30
+ 1. Always validate files before uploading (use useMediaValidation hook)
31
+ 2. Compression quality must be in 0-1 range
32
+ 3. Dimensions must be in pixels (maxWidth, maxHeight)
33
+ 4. Progress updates must be emitted every 10% or on status change
34
+ 5. Upload state must be cleared on error or completion
35
+ 6. Return complete MediaAttachment object on success
36
+ 7. Generate thumbnail URL automatically for visual media
37
+ 8. Calculate duration for audio/video files
38
+ 9. Update progress status: uploading -> completed or error
39
+ 10. Include unique fileId in progress tracking
40
+
41
+ ## AI Agent Guidelines
42
+
43
+ When working with useMediaUpload hook:
44
+
45
+ 1. **Pre-upload Validation**: Always use useMediaValidation before calling uploadMedia
46
+ 2. **Progress Tracking**: Monitor uploadProgress state for real-time updates
47
+ 3. **Compression**: Apply appropriate compression based on use case
48
+ 4. **Error Recovery**: Handle upload errors and allow retry logic
49
+ 5. **File Size**: Consider file size when choosing compression settings
50
+
51
+ ### Upload Workflow
52
+
53
+ 1. Validate file with useMediaValidation hook
54
+ 2. Select compression options based on file type and size
55
+ 3. Call uploadMedia with file and options
56
+ 4. Monitor uploadProgress for status updates
57
+ 5. Handle completion (success or error)
58
+ 6. Process returned MediaAttachment object
59
+
60
+ ### Compression Guidelines
61
+
62
+ **High Quality** (quality: 0.9, maxWidth: 4096)
63
+ - Use for professional photos, detailed graphics
64
+ - Larger file size, best quality
65
+
66
+ **Medium Quality** (quality: 0.7, maxWidth: 1920) - RECOMMENDED
67
+ - Balanced quality and size
68
+ - Good for most use cases
69
+
70
+ **Low Quality** (quality: 0.5, maxWidth: 1280)
71
+ - Use for thumbnails, previews
72
+ - Smallest file size, reduced quality
73
+
74
+ ### Upload Progress States
75
+
76
+ - **uploading**: Upload in progress, progress 0-99%
77
+ - **completed**: Upload finished successfully, progress 100%
78
+ - **error**: Upload failed, error message available
79
+
80
+ ### MediaAttachment Structure
81
+
82
+ Returned object includes:
83
+ - id: Unique identifier
84
+ - url: Uploaded file URL
85
+ - type: MediaType (IMAGE, VIDEO, AUDIO)
86
+ - position: MediaPosition (front, back, both)
87
+ - filename: Original filename
88
+ - fileSize: Size in bytes
89
+ - mimeType: MIME type string
90
+ - duration: Audio/video duration in seconds
91
+ - thumbnailUrl: Thumbnail URL for visual media
92
+ - caption: Optional caption text
93
+ - isDownloaded: Download status flag
94
+ - createdAt: ISO timestamp
95
+
96
+ ### Integration Requirements
97
+
98
+ - Configure API endpoint for upload service
99
+ - Implement actual upload logic in MediaUploadService
100
+ - Handle authentication tokens for uploads
101
+ - Support retry logic for failed uploads
102
+ - Implement timeout handling for large files
103
+
104
+ ## Dependencies
105
+
106
+ - MediaUploadService (infrastructure layer)
107
+ - Domain types: MediaAttachment, MediaCompressionOptions, MediaUploadProgress
108
+ - useMediaValidation (for pre-upload validation)
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Media Upload Hook
3
+ * Hook for uploading media files
4
+ */
5
+
6
+ import React from "react";
7
+ import {
8
+ generateThumbnail,
9
+ getMediaDuration,
10
+ getMediaType,
11
+ } from "../../infrastructure/utils/mediaHelpers";
12
+ import type { UseMediaUploadResult } from "./multimedia.types";
13
+ import type {
14
+ MediaAttachment,
15
+ MediaCompressionOptions,
16
+ MediaUploadProgress,
17
+ } from "../../domain/entities/MultimediaFlashcardTypes";
18
+
19
+ export const useMediaUpload = (): UseMediaUploadResult => {
20
+ const [isUploading, setIsUploading] = React.useState(false);
21
+ const [uploadProgress, setUploadProgress] =
22
+ React.useState<MediaUploadProgress | null>(null);
23
+ const [error, setError] = React.useState<string | null>(null);
24
+
25
+ const uploadMedia = React.useCallback(
26
+ async (file: any, options?: MediaCompressionOptions) => {
27
+ try {
28
+ setIsUploading(true);
29
+ setError(null);
30
+
31
+ // Simulate upload progress
32
+ setUploadProgress({
33
+ fileId: `upload_${Date.now()}`,
34
+ progress: 0,
35
+ status: "uploading",
36
+ });
37
+
38
+ // Simulate progress updates
39
+ for (let i = 1; i <= 100; i += 10) {
40
+ await new Promise((resolve) => setTimeout(resolve, 100));
41
+ setUploadProgress((prev) => (prev ? { ...prev, progress: i } : null));
42
+ }
43
+
44
+ const attachment: MediaAttachment = {
45
+ id: `media_${Date.now()}`,
46
+ type: getMediaType(file.type),
47
+ position: "both",
48
+ url: `https://storage.example.com/media/${Date.now()}_${file.name}`,
49
+ filename: file.name,
50
+ fileSize: file.size || 100000,
51
+ mimeType: file.type,
52
+ duration: await getMediaDuration(file),
53
+ thumbnailUrl: generateThumbnail(file),
54
+ caption: "",
55
+ isDownloaded: true,
56
+ createdAt: new Date().toISOString(),
57
+ };
58
+
59
+ setUploadProgress({
60
+ fileId: `upload_${Date.now()}`,
61
+ progress: 100,
62
+ status: "completed",
63
+ url: attachment.url,
64
+ });
65
+
66
+ return attachment;
67
+ } catch (err) {
68
+ const errorMessage =
69
+ err instanceof Error ? err.message : "Upload failed";
70
+ setError(errorMessage);
71
+ setIsUploading(false);
72
+ throw err;
73
+ } finally {
74
+ setIsUploading(false);
75
+ }
76
+ },
77
+ [],
78
+ );
79
+
80
+ return {
81
+ uploadMedia,
82
+ isUploading,
83
+ uploadProgress,
84
+ error,
85
+ };
86
+ };
@@ -0,0 +1,134 @@
1
+ # useMediaValidation
2
+
3
+ ## Purpose
4
+ React hook for validating media files before upload, checking file size, type, and providing improvement recommendations.
5
+
6
+ ## File Location
7
+ `src/presentation/hooks/useMediaValidation.ts`
8
+
9
+ ## Strategy
10
+ - Provide comprehensive media file validation before upload
11
+ - Check file size limits with appropriate warnings
12
+ - Validate MIME types against supported formats
13
+ - Provide three-tier feedback: errors (blocking), warnings (performance), recommendations (improvements)
14
+ - Support validation state management
15
+ - Enable pre-upload validation workflow
16
+ - Return actionable feedback for each validation issue
17
+
18
+ ## Forbidden
19
+ - **DO NOT** upload files that fail validation (errors present)
20
+ - **DO NOT** ignore warnings - they indicate performance issues
21
+ - **DO NOT** bypass file type validation
22
+ - **DO NOT** use mock validation in production
23
+ - **DO NOT** allow files exceeding maximum size limits
24
+ - **DO NOT** modify file during validation process
25
+ - **DO NOT** store validation results permanently in hook state
26
+ - **DO NOT** validate empty or missing files
27
+ - **DO NOT** suppress validation errors for user convenience
28
+
29
+ ## Rules
30
+ 1. Always validate before upload operations
31
+ 2. Files over 50 MB must be rejected with error
32
+ 3. Files over 10 MB must trigger warning and recommendation
33
+ 4. Unsupported MIME types must be rejected
34
+ 5. Validation must check file size, type, and format
35
+ 6. Return errors array for blocking issues
36
+ 7. Return warnings array for performance concerns
37
+ 8. Return recommendations array for improvements
38
+ 9. Clear validation state on new validation requests
39
+ 10. Support synchronous and asynchronous validation
40
+
41
+ ## AI Agent Guidelines
42
+
43
+ When working with useMediaValidation hook:
44
+
45
+ 1. **Pre-upload Check**: Always validate before useMediaUpload calls
46
+ 2. **Three-Tier Feedback**: Distinguish between errors, warnings, recommendations
47
+ 3. **User Decision**: Show warnings but allow user to proceed
48
+ 4. **File Size**: Be strict with maximum limits, flexible with warnings
49
+ 5. **Type Safety**: Validate MIME types against supported formats
50
+
51
+ ### Validation Levels
52
+
53
+ **Errors** (Blocking - Must fix before upload):
54
+ - File size exceeds 50 MB
55
+ - Unsupported file type
56
+ - Invalid file format
57
+ - Missing required properties
58
+
59
+ **Warnings** (Performance - Should fix but can proceed):
60
+ - File size over 10 MB (performance impact)
61
+ - Large dimensions (may need optimization)
62
+ - Non-standard format (compatibility issues)
63
+
64
+ **Recommendations** (Improvements - Optional suggestions):
65
+ - Reduce file size for better performance
66
+ - Use recommended format (JPEG for images, MP4 for video)
67
+ - Optimize dimensions for target use case
68
+ - Compress to balance quality and size
69
+
70
+ ### Supported File Types
71
+
72
+ **Images:**
73
+ - image/jpeg (JPEG photos)
74
+ - image/png (PNG graphics with transparency)
75
+ - image/webp (WebP format)
76
+
77
+ **Audio:**
78
+ - audio/mp3 (MP3 compressed audio)
79
+ - audio/wav (WAV uncompressed audio)
80
+ - audio/m4a (M4A audio format)
81
+
82
+ **Video:**
83
+ - video/mp4 (MP4 video)
84
+ - video/mov (QuickTime video)
85
+
86
+ ### Validation Workflow
87
+
88
+ 1. Receive file object with name, type, size, uri
89
+ 2. Check file size against limits (50 MB max, 10 MB warning)
90
+ 3. Validate MIME type against supported formats
91
+ 4. Generate appropriate errors, warnings, recommendations
92
+ 5. Return MediaValidation object with results
93
+ 6. Display feedback to user for action
94
+
95
+ ### Validation State Management
96
+
97
+ - isValid: Boolean (true if no errors)
98
+ - errors: String array (blocking issues)
99
+ - warnings: String array (performance concerns)
100
+ - recommendations: String array (improvement suggestions)
101
+
102
+ ### Integration with Upload Flow
103
+
104
+ Typical validation-upload workflow:
105
+ 1. Select file from picker or file system
106
+ 2. Call validateMedia(file)
107
+ 3. Check validation.isValid
108
+ 4. If errors: Show to user, block upload
109
+ 5. If warnings: Show to user, ask confirmation
110
+ 6. If recommendations: Show to user for reference
111
+ 7. Proceed to upload if no errors or user confirms warnings
112
+
113
+ ### File Size Guidelines
114
+
115
+ **Images:**
116
+ - Optimal: Under 2 MB
117
+ - Warning: 2-10 MB
118
+ - Error: Over 50 MB
119
+
120
+ **Audio:**
121
+ - Optimal: Under 5 MB
122
+ - Warning: 5-10 MB
123
+ - Error: Over 50 MB
124
+
125
+ **Video:**
126
+ - Optimal: Under 10 MB
127
+ - Warning: 10-50 MB
128
+ - Error: Over 50 MB
129
+
130
+ ## Dependencies
131
+
132
+ - MediaValidationService (infrastructure layer)
133
+ - Domain types: MediaValidation, file input interfaces
134
+ - Media constants (size limits, supported types)
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Media Validation Hook
3
+ * Hook for validating media files
4
+ */
5
+
6
+ import React from "react";
7
+ import { formatFileSize } from "../../infrastructure/utils/mediaHelpers";
8
+ import type { UseMediaValidationResult } from "./multimedia.types";
9
+ import type { MediaValidation } from "../../domain/entities/MultimediaFlashcardTypes";
10
+
11
+ export const useMediaValidation = (): UseMediaValidationResult => {
12
+ const [isValidating, setIsValidating] = React.useState(false);
13
+ const [validation, setValidation] = React.useState<MediaValidation | null>(
14
+ null,
15
+ );
16
+ const [error, setError] = React.useState<string | null>(null);
17
+
18
+ const validateMedia = React.useCallback(
19
+ async (file: any): Promise<MediaValidation> => {
20
+ try {
21
+ setIsValidating(true);
22
+ setError(null);
23
+
24
+ // Simulate validation
25
+ await new Promise((resolve) => setTimeout(resolve, 500));
26
+
27
+ const errors: string[] = [];
28
+ const warnings: string[] = [];
29
+ const recommendations: string[] = [];
30
+
31
+ // File size validation
32
+ const maxSize = 50 * 1024 * 1024; // 50MB
33
+ if (file.size > maxSize) {
34
+ errors.push(
35
+ `File size (${formatFileSize(file.size)}) exceeds maximum allowed size (${formatFileSize(maxSize)})`,
36
+ );
37
+ } else if (file.size > 10 * 1024 * 1024) {
38
+ // 10MB
39
+ warnings.push(`Large file size may impact performance`);
40
+ recommendations.push("Consider compressing file");
41
+ }
42
+
43
+ // File type validation
44
+ const supportedTypes = [
45
+ "image/jpeg",
46
+ "image/png",
47
+ "image/webp",
48
+ "audio/mp3",
49
+ "audio/wav",
50
+ "audio/m4a",
51
+ "video/mp4",
52
+ "video/mov",
53
+ ];
54
+
55
+ if (!supportedTypes.includes(file.type)) {
56
+ errors.push(`Unsupported file type: ${file.type}`);
57
+ }
58
+
59
+ const result: MediaValidation = {
60
+ isValid: errors.length === 0,
61
+ errors,
62
+ warnings,
63
+ recommendations,
64
+ };
65
+
66
+ setValidation(result);
67
+ return result;
68
+ } catch (err) {
69
+ const errorMessage =
70
+ err instanceof Error ? err.message : "Validation failed";
71
+ setError(errorMessage);
72
+ setIsValidating(false);
73
+
74
+ return {
75
+ isValid: false,
76
+ errors: [errorMessage],
77
+ warnings: [],
78
+ recommendations: [],
79
+ };
80
+ } finally {
81
+ setIsValidating(false);
82
+ }
83
+ },
84
+ [],
85
+ );
86
+
87
+ return {
88
+ validateMedia,
89
+ isValidating,
90
+ validation,
91
+ error,
92
+ };
93
+ };
@@ -0,0 +1,141 @@
1
+ # useMultimediaFlashcard
2
+
3
+ ## Purpose
4
+ Main hook for creating and managing flashcards with media attachments, providing all multimedia operations in one place.
5
+
6
+ ## File Location
7
+ `src/presentation/hooks/useMultimediaFlashcard.ts`
8
+
9
+ ## Strategy
10
+ - Provide unified interface for flashcard creation with media support
11
+ - Support adding, updating, and deleting media on flashcards
12
+ - Automatically analyze media composition (types, sizes, positions)
13
+ - Calculate estimated storage requirements
14
+ - Track download status for offline support
15
+ - Enable rich multimedia flashcard experiences
16
+ - Maintain separation between card data and media management
17
+
18
+ ## Forbidden
19
+ - **DO NOT** create flashcards without required fields (front, back)
20
+ - **DO NOT** add media without proper validation first
21
+ - **DO NOT** allow duplicate media attachments with same ID
22
+ - **DO NOT** mock card operations in production without backend integration
23
+ - **DO NOT** assume all media is downloaded (check isDownloaded flag)
24
+ - **DO NOT** modify card structure after creation (use update functions)
25
+ - **DO NOT** exceed practical media limits per card (performance)
26
+ - **DO NOT** store large media directly in card object (use references)
27
+ - **DO NOT** bypass media analysis for size estimation
28
+
29
+ ## Rules
30
+ 1. Always validate media before adding to flashcard
31
+ 2. Calculate estimatedSize from all media attachments
32
+ 3. Generate unique ID for each flashcard
33
+ 4. Analyze media types and populate mediaType array
34
+ 5. Set hasMedia flag based on media array length
35
+ 6. Set isDownloaded based on all media download status
36
+ 7. Support front, back, and both positions for media
37
+ 8. Return complete MultimediaFlashcard object
38
+ 9. Clear processing state on completion or error
39
+ 10. Support empty media array for text-only cards
40
+
41
+ ## AI Agent Guidelines
42
+
43
+ When working with useMultimediaFlashcard hook:
44
+
45
+ 1. **Media First**: Upload and validate media before creating card
46
+ 2. **Size Awareness**: Monitor estimatedSize for performance implications
47
+ 3. **Type Analysis**: Use mediaType array to determine card capabilities
48
+ 4. **Download Status**: Check isDownloaded before displaying media
49
+ 5. **Position Strategy**: Assign appropriate position (front, back, both)
50
+
51
+ ### Card Creation Workflow
52
+
53
+ 1. Prepare card content (front text, back text)
54
+ 2. Upload and validate media files separately
55
+ 3. Collect MediaAttachment objects
56
+ 4. Call createMultimediaCard with data
57
+ 5. Receive complete MultimediaFlashcard object
58
+ 6. Use returned card for display and storage
59
+
60
+ ### Flashcard Structure
61
+
62
+ MultimediaFlashcard includes:
63
+ - id: Unique card identifier
64
+ - front: Front side content (question/prompt)
65
+ - back: Back side content (answer/explanation)
66
+ - difficulty: easy/medium/hard
67
+ - tags: Array of topic tags
68
+ - media: Array of MediaAttachment objects
69
+ - hasMedia: Boolean flag for media presence
70
+ - mediaType: Array of unique media types present
71
+ - isDownloaded: Boolean (all media downloaded)
72
+ - estimatedSize: Total size in bytes
73
+ - createdAt: ISO timestamp
74
+
75
+ ### Media Analysis
76
+
77
+ **hasMedia**: True if media array has items
78
+ **mediaType**: Unique array of media types (image, audio, video)
79
+ **isDownloaded**: True if all media.isDownloaded are true
80
+ **estimatedSize**: Sum of all media.fileSize values
81
+
82
+ ### Media Positioning
83
+
84
+ Media can be assigned to:
85
+ - **front**: Displayed on front side of card
86
+ - **back**: Displayed on back side of card
87
+ - **both**: Displayed on both sides
88
+
89
+ ### Card Management Operations
90
+
91
+ **createMultimediaCard**: Create new card with media
92
+ - Validates required fields (front, back)
93
+ - Processes media array
94
+ - Generates unique ID
95
+ - Analyzes media composition
96
+ - Calculates estimated size
97
+
98
+ **updateMedia**: Replace media on existing card
99
+ - Updates media array
100
+ - Re-analyzes composition
101
+ - Recalculates size
102
+ - Preserves card ID and metadata
103
+
104
+ **deleteMedia**: Remove specific media attachment
105
+ - Removes from media array by ID
106
+ - Updates analysis
107
+ - Recalculates size
108
+
109
+ ### Integration with Other Hooks
110
+
111
+ Typical workflow combining multiple hooks:
112
+ 1. useMedia: Select images/videos
113
+ 2. useMediaUpload: Upload selected media
114
+ 3. useMediaValidation: Validate before upload
115
+ 4. useMediaGeneration: Generate AI media (optional)
116
+ 5. useMultimediaFlashcard: Create card with media
117
+
118
+ ### Performance Considerations
119
+
120
+ - Limit media count per card (recommend 5-10 items)
121
+ - Monitor estimatedSize (warn over 25 MB)
122
+ - Use thumbnails for previews
123
+ - Lazy load media when displaying cards
124
+ - Cache cards with downloaded media
125
+
126
+ ### Best Practices
127
+
128
+ 1. Always validate media before adding to cards
129
+ 2. Use descriptive tags for card organization
130
+ 3. Set appropriate difficulty levels
131
+ 4. Balance media types (don't overload with videos)
132
+ 5. Consider offline usage (isDownloaded flag)
133
+ 6. Provide captions for accessibility
134
+
135
+ ## Dependencies
136
+
137
+ - MultimediaFlashcardService (infrastructure layer)
138
+ - Domain types: MultimediaFlashcard, MediaAttachment
139
+ - useMediaUpload (for media upload)
140
+ - useMediaValidation (for media validation)
141
+ - useMediaGeneration (for AI media generation)