@umituz/react-native-ai-generation-content 1.27.7 → 1.27.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 +1 -1
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +3 -30
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +3 -30
- package/src/domains/generation/wizard/infrastructure/strategies/wizard-strategy.constants.ts +0 -2
- package/src/domains/scenarios/configs/wizard-configs.ts +28 -28
- package/src/domains/scenarios/index.ts +3 -3
- package/src/features/image-to-video/README.md +414 -0
- package/src/features/image-to-video/domain/constants/animation.constants.ts +47 -0
- package/src/features/image-to-video/domain/constants/duration.constants.ts +13 -0
- package/src/features/image-to-video/domain/constants/form.constants.ts +22 -0
- package/src/features/image-to-video/domain/constants/index.ts +23 -0
- package/src/features/image-to-video/domain/constants/music.constants.ts +53 -0
- package/src/features/image-to-video/domain/index.ts +5 -0
- package/src/features/image-to-video/domain/types/animation.types.ts +20 -0
- package/src/features/image-to-video/domain/types/config.types.ts +56 -0
- package/src/features/image-to-video/domain/types/duration.types.ts +11 -0
- package/src/features/image-to-video/domain/types/form.types.ts +35 -0
- package/src/features/image-to-video/domain/types/image-to-video.types.ts +122 -0
- package/src/features/image-to-video/domain/types/index.ts +39 -0
- package/src/features/image-to-video/domain/types/music.types.ts +21 -0
- package/src/features/image-to-video/index.ts +116 -0
- package/src/features/image-to-video/infrastructure/index.ts +1 -0
- package/src/features/image-to-video/infrastructure/services/image-to-video-executor.ts +165 -0
- package/src/features/image-to-video/infrastructure/services/index.ts +5 -0
- package/src/features/image-to-video/presentation/components/AddMoreCard.tsx +52 -0
- package/src/features/image-to-video/presentation/components/AnimationStyleSelector.tsx +135 -0
- package/src/features/image-to-video/presentation/components/DurationSelector.tsx +110 -0
- package/src/features/image-to-video/presentation/components/EmptyGridState.tsx +69 -0
- package/src/features/image-to-video/presentation/components/GridImageItem.tsx +64 -0
- package/src/features/image-to-video/presentation/components/ImageSelectionGrid.styles.ts +84 -0
- package/src/features/image-to-video/presentation/components/ImageSelectionGrid.tsx +77 -0
- package/src/features/image-to-video/presentation/components/ImageSelectionGrid.types.ts +18 -0
- package/src/features/image-to-video/presentation/components/MusicMoodSelector.tsx +181 -0
- package/src/features/image-to-video/presentation/components/index.ts +30 -0
- package/src/features/image-to-video/presentation/hooks/index.ts +27 -0
- package/src/features/image-to-video/presentation/hooks/useFormState.ts +116 -0
- package/src/features/image-to-video/presentation/hooks/useGeneration.ts +85 -0
- package/src/features/image-to-video/presentation/hooks/useGenerationExecution.ts +143 -0
- package/src/features/image-to-video/presentation/hooks/useImageToVideoFeature.ts +107 -0
- package/src/features/image-to-video/presentation/hooks/useImageToVideoForm.ts +119 -0
- package/src/features/image-to-video/presentation/hooks/useImageToVideoValidation.ts +46 -0
- package/src/features/image-to-video/presentation/index.ts +5 -0
- package/src/features/text-to-image/README.md +394 -0
- package/src/features/text-to-image/domain/constants/index.ts +25 -0
- package/src/features/text-to-image/domain/constants/options.constants.ts +39 -0
- package/src/features/text-to-image/domain/constants/styles.constants.ts +34 -0
- package/src/features/text-to-image/domain/index.ts +7 -0
- package/src/features/text-to-image/domain/types/config.types.ts +75 -0
- package/src/features/text-to-image/domain/types/form.types.ts +58 -0
- package/src/features/text-to-image/domain/types/index.ts +38 -0
- package/src/features/text-to-image/domain/types/text-to-image.types.ts +58 -0
- package/src/features/text-to-image/index.ts +116 -0
- package/src/features/text-to-image/infrastructure/index.ts +1 -0
- package/src/features/text-to-image/infrastructure/services/index.ts +5 -0
- package/src/features/text-to-image/infrastructure/services/text-to-image-executor.ts +147 -0
- package/src/features/text-to-image/presentation/components/index.ts +30 -0
- package/src/features/text-to-image/presentation/hooks/index.ts +30 -0
- package/src/features/text-to-image/presentation/hooks/useFormState.ts +103 -0
- package/src/features/text-to-image/presentation/hooks/useGeneration.ts +134 -0
- package/src/features/text-to-image/presentation/hooks/useTextToImageFeature.ts +111 -0
- package/src/features/text-to-image/presentation/hooks/useTextToImageForm.ts +58 -0
- package/src/features/text-to-image/presentation/index.ts +7 -0
- package/src/features/text-to-video/README.md +412 -0
- package/src/features/text-to-video/domain/index.ts +1 -0
- package/src/features/text-to-video/domain/types/callback.types.ts +69 -0
- package/src/features/text-to-video/domain/types/component.types.ts +106 -0
- package/src/features/text-to-video/domain/types/config.types.ts +61 -0
- package/src/features/text-to-video/domain/types/index.ts +56 -0
- package/src/features/text-to-video/domain/types/request.types.ts +36 -0
- package/src/features/text-to-video/domain/types/state.types.ts +53 -0
- package/src/features/text-to-video/index.ts +68 -0
- package/src/features/text-to-video/infrastructure/index.ts +1 -0
- package/src/features/text-to-video/infrastructure/services/index.ts +5 -0
- package/src/features/text-to-video/infrastructure/services/text-to-video-executor.ts +141 -0
- package/src/features/text-to-video/presentation/components/FrameSelector.tsx +153 -0
- package/src/features/text-to-video/presentation/components/GenerationTabs.tsx +73 -0
- package/src/features/text-to-video/presentation/components/HeroSection.tsx +61 -0
- package/src/features/text-to-video/presentation/components/HintCarousel.tsx +96 -0
- package/src/features/text-to-video/presentation/components/OptionsPanel.tsx +121 -0
- package/src/features/text-to-video/presentation/components/index.ts +10 -0
- package/src/features/text-to-video/presentation/hooks/index.ts +17 -0
- package/src/features/text-to-video/presentation/hooks/useTextToVideoFeature.ts +187 -0
- package/src/features/text-to-video/presentation/hooks/useTextToVideoForm.ts +134 -0
- package/src/features/text-to-video/presentation/index.ts +7 -0
- package/src/index.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.27.
|
|
3
|
+
"version": "1.27.9",
|
|
4
4
|
"description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts
CHANGED
|
@@ -142,29 +142,6 @@ async function executeImageGeneration(
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
// ============================================================================
|
|
146
|
-
// Prompt Extraction
|
|
147
|
-
// ============================================================================
|
|
148
|
-
|
|
149
|
-
function extractPromptFromWizardData(wizardData: Record<string, unknown>): string | null {
|
|
150
|
-
// Check for text_input key (standard wizard text input step)
|
|
151
|
-
if (wizardData.text_input && typeof wizardData.text_input === "string") {
|
|
152
|
-
return wizardData.text_input.trim() || null;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Check for nested prompt in text_input object
|
|
156
|
-
const textInput = wizardData.text_input as { value?: string; text?: string } | undefined;
|
|
157
|
-
if (textInput?.value) return textInput.value.trim() || null;
|
|
158
|
-
if (textInput?.text) return textInput.text.trim() || null;
|
|
159
|
-
|
|
160
|
-
// Check for direct prompt key
|
|
161
|
-
if (wizardData.prompt && typeof wizardData.prompt === "string") {
|
|
162
|
-
return wizardData.prompt.trim() || null;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
145
|
// ============================================================================
|
|
169
146
|
// Input Builder
|
|
170
147
|
// ============================================================================
|
|
@@ -176,15 +153,11 @@ export async function buildImageInput(
|
|
|
176
153
|
const photos = await extractPhotosFromWizardData(wizardData);
|
|
177
154
|
if (!photos) return null;
|
|
178
155
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const basePrompt = userPrompt || scenario.aiPrompt?.trim();
|
|
182
|
-
|
|
183
|
-
if (!basePrompt) {
|
|
184
|
-
throw new Error(`No prompt found. Provide text_input in wizard or aiPrompt in scenario "${scenario.id}".`);
|
|
156
|
+
if (!scenario.aiPrompt?.trim()) {
|
|
157
|
+
throw new Error(`Scenario "${scenario.id}" must have aiPrompt field`);
|
|
185
158
|
}
|
|
186
159
|
|
|
187
|
-
let prompt =
|
|
160
|
+
let prompt = scenario.aiPrompt;
|
|
188
161
|
|
|
189
162
|
const styleEnhancements: string[] = [];
|
|
190
163
|
|
package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts
CHANGED
|
@@ -74,29 +74,6 @@ function getVideoFeatureType(scenarioId: string): VideoFeatureType {
|
|
|
74
74
|
throw new Error(`Unknown video feature type for scenario "${scenarioId}". Add pattern to VIDEO_FEATURE_PATTERNS.`);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
// ============================================================================
|
|
78
|
-
// Prompt Extraction
|
|
79
|
-
// ============================================================================
|
|
80
|
-
|
|
81
|
-
function extractPromptFromWizardData(wizardData: Record<string, unknown>): string | null {
|
|
82
|
-
// Check for text_input key (standard wizard text input step)
|
|
83
|
-
if (wizardData.text_input && typeof wizardData.text_input === "string") {
|
|
84
|
-
return wizardData.text_input.trim() || null;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Check for nested prompt in text_input object
|
|
88
|
-
const textInput = wizardData.text_input as { value?: string; text?: string } | undefined;
|
|
89
|
-
if (textInput?.value) return textInput.value.trim() || null;
|
|
90
|
-
if (textInput?.text) return textInput.text.trim() || null;
|
|
91
|
-
|
|
92
|
-
// Check for direct prompt key
|
|
93
|
-
if (wizardData.prompt && typeof wizardData.prompt === "string") {
|
|
94
|
-
return wizardData.prompt.trim() || null;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
77
|
// ============================================================================
|
|
101
78
|
// Input Builder
|
|
102
79
|
// ============================================================================
|
|
@@ -108,18 +85,14 @@ export async function buildVideoInput(
|
|
|
108
85
|
const photos = await extractPhotosFromWizardData(wizardData);
|
|
109
86
|
if (!photos || photos.length < 1) return null;
|
|
110
87
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const prompt = userPrompt || scenario.aiPrompt?.trim();
|
|
114
|
-
|
|
115
|
-
if (!prompt) {
|
|
116
|
-
throw new Error(`No prompt found. Provide text_input in wizard or aiPrompt in scenario "${scenario.id}".`);
|
|
88
|
+
if (!scenario.aiPrompt?.trim()) {
|
|
89
|
+
throw new Error(`Scenario "${scenario.id}" must have aiPrompt field`);
|
|
117
90
|
}
|
|
118
91
|
|
|
119
92
|
return {
|
|
120
93
|
sourceImageBase64: photos[0],
|
|
121
94
|
targetImageBase64: photos[1] || photos[0],
|
|
122
|
-
prompt,
|
|
95
|
+
prompt: scenario.aiPrompt,
|
|
123
96
|
};
|
|
124
97
|
}
|
|
125
98
|
|
|
@@ -13,7 +13,7 @@ declare const __DEV__: boolean;
|
|
|
13
13
|
* Based on what inputs the wizard needs (photos, text)
|
|
14
14
|
* NOT based on app-specific scenario names
|
|
15
15
|
*/
|
|
16
|
-
export enum
|
|
16
|
+
export enum WizardInputType {
|
|
17
17
|
/** Two images required (any two-person/two-image scenario) */
|
|
18
18
|
DUAL_IMAGE = "dual_image",
|
|
19
19
|
/** Single image required */
|
|
@@ -24,20 +24,20 @@ export enum InputType {
|
|
|
24
24
|
DUAL_IMAGE_FACE = "dual_image_face",
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/** @deprecated Use
|
|
28
|
-
export const FeatureType =
|
|
27
|
+
/** @deprecated Use WizardInputType instead */
|
|
28
|
+
export const FeatureType = WizardInputType;
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Generic Input Detection Patterns
|
|
32
32
|
* Only patterns that describe input/output, NOT app-specific scenarios
|
|
33
33
|
*/
|
|
34
|
-
const INPUT_PATTERNS: Record<
|
|
35
|
-
[
|
|
34
|
+
const INPUT_PATTERNS: Record<WizardInputType, RegExp[]> = {
|
|
35
|
+
[WizardInputType.DUAL_IMAGE]: [
|
|
36
36
|
// Empty - app must specify explicitly for dual image scenarios
|
|
37
37
|
// This prevents accidental matches with app-specific terms
|
|
38
38
|
],
|
|
39
39
|
|
|
40
|
-
[
|
|
40
|
+
[WizardInputType.SINGLE_IMAGE]: [
|
|
41
41
|
/^image-to-video$/i,
|
|
42
42
|
/upscale/i,
|
|
43
43
|
/restore/i,
|
|
@@ -49,13 +49,13 @@ const INPUT_PATTERNS: Record<InputType, RegExp[]> = {
|
|
|
49
49
|
/anime-selfie/i,
|
|
50
50
|
],
|
|
51
51
|
|
|
52
|
-
[
|
|
52
|
+
[WizardInputType.TEXT_INPUT]: [
|
|
53
53
|
/^text-to-video$/i,
|
|
54
54
|
/^text-to-image$/i,
|
|
55
55
|
/prompt-to/i,
|
|
56
56
|
],
|
|
57
57
|
|
|
58
|
-
[
|
|
58
|
+
[WizardInputType.DUAL_IMAGE_FACE]: [
|
|
59
59
|
/face-swap/i,
|
|
60
60
|
/swap-face/i,
|
|
61
61
|
],
|
|
@@ -66,13 +66,13 @@ const INPUT_PATTERNS: Record<InputType, RegExp[]> = {
|
|
|
66
66
|
* Only matches generic I/O patterns
|
|
67
67
|
* Returns SINGLE_IMAGE as safe default
|
|
68
68
|
*/
|
|
69
|
-
export const
|
|
69
|
+
export const detectWizardInputType = (scenarioId: string): WizardInputType => {
|
|
70
70
|
// Check patterns in priority order: TEXT_INPUT, SINGLE_IMAGE, DUAL_IMAGE_FACE
|
|
71
71
|
// DUAL_IMAGE has no patterns - must be explicitly specified
|
|
72
|
-
const checkOrder:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
const checkOrder: WizardInputType[] = [
|
|
73
|
+
WizardInputType.TEXT_INPUT,
|
|
74
|
+
WizardInputType.DUAL_IMAGE_FACE,
|
|
75
|
+
WizardInputType.SINGLE_IMAGE,
|
|
76
76
|
];
|
|
77
77
|
|
|
78
78
|
for (const type of checkOrder) {
|
|
@@ -83,7 +83,7 @@ export const detectInputType = (scenarioId: string): InputType => {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
// Safe default: SINGLE_IMAGE (most common use case)
|
|
86
|
-
return
|
|
86
|
+
return WizardInputType.SINGLE_IMAGE;
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
/**
|
|
@@ -186,11 +186,11 @@ const createDualImageFaceConfig = (scenarioId: string): WizardFeatureConfig => (
|
|
|
186
186
|
/**
|
|
187
187
|
* Config Factories Registry
|
|
188
188
|
*/
|
|
189
|
-
const CONFIG_FACTORIES: Record<
|
|
190
|
-
[
|
|
191
|
-
[
|
|
192
|
-
[
|
|
193
|
-
[
|
|
189
|
+
const CONFIG_FACTORIES: Record<WizardInputType, (id: string) => WizardFeatureConfig> = {
|
|
190
|
+
[WizardInputType.DUAL_IMAGE]: createDualImageConfig,
|
|
191
|
+
[WizardInputType.SINGLE_IMAGE]: createSingleImageConfig,
|
|
192
|
+
[WizardInputType.TEXT_INPUT]: createTextInputConfig,
|
|
193
|
+
[WizardInputType.DUAL_IMAGE_FACE]: createDualImageFaceConfig,
|
|
194
194
|
};
|
|
195
195
|
|
|
196
196
|
/**
|
|
@@ -219,7 +219,7 @@ const mergeConfigOverrides = (
|
|
|
219
219
|
*/
|
|
220
220
|
export interface WizardConfigOptions {
|
|
221
221
|
/** Explicit input type - highest priority */
|
|
222
|
-
readonly inputType?:
|
|
222
|
+
readonly inputType?: WizardInputType;
|
|
223
223
|
/** Additional steps to append */
|
|
224
224
|
readonly additionalSteps?: WizardFeatureConfig["steps"];
|
|
225
225
|
/** Custom overrides */
|
|
@@ -239,7 +239,7 @@ export interface WizardConfigOptions {
|
|
|
239
239
|
* getScenarioWizardConfig("text-to-video")
|
|
240
240
|
*
|
|
241
241
|
* // Explicit input type for app-specific scenarios
|
|
242
|
-
* getScenarioWizardConfig("ai-kiss", { inputType:
|
|
242
|
+
* getScenarioWizardConfig("ai-kiss", { inputType: WizardInputType.DUAL_IMAGE })
|
|
243
243
|
*/
|
|
244
244
|
export const getScenarioWizardConfig = (
|
|
245
245
|
scenarioId: string,
|
|
@@ -278,7 +278,7 @@ export const getScenarioWizardConfig = (
|
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
// 3. Auto-detect from scenario ID
|
|
281
|
-
const inputType =
|
|
281
|
+
const inputType = detectWizardInputType(scenarioId);
|
|
282
282
|
|
|
283
283
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
284
284
|
console.log("[WizardConfig] Auto-detected inputType", {
|
|
@@ -318,12 +318,12 @@ export const hasExplicitConfig = (scenarioId: string): boolean => {
|
|
|
318
318
|
/**
|
|
319
319
|
* Get input type for a scenario
|
|
320
320
|
*/
|
|
321
|
-
export const
|
|
322
|
-
return
|
|
321
|
+
export const getScenarioWizardInputType = (scenarioId: string): WizardInputType => {
|
|
322
|
+
return detectWizardInputType(scenarioId);
|
|
323
323
|
};
|
|
324
324
|
|
|
325
|
-
/** @deprecated Use
|
|
326
|
-
export const getScenarioFeatureType =
|
|
325
|
+
/** @deprecated Use getScenarioWizardInputType instead */
|
|
326
|
+
export const getScenarioFeatureType = getScenarioWizardInputType;
|
|
327
327
|
|
|
328
|
-
/** @deprecated Use
|
|
329
|
-
export const detectFeatureType =
|
|
328
|
+
/** @deprecated Use detectWizardInputType instead */
|
|
329
|
+
export const detectFeatureType = detectWizardInputType;
|
|
@@ -16,12 +16,12 @@ export { createStoryTemplate } from "./infrastructure/utils/scenario-utils";
|
|
|
16
16
|
|
|
17
17
|
// Wizard Configurations - App-agnostic, classifies by INPUT REQUIREMENTS
|
|
18
18
|
export {
|
|
19
|
-
|
|
19
|
+
WizardInputType,
|
|
20
20
|
SCENARIO_WIZARD_CONFIGS,
|
|
21
|
-
|
|
21
|
+
detectWizardInputType,
|
|
22
22
|
getScenarioWizardConfig,
|
|
23
23
|
hasExplicitConfig,
|
|
24
|
-
|
|
24
|
+
getScenarioWizardInputType,
|
|
25
25
|
registerWizardConfig,
|
|
26
26
|
// Deprecated (backward compatibility)
|
|
27
27
|
FeatureType,
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
# Image to Video Feature
|
|
2
|
+
|
|
3
|
+
Convert static images into animated videos using AI.
|
|
4
|
+
|
|
5
|
+
## 📍 Import Path
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { useImageToVideoFeature } from '@umituz/react-native-ai-generation-content';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Location**: `src/features/image-to-video/`
|
|
12
|
+
|
|
13
|
+
## 🎯 Feature Purpose
|
|
14
|
+
|
|
15
|
+
Transform static photos into dynamic animated videos using AI. Supports multiple motion types including zoom in/out, pan, and 3D parallax effects for creating engaging video content from still images.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 📋 Usage Strategy
|
|
20
|
+
|
|
21
|
+
### When to Use This Feature
|
|
22
|
+
|
|
23
|
+
✅ **Use Cases:**
|
|
24
|
+
- Creating social media content from photos
|
|
25
|
+
- Adding motion to product images
|
|
26
|
+
- Creating photo slideshows
|
|
27
|
+
- Enhancing storytelling with movement
|
|
28
|
+
- Dynamic video presentations
|
|
29
|
+
|
|
30
|
+
❌ **When NOT to Use:**
|
|
31
|
+
- Video from text descriptions (use Text to Video)
|
|
32
|
+
- Video editing of existing footage (use video editing software)
|
|
33
|
+
- Complex video effects (use professional video tools)
|
|
34
|
+
- Adding overlays/text to video (use video editing tools)
|
|
35
|
+
|
|
36
|
+
### Implementation Strategy
|
|
37
|
+
|
|
38
|
+
1. **Select static image** to animate
|
|
39
|
+
2. **Choose motion type** (zoom-in, zoom-out, pan-left, pan-right, 3D)
|
|
40
|
+
3. **Set duration** and intensity level
|
|
41
|
+
4. **Generate animated video** with progress tracking
|
|
42
|
+
5. **Preview result** and offer regeneration
|
|
43
|
+
6. **Save or share** final video
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## ⚠️ Critical Rules (MUST FOLLOW)
|
|
48
|
+
|
|
49
|
+
### 1. Image Requirements
|
|
50
|
+
- **MUST** provide ONE image to animate
|
|
51
|
+
- **MUST** use high-quality images (min 512x512 recommended)
|
|
52
|
+
- **MUST** have clear focal point for best motion results
|
|
53
|
+
- **MUST NOT** exceed file size limits (10MB max)
|
|
54
|
+
- **MUST NOT** use extremely blurry or low-resolution images
|
|
55
|
+
|
|
56
|
+
### 2. Configuration
|
|
57
|
+
- **MUST** provide valid `userId` for tracking
|
|
58
|
+
- **MUST** specify `motionType` (zoom-in, zoom-out, pan-left, pan-right, 3D)
|
|
59
|
+
- **MUST** set `duration` in seconds (2-8 range)
|
|
60
|
+
- **MUST** implement `onError` callback
|
|
61
|
+
- **MUST** implement `onSelectImage` callback
|
|
62
|
+
|
|
63
|
+
### 3. State Management
|
|
64
|
+
- **MUST** check `isReady` before enabling generate button
|
|
65
|
+
- **MUST** display progress during video generation
|
|
66
|
+
- **MUST** handle long processing times
|
|
67
|
+
- **MUST** display `error` state with clear messages
|
|
68
|
+
- **MUST** implement proper cleanup on unmount
|
|
69
|
+
|
|
70
|
+
### 4. Performance
|
|
71
|
+
- **MUST** implement image compression before upload
|
|
72
|
+
- **MUST** show progress indicator for processing
|
|
73
|
+
- **MUST** cache generated videos locally
|
|
74
|
+
- **MUST** allow users to cancel processing
|
|
75
|
+
- **MUST NOT** generate multiple videos simultaneously
|
|
76
|
+
|
|
77
|
+
### 5. Content Quality
|
|
78
|
+
- **MUST** provide video preview before save
|
|
79
|
+
- **MUST** allow duration adjustment
|
|
80
|
+
- **MUST** support various motion types
|
|
81
|
+
- **MUST** handle intensity adjustment
|
|
82
|
+
- **MUST** offer motion regeneration
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 🚫 Prohibitions (MUST AVOID)
|
|
87
|
+
|
|
88
|
+
### Strictly Forbidden
|
|
89
|
+
|
|
90
|
+
❌ **NEVER** do the following:
|
|
91
|
+
|
|
92
|
+
1. **No Missing Images**
|
|
93
|
+
- Always validate image is selected
|
|
94
|
+
- Never call process() without image
|
|
95
|
+
|
|
96
|
+
2. **No Auto-Processing**
|
|
97
|
+
- Never start animation without user action
|
|
98
|
+
- Always require explicit "Create Video" button press
|
|
99
|
+
- Show preview before processing
|
|
100
|
+
|
|
101
|
+
3. **No Hardcoded Credentials**
|
|
102
|
+
- Never store API keys in component files
|
|
103
|
+
- Use environment variables or secure storage
|
|
104
|
+
|
|
105
|
+
4. **No Unhandled Errors**
|
|
106
|
+
- Never ignore generation failures
|
|
107
|
+
- Always explain what went wrong
|
|
108
|
+
- Provide retry or alternative options
|
|
109
|
+
|
|
110
|
+
5. **No Memory Leaks**
|
|
111
|
+
- Never store both original and video simultaneously
|
|
112
|
+
- Clean up temporary video files
|
|
113
|
+
- Implement proper video disposal
|
|
114
|
+
|
|
115
|
+
6. **No Blocked UI**
|
|
116
|
+
- Never block main thread with video processing
|
|
117
|
+
- Always show progress indicator
|
|
118
|
+
- Allow cancellation
|
|
119
|
+
|
|
120
|
+
7. **No Copyright Issues**
|
|
121
|
+
- Never claim copyrighted content as original
|
|
122
|
+
- Allow only user-provided images
|
|
123
|
+
- Implement proper attribution
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 🤖 AI Agent Directions
|
|
128
|
+
|
|
129
|
+
### For AI Code Generation Tools
|
|
130
|
+
|
|
131
|
+
When using this feature with AI code generation tools, follow these guidelines:
|
|
132
|
+
|
|
133
|
+
#### Prompt Template for AI Agents
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
You are implementing an image to video feature using @umituz/react-native-ai-generation-content.
|
|
137
|
+
|
|
138
|
+
REQUIREMENTS:
|
|
139
|
+
1. Import from: @umituz/react-native-ai-generation-content
|
|
140
|
+
2. Use the useImageToVideoFeature hook
|
|
141
|
+
3. Select motion type (zoom-in, zoom-out, pan-left, pan-right, 3D)
|
|
142
|
+
4. Implement image selection UI
|
|
143
|
+
5. Set duration (2-8 seconds)
|
|
144
|
+
6. Adjust intensity level (0.0 to 1.0)
|
|
145
|
+
7. Validate image before generation
|
|
146
|
+
8. Show video preview with playback controls
|
|
147
|
+
9. Handle long processing times with progress
|
|
148
|
+
10. Implement proper error handling
|
|
149
|
+
11. Implement cleanup on unmount
|
|
150
|
+
|
|
151
|
+
CRITICAL RULES:
|
|
152
|
+
- MUST validate image before calling generate()
|
|
153
|
+
- MUST show video preview with playback controls
|
|
154
|
+
- MUST handle motion type selection
|
|
155
|
+
- MUST adjust duration appropriately
|
|
156
|
+
- MUST implement debouncing (300ms)
|
|
157
|
+
- MUST allow motion regeneration
|
|
158
|
+
|
|
159
|
+
CONFIGURATION:
|
|
160
|
+
- Provide valid userId (string)
|
|
161
|
+
- Set motionType: 'zoom-in' | 'zoom-out' | 'pan-left' | 'pan-right' | '3d'
|
|
162
|
+
- Set duration: 2-8 (seconds)
|
|
163
|
+
- Set intensity: 0.0 to 1.0 (default: 0.7)
|
|
164
|
+
- Set fps: 30 (frames per second)
|
|
165
|
+
- Implement onSelectImage callback
|
|
166
|
+
- Implement onSaveVideo callback
|
|
167
|
+
- Configure callbacks: onProcessingStart, onProcessingComplete, onError
|
|
168
|
+
|
|
169
|
+
OPTIONS:
|
|
170
|
+
- motionType: Select animation style
|
|
171
|
+
- duration: 2-8 seconds
|
|
172
|
+
- intensity: 0.0 (subtle) to 1.0 (strong motion)
|
|
173
|
+
- fps: Frames per second (default: 30)
|
|
174
|
+
|
|
175
|
+
STRICTLY FORBIDDEN:
|
|
176
|
+
- No missing image validation
|
|
177
|
+
- No auto-processing without user action
|
|
178
|
+
- No hardcoded API keys
|
|
179
|
+
- No unhandled errors
|
|
180
|
+
- No memory leaks
|
|
181
|
+
- No blocking UI
|
|
182
|
+
- No copyright violations
|
|
183
|
+
|
|
184
|
+
QUALITY CHECKLIST:
|
|
185
|
+
- [ ] Image selection implemented
|
|
186
|
+
- [ ] Motion type selector added
|
|
187
|
+
- [ ] Duration control included
|
|
188
|
+
- [ ] Intensity slider added
|
|
189
|
+
- [ ] Video preview with playback
|
|
190
|
+
- [ ] Progress indicator during processing
|
|
191
|
+
- [ ] Error display with retry option
|
|
192
|
+
- [ ] Download/share functionality
|
|
193
|
+
- [ ] Motion regeneration option
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### AI Implementation Checklist
|
|
197
|
+
|
|
198
|
+
Use this checklist when generating code:
|
|
199
|
+
|
|
200
|
+
- [ ] Feature imported from correct path
|
|
201
|
+
- [ ] Image selection implemented
|
|
202
|
+
- [ ] Motion type selector added
|
|
203
|
+
- [ ] Duration control implemented
|
|
204
|
+
- [ ] Intensity slider included
|
|
205
|
+
- [ ] Validation before generate()
|
|
206
|
+
- [ ] Video preview with playback
|
|
207
|
+
- [ ] Progress indicator during processing
|
|
208
|
+
- [ ] Error display with user-friendly message
|
|
209
|
+
- [ ] Download/share buttons
|
|
210
|
+
- [ ] Motion regeneration option
|
|
211
|
+
- [ ] Cleanup on unmount
|
|
212
|
+
- [ ] Original image preserved
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 🛠️ Configuration Strategy
|
|
217
|
+
|
|
218
|
+
### Essential Configuration
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
// Required fields
|
|
222
|
+
{
|
|
223
|
+
userId: string
|
|
224
|
+
motionType: 'zoom-in' | 'zoom-out' | 'pan-left' | 'pan-right' | '3d'
|
|
225
|
+
duration: number // 2-8 seconds
|
|
226
|
+
onSelectImage: () => Promise<string | null>
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Optional callbacks
|
|
230
|
+
{
|
|
231
|
+
onProcessingStart?: () => void
|
|
232
|
+
onProcessingComplete?: (result) => void
|
|
233
|
+
onError?: (error: string) => void
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Recommended Settings
|
|
238
|
+
|
|
239
|
+
1. **Motion Types**
|
|
240
|
+
- Zoom In: Gradually zoom into focal point
|
|
241
|
+
- Zoom Out: Gradually zoom out from image
|
|
242
|
+
- Pan Left: Slowly pan image to the left
|
|
243
|
+
- Pan Right: Slowly pan image to the right
|
|
244
|
+
- 3D: Add depth with parallax effect
|
|
245
|
+
|
|
246
|
+
2. **Duration Settings**
|
|
247
|
+
- Short: 2-3s (social media, quick views)
|
|
248
|
+
- Medium: 4-5s (standard content)
|
|
249
|
+
- Long: 6-8s (presentations, detailed views)
|
|
250
|
+
|
|
251
|
+
3. **Intensity Levels**
|
|
252
|
+
- 0.3-0.5: Subtle motion
|
|
253
|
+
- 0.6-0.8: Balanced animation (recommended)
|
|
254
|
+
- 0.9-1.0: Strong motion effects
|
|
255
|
+
|
|
256
|
+
4. **Image Quality**
|
|
257
|
+
- Minimum: 512x512 resolution
|
|
258
|
+
- Recommended: 1024x1024 or higher
|
|
259
|
+
- Format: JPEG or PNG
|
|
260
|
+
- Max size: 10MB
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## 📊 State Management
|
|
265
|
+
|
|
266
|
+
### Feature States
|
|
267
|
+
|
|
268
|
+
**isReady**: boolean
|
|
269
|
+
- Image selected and validated
|
|
270
|
+
- Check before enabling generate button
|
|
271
|
+
|
|
272
|
+
**isProcessing**: boolean
|
|
273
|
+
- Video generation in progress
|
|
274
|
+
- Show loading/progress indicator
|
|
275
|
+
- Disable generate button
|
|
276
|
+
|
|
277
|
+
**progress**: number (0-100)
|
|
278
|
+
- Generation progress percentage
|
|
279
|
+
- Update progress bar
|
|
280
|
+
|
|
281
|
+
**error**: string | null
|
|
282
|
+
- Error message if generation failed
|
|
283
|
+
- Display to user with clear message
|
|
284
|
+
|
|
285
|
+
**result**: {
|
|
286
|
+
videoUrl: string
|
|
287
|
+
thumbnailUrl?: string
|
|
288
|
+
duration?: number
|
|
289
|
+
motionType?: string
|
|
290
|
+
intensity?: number
|
|
291
|
+
metadata?: any
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## 🎨 Best Practices
|
|
297
|
+
|
|
298
|
+
### Image Selection
|
|
299
|
+
|
|
300
|
+
1. **Image Quality**
|
|
301
|
+
- Good: High-resolution, clear focal point
|
|
302
|
+
- Bad: Blurry, cluttered images
|
|
303
|
+
|
|
304
|
+
2. **Motion Matching**
|
|
305
|
+
- Match motion to image content
|
|
306
|
+
- Consider subject for motion direction
|
|
307
|
+
- Landscape vs portrait considerations
|
|
308
|
+
|
|
309
|
+
3. **Duration**
|
|
310
|
+
- Start with medium duration (4-5s)
|
|
311
|
+
- Adjust based on content complexity
|
|
312
|
+
- Shorter for social media
|
|
313
|
+
- Longer for presentations
|
|
314
|
+
|
|
315
|
+
4. **Intensity**
|
|
316
|
+
- Use moderate intensity (0.6-0.8) for natural motion
|
|
317
|
+
- Lower intensity for subtle effects
|
|
318
|
+
- Higher intensity for dramatic motion
|
|
319
|
+
|
|
320
|
+
### User Experience
|
|
321
|
+
|
|
322
|
+
1. **Motion Preview**
|
|
323
|
+
- Show examples of each motion type
|
|
324
|
+
- Preview motion before applying
|
|
325
|
+
- Explain motion characteristics
|
|
326
|
+
|
|
327
|
+
2. **Progress Feedback**
|
|
328
|
+
- Show estimated time remaining
|
|
329
|
+
- Update progress regularly
|
|
330
|
+
- Allow cancellation
|
|
331
|
+
|
|
332
|
+
3. **Video Playback**
|
|
333
|
+
- Support standard video controls
|
|
334
|
+
- Loop preview for continuous viewing
|
|
335
|
+
- Show video metadata
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## 🐛 Common Pitfalls
|
|
340
|
+
|
|
341
|
+
### Quality Issues
|
|
342
|
+
|
|
343
|
+
❌ **Problem**: Poor animation quality
|
|
344
|
+
✅ **Solution**: Use higher quality images, try different motion type or intensity
|
|
345
|
+
|
|
346
|
+
### Motion Issues
|
|
347
|
+
|
|
348
|
+
❌ **Problem**: Motion doesn't match image content
|
|
349
|
+
✅ **Solution**: Try different motion type, adjust intensity, consider focal point
|
|
350
|
+
|
|
351
|
+
### Performance Issues
|
|
352
|
+
|
|
353
|
+
❌ **Problem**: Slow generation
|
|
354
|
+
✅ **Solution**: Compress images, show progress, allow cancellation
|
|
355
|
+
|
|
356
|
+
### Memory Issues
|
|
357
|
+
|
|
358
|
+
❌ **Problem**: App crashes with large images
|
|
359
|
+
✅ **Solution**: Compress images, clean up properly, optimize memory
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## 📦 Related Components
|
|
364
|
+
|
|
365
|
+
Use these components from the library:
|
|
366
|
+
|
|
367
|
+
- **PhotoUploadCard**: Upload image interface
|
|
368
|
+
- **MotionTypeSelector**: Choose animation style
|
|
369
|
+
- **DurationSelector**: Set video length
|
|
370
|
+
- **IntensitySlider**: Adjust motion intensity
|
|
371
|
+
- **ProgressBar**: Progress display
|
|
372
|
+
- **VideoPlayer**: Video playback component
|
|
373
|
+
|
|
374
|
+
Located at: `src/presentation/components/`
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## 🔄 Migration Strategy
|
|
379
|
+
|
|
380
|
+
If migrating from previous implementation:
|
|
381
|
+
|
|
382
|
+
1. **Update imports** to new path
|
|
383
|
+
2. **Add motion type selector**
|
|
384
|
+
3. **Implement duration control**
|
|
385
|
+
4. **Update state handling** for new structure
|
|
386
|
+
5. **Add video preview component**
|
|
387
|
+
6. **Test all motion types**
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## 📚 Additional Resources
|
|
392
|
+
|
|
393
|
+
- Main documentation: `/docs/`
|
|
394
|
+
- API reference: `/docs/api/`
|
|
395
|
+
- Examples: `/docs/examples/basic/image-to-video/`
|
|
396
|
+
- Architecture: `/ARCHITECTURE.md`
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
**Last Updated**: 2025-01-08
|
|
401
|
+
**Version**: 2.0.0 (Strategy-based Documentation)
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## 📝 Changelog
|
|
406
|
+
|
|
407
|
+
### v2.0.0 - 2025-01-08
|
|
408
|
+
- **BREAKING**: Documentation format changed to strategy-based
|
|
409
|
+
- Removed extensive code examples
|
|
410
|
+
- Added rules, prohibitions, and AI agent directions
|
|
411
|
+
- Focus on best practices and implementation guidance
|
|
412
|
+
|
|
413
|
+
### v1.0.0 - Initial Release
|
|
414
|
+
- Initial feature documentation
|