@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.
- package/package.json +10 -6
- package/src/device/infrastructure/repositories/LegacyDeviceIdRepository.ts +1 -1
- package/src/device/infrastructure/services/DeviceFeatureService.ts +1 -1
- package/src/exception/infrastructure/services/ExceptionLogger.ts +1 -1
- package/src/exception/infrastructure/storage/ExceptionStore.ts +1 -1
- package/src/exports/filesystem.ts +1 -0
- package/src/exports/media.ts +1 -0
- package/src/exports/storage.ts +1 -0
- package/src/filesystem/domain/constants/FileConstants.ts +20 -0
- package/src/filesystem/domain/entities/File.ts +20 -0
- package/src/filesystem/domain/types/FileTypes.ts +43 -0
- package/src/filesystem/domain/utils/FileUtils.ts +86 -0
- package/src/filesystem/index.ts +23 -0
- package/src/filesystem/infrastructure/services/FileSystemService.ts +45 -0
- package/src/filesystem/infrastructure/services/cache.service.ts +48 -0
- package/src/filesystem/infrastructure/services/directory.service.ts +66 -0
- package/src/filesystem/infrastructure/services/download.constants.ts +6 -0
- package/src/filesystem/infrastructure/services/download.service.ts +74 -0
- package/src/filesystem/infrastructure/services/download.types.ts +7 -0
- package/src/filesystem/infrastructure/services/encoding.service.ts +25 -0
- package/src/filesystem/infrastructure/services/file-info.service.ts +52 -0
- package/src/filesystem/infrastructure/services/file-manager.service.ts +81 -0
- package/src/filesystem/infrastructure/services/file-path.service.ts +22 -0
- package/src/filesystem/infrastructure/services/file-reader.service.ts +52 -0
- package/src/filesystem/infrastructure/services/file-writer.service.ts +32 -0
- package/src/filesystem/infrastructure/utils/blob.utils.ts +20 -0
- package/src/image/infrastructure/services/ImageStorageService.ts +1 -1
- package/src/index.ts +14 -0
- package/src/media/domain/entities/CardMultimedia.types.README.md +129 -0
- package/src/media/domain/entities/CardMultimedia.types.ts +105 -0
- package/src/media/domain/entities/Media.README.md +80 -0
- package/src/media/domain/entities/Media.ts +139 -0
- package/src/media/domain/entities/MultimediaFlashcardTypes.README.md +144 -0
- package/src/media/domain/entities/MultimediaFlashcardTypes.ts +105 -0
- package/src/media/domain/utils/MediaUtils.README.md +178 -0
- package/src/media/domain/utils/MediaUtils.ts +82 -0
- package/src/media/index.ts +70 -0
- package/src/media/index.ts.README.md +191 -0
- package/src/media/infrastructure/services/CardMediaGenerationService.README.md +99 -0
- package/src/media/infrastructure/services/CardMediaGenerationService.ts +101 -0
- package/src/media/infrastructure/services/CardMediaOptimizerService.README.md +167 -0
- package/src/media/infrastructure/services/CardMediaOptimizerService.ts +36 -0
- package/src/media/infrastructure/services/CardMediaUploadService.README.md +123 -0
- package/src/media/infrastructure/services/CardMediaUploadService.ts +67 -0
- package/src/media/infrastructure/services/CardMediaValidationService.README.md +134 -0
- package/src/media/infrastructure/services/CardMediaValidationService.ts +81 -0
- package/src/media/infrastructure/services/CardMultimediaService.README.md +176 -0
- package/src/media/infrastructure/services/CardMultimediaService.ts +97 -0
- package/src/media/infrastructure/services/MediaGenerationService.README.md +142 -0
- package/src/media/infrastructure/services/MediaGenerationService.ts +80 -0
- package/src/media/infrastructure/services/MediaOptimizerService.README.md +145 -0
- package/src/media/infrastructure/services/MediaOptimizerService.ts +32 -0
- package/src/media/infrastructure/services/MediaPickerService.README.md +106 -0
- package/src/media/infrastructure/services/MediaPickerService.ts +173 -0
- package/src/media/infrastructure/services/MediaSaveService.README.md +120 -0
- package/src/media/infrastructure/services/MediaSaveService.ts +154 -0
- package/src/media/infrastructure/services/MediaUploadService.README.md +135 -0
- package/src/media/infrastructure/services/MediaUploadService.ts +62 -0
- package/src/media/infrastructure/services/MediaValidationService.README.md +135 -0
- package/src/media/infrastructure/services/MediaValidationService.ts +61 -0
- package/src/media/infrastructure/services/MultimediaFlashcardService.README.md +142 -0
- package/src/media/infrastructure/services/MultimediaFlashcardService.ts +95 -0
- package/src/media/infrastructure/utils/mediaHelpers.README.md +96 -0
- package/src/media/infrastructure/utils/mediaHelpers.ts +82 -0
- package/src/media/infrastructure/utils/mediaPickerMappers.README.md +129 -0
- package/src/media/infrastructure/utils/mediaPickerMappers.ts +76 -0
- package/src/media/presentation/hooks/card-multimedia.types.README.md +177 -0
- package/src/media/presentation/hooks/card-multimedia.types.ts +51 -0
- package/src/media/presentation/hooks/multimedia.types.README.md +201 -0
- package/src/media/presentation/hooks/multimedia.types.ts +51 -0
- package/src/media/presentation/hooks/useCardMediaGeneration.README.md +164 -0
- package/src/media/presentation/hooks/useCardMediaGeneration.ts +124 -0
- package/src/media/presentation/hooks/useCardMediaUpload.README.md +153 -0
- package/src/media/presentation/hooks/useCardMediaUpload.ts +86 -0
- package/src/media/presentation/hooks/useCardMediaValidation.README.md +176 -0
- package/src/media/presentation/hooks/useCardMediaValidation.ts +101 -0
- package/src/media/presentation/hooks/useCardMultimediaFlashcard.README.md +158 -0
- package/src/media/presentation/hooks/useCardMultimediaFlashcard.ts +104 -0
- package/src/media/presentation/hooks/useMedia.README.md +94 -0
- package/src/media/presentation/hooks/useMedia.ts +186 -0
- package/src/media/presentation/hooks/useMediaGeneration.README.md +118 -0
- package/src/media/presentation/hooks/useMediaGeneration.ts +101 -0
- package/src/media/presentation/hooks/useMediaUpload.README.md +108 -0
- package/src/media/presentation/hooks/useMediaUpload.ts +86 -0
- package/src/media/presentation/hooks/useMediaValidation.README.md +134 -0
- package/src/media/presentation/hooks/useMediaValidation.ts +93 -0
- package/src/media/presentation/hooks/useMultimediaFlashcard.README.md +141 -0
- package/src/media/presentation/hooks/useMultimediaFlashcard.ts +103 -0
- package/src/molecules/alerts/AlertStore.ts +1 -1
- package/src/molecules/calendar/infrastructure/storage/EventActions.ts +1 -1
- package/src/molecules/calendar/infrastructure/stores/storageAdapter.ts +1 -1
- package/src/offline/infrastructure/storage/OfflineStore.ts +1 -1
- package/src/onboarding/infrastructure/storage/OnboardingStore.ts +2 -2
- package/src/onboarding/infrastructure/storage/__tests__/OnboardingStore.test.ts +1 -1
- package/src/onboarding/infrastructure/storage/actions/answerActions.ts +1 -1
- package/src/onboarding/infrastructure/storage/actions/storageHelpers.ts +1 -1
- package/src/storage/README.md +185 -0
- package/src/storage/__tests__/integration.test.ts +391 -0
- package/src/storage/__tests__/mocks/asyncStorage.mock.ts +52 -0
- package/src/storage/__tests__/performance.test.tsx +352 -0
- package/src/storage/__tests__/setup.ts +63 -0
- package/src/storage/application/README.md +158 -0
- package/src/storage/application/ports/IStorageRepository.ts +61 -0
- package/src/storage/application/ports/README.md +127 -0
- package/src/storage/cache/README.md +154 -0
- package/src/storage/cache/__tests__/PerformanceAndMemory.test.ts +387 -0
- package/src/storage/cache/__tests__/setup.ts +19 -0
- package/src/storage/cache/domain/Cache.ts +146 -0
- package/src/storage/cache/domain/CacheManager.md +83 -0
- package/src/storage/cache/domain/CacheManager.ts +48 -0
- package/src/storage/cache/domain/CacheStatsTracker.md +169 -0
- package/src/storage/cache/domain/CacheStatsTracker.ts +49 -0
- package/src/storage/cache/domain/CachedValue.md +97 -0
- package/src/storage/cache/domain/ErrorHandler.md +99 -0
- package/src/storage/cache/domain/ErrorHandler.ts +42 -0
- package/src/storage/cache/domain/PatternMatcher.md +122 -0
- package/src/storage/cache/domain/PatternMatcher.ts +30 -0
- package/src/storage/cache/domain/README.md +118 -0
- package/src/storage/cache/domain/__tests__/Cache.test.ts +293 -0
- package/src/storage/cache/domain/__tests__/CacheManager.test.ts +276 -0
- package/src/storage/cache/domain/__tests__/ErrorHandler.test.ts +303 -0
- package/src/storage/cache/domain/__tests__/PatternMatcher.test.ts +261 -0
- package/src/storage/cache/domain/strategies/EvictionStrategy.ts +9 -0
- package/src/storage/cache/domain/strategies/FIFOStrategy.ts +12 -0
- package/src/storage/cache/domain/strategies/LFUStrategy.ts +22 -0
- package/src/storage/cache/domain/strategies/LRUStrategy.ts +22 -0
- package/src/storage/cache/domain/strategies/README.md +117 -0
- package/src/storage/cache/domain/strategies/TTLStrategy.ts +23 -0
- package/src/storage/cache/domain/strategies/__tests__/EvictionStrategies.test.ts +293 -0
- package/src/storage/cache/domain/types/Cache.ts +28 -0
- package/src/storage/cache/domain/types/README.md +107 -0
- package/src/storage/cache/index.ts +28 -0
- package/src/storage/cache/infrastructure/README.md +126 -0
- package/src/storage/cache/infrastructure/TTLCache.ts +103 -0
- package/src/storage/cache/infrastructure/__tests__/TTLCache.test.ts +303 -0
- package/src/storage/cache/presentation/README.md +123 -0
- package/src/storage/cache/presentation/__tests__/ReactHooks.test.ts +514 -0
- package/src/storage/cache/presentation/useCache.ts +76 -0
- package/src/storage/cache/presentation/useCachedValue.ts +88 -0
- package/src/storage/cache/types.d.ts +3 -0
- package/src/storage/domain/README.md +128 -0
- package/src/storage/domain/constants/CacheDefaults.ts +64 -0
- package/src/storage/domain/constants/README.md +105 -0
- package/src/storage/domain/entities/CachedValue.ts +86 -0
- package/src/storage/domain/entities/README.md +109 -0
- package/src/storage/domain/entities/StorageResult.ts +75 -0
- package/src/storage/domain/entities/__tests__/CachedValue.test.ts +149 -0
- package/src/storage/domain/entities/__tests__/StorageResult.test.ts +122 -0
- package/src/storage/domain/errors/README.md +126 -0
- package/src/storage/domain/errors/StorageError.ts +81 -0
- package/src/storage/domain/errors/__tests__/StorageError.test.ts +127 -0
- package/src/storage/domain/factories/README.md +138 -0
- package/src/storage/domain/factories/StoreFactory.ts +59 -0
- package/src/storage/domain/types/README.md +522 -0
- package/src/storage/domain/types/Store.ts +44 -0
- package/src/storage/domain/utils/CacheKeyGenerator.ts +66 -0
- package/src/storage/domain/utils/README.md +127 -0
- package/src/storage/domain/utils/__tests__/devUtils.test.ts +97 -0
- package/src/storage/domain/utils/devUtils.ts +37 -0
- package/src/storage/domain/value-objects/README.md +120 -0
- package/src/storage/domain/value-objects/StorageKey.ts +60 -0
- package/src/storage/index.ts +175 -0
- package/src/storage/infrastructure/README.md +165 -0
- package/src/storage/infrastructure/adapters/README.md +175 -0
- package/src/storage/infrastructure/adapters/StorageService.md +103 -0
- package/src/storage/infrastructure/adapters/StorageService.ts +49 -0
- package/src/storage/infrastructure/repositories/AsyncStorageRepository.ts +98 -0
- package/src/storage/infrastructure/repositories/BaseStorageOperations.ts +100 -0
- package/src/storage/infrastructure/repositories/BatchStorageOperations.ts +42 -0
- package/src/storage/infrastructure/repositories/README.md +121 -0
- package/src/storage/infrastructure/repositories/StringStorageOperations.ts +44 -0
- package/src/storage/infrastructure/repositories/__tests__/AsyncStorageRepository.test.ts +170 -0
- package/src/storage/infrastructure/repositories/__tests__/BaseStorageOperations.test.ts +201 -0
- package/src/storage/presentation/README.md +181 -0
- package/src/storage/presentation/hooks/CacheStorageOperations.ts +94 -0
- package/src/storage/presentation/hooks/README.md +128 -0
- package/src/storage/presentation/hooks/__tests__/usePersistentCache.test.ts +405 -0
- package/src/storage/presentation/hooks/__tests__/useStorage.test.ts +247 -0
- package/src/storage/presentation/hooks/__tests__/useStorageState.test.ts +293 -0
- package/src/storage/presentation/hooks/useCacheState.ts +53 -0
- package/src/storage/presentation/hooks/usePersistentCache.ts +154 -0
- package/src/storage/presentation/hooks/useStorage.ts +102 -0
- package/src/storage/presentation/hooks/useStorageState.ts +71 -0
- package/src/storage/presentation/hooks/useStore.ts +15 -0
- package/src/storage/types/README.md +103 -0
- package/src/theme/infrastructure/globalThemeStore.ts +1 -1
- package/src/theme/infrastructure/storage/ThemeStorage.ts +1 -1
- package/src/theme/infrastructure/stores/themeStore.ts +1 -1
- package/src/utilities/sharing/infrastructure/services/SharingService.ts +1 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# MediaGenerationService
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Provides AI-powered media generation capabilities including text-to-image and text-to-audio generation with credit/balance management.
|
|
5
|
+
|
|
6
|
+
## File Location
|
|
7
|
+
`/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-media/src/infrastructure/services/MediaGenerationService`
|
|
8
|
+
|
|
9
|
+
## Strategy
|
|
10
|
+
|
|
11
|
+
### Core Purpose
|
|
12
|
+
- Generate images from text descriptions (text-to-image)
|
|
13
|
+
- Generate audio from text (text-to-audio)
|
|
14
|
+
- Support multiple result generation
|
|
15
|
+
- Track processing time and performance
|
|
16
|
+
- Manage generation costs/credits
|
|
17
|
+
|
|
18
|
+
### Usage Scenarios
|
|
19
|
+
- AI-generated visual content for cards
|
|
20
|
+
- Text-to-speech conversion
|
|
21
|
+
- Creative content generation
|
|
22
|
+
- Localization and voice-over creation
|
|
23
|
+
- Dynamic asset generation
|
|
24
|
+
|
|
25
|
+
### Integration Points
|
|
26
|
+
- AI-powered content creation workflows
|
|
27
|
+
- Text-to-speech features
|
|
28
|
+
- Automated asset generation
|
|
29
|
+
- Creative assistance tools
|
|
30
|
+
- Educational content generation
|
|
31
|
+
|
|
32
|
+
## Forbidden
|
|
33
|
+
|
|
34
|
+
### MUST NOT
|
|
35
|
+
- Generate without sufficient credits/balance
|
|
36
|
+
- Assume generation always succeeds
|
|
37
|
+
- Generate inappropriate or harmful content
|
|
38
|
+
- Ignore rate limiting or API constraints
|
|
39
|
+
- Cache generated content without validation
|
|
40
|
+
- Generate without user prompt input
|
|
41
|
+
|
|
42
|
+
### MUST NEVER
|
|
43
|
+
- Expose API keys or credentials
|
|
44
|
+
- Allow unlimited free generation
|
|
45
|
+
- Ignore generation failures
|
|
46
|
+
- Bypass credit/balance checks
|
|
47
|
+
- Generate without proper error handling
|
|
48
|
+
- Assume instant generation results
|
|
49
|
+
|
|
50
|
+
## Rules
|
|
51
|
+
|
|
52
|
+
### Generation Operations
|
|
53
|
+
- MUST validate prompt before generation
|
|
54
|
+
- MUST check sufficient credits/balance
|
|
55
|
+
- MUST handle generation failures
|
|
56
|
+
- MUST track processing time
|
|
57
|
+
- MUST return unique request ID
|
|
58
|
+
- MUST respect result limits (maxResults)
|
|
59
|
+
|
|
60
|
+
### Text-to-Image Generation
|
|
61
|
+
- MUST support style options
|
|
62
|
+
- MUST support aspect ratio options
|
|
63
|
+
- MUST generate multiple results if requested
|
|
64
|
+
- MUST validate image generation parameters
|
|
65
|
+
- MUST handle generation timeouts
|
|
66
|
+
|
|
67
|
+
### Text-to-Audio Generation
|
|
68
|
+
- MUST support voice options
|
|
69
|
+
- MUST support language selection
|
|
70
|
+
- MUST support speed adjustment
|
|
71
|
+
- MUST return audio duration
|
|
72
|
+
- MUST validate audio parameters
|
|
73
|
+
|
|
74
|
+
### Credit Management
|
|
75
|
+
- MUST deduct credits per generation
|
|
76
|
+
- MUST track credit usage in results
|
|
77
|
+
- MUST validate credit availability
|
|
78
|
+
- MUST prevent generation with insufficient credits
|
|
79
|
+
- MUST report credits used in result
|
|
80
|
+
|
|
81
|
+
### Return Values
|
|
82
|
+
- MUST include success status
|
|
83
|
+
- MUST include generated media attachments
|
|
84
|
+
- MUST include credits used
|
|
85
|
+
- MUST include processing time
|
|
86
|
+
- MUST include unique request ID
|
|
87
|
+
- MUST include error details on failure
|
|
88
|
+
|
|
89
|
+
### Error Handling
|
|
90
|
+
- MUST handle insufficient credits
|
|
91
|
+
- MUST handle generation timeouts
|
|
92
|
+
- MUST handle invalid prompts
|
|
93
|
+
- MUST handle API failures
|
|
94
|
+
- MUST provide meaningful error messages
|
|
95
|
+
- MUST allow retry after appropriate delay
|
|
96
|
+
|
|
97
|
+
## AI Agent Guidelines
|
|
98
|
+
|
|
99
|
+
### When Implementing Generation Features
|
|
100
|
+
1. Always validate prompt input
|
|
101
|
+
2. Check credit/balance before generation
|
|
102
|
+
3. Set appropriate timeouts
|
|
103
|
+
4. Handle both success and failure cases
|
|
104
|
+
5. Track and report processing metrics
|
|
105
|
+
|
|
106
|
+
### When Working with Text-to-Image
|
|
107
|
+
- Support common aspect ratios (16:9, 4:3, 1:1)
|
|
108
|
+
- Provide style presets (realistic, artistic, etc.)
|
|
109
|
+
- Limit max results to reasonable number
|
|
110
|
+
- Validate image generation parameters
|
|
111
|
+
|
|
112
|
+
### When Working with Text-to-Audio
|
|
113
|
+
- Support common languages
|
|
114
|
+
- Provide voice options (male, female)
|
|
115
|
+
- Allow speed adjustment (0.5-2.0)
|
|
116
|
+
- Return accurate duration
|
|
117
|
+
|
|
118
|
+
### When Adding Features
|
|
119
|
+
- Add new generation types with validation
|
|
120
|
+
- Extend options without breaking compatibility
|
|
121
|
+
- Add new credit tiers carefully
|
|
122
|
+
- Support batch generation if needed
|
|
123
|
+
- Add content filtering if required
|
|
124
|
+
|
|
125
|
+
### When Refactoring
|
|
126
|
+
- Keep generation API stable
|
|
127
|
+
- Preserve credit calculation logic
|
|
128
|
+
- Maintain request ID generation
|
|
129
|
+
- Don't change result structure
|
|
130
|
+
- Add deprecation warnings for breaking changes
|
|
131
|
+
|
|
132
|
+
### Common Patterns to Follow
|
|
133
|
+
- Validate prompt -> Check credits -> Generate -> Return result
|
|
134
|
+
- Handle timeout -> Retry if appropriate -> Return error
|
|
135
|
+
- Calculate credits -> Deduct -> Track usage
|
|
136
|
+
- Always wrap in try-catch for unexpected errors
|
|
137
|
+
- Provide user feedback for generation status
|
|
138
|
+
|
|
139
|
+
## Dependencies
|
|
140
|
+
|
|
141
|
+
- Domain types: MediaAttachment, MediaGenerationRequest, MediaGenerationResult, MediaType, MediaPosition from MultimediaFlashcardTypes
|
|
142
|
+
- No external library dependencies (uses native APIs)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media Generation Service
|
|
3
|
+
* Handles AI media generation (text-to-image, text-to-audio)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
MediaAttachment,
|
|
8
|
+
MediaGenerationRequest,
|
|
9
|
+
MediaGenerationResult,
|
|
10
|
+
MediaType,
|
|
11
|
+
MediaPosition,
|
|
12
|
+
} from "../../domain/entities/MultimediaFlashcardTypes";
|
|
13
|
+
|
|
14
|
+
export class MediaGenerationService {
|
|
15
|
+
/**
|
|
16
|
+
* Generate media from AI (text-to-image, text-to-audio, etc.)
|
|
17
|
+
*/
|
|
18
|
+
async generateMedia(
|
|
19
|
+
request: MediaGenerationRequest,
|
|
20
|
+
): Promise<MediaGenerationResult> {
|
|
21
|
+
try {
|
|
22
|
+
const startTime = Date.now();
|
|
23
|
+
|
|
24
|
+
// Simulate AI generation
|
|
25
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
26
|
+
|
|
27
|
+
const attachments: MediaAttachment[] = [];
|
|
28
|
+
|
|
29
|
+
switch (request.type) {
|
|
30
|
+
case "text_to_image":
|
|
31
|
+
for (let i = 0; i < (request.options.maxResults || 1); i++) {
|
|
32
|
+
attachments.push({
|
|
33
|
+
id: `ai_img_${Date.now()}_${i}`,
|
|
34
|
+
type: "image" as MediaType,
|
|
35
|
+
position: "both" as MediaPosition,
|
|
36
|
+
url: `https://picsum.photos/400/300?random=${Date.now() + i}`,
|
|
37
|
+
filename: `ai_generated_${i}.jpg`,
|
|
38
|
+
fileSize: 150000,
|
|
39
|
+
mimeType: "image/jpeg",
|
|
40
|
+
isDownloaded: false,
|
|
41
|
+
createdAt: new Date().toISOString(),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
break;
|
|
45
|
+
|
|
46
|
+
case "text_to_audio":
|
|
47
|
+
attachments.push({
|
|
48
|
+
id: `ai_audio_${Date.now()}`,
|
|
49
|
+
type: "audio" as MediaType,
|
|
50
|
+
position: "back" as MediaPosition,
|
|
51
|
+
url: `https://example.com/audio_${Date.now()}.mp3`,
|
|
52
|
+
filename: `ai_generated_${Date.now()}.mp3`,
|
|
53
|
+
fileSize: 80000,
|
|
54
|
+
mimeType: "audio/mp3",
|
|
55
|
+
duration: 10,
|
|
56
|
+
isDownloaded: false,
|
|
57
|
+
createdAt: new Date().toISOString(),
|
|
58
|
+
});
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
success: true,
|
|
64
|
+
attachments,
|
|
65
|
+
creditsUsed: request.type === "text_to_image" ? 5 : 3,
|
|
66
|
+
processingTime: Date.now() - startTime,
|
|
67
|
+
requestId: `req_${Date.now()}`,
|
|
68
|
+
};
|
|
69
|
+
} catch (error) {
|
|
70
|
+
return {
|
|
71
|
+
success: false,
|
|
72
|
+
attachments: [],
|
|
73
|
+
creditsUsed: 0,
|
|
74
|
+
processingTime: 0,
|
|
75
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
76
|
+
requestId: "",
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# MediaOptimizerService
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Optimizes and compresses media files to reduce file size while maintaining acceptable quality, and manages media deletion operations.
|
|
5
|
+
|
|
6
|
+
## File Location
|
|
7
|
+
`/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-media/src/infrastructure/services/MediaOptimizerService`
|
|
8
|
+
|
|
9
|
+
## Strategy
|
|
10
|
+
|
|
11
|
+
### Core Purpose
|
|
12
|
+
- Reduce media file size through compression
|
|
13
|
+
- Maintain acceptable quality after optimization
|
|
14
|
+
- Support quality and dimension constraints
|
|
15
|
+
- Delete media from server and local storage
|
|
16
|
+
- Generate optimized versions of existing media
|
|
17
|
+
|
|
18
|
+
### Usage Scenarios
|
|
19
|
+
- Pre-upload optimization
|
|
20
|
+
- Storage cost reduction
|
|
21
|
+
- Performance improvement
|
|
22
|
+
- Bandwidth optimization
|
|
23
|
+
- Media cleanup workflows
|
|
24
|
+
|
|
25
|
+
### Integration Points
|
|
26
|
+
- After upload, before storage
|
|
27
|
+
- In media management workflows
|
|
28
|
+
- Storage optimization processes
|
|
29
|
+
- Media cleanup routines
|
|
30
|
+
- Performance tuning operations
|
|
31
|
+
|
|
32
|
+
## Forbidden
|
|
33
|
+
|
|
34
|
+
### MUST NOT
|
|
35
|
+
- Optimize media beyond usable quality
|
|
36
|
+
- Delete media without proper authorization
|
|
37
|
+
- Assume optimization always succeeds
|
|
38
|
+
- Modify original media files
|
|
39
|
+
- Ignore quality settings
|
|
40
|
+
- Delete without confirmation in critical workflows
|
|
41
|
+
|
|
42
|
+
### MUST NEVER
|
|
43
|
+
- Optimize already optimized media repeatedly
|
|
44
|
+
- Use quality below 0.3 without explicit request
|
|
45
|
+
- Delete media without backup when required
|
|
46
|
+
- Assume optimization is lossless
|
|
47
|
+
- Ignore file size after optimization
|
|
48
|
+
- Return different media ID after optimization
|
|
49
|
+
|
|
50
|
+
## Rules
|
|
51
|
+
|
|
52
|
+
### Optimization Operations
|
|
53
|
+
- MUST accept media attachment and options
|
|
54
|
+
- MUST preserve original media (create new version)
|
|
55
|
+
- MUST return optimized media attachment
|
|
56
|
+
- MUST maintain same media ID
|
|
57
|
+
- MUST update file size accurately
|
|
58
|
+
- MUST add optimization indicator to URL
|
|
59
|
+
|
|
60
|
+
### Compression Options
|
|
61
|
+
- MUST support quality adjustment (0-1)
|
|
62
|
+
- MUST support max width constraint
|
|
63
|
+
- MUST support max height constraint
|
|
64
|
+
- MUST support format conversion
|
|
65
|
+
- MUST validate compression parameters
|
|
66
|
+
- MUST respect quality vs size tradeoff
|
|
67
|
+
|
|
68
|
+
### Quality Levels
|
|
69
|
+
- High quality (0.9-1.0): 10-20% size reduction
|
|
70
|
+
- Medium quality (0.7-0.8): 30-50% size reduction
|
|
71
|
+
- Low quality (0.5-0.6): 50-70% size reduction
|
|
72
|
+
- Preview quality (0.3-0.4): 70-80% size reduction
|
|
73
|
+
- MUST document quality tradeoffs
|
|
74
|
+
|
|
75
|
+
### Deletion Operations
|
|
76
|
+
- MUST accept media ID for deletion
|
|
77
|
+
- MUST delete from both server and local storage
|
|
78
|
+
- MUST handle non-existent media gracefully
|
|
79
|
+
- MUST confirm deletion success
|
|
80
|
+
- MUST be permanent and irreversible
|
|
81
|
+
|
|
82
|
+
### Return Values
|
|
83
|
+
- MUST preserve original media ID
|
|
84
|
+
- MUST preserve media type
|
|
85
|
+
- MUST update file size
|
|
86
|
+
- MUST preserve MIME type
|
|
87
|
+
- MUST preserve creation date
|
|
88
|
+
- MUST update URL with optimization indicator
|
|
89
|
+
|
|
90
|
+
### Error Handling
|
|
91
|
+
- MUST handle optimization failures
|
|
92
|
+
- MUST handle deletion failures
|
|
93
|
+
- MUST handle invalid media IDs
|
|
94
|
+
- MUST handle invalid compression options
|
|
95
|
+
- MUST provide meaningful error messages
|
|
96
|
+
- MUST allow retry on transient failures
|
|
97
|
+
|
|
98
|
+
## AI Agent Guidelines
|
|
99
|
+
|
|
100
|
+
### When Implementing Optimization
|
|
101
|
+
1. Always validate compression options
|
|
102
|
+
2. Calculate expected file size reduction
|
|
103
|
+
3. Apply compression with specified quality
|
|
104
|
+
4. Update metadata accurately
|
|
105
|
+
5. Return optimized version with same ID
|
|
106
|
+
|
|
107
|
+
### When Working with Quality Settings
|
|
108
|
+
- Use 0.7-0.8 for general use (recommended)
|
|
109
|
+
- Use 0.9-1.0 for high-quality requirements
|
|
110
|
+
- Use 0.5-0.6 for previews and thumbnails
|
|
111
|
+
- Avoid quality below 0.3 unless specifically needed
|
|
112
|
+
- Consider content type when setting quality
|
|
113
|
+
|
|
114
|
+
### When Performing Deletion
|
|
115
|
+
- Confirm media ID exists before deletion
|
|
116
|
+
- Handle deletion from both storage locations
|
|
117
|
+
- Provide confirmation in critical workflows
|
|
118
|
+
- Log deletion operations for audit
|
|
119
|
+
- Handle non-existent media gracefully
|
|
120
|
+
|
|
121
|
+
### When Adding Features
|
|
122
|
+
- Add new compression formats carefully
|
|
123
|
+
- Support new dimension constraints
|
|
124
|
+
- Add batch optimization if needed
|
|
125
|
+
- Maintain backward compatibility
|
|
126
|
+
- Add optimization presets for common cases
|
|
127
|
+
|
|
128
|
+
### When Refactoring
|
|
129
|
+
- Keep optimization API stable
|
|
130
|
+
- Preserve ID generation logic
|
|
131
|
+
- Maintain URL structure
|
|
132
|
+
- Don't change return value structure
|
|
133
|
+
- Add deprecation warnings for breaking changes
|
|
134
|
+
|
|
135
|
+
### Common Patterns to Follow
|
|
136
|
+
- Receive attachment -> Validate options -> Optimize -> Return optimized
|
|
137
|
+
- Calculate size -> Apply quality -> Update metadata -> Return
|
|
138
|
+
- Receive ID -> Validate -> Delete -> Confirm
|
|
139
|
+
- Always wrap in try-catch for unexpected errors
|
|
140
|
+
- Provide user feedback for optimization progress
|
|
141
|
+
|
|
142
|
+
## Dependencies
|
|
143
|
+
|
|
144
|
+
- Domain types: MediaAttachment, MediaCompressionOptions from MultimediaFlashcardTypes
|
|
145
|
+
- No external library dependencies (uses native APIs)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media Optimizer Service
|
|
3
|
+
* Handles media optimization and deletion
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
MediaAttachment,
|
|
8
|
+
MediaCompressionOptions,
|
|
9
|
+
} from "../../domain/entities/MultimediaFlashcardTypes";
|
|
10
|
+
|
|
11
|
+
export class MediaOptimizerService {
|
|
12
|
+
/**
|
|
13
|
+
* Optimize media file
|
|
14
|
+
*/
|
|
15
|
+
async optimizeMedia(
|
|
16
|
+
attachment: MediaAttachment,
|
|
17
|
+
options: MediaCompressionOptions,
|
|
18
|
+
): Promise<MediaAttachment> {
|
|
19
|
+
return {
|
|
20
|
+
...attachment,
|
|
21
|
+
fileSize: Math.floor(attachment.fileSize * options.quality),
|
|
22
|
+
url: `${attachment.url}?optimized=true`,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Delete media attachment
|
|
28
|
+
*/
|
|
29
|
+
async deleteMedia(_attachmentId: string): Promise<void> {
|
|
30
|
+
// Mock implementation
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# MediaPickerService
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Provides image and video selection functionality from device camera and gallery, including permission management and media type filtering.
|
|
5
|
+
|
|
6
|
+
## File Location
|
|
7
|
+
`/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-media/src/infrastructure/services/MediaPickerService`
|
|
8
|
+
|
|
9
|
+
## Strategy
|
|
10
|
+
|
|
11
|
+
### Core Purpose
|
|
12
|
+
- Enable users to select media from device gallery or capture using camera
|
|
13
|
+
- Support single and multiple media selection
|
|
14
|
+
- Handle platform-specific permission requirements
|
|
15
|
+
- Provide customizable selection options
|
|
16
|
+
|
|
17
|
+
### Usage Scenarios
|
|
18
|
+
- User profile picture selection
|
|
19
|
+
- Content creation workflows
|
|
20
|
+
- Multi-image selection for galleries
|
|
21
|
+
- Video recording for user-generated content
|
|
22
|
+
- Mixed media selection (images and videos)
|
|
23
|
+
|
|
24
|
+
### Integration Points
|
|
25
|
+
- Forms requiring media attachments
|
|
26
|
+
- Content management systems
|
|
27
|
+
- Social media features
|
|
28
|
+
- Document upload workflows
|
|
29
|
+
|
|
30
|
+
## Forbidden
|
|
31
|
+
|
|
32
|
+
### MUST NOT
|
|
33
|
+
- Bypass permission checks or force camera/gallery access
|
|
34
|
+
- Assume permissions are always granted
|
|
35
|
+
- Hardcode file paths or URIs
|
|
36
|
+
- Access media without explicit user action
|
|
37
|
+
- Automatically launch camera without user consent
|
|
38
|
+
- Store selected media URIs in permanent storage without validation
|
|
39
|
+
|
|
40
|
+
### MUST NEVER
|
|
41
|
+
- Allow infinite selection limits without boundaries
|
|
42
|
+
- Use base64 conversion by default (performance impact)
|
|
43
|
+
- Assume all devices support the same media types
|
|
44
|
+
- Ignore permission denial states
|
|
45
|
+
- Access camera roll without proper permissions
|
|
46
|
+
|
|
47
|
+
## Rules
|
|
48
|
+
|
|
49
|
+
### Permission Management
|
|
50
|
+
- MUST request camera permission before launching camera
|
|
51
|
+
- MUST request media library permission before accessing gallery
|
|
52
|
+
- MUST handle permission denial gracefully
|
|
53
|
+
- MUST check permission status before operations
|
|
54
|
+
- MUST provide clear error messages when permissions are denied
|
|
55
|
+
|
|
56
|
+
### Media Selection
|
|
57
|
+
- MUST respect selection limits
|
|
58
|
+
- MUST validate selected media before processing
|
|
59
|
+
- MUST handle user cancellation (canceled: true)
|
|
60
|
+
- MUST support both single and multiple selection modes
|
|
61
|
+
- MUST filter media types appropriately
|
|
62
|
+
|
|
63
|
+
### Platform Considerations
|
|
64
|
+
- MUST handle iOS and Android permission differences
|
|
65
|
+
- MUST account for platform-specific media type restrictions
|
|
66
|
+
- MUST test on both platforms for compatibility
|
|
67
|
+
- MUST handle aspect ratio options correctly (only works with allowsEditing: true)
|
|
68
|
+
|
|
69
|
+
### Performance
|
|
70
|
+
- MUST avoid base64 conversion unless explicitly required
|
|
71
|
+
- MUST set reasonable quality defaults
|
|
72
|
+
- MUST handle large media files appropriately
|
|
73
|
+
- MUST provide loading states during selection
|
|
74
|
+
|
|
75
|
+
## AI Agent Guidelines
|
|
76
|
+
|
|
77
|
+
### When Implementing Media Selection
|
|
78
|
+
1. Always check permissions before launching picker
|
|
79
|
+
2. Handle both success (canceled: false) and cancellation (canceled: true)
|
|
80
|
+
3. Validate returned assets array exists and has items
|
|
81
|
+
4. Consider media type (image vs video) for different handling
|
|
82
|
+
5. Use appropriate quality settings based on use case
|
|
83
|
+
|
|
84
|
+
### When Adding Features
|
|
85
|
+
- Add new permission types only if required by new functionality
|
|
86
|
+
- Extend options interface without breaking existing functionality
|
|
87
|
+
- Maintain backward compatibility with existing selection methods
|
|
88
|
+
- Add error handling for new edge cases
|
|
89
|
+
|
|
90
|
+
### When Refactoring
|
|
91
|
+
- Keep public API stable
|
|
92
|
+
- Preserve permission handling logic
|
|
93
|
+
- Maintain platform-specific behavior differences
|
|
94
|
+
- Don't remove existing selection methods without deprecation
|
|
95
|
+
|
|
96
|
+
### Common Patterns to Follow
|
|
97
|
+
- Request permission -> Check status -> Launch picker
|
|
98
|
+
- Handle result -> Validate -> Return or process
|
|
99
|
+
- Always wrap in try-catch for unexpected errors
|
|
100
|
+
- Provide user feedback for permission states
|
|
101
|
+
|
|
102
|
+
## Dependencies
|
|
103
|
+
|
|
104
|
+
- Domain types: MediaPickerOptions, MediaPickerResult, CameraOptions, MediaType, MediaLibraryPermission, MEDIA_CONSTANTS from Media
|
|
105
|
+
- External libraries: expo-image-picker
|
|
106
|
+
- Internal utilities: mediaPickerMappers (mapMediaType, mapPermissionStatus, mapPickerResult)
|
|
@@ -0,0 +1,173 @@
|
|
|
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
|
+
MediaLibraryPermission,
|
|
16
|
+
MediaType,
|
|
17
|
+
MEDIA_CONSTANTS,
|
|
18
|
+
} from "../../domain/entities/Media";
|
|
19
|
+
import {
|
|
20
|
+
mapMediaType,
|
|
21
|
+
mapPermissionStatus,
|
|
22
|
+
mapPickerResult,
|
|
23
|
+
} from "../utils/mediaPickerMappers";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Media picker service for selecting images/videos
|
|
27
|
+
*/
|
|
28
|
+
export class MediaPickerService {
|
|
29
|
+
static async requestCameraPermission(): Promise<MediaLibraryPermission> {
|
|
30
|
+
try {
|
|
31
|
+
const { status } = await ImagePicker.requestCameraPermissionsAsync();
|
|
32
|
+
return mapPermissionStatus(status);
|
|
33
|
+
} catch {
|
|
34
|
+
return MediaLibraryPermission.DENIED;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static async requestMediaLibraryPermission(): Promise<MediaLibraryPermission> {
|
|
39
|
+
try {
|
|
40
|
+
const { status } =
|
|
41
|
+
await ImagePicker.requestMediaLibraryPermissionsAsync();
|
|
42
|
+
return mapPermissionStatus(status);
|
|
43
|
+
} catch {
|
|
44
|
+
return MediaLibraryPermission.DENIED;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static async getCameraPermissionStatus(): Promise<MediaLibraryPermission> {
|
|
49
|
+
try {
|
|
50
|
+
const { status } = await ImagePicker.getCameraPermissionsAsync();
|
|
51
|
+
return mapPermissionStatus(status);
|
|
52
|
+
} catch {
|
|
53
|
+
return MediaLibraryPermission.DENIED;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static async getMediaLibraryPermissionStatus(): Promise<MediaLibraryPermission> {
|
|
58
|
+
try {
|
|
59
|
+
const { status } = await ImagePicker.getMediaLibraryPermissionsAsync();
|
|
60
|
+
return mapPermissionStatus(status);
|
|
61
|
+
} catch {
|
|
62
|
+
return MediaLibraryPermission.DENIED;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static async launchCamera(
|
|
67
|
+
options?: CameraOptions
|
|
68
|
+
): Promise<MediaPickerResult> {
|
|
69
|
+
try {
|
|
70
|
+
const permission = await MediaPickerService.requestCameraPermission();
|
|
71
|
+
if (permission === MediaLibraryPermission.DENIED) {
|
|
72
|
+
return { canceled: true };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const result = await ImagePicker.launchCameraAsync({
|
|
76
|
+
mediaTypes: ["images"],
|
|
77
|
+
allowsEditing: options?.allowsEditing ?? false,
|
|
78
|
+
aspect: options?.aspect,
|
|
79
|
+
quality: options?.quality ?? MEDIA_CONSTANTS.DEFAULT_QUALITY,
|
|
80
|
+
base64: options?.base64 ?? false,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
return mapPickerResult(result);
|
|
84
|
+
} catch {
|
|
85
|
+
return { canceled: true };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
static async launchCameraForVideo(
|
|
90
|
+
options?: CameraOptions
|
|
91
|
+
): Promise<MediaPickerResult> {
|
|
92
|
+
try {
|
|
93
|
+
const permission = await MediaPickerService.requestCameraPermission();
|
|
94
|
+
if (permission === MediaLibraryPermission.DENIED) {
|
|
95
|
+
return { canceled: true };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const result = await ImagePicker.launchCameraAsync({
|
|
99
|
+
mediaTypes: ["videos"],
|
|
100
|
+
allowsEditing: options?.allowsEditing ?? false,
|
|
101
|
+
quality: options?.quality ?? MEDIA_CONSTANTS.DEFAULT_QUALITY,
|
|
102
|
+
videoMaxDuration: options?.videoMaxDuration,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return mapPickerResult(result);
|
|
106
|
+
} catch {
|
|
107
|
+
return { canceled: true };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static async pickImage(
|
|
112
|
+
options?: MediaPickerOptions
|
|
113
|
+
): Promise<MediaPickerResult> {
|
|
114
|
+
try {
|
|
115
|
+
const permission =
|
|
116
|
+
await MediaPickerService.requestMediaLibraryPermission();
|
|
117
|
+
if (permission === MediaLibraryPermission.DENIED) {
|
|
118
|
+
return { canceled: true };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const result = await ImagePicker.launchImageLibraryAsync({
|
|
122
|
+
mediaTypes: mapMediaType(options?.mediaTypes),
|
|
123
|
+
allowsEditing: options?.allowsEditing ?? false,
|
|
124
|
+
allowsMultipleSelection: options?.allowsMultipleSelection ?? false,
|
|
125
|
+
aspect: options?.aspect,
|
|
126
|
+
quality: options?.quality ?? MEDIA_CONSTANTS.DEFAULT_QUALITY,
|
|
127
|
+
selectionLimit:
|
|
128
|
+
options?.selectionLimit ?? MEDIA_CONSTANTS.DEFAULT_SELECTION_LIMIT,
|
|
129
|
+
base64: options?.base64 ?? false,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
return mapPickerResult(result);
|
|
133
|
+
} catch {
|
|
134
|
+
return { canceled: true };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
static async pickSingleImage(
|
|
139
|
+
options?: Omit<MediaPickerOptions, "allowsMultipleSelection">
|
|
140
|
+
): Promise<MediaPickerResult> {
|
|
141
|
+
return MediaPickerService.pickImage({
|
|
142
|
+
...options,
|
|
143
|
+
allowsMultipleSelection: false,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static async pickMultipleImages(
|
|
148
|
+
options?: Omit<MediaPickerOptions, "allowsMultipleSelection">
|
|
149
|
+
): Promise<MediaPickerResult> {
|
|
150
|
+
return MediaPickerService.pickImage({
|
|
151
|
+
...options,
|
|
152
|
+
allowsMultipleSelection: true,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
static async pickVideo(
|
|
157
|
+
options?: Omit<MediaPickerOptions, "mediaTypes">
|
|
158
|
+
): Promise<MediaPickerResult> {
|
|
159
|
+
return MediaPickerService.pickImage({
|
|
160
|
+
...options,
|
|
161
|
+
mediaTypes: MediaType.VIDEO,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
static async pickMedia(
|
|
166
|
+
options?: MediaPickerOptions
|
|
167
|
+
): Promise<MediaPickerResult> {
|
|
168
|
+
return MediaPickerService.pickImage({
|
|
169
|
+
...options,
|
|
170
|
+
mediaTypes: MediaType.ALL,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|