@umituz/react-native-ai-generation-content 1.27.8 → 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.
Files changed (83) hide show
  1. package/package.json +1 -1
  2. package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +3 -30
  3. package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +3 -30
  4. package/src/domains/generation/wizard/infrastructure/strategies/wizard-strategy.constants.ts +0 -2
  5. package/src/features/image-to-video/README.md +414 -0
  6. package/src/features/image-to-video/domain/constants/animation.constants.ts +47 -0
  7. package/src/features/image-to-video/domain/constants/duration.constants.ts +13 -0
  8. package/src/features/image-to-video/domain/constants/form.constants.ts +22 -0
  9. package/src/features/image-to-video/domain/constants/index.ts +23 -0
  10. package/src/features/image-to-video/domain/constants/music.constants.ts +53 -0
  11. package/src/features/image-to-video/domain/index.ts +5 -0
  12. package/src/features/image-to-video/domain/types/animation.types.ts +20 -0
  13. package/src/features/image-to-video/domain/types/config.types.ts +56 -0
  14. package/src/features/image-to-video/domain/types/duration.types.ts +11 -0
  15. package/src/features/image-to-video/domain/types/form.types.ts +35 -0
  16. package/src/features/image-to-video/domain/types/image-to-video.types.ts +122 -0
  17. package/src/features/image-to-video/domain/types/index.ts +39 -0
  18. package/src/features/image-to-video/domain/types/music.types.ts +21 -0
  19. package/src/features/image-to-video/index.ts +116 -0
  20. package/src/features/image-to-video/infrastructure/index.ts +1 -0
  21. package/src/features/image-to-video/infrastructure/services/image-to-video-executor.ts +165 -0
  22. package/src/features/image-to-video/infrastructure/services/index.ts +5 -0
  23. package/src/features/image-to-video/presentation/components/AddMoreCard.tsx +52 -0
  24. package/src/features/image-to-video/presentation/components/AnimationStyleSelector.tsx +135 -0
  25. package/src/features/image-to-video/presentation/components/DurationSelector.tsx +110 -0
  26. package/src/features/image-to-video/presentation/components/EmptyGridState.tsx +69 -0
  27. package/src/features/image-to-video/presentation/components/GridImageItem.tsx +64 -0
  28. package/src/features/image-to-video/presentation/components/ImageSelectionGrid.styles.ts +84 -0
  29. package/src/features/image-to-video/presentation/components/ImageSelectionGrid.tsx +77 -0
  30. package/src/features/image-to-video/presentation/components/ImageSelectionGrid.types.ts +18 -0
  31. package/src/features/image-to-video/presentation/components/MusicMoodSelector.tsx +181 -0
  32. package/src/features/image-to-video/presentation/components/index.ts +30 -0
  33. package/src/features/image-to-video/presentation/hooks/index.ts +27 -0
  34. package/src/features/image-to-video/presentation/hooks/useFormState.ts +116 -0
  35. package/src/features/image-to-video/presentation/hooks/useGeneration.ts +85 -0
  36. package/src/features/image-to-video/presentation/hooks/useGenerationExecution.ts +143 -0
  37. package/src/features/image-to-video/presentation/hooks/useImageToVideoFeature.ts +107 -0
  38. package/src/features/image-to-video/presentation/hooks/useImageToVideoForm.ts +119 -0
  39. package/src/features/image-to-video/presentation/hooks/useImageToVideoValidation.ts +46 -0
  40. package/src/features/image-to-video/presentation/index.ts +5 -0
  41. package/src/features/text-to-image/README.md +394 -0
  42. package/src/features/text-to-image/domain/constants/index.ts +25 -0
  43. package/src/features/text-to-image/domain/constants/options.constants.ts +39 -0
  44. package/src/features/text-to-image/domain/constants/styles.constants.ts +34 -0
  45. package/src/features/text-to-image/domain/index.ts +7 -0
  46. package/src/features/text-to-image/domain/types/config.types.ts +75 -0
  47. package/src/features/text-to-image/domain/types/form.types.ts +58 -0
  48. package/src/features/text-to-image/domain/types/index.ts +38 -0
  49. package/src/features/text-to-image/domain/types/text-to-image.types.ts +58 -0
  50. package/src/features/text-to-image/index.ts +116 -0
  51. package/src/features/text-to-image/infrastructure/index.ts +1 -0
  52. package/src/features/text-to-image/infrastructure/services/index.ts +5 -0
  53. package/src/features/text-to-image/infrastructure/services/text-to-image-executor.ts +147 -0
  54. package/src/features/text-to-image/presentation/components/index.ts +30 -0
  55. package/src/features/text-to-image/presentation/hooks/index.ts +30 -0
  56. package/src/features/text-to-image/presentation/hooks/useFormState.ts +103 -0
  57. package/src/features/text-to-image/presentation/hooks/useGeneration.ts +134 -0
  58. package/src/features/text-to-image/presentation/hooks/useTextToImageFeature.ts +111 -0
  59. package/src/features/text-to-image/presentation/hooks/useTextToImageForm.ts +58 -0
  60. package/src/features/text-to-image/presentation/index.ts +7 -0
  61. package/src/features/text-to-video/README.md +412 -0
  62. package/src/features/text-to-video/domain/index.ts +1 -0
  63. package/src/features/text-to-video/domain/types/callback.types.ts +69 -0
  64. package/src/features/text-to-video/domain/types/component.types.ts +106 -0
  65. package/src/features/text-to-video/domain/types/config.types.ts +61 -0
  66. package/src/features/text-to-video/domain/types/index.ts +56 -0
  67. package/src/features/text-to-video/domain/types/request.types.ts +36 -0
  68. package/src/features/text-to-video/domain/types/state.types.ts +53 -0
  69. package/src/features/text-to-video/index.ts +68 -0
  70. package/src/features/text-to-video/infrastructure/index.ts +1 -0
  71. package/src/features/text-to-video/infrastructure/services/index.ts +5 -0
  72. package/src/features/text-to-video/infrastructure/services/text-to-video-executor.ts +141 -0
  73. package/src/features/text-to-video/presentation/components/FrameSelector.tsx +153 -0
  74. package/src/features/text-to-video/presentation/components/GenerationTabs.tsx +73 -0
  75. package/src/features/text-to-video/presentation/components/HeroSection.tsx +61 -0
  76. package/src/features/text-to-video/presentation/components/HintCarousel.tsx +96 -0
  77. package/src/features/text-to-video/presentation/components/OptionsPanel.tsx +121 -0
  78. package/src/features/text-to-video/presentation/components/index.ts +10 -0
  79. package/src/features/text-to-video/presentation/hooks/index.ts +17 -0
  80. package/src/features/text-to-video/presentation/hooks/useTextToVideoFeature.ts +187 -0
  81. package/src/features/text-to-video/presentation/hooks/useTextToVideoForm.ts +134 -0
  82. package/src/features/text-to-video/presentation/index.ts +7 -0
  83. package/src/index.ts +5 -0
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Animation Types for Image-to-Video
3
+ * Defines animation style options
4
+ */
5
+
6
+ export interface AnimationStyle {
7
+ id: string;
8
+ name: string;
9
+ description: string;
10
+ icon: string;
11
+ }
12
+
13
+ export type AnimationStyleId =
14
+ | "ken_burns"
15
+ | "zoom_in"
16
+ | "zoom_out"
17
+ | "slide_left"
18
+ | "slide_right"
19
+ | "parallax"
20
+ | string;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Config Types for Image-to-Video
3
+ * Defines callbacks and configuration options
4
+ */
5
+
6
+ import type { ImageToVideoResult } from "./image-to-video.types";
7
+ import type { ImageToVideoFormState } from "./form.types";
8
+
9
+ export interface ImageToVideoCallbacks {
10
+ onGenerate: (formState: ImageToVideoFormState) => Promise<void>;
11
+ onSelectImages?: () => Promise<string[]>;
12
+ onSelectCustomAudio?: () => Promise<string | null>;
13
+ onCreditCheck?: (cost: number) => boolean;
14
+ onShowPaywall?: (cost: number) => void;
15
+ onSuccess?: (result: ImageToVideoResult) => void;
16
+ onError?: (error: string) => void;
17
+ }
18
+
19
+ export interface ImageToVideoFormConfig {
20
+ maxImages?: number;
21
+ creditCost?: number;
22
+ enableCustomAudio?: boolean;
23
+ enableMotionPrompt?: boolean;
24
+ }
25
+
26
+ export interface ImageToVideoTranslationsExtended {
27
+ sectionTitles: {
28
+ selectedImages: string;
29
+ animationStyle: string;
30
+ durationPerImage: string;
31
+ addMusic: string;
32
+ };
33
+ imageSelection: {
34
+ selectImages: string;
35
+ chooseUpTo: string;
36
+ addMore: string;
37
+ };
38
+ duration: {
39
+ totalVideo: string;
40
+ };
41
+ music: {
42
+ customAudioSelected: string;
43
+ };
44
+ hero: {
45
+ title: string;
46
+ subtitle: string;
47
+ };
48
+ generate: {
49
+ buttonText: string;
50
+ generatingText: string;
51
+ };
52
+ errors: {
53
+ noImages: string;
54
+ noImagesMessage: string;
55
+ };
56
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Duration Types for Image-to-Video
3
+ * Defines video duration options
4
+ */
5
+
6
+ export type VideoDuration = 4 | 8 | number;
7
+
8
+ export interface DurationOption {
9
+ value: VideoDuration;
10
+ label?: string;
11
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Form Types for Image-to-Video
3
+ * Defines form state and actions
4
+ */
5
+
6
+ import type { AnimationStyleId } from "./animation.types";
7
+ import type { MusicMoodId } from "./music.types";
8
+ import type { VideoDuration } from "./duration.types";
9
+
10
+ export interface ImageToVideoFormState {
11
+ selectedImages: string[];
12
+ animationStyle: AnimationStyleId;
13
+ duration: VideoDuration;
14
+ musicMood: MusicMoodId;
15
+ customAudioUri: string | null;
16
+ motionPrompt: string;
17
+ }
18
+
19
+ export interface ImageToVideoFormActions {
20
+ setSelectedImages: (images: string[]) => void;
21
+ addImages: (images: string[]) => void;
22
+ removeImage: (index: number) => void;
23
+ setAnimationStyle: (style: AnimationStyleId) => void;
24
+ setDuration: (duration: VideoDuration) => void;
25
+ setMusicMood: (mood: MusicMoodId) => void;
26
+ setCustomAudioUri: (uri: string | null) => void;
27
+ setMotionPrompt: (prompt: string) => void;
28
+ reset: () => void;
29
+ }
30
+
31
+ export interface ImageToVideoFormDefaults {
32
+ animationStyle?: AnimationStyleId;
33
+ duration?: VideoDuration;
34
+ musicMood?: MusicMoodId;
35
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Image-to-Video Feature Types
3
+ * Request, Result, Config types for image-to-video generation
4
+ */
5
+
6
+ import type { AnimationStyleId } from "./animation.types";
7
+ import type { MusicMoodId } from "./music.types";
8
+ import type { VideoDuration } from "./duration.types";
9
+
10
+ export interface ImageToVideoOptions {
11
+ duration?: number;
12
+ motionStrength?: number;
13
+ aspectRatio?: "16:9" | "9:16" | "1:1";
14
+ fps?: number;
15
+ animationStyle?: AnimationStyleId;
16
+ musicMood?: MusicMoodId;
17
+ }
18
+
19
+ export interface ImageToVideoGenerateParams extends ImageToVideoOptions {
20
+ imageUri?: string;
21
+ motionPrompt?: string;
22
+ }
23
+
24
+ export interface ImageToVideoRequest {
25
+ imageUri: string;
26
+ imageBase64?: string;
27
+ userId: string;
28
+ motionPrompt?: string;
29
+ options?: ImageToVideoOptions;
30
+ allImages?: string[];
31
+ customAudioUri?: string | null;
32
+ animationStyle?: AnimationStyleId;
33
+ duration?: VideoDuration;
34
+ musicMood?: MusicMoodId;
35
+ model?: string;
36
+ }
37
+
38
+ export interface ImageToVideoResult {
39
+ success: boolean;
40
+ videoUrl?: string;
41
+ thumbnailUrl?: string;
42
+ error?: string;
43
+ requestId?: string;
44
+ }
45
+
46
+ export interface ImageToVideoGenerationState {
47
+ isGenerating: boolean;
48
+ progress: number;
49
+ error: string | null;
50
+ }
51
+
52
+ export interface ImageToVideoFeatureState {
53
+ imageUri: string | null;
54
+ motionPrompt: string;
55
+ videoUrl: string | null;
56
+ thumbnailUrl: string | null;
57
+ isProcessing: boolean;
58
+ progress: number;
59
+ error: string | null;
60
+ }
61
+
62
+ export interface ImageToVideoTranslations {
63
+ uploadTitle: string;
64
+ uploadSubtitle: string;
65
+ motionPromptPlaceholder: string;
66
+ generateButtonText: string;
67
+ processingText: string;
68
+ successText: string;
69
+ saveButtonText: string;
70
+ tryAnotherText: string;
71
+ }
72
+
73
+ export type ImageToVideoInputBuilder = (
74
+ imageBase64: string,
75
+ motionPrompt?: string,
76
+ options?: ImageToVideoOptions,
77
+ ) => Record<string, unknown>;
78
+
79
+ export type ImageToVideoResultExtractor = (
80
+ result: unknown,
81
+ ) => { videoUrl?: string; thumbnailUrl?: string } | undefined;
82
+
83
+ export interface ImageToVideoFeatureCallbacks {
84
+ onCreditCheck?: (cost: number) => Promise<boolean>;
85
+ onCreditDeduct?: (cost: number) => Promise<void>;
86
+ onAuthCheck?: () => boolean;
87
+ onShowPaywall?: (creditCost: number) => void;
88
+ onGenerationStart?: (data: ImageToVideoGenerationStartData) => Promise<void>;
89
+ onCreationSave?: (data: ImageToVideoCreationData) => Promise<void>;
90
+ onGenerate?: (result: ImageToVideoResult) => void;
91
+ onProgress?: (progress: number) => void;
92
+ onError?: (error: string) => void;
93
+ }
94
+
95
+ export interface ImageToVideoGenerationStartData {
96
+ creationId: string;
97
+ type: string;
98
+ imageUri: string;
99
+ metadata?: Record<string, unknown>;
100
+ }
101
+
102
+ export interface ImageToVideoCreationData {
103
+ creationId: string;
104
+ type: string;
105
+ videoUrl: string;
106
+ thumbnailUrl?: string;
107
+ imageUri: string;
108
+ metadata?: Record<string, unknown>;
109
+ }
110
+
111
+ export interface ImageToVideoFeatureConfig {
112
+ providerId?: string;
113
+ creditCost?: number;
114
+ model: string;
115
+ buildInput: ImageToVideoInputBuilder;
116
+ extractResult?: ImageToVideoResultExtractor;
117
+ prepareImage: (imageUri: string) => Promise<string>;
118
+ onImageSelect?: (uri: string) => void;
119
+ onProcessingStart?: () => void;
120
+ onProcessingComplete?: (result: ImageToVideoResult) => void;
121
+ onError?: (error: string) => void;
122
+ }
@@ -0,0 +1,39 @@
1
+ // Animation Types
2
+ export type { AnimationStyle, AnimationStyleId } from "./animation.types";
3
+
4
+ // Music Types
5
+ export type { MusicMood, MusicMoodId } from "./music.types";
6
+
7
+ // Duration Types
8
+ export type { VideoDuration, DurationOption } from "./duration.types";
9
+
10
+ // Form Types
11
+ export type {
12
+ ImageToVideoFormState,
13
+ ImageToVideoFormActions,
14
+ ImageToVideoFormDefaults,
15
+ } from "./form.types";
16
+
17
+ // Config Types
18
+ export type {
19
+ ImageToVideoCallbacks,
20
+ ImageToVideoFormConfig,
21
+ ImageToVideoTranslationsExtended,
22
+ } from "./config.types";
23
+
24
+ // Core Feature Types
25
+ export type {
26
+ ImageToVideoOptions,
27
+ ImageToVideoGenerateParams,
28
+ ImageToVideoRequest,
29
+ ImageToVideoResult,
30
+ ImageToVideoGenerationState,
31
+ ImageToVideoFeatureState,
32
+ ImageToVideoTranslations,
33
+ ImageToVideoInputBuilder,
34
+ ImageToVideoResultExtractor,
35
+ ImageToVideoFeatureCallbacks,
36
+ ImageToVideoGenerationStartData,
37
+ ImageToVideoCreationData,
38
+ ImageToVideoFeatureConfig,
39
+ } from "./image-to-video.types";
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Music Types for Image-to-Video
3
+ * Defines music mood options
4
+ */
5
+
6
+ export interface MusicMood {
7
+ id: string;
8
+ name: string;
9
+ description: string;
10
+ icon: string;
11
+ }
12
+
13
+ export type MusicMoodId =
14
+ | "none"
15
+ | "energetic"
16
+ | "calm"
17
+ | "happy"
18
+ | "emotional"
19
+ | "rhythmic"
20
+ | "custom"
21
+ | string;
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Image-to-Video Feature
3
+ * Provider-agnostic image-to-video generation feature
4
+ */
5
+
6
+ // =============================================================================
7
+ // DOMAIN LAYER - Types
8
+ // =============================================================================
9
+
10
+ // Animation Types
11
+ export type { AnimationStyle, AnimationStyleId } from "./domain";
12
+
13
+ // Music Types
14
+ export type { MusicMood, MusicMoodId } from "./domain";
15
+
16
+ // Duration Types
17
+ export type { VideoDuration, DurationOption } from "./domain";
18
+
19
+ // Form Types
20
+ export type {
21
+ ImageToVideoFormState,
22
+ ImageToVideoFormActions,
23
+ ImageToVideoFormDefaults,
24
+ } from "./domain";
25
+
26
+ // Config Types
27
+ export type {
28
+ ImageToVideoCallbacks,
29
+ ImageToVideoFormConfig,
30
+ ImageToVideoTranslationsExtended,
31
+ } from "./domain";
32
+
33
+ // Core Feature Types
34
+ export type {
35
+ ImageToVideoOptions,
36
+ ImageToVideoGenerateParams,
37
+ ImageToVideoRequest,
38
+ ImageToVideoResult,
39
+ ImageToVideoGenerationState,
40
+ ImageToVideoFeatureState,
41
+ ImageToVideoTranslations,
42
+ ImageToVideoInputBuilder,
43
+ ImageToVideoResultExtractor,
44
+ ImageToVideoFeatureCallbacks,
45
+ ImageToVideoGenerationStartData,
46
+ ImageToVideoCreationData,
47
+ ImageToVideoFeatureConfig,
48
+ } from "./domain";
49
+
50
+ // =============================================================================
51
+ // DOMAIN LAYER - Constants
52
+ // =============================================================================
53
+
54
+ export {
55
+ DEFAULT_ANIMATION_STYLES as IMAGE_TO_VIDEO_ANIMATION_STYLES,
56
+ DEFAULT_ANIMATION_STYLE_ID as IMAGE_TO_VIDEO_DEFAULT_ANIMATION,
57
+ DEFAULT_MUSIC_MOODS as IMAGE_TO_VIDEO_MUSIC_MOODS,
58
+ DEFAULT_MUSIC_MOOD_ID as IMAGE_TO_VIDEO_DEFAULT_MUSIC,
59
+ DEFAULT_DURATION_OPTIONS as IMAGE_TO_VIDEO_DURATION_OPTIONS,
60
+ DEFAULT_VIDEO_DURATION as IMAGE_TO_VIDEO_DEFAULT_DURATION,
61
+ DEFAULT_FORM_VALUES as IMAGE_TO_VIDEO_FORM_DEFAULTS,
62
+ DEFAULT_FORM_CONFIG as IMAGE_TO_VIDEO_CONFIG,
63
+ } from "./domain";
64
+
65
+ // =============================================================================
66
+ // INFRASTRUCTURE LAYER
67
+ // =============================================================================
68
+
69
+ export { executeImageToVideo, hasImageToVideoSupport } from "./infrastructure";
70
+ export type { ExecuteImageToVideoOptions } from "./infrastructure";
71
+
72
+ // =============================================================================
73
+ // PRESENTATION LAYER - Hooks
74
+ // =============================================================================
75
+
76
+ export {
77
+ useImageToVideoFormState,
78
+ useImageToVideoGeneration,
79
+ useImageToVideoForm,
80
+ } from "./presentation";
81
+ export type {
82
+ UseImageToVideoFormStateOptions,
83
+ UseImageToVideoFormStateReturn,
84
+ UseImageToVideoGenerationOptions,
85
+ UseImageToVideoGenerationReturn,
86
+ UseImageToVideoFormOptions,
87
+ UseImageToVideoFormReturn,
88
+ } from "./presentation";
89
+
90
+ // Provider-based Feature Hook
91
+ export { useImageToVideoFeature } from "./presentation";
92
+ export type {
93
+ UseImageToVideoFeatureProps,
94
+ UseImageToVideoFeatureReturn,
95
+ } from "./presentation";
96
+
97
+ // =============================================================================
98
+ // PRESENTATION LAYER - Components
99
+ // =============================================================================
100
+
101
+ export {
102
+ ImageToVideoAnimationStyleSelector,
103
+ ImageToVideoDurationSelector,
104
+ ImageToVideoMusicMoodSelector,
105
+ ImageToVideoSelectionGrid,
106
+ ImageToVideoGenerateButton,
107
+ } from "./presentation";
108
+
109
+ export type {
110
+ ImageToVideoAnimationStyleSelectorProps,
111
+ ImageToVideoDurationSelectorProps,
112
+ ImageToVideoMusicMoodSelectorProps,
113
+ ImageToVideoSelectionGridProps,
114
+ ImageToVideoSelectionGridTranslations,
115
+ ImageToVideoGenerateButtonProps,
116
+ } from "./presentation";
@@ -0,0 +1 @@
1
+ export * from "./services";
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Image-to-Video Executor
3
+ * Provider-agnostic image-to-video execution using active AI provider
4
+ * Uses progress mapper for consistent progress reporting
5
+ */
6
+
7
+ import { providerRegistry } from "../../../../infrastructure/services";
8
+
9
+ /** Map job status to progress percentage */
10
+ const getProgressFromJobStatus = (status: string): number => {
11
+ switch (status.toLowerCase()) {
12
+ case "queued": return 10;
13
+ case "in_queue": return 15;
14
+ case "processing": return 50;
15
+ case "in_progress": return 60;
16
+ case "completed": return 100;
17
+ default: return 30;
18
+ }
19
+ };
20
+ import type {
21
+ ImageToVideoRequest,
22
+ ImageToVideoResult,
23
+ ImageToVideoInputBuilder,
24
+ ImageToVideoResultExtractor,
25
+ } from "../../domain/types";
26
+
27
+ declare const __DEV__: boolean;
28
+
29
+ export interface ExecuteImageToVideoOptions {
30
+ model: string;
31
+ buildInput: ImageToVideoInputBuilder;
32
+ extractResult?: ImageToVideoResultExtractor;
33
+ onProgress?: (progress: number) => void;
34
+ }
35
+
36
+ function defaultExtractResult(
37
+ result: unknown,
38
+ ): { videoUrl?: string; thumbnailUrl?: string } | undefined {
39
+ if (typeof result !== "object" || result === null) return undefined;
40
+
41
+ const r = result as Record<string, unknown>;
42
+
43
+ if (typeof r.video === "string") {
44
+ return { videoUrl: r.video };
45
+ }
46
+
47
+ if (r.video && typeof r.video === "object") {
48
+ const video = r.video as Record<string, unknown>;
49
+ if (typeof video.url === "string") {
50
+ return {
51
+ videoUrl: video.url,
52
+ thumbnailUrl:
53
+ typeof r.thumbnail === "string" ? r.thumbnail : undefined,
54
+ };
55
+ }
56
+ }
57
+
58
+ return undefined;
59
+ }
60
+
61
+ export async function executeImageToVideo(
62
+ request: ImageToVideoRequest,
63
+ options: ExecuteImageToVideoOptions,
64
+ ): Promise<ImageToVideoResult> {
65
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
66
+
67
+ console.log("[ImageToVideoExecutor] executeImageToVideo() called");
68
+ }
69
+
70
+ const provider = providerRegistry.getActiveProvider();
71
+
72
+ if (!provider) {
73
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
74
+
75
+ console.error("[ImageToVideoExecutor] No AI provider configured");
76
+ }
77
+ return { success: false, error: "No AI provider configured" };
78
+ }
79
+
80
+ if (!provider.isInitialized()) {
81
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
82
+
83
+ console.error("[ImageToVideoExecutor] AI provider not initialized");
84
+ }
85
+ return { success: false, error: "AI provider not initialized" };
86
+ }
87
+
88
+ if (!request.imageBase64) {
89
+ return { success: false, error: "Image base64 is required" };
90
+ }
91
+
92
+ const { model, buildInput, extractResult, onProgress } = options;
93
+
94
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
95
+
96
+ console.log(`[ImageToVideoExecutor] Provider: ${provider.providerId}, Model: ${model}`);
97
+ }
98
+
99
+ try {
100
+ onProgress?.(5);
101
+
102
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
103
+
104
+ console.log("[ImageToVideoExecutor] Starting provider.subscribe()...");
105
+ }
106
+
107
+ // Build input directly - let buildInput handle base64 format
108
+ const input = buildInput(request.imageBase64, request.motionPrompt, request.options);
109
+
110
+ // Use subscribe for video generation (long-running operation with queue)
111
+ // subscribe provides progress updates unlike run()
112
+ const result = await provider.subscribe(model, input, {
113
+ onQueueUpdate: (status) => {
114
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
115
+
116
+ console.log("[ImageToVideoExecutor] Queue status:", status.status, "position:", status.queuePosition);
117
+ }
118
+ // Map provider status to progress using centralized mapper
119
+ const progress = getProgressFromJobStatus(status.status);
120
+ onProgress?.(progress);
121
+ },
122
+ timeoutMs: 300000, // 5 minutes timeout for video generation
123
+ });
124
+
125
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
126
+
127
+ console.log("[ImageToVideoExecutor] Subscribe resolved, result keys:", result ? Object.keys(result as object) : "null");
128
+ }
129
+
130
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
131
+
132
+ console.log("[ImageToVideoExecutor] provider.subscribe() completed");
133
+ }
134
+
135
+ const extractor = extractResult || defaultExtractResult;
136
+ const extracted = extractor(result);
137
+ onProgress?.(100);
138
+
139
+ if (!extracted?.videoUrl) {
140
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
141
+
142
+ console.error("[ImageToVideoExecutor] No video URL in response");
143
+ }
144
+ return { success: false, error: "No video in response" };
145
+ }
146
+
147
+ return {
148
+ success: true,
149
+ videoUrl: extracted.videoUrl,
150
+ thumbnailUrl: extracted.thumbnailUrl,
151
+ };
152
+ } catch (error) {
153
+ const message = error instanceof Error ? error.message : String(error);
154
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
155
+
156
+ console.error("[ImageToVideoExecutor] Error:", message);
157
+ }
158
+ return { success: false, error: message };
159
+ }
160
+ }
161
+
162
+ export function hasImageToVideoSupport(): boolean {
163
+ const provider = providerRegistry.getActiveProvider();
164
+ return provider !== null && provider.isInitialized();
165
+ }
@@ -0,0 +1,5 @@
1
+ export {
2
+ executeImageToVideo,
3
+ hasImageToVideoSupport,
4
+ } from "./image-to-video-executor";
5
+ export type { ExecuteImageToVideoOptions } from "./image-to-video-executor";
@@ -0,0 +1,52 @@
1
+ /**
2
+ * AddMoreCard Component
3
+ * Displays "Add More" button in the image grid
4
+ */
5
+
6
+ import React from "react";
7
+ import { TouchableOpacity } from "react-native";
8
+ import {
9
+ AtomicIcon,
10
+ AtomicText,
11
+ useAppDesignTokens,
12
+ } from "@umituz/react-native-design-system";
13
+ import type { ImageSelectionGridStyles } from "./ImageSelectionGrid.styles";
14
+
15
+ interface AddMoreCardProps {
16
+ styles: ImageSelectionGridStyles;
17
+ addMoreText: string;
18
+ onPress: () => void;
19
+ }
20
+
21
+ export function AddMoreCard({
22
+ styles,
23
+ addMoreText,
24
+ onPress,
25
+ }: AddMoreCardProps) {
26
+ const tokens = useAppDesignTokens();
27
+
28
+ return (
29
+ <TouchableOpacity
30
+ style={[
31
+ styles.addMoreCard,
32
+ {
33
+ backgroundColor: tokens.colors.surface,
34
+ borderColor: tokens.colors.borderLight,
35
+ },
36
+ ]}
37
+ onPress={onPress}
38
+ activeOpacity={0.7}
39
+ >
40
+ <AtomicIcon name="add" size="lg" color="primary" />
41
+ <AtomicText
42
+ type="labelSmall"
43
+ style={[
44
+ styles.addMoreText,
45
+ { color: tokens.colors.primary },
46
+ ]}
47
+ >
48
+ {addMoreText}
49
+ </AtomicText>
50
+ </TouchableOpacity>
51
+ );
52
+ }