@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,124 @@
1
+ /**
2
+ * Card Media Generation Hook
3
+ * Hook for generating card media with AI
4
+ */
5
+
6
+ import React from "react";
7
+ import type { UseCardMediaGenerationResult } from "./card-multimedia.types";
8
+ import type {
9
+ CardMediaAttachment,
10
+ CardMediaGenerationRequest,
11
+ CardMediaGenerationResult,
12
+ } from "../../domain/entities/CardMultimedia.types";
13
+
14
+ export const useCardMediaGeneration = (): UseCardMediaGenerationResult => {
15
+ const [isGenerating, setIsGenerating] = React.useState(false);
16
+ const [generationResult, setGenerationResult] =
17
+ React.useState<CardMediaGenerationResult | null>(null);
18
+ const [error, setError] = React.useState<string | null>(null);
19
+
20
+ const generateMedia = React.useCallback(
21
+ async (
22
+ request: CardMediaGenerationRequest,
23
+ ): Promise<CardMediaGenerationResult> => {
24
+ try {
25
+ setIsGenerating(true);
26
+ setError(null);
27
+
28
+ // Simulate generation
29
+ await new Promise((resolve) => setTimeout(resolve, 3000));
30
+
31
+ const attachments: CardMediaAttachment[] = [];
32
+
33
+ switch (request.type) {
34
+ case "text_to_image":
35
+ for (let i = 0; i < (request.options.maxResults || 1); i++) {
36
+ attachments.push({
37
+ id: `ai_img_${Date.now()}_${i}`,
38
+ type: "image",
39
+ position: "both",
40
+ url: `https://picsum.photos/400/300?random=${Date.now() + i}`,
41
+ filename: `ai_generated_${i}.jpg`,
42
+ fileSize: 150000, // 150KB
43
+ mimeType: "image/jpeg",
44
+ isDownloaded: false,
45
+ createdAt: new Date().toISOString(),
46
+ });
47
+ }
48
+ break;
49
+
50
+ case "text_to_audio":
51
+ attachments.push({
52
+ id: `ai_audio_${Date.now()}`,
53
+ type: "audio",
54
+ position: "back",
55
+ url: `https://example.com/audio_${Date.now()}.mp3`,
56
+ filename: `ai_generated_${Date.now()}.mp3`,
57
+ fileSize: 80000, // 80KB
58
+ mimeType: "audio/mp3",
59
+ duration: 10, // 10 seconds
60
+ isDownloaded: false,
61
+ createdAt: new Date().toISOString(),
62
+ });
63
+ break;
64
+
65
+ case "image_search":
66
+ for (let i = 0; i < (request.options.maxResults || 5); i++) {
67
+ attachments.push({
68
+ id: `search_img_${Date.now()}_${i}`,
69
+ type: "image",
70
+ position: "both",
71
+ url: `https://picsum.photos/400/300?random=${Date.now() + i}`,
72
+ filename: `search_result_${i}.jpg`,
73
+ fileSize: 120000, // 120KB
74
+ mimeType: "image/jpeg",
75
+ isDownloaded: false,
76
+ createdAt: new Date().toISOString(),
77
+ });
78
+ }
79
+ break;
80
+ }
81
+
82
+ const result: CardMediaGenerationResult = {
83
+ success: true,
84
+ attachments,
85
+ creditsUsed:
86
+ request.type === "text_to_image"
87
+ ? 5
88
+ : request.type === "text_to_audio"
89
+ ? 3
90
+ : 2,
91
+ processingTime: 3000,
92
+ requestId: `req_${Date.now()}`,
93
+ };
94
+
95
+ setGenerationResult(result);
96
+ return result;
97
+ } catch (err) {
98
+ const errorMessage =
99
+ err instanceof Error ? err.message : "Generation failed";
100
+ setError(errorMessage);
101
+ setIsGenerating(false);
102
+
103
+ return {
104
+ success: false,
105
+ attachments: [],
106
+ creditsUsed: 0,
107
+ processingTime: 0,
108
+ error: errorMessage,
109
+ requestId: "",
110
+ };
111
+ } finally {
112
+ setIsGenerating(false);
113
+ }
114
+ },
115
+ [],
116
+ );
117
+
118
+ return {
119
+ generateMedia,
120
+ isGenerating,
121
+ generationResult,
122
+ error,
123
+ };
124
+ };
@@ -0,0 +1,153 @@
1
+ # useCardMediaUpload
2
+
3
+ ## Purpose
4
+ Card-specific React hook for uploading flashcard media files to server with progress tracking and compression support.
5
+
6
+ ## File Location
7
+ `src/presentation/hooks/useCardMediaUpload.ts`
8
+
9
+ ## Strategy
10
+ - Provide card-specific media upload interface
11
+ - Support compression options for optimization
12
+ - Track upload progress with percentage and status
13
+ - Return CardMediaAttachment with position property
14
+ - Handle upload errors gracefully
15
+ - Generate thumbnails for visual media
16
+ - Support various media types for cards
17
+
18
+ ## Forbidden
19
+ - **DO NOT** start upload while previous is in progress
20
+ - **DO NOT** ignore compression options
21
+ - **DO NOT** upload without validation (use useCardMediaValidation)
22
+ - **DO NOT** mock upload in production without backend integration
23
+ - **DO NOT** modify file during upload (compress before)
24
+ - **DO NOT** assume upload will succeed
25
+ - **DO NOT** use hardcoded API endpoints
26
+ - **DO NOT** bypass progress tracking
27
+ - **DO NOT** store upload results permanently in state
28
+ - **DO NOT** use incorrect ID prefixes (must use card_media_)
29
+
30
+ ## Rules
31
+ 1. Always validate before uploading (use useCardMediaValidation)
32
+ 2. Compression quality must be in 0-1 range
33
+ 3. Dimensions must be in pixels
34
+ 4. Progress updates every 10% or on status change
35
+ 5. Clear upload state on error or completion
36
+ 6. Return CardMediaAttachment with position property
37
+ 7. Generate thumbnail URL automatically
38
+ 8. Calculate duration for audio/video
39
+ 9. Update progress status: uploading -> completed/error
40
+ 10. Include unique fileId in progress tracking
41
+
42
+ ## AI Agent Guidelines
43
+
44
+ When working with useCardMediaUpload hook:
45
+
46
+ 1. **Type Correctness**: Returns CardMediaAttachment (not MediaAttachment)
47
+ 2. **Position Property**: Uploaded media includes position field
48
+ 3. **Pre-upload Validation**: Always use useCardMediaValidation first
49
+ 4. **Progress Tracking**: Monitor uploadProgress for real-time updates
50
+ 5. **Compression**: Apply appropriate compression settings
51
+
52
+ ### Upload Workflow
53
+
54
+ 1. Validate file with useCardMediaValidation
55
+ 2. Select compression options based on type and size
56
+ 3. Call uploadMedia with file and options
57
+ 4. Monitor uploadProgress state
58
+ 5. Handle completion (success or error)
59
+ 6. Process returned CardMediaAttachment
60
+
61
+ ### CardMediaAttachment Structure
62
+
63
+ Returned object includes:
64
+ - id: Unique ID with card_media_ prefix
65
+ - type: CardMediaType (IMAGE, VIDEO, AUDIO)
66
+ - position: CardMediaPosition (defaults to 'both')
67
+ - url: Uploaded file URL
68
+ - filename: Original filename
69
+ - fileSize: Size in bytes
70
+ - mimeType: MIME type string
71
+ - duration: Audio/video duration
72
+ - thumbnailUrl: Thumbnail for visual media
73
+ - caption: Optional caption text
74
+ - isDownloaded: Download status
75
+ - createdAt: ISO timestamp
76
+
77
+ ### Compression Guidelines
78
+
79
+ **High Quality** (quality: 0.9, maxWidth: 4096)
80
+ - Use for detailed card images
81
+ - Larger file size, best quality
82
+
83
+ **Medium Quality** (quality: 0.7, maxWidth: 1920) - RECOMMENDED
84
+ - Balanced quality and size
85
+ - Good for most card media
86
+
87
+ **Low Quality** (quality: 0.5, maxWidth: 1280)
88
+ - Use for card thumbnails
89
+ - Smallest size, reduced quality
90
+
91
+ ### Upload Progress States
92
+
93
+ - **uploading**: Upload in progress (0-99%)
94
+ - **completed**: Upload finished successfully (100%)
95
+ - **error**: Upload failed with error message
96
+
97
+ ### CardMediaUploadProgress
98
+
99
+ Progress object includes:
100
+ - fileId: Unique file identifier
101
+ - progress: Percentage (0-100)
102
+ - status: Current state (uploading/completed/error)
103
+ - url: Final URL when completed
104
+
105
+ ### Integration with Card Creation
106
+
107
+ Typical workflow:
108
+ 1. Select or generate media
109
+ 2. Validate with useCardMediaValidation
110
+ 3. Upload with useCardMediaUpload
111
+ 4. Receive CardMediaAttachment with position
112
+ 5. Add to card media array
113
+ 6. Create card with useCardMultimediaFlashcard
114
+
115
+ ### Position Assignment
116
+
117
+ Uploaded media gets position property:
118
+ - Default: 'both' (shown on both sides)
119
+ - Can be overridden: 'front' or 'back'
120
+ - Used to control media display on card sides
121
+
122
+ ### Multiple File Upload
123
+
124
+ For multiple media files:
125
+ 1. Upload files sequentially or in parallel
126
+ 2. Collect CardMediaAttachment objects
127
+ 3. Assign positions appropriately
128
+ 4. Add to card media array
129
+ 5. Track individual upload progress
130
+
131
+ ### Integration Requirements
132
+
133
+ - Configure API endpoint for card media upload
134
+ - Implement authentication for uploads
135
+ - Handle file size limits
136
+ - Support retry logic for failures
137
+ - Generate thumbnails automatically
138
+ - Calculate media duration for audio/video
139
+
140
+ ### Error Handling
141
+
142
+ Common error scenarios:
143
+ - File too large: Validate before upload
144
+ - Unsupported type: Check MIME type
145
+ - Network timeout: Implement retry with backoff
146
+ - Server error: Display user-friendly message
147
+ - Authentication failure: Check token validity
148
+
149
+ ## Dependencies
150
+
151
+ - CardMediaUploadService (infrastructure layer)
152
+ - Domain types: CardMediaAttachment, CardMediaCompressionOptions, CardMediaUploadProgress
153
+ - useCardMediaValidation (for pre-upload validation)
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Card Media Upload Hook
3
+ * Hook for uploading card media files
4
+ */
5
+
6
+ import React from "react";
7
+ import {
8
+ generateThumbnail,
9
+ getCardMediaType,
10
+ getMediaDuration,
11
+ } from "../../infrastructure/utils/mediaHelpers";
12
+ import type { UseCardMediaUploadResult } from "./card-multimedia.types";
13
+ import type {
14
+ CardMediaAttachment,
15
+ CardMediaCompressionOptions,
16
+ CardMediaUploadProgress,
17
+ } from "../../domain/entities/CardMultimedia.types";
18
+
19
+ export const useCardMediaUpload = (): UseCardMediaUploadResult => {
20
+ const [isUploading, setIsUploading] = React.useState(false);
21
+ const [uploadProgress, setUploadProgress] =
22
+ React.useState<CardMediaUploadProgress | null>(null);
23
+ const [error, setError] = React.useState<string | null>(null);
24
+
25
+ const uploadMedia = React.useCallback(
26
+ async (file: any, options?: CardMediaCompressionOptions) => {
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, 50));
41
+ setUploadProgress((prev) => (prev ? { ...prev, progress: i } : null));
42
+ }
43
+
44
+ const attachment: CardMediaAttachment = {
45
+ id: `card_media_${Date.now()}`,
46
+ type: getCardMediaType(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,176 @@
1
+ # useCardMediaValidation
2
+
3
+ ## Purpose
4
+ Card-specific React hook for validating flashcard media files before upload with enhanced controls for different media types.
5
+
6
+ ## File Location
7
+ `src/presentation/hooks/useCardMediaValidation.ts`
8
+
9
+ ## Strategy
10
+ - Provide comprehensive validation for card media files
11
+ - Enhanced controls for images (5 MB warning threshold)
12
+ - Support audio/video duration validation
13
+ - Provide three-tier feedback: errors, warnings, recommendations
14
+ - Card-specific validation rules compared to general media
15
+ - Enable pre-upload validation workflow for cards
16
+ - Return actionable feedback with media-type specific recommendations
17
+
18
+ ## Forbidden
19
+ - **DO NOT** upload files that fail validation (have errors)
20
+ - **DO NOT** ignore warnings - they indicate card performance issues
21
+ - **DO NOT** bypass file type validation
22
+ - **DO NOT** use mock validation in production
23
+ - **DO NOT** allow files exceeding 50 MB limit
24
+ - **DO NOT** modify files during validation
25
+ - **DO NOT** store validation results permanently
26
+ - **DO NOT** validate empty or missing files
27
+ - **DO NOT** suppress errors for user convenience
28
+
29
+ ## Rules
30
+ 1. Always validate before card media upload
31
+ 2. Files over 50 MB must be rejected
32
+ 3. Files over 10 MB trigger warning
33
+ 4. Images over 5 MB trigger additional warning
34
+ 5. Unsupported MIME types must be rejected
35
+ 6. Validate file size, type, and format
36
+ 7. Return errors array for blocking issues
37
+ 8. Return warnings array for performance concerns
38
+ 9. Return recommendations array for improvements
39
+ 10. Clear validation state on new requests
40
+
41
+ ## AI Agent Guidelines
42
+
43
+ When working with useCardMediaValidation hook:
44
+
45
+ 1. **Card-Specific Rules**: Use for card media (not general media)
46
+ 2. **Enhanced Image Control**: 5 MB threshold for images (stricter than general)
47
+ 3. **Three-Tier Feedback**: Distinguish errors, warnings, recommendations
48
+ 4. **Duration Control**: Check audio/video duration when available
49
+ 5. **Pre-upload Check**: Always validate before useCardMediaUpload
50
+
51
+ ### Validation Levels
52
+
53
+ **Errors** (Blocking - Must fix):
54
+ - File size exceeds 50 MB
55
+ - Unsupported file type
56
+ - Invalid file format
57
+ - Missing required properties
58
+
59
+ **Warnings** (Performance - Should fix):
60
+ - File size over 10 MB (general warning)
61
+ - Image size over 5 MB (card-specific warning)
62
+ - Long duration audio/video
63
+ - Large dimensions
64
+
65
+ **Recommendations** (Improvements - Optional):
66
+ - Reduce file size for card performance
67
+ - Use recommended formats
68
+ - Optimize dimensions
69
+ - Compress for balance
70
+
71
+ ### Card-Specific vs General Validation
72
+
73
+ | Feature | useMediaValidation | useCardMediaValidation |
74
+ |---------|-------------------|------------------------|
75
+ | Max file size | 50 MB | 50 MB |
76
+ | General warning | 10 MB | 10 MB |
77
+ | Image warning | None | 5 MB (extra) |
78
+ | Duration check | No | Yes (5 min warning) |
79
+ | Type support | Same | Same |
80
+
81
+ ### Supported File Types
82
+
83
+ **Images:**
84
+ - image/jpeg
85
+ - image/png
86
+ - image/webp
87
+
88
+ **Audio:**
89
+ - audio/mp3
90
+ - audio/wav
91
+ - audio/m4a
92
+
93
+ **Video:**
94
+ - video/mp4
95
+ - video/mov
96
+
97
+ ### Validation Workflow
98
+
99
+ 1. Receive file object (name, type, size, uri)
100
+ 2. Check file size against limits
101
+ 3. Validate MIME type
102
+ 4. Apply card-specific rules (5 MB image warning)
103
+ 5. Check duration if available
104
+ 6. Generate errors, warnings, recommendations
105
+ 7. Return CardMediaValidation object
106
+
107
+ ### CardMediaValidation Structure
108
+
109
+ Validation result includes:
110
+ - isValid: Boolean (true if no errors)
111
+ - errors: String array (blocking issues)
112
+ - warnings: String array (performance concerns)
113
+ - recommendations: String array (improvements)
114
+
115
+ ### File Size Guidelines
116
+
117
+ **Images:**
118
+ - Optimal: Under 2 MB
119
+ - Card warning: 2-5 MB
120
+ - Extra warning: 5-10 MB
121
+ - Error: Over 50 MB
122
+
123
+ **Audio:**
124
+ - Optimal: Under 5 MB
125
+ - Warning: 5-10 MB
126
+ - Duration warning: Over 5 minutes
127
+ - Error: Over 50 MB
128
+
129
+ **Video:**
130
+ - Optimal: Under 10 MB
131
+ - Warning: 10-50 MB
132
+ - Duration warning: Over 5 minutes
133
+ - Error: Over 50 MB
134
+
135
+ ### Media Type Special Controls
136
+
137
+ **Image Controls:**
138
+ - Additional 5 MB warning threshold
139
+ - Dimension recommendations
140
+ - Format recommendations (JPEG for photos, PNG for graphics)
141
+
142
+ **Audio Controls:**
143
+ - Duration check (warn over 5 minutes)
144
+ - Format recommendation (MP3 preferred)
145
+ - Bitrate considerations
146
+
147
+ **Video Controls:**
148
+ - Duration check (warn over 5 minutes)
149
+ - Format recommendation (MP4 preferred)
150
+ - Resolution recommendations
151
+
152
+ ### Integration with Card Upload Flow
153
+
154
+ Typical validation-upload workflow:
155
+ 1. Select file from picker
156
+ 2. Call validateMedia(file) from useCardMediaValidation
157
+ 3. Check validation.isValid
158
+ 4. If errors: Display and block upload
159
+ 5. If warnings: Display and get confirmation
160
+ 6. If recommendations: Display for reference
161
+ 7. Proceed to useCardMediaUpload if valid or confirmed
162
+
163
+ ### Best Practices
164
+
165
+ 1. Always validate before card media upload
166
+ 2. Show all three feedback levels to users
167
+ 3. Allow users to proceed with warnings
168
+ 4. Provide actionable recommendations
169
+ 5. Consider card performance implications
170
+ 6. Balance quality vs. file size
171
+
172
+ ## Dependencies
173
+
174
+ - CardMediaValidationService (infrastructure layer)
175
+ - Domain types: CardMediaValidation, file input interfaces
176
+ - Media constants (card-specific size limits)
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Card Media Validation Hook
3
+ * Hook for validating card media files
4
+ */
5
+
6
+ import React from "react";
7
+ import { formatFileSize } from "../../infrastructure/utils/mediaHelpers";
8
+ import type { UseCardMediaValidationResult } from "./card-multimedia.types";
9
+ import type { CardMediaValidation } from "../../domain/entities/CardMultimedia.types";
10
+
11
+ export const useCardMediaValidation = (): UseCardMediaValidationResult => {
12
+ const [isValidating, setIsValidating] = React.useState(false);
13
+ const [validation, setValidation] =
14
+ React.useState<CardMediaValidation | null>(null);
15
+ const [error, setError] = React.useState<string | null>(null);
16
+
17
+ const validateMedia = React.useCallback(
18
+ async (file: any): Promise<CardMediaValidation> => {
19
+ try {
20
+ setIsValidating(true);
21
+ setError(null);
22
+
23
+ // Simulate validation
24
+ await new Promise((resolve) => setTimeout(resolve, 500));
25
+
26
+ const errors: string[] = [];
27
+ const warnings: string[] = [];
28
+ const recommendations: string[] = [];
29
+
30
+ // File size validation
31
+ const maxSize = 50 * 1024 * 1024; // 50MB
32
+ if (file.size > maxSize) {
33
+ errors.push(
34
+ `File size (${formatFileSize(file.size)}) exceeds maximum allowed size (${formatFileSize(maxSize)})`,
35
+ );
36
+ } else if (file.size > 10 * 1024 * 1024) {
37
+ // 10MB
38
+ warnings.push(`Large file size may impact performance`);
39
+ recommendations.push("Consider compressing file");
40
+ }
41
+
42
+ // File type validation
43
+ const supportedTypes = [
44
+ "image/jpeg",
45
+ "image/png",
46
+ "image/webp",
47
+ "audio/mp3",
48
+ "audio/wav",
49
+ "audio/m4a",
50
+ "video/mp4",
51
+ "video/mov",
52
+ ];
53
+
54
+ if (!supportedTypes.includes(file.type)) {
55
+ errors.push(`Unsupported file type: ${file.type}`);
56
+ }
57
+
58
+ // Media-specific validations
59
+ if (file.type.startsWith("image/")) {
60
+ if (file.size > 5 * 1024 * 1024) {
61
+ // 5MB for images
62
+ warnings.push("Very large image may cause performance issues");
63
+ recommendations.push("Consider resizing image to under 5MB");
64
+ }
65
+ }
66
+
67
+ const result: CardMediaValidation = {
68
+ isValid: errors.length === 0,
69
+ errors,
70
+ warnings,
71
+ recommendations,
72
+ };
73
+
74
+ setValidation(result);
75
+ return result;
76
+ } catch (err) {
77
+ const errorMessage =
78
+ err instanceof Error ? err.message : "Validation failed";
79
+ setError(errorMessage);
80
+ setIsValidating(false);
81
+
82
+ return {
83
+ isValid: false,
84
+ errors: [errorMessage],
85
+ warnings: [],
86
+ recommendations: [],
87
+ };
88
+ } finally {
89
+ setIsValidating(false);
90
+ }
91
+ },
92
+ [],
93
+ );
94
+
95
+ return {
96
+ validateMedia,
97
+ isValidating,
98
+ validation,
99
+ error,
100
+ };
101
+ };