@umituz/react-native-ai-generation-content 1.17.23 → 1.17.25

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 (90) hide show
  1. package/package.json +1 -1
  2. package/src/domain/interfaces/ai-provider.interface.ts +66 -0
  3. package/src/features/ai-hug/domain/types/ai-hug.types.ts +4 -13
  4. package/src/features/ai-hug/domain/types/index.ts +0 -1
  5. package/src/features/ai-hug/index.ts +1 -6
  6. package/src/features/ai-hug/presentation/components/AIHugFeature.tsx +14 -22
  7. package/src/features/ai-hug/presentation/hooks/useAIHugFeature.ts +16 -35
  8. package/src/features/ai-kiss/domain/types/ai-kiss.types.ts +4 -13
  9. package/src/features/ai-kiss/domain/types/index.ts +0 -1
  10. package/src/features/ai-kiss/index.ts +1 -6
  11. package/src/features/ai-kiss/presentation/components/AIKissFeature.tsx +13 -20
  12. package/src/features/ai-kiss/presentation/hooks/useAIKissFeature.ts +16 -35
  13. package/src/features/anime-selfie/domain/types/anime-selfie.types.ts +0 -8
  14. package/src/features/anime-selfie/domain/types/index.ts +0 -1
  15. package/src/features/anime-selfie/index.ts +0 -5
  16. package/src/features/anime-selfie/presentation/components/AnimeSelfieFeature.tsx +0 -3
  17. package/src/features/anime-selfie/presentation/hooks/useAnimeSelfieFeature.ts +9 -27
  18. package/src/features/face-swap/domain/types/face-swap.types.ts +0 -9
  19. package/src/features/face-swap/domain/types/index.ts +0 -1
  20. package/src/features/face-swap/index.ts +0 -5
  21. package/src/features/face-swap/presentation/components/FaceSwapFeature.tsx +0 -3
  22. package/src/features/face-swap/presentation/hooks/useFaceSwapFeature.ts +9 -28
  23. package/src/features/hd-touch-up/domain/types/hd-touch-up.types.ts +0 -8
  24. package/src/features/hd-touch-up/domain/types/index.ts +0 -1
  25. package/src/features/hd-touch-up/index.ts +0 -5
  26. package/src/features/hd-touch-up/presentation/components/HDTouchUpFeature.tsx +0 -3
  27. package/src/features/hd-touch-up/presentation/hooks/useHDTouchUpFeature.ts +9 -26
  28. package/src/features/photo-restoration/domain/types/index.ts +0 -1
  29. package/src/features/photo-restoration/domain/types/photo-restore.types.ts +0 -8
  30. package/src/features/photo-restoration/index.ts +0 -5
  31. package/src/features/photo-restoration/presentation/components/PhotoRestoreFeature.tsx +0 -4
  32. package/src/features/photo-restoration/presentation/hooks/usePhotoRestoreFeature.ts +9 -26
  33. package/src/features/remove-background/domain/types/index.ts +0 -1
  34. package/src/features/remove-background/domain/types/remove-background.types.ts +0 -8
  35. package/src/features/remove-background/index.ts +0 -5
  36. package/src/features/remove-background/presentation/components/RemoveBackgroundFeature.tsx +0 -3
  37. package/src/features/remove-background/presentation/hooks/useRemoveBackgroundFeature.ts +9 -26
  38. package/src/features/remove-object/domain/types/index.ts +0 -1
  39. package/src/features/remove-object/domain/types/remove-object.types.ts +0 -8
  40. package/src/features/remove-object/index.ts +0 -5
  41. package/src/features/remove-object/presentation/components/RemoveObjectFeature.tsx +0 -3
  42. package/src/features/remove-object/presentation/hooks/useRemoveObjectFeature.ts +9 -24
  43. package/src/features/replace-background/domain/types/index.ts +0 -1
  44. package/src/features/replace-background/domain/types/replace-background.types.ts +0 -9
  45. package/src/features/replace-background/index.ts +55 -82
  46. package/src/features/replace-background/infrastructure/constants/prompts.constants.ts +6 -6
  47. package/src/features/replace-background/infrastructure/index.ts +2 -2
  48. package/src/features/replace-background/presentation/components/ReplaceBackgroundFeature.tsx +0 -3
  49. package/src/features/replace-background/presentation/hooks/useReplaceBackgroundFeature.ts +8 -23
  50. package/src/features/text-to-video/domain/types/callback.types.ts +3 -3
  51. package/src/features/text-to-video/domain/types/index.ts +1 -1
  52. package/src/features/text-to-video/index.ts +1 -1
  53. package/src/features/text-to-video/presentation/hooks/useTextToVideoFeature.ts +1 -1
  54. package/src/features/upscaling/domain/types/upscale.types.ts +0 -8
  55. package/src/features/upscaling/index.ts +0 -5
  56. package/src/features/upscaling/presentation/components/UpscaleFeature.tsx +0 -4
  57. package/src/features/upscaling/presentation/hooks/useUpscaleFeature.ts +8 -23
  58. package/src/index.ts +4 -0
  59. package/src/infrastructure/services/image-feature-executor.service.ts +143 -0
  60. package/src/infrastructure/services/index.ts +20 -0
  61. package/src/infrastructure/services/video-feature-executor.service.ts +140 -0
  62. package/src/features/ai-hug/infrastructure/index.ts +0 -5
  63. package/src/features/ai-hug/infrastructure/services/ai-hug-executor.ts +0 -96
  64. package/src/features/ai-hug/infrastructure/services/index.ts +0 -6
  65. package/src/features/ai-kiss/infrastructure/index.ts +0 -5
  66. package/src/features/ai-kiss/infrastructure/services/ai-kiss-executor.ts +0 -96
  67. package/src/features/ai-kiss/infrastructure/services/index.ts +0 -6
  68. package/src/features/anime-selfie/infrastructure/index.ts +0 -5
  69. package/src/features/anime-selfie/infrastructure/services/anime-selfie-executor.ts +0 -95
  70. package/src/features/anime-selfie/infrastructure/services/index.ts +0 -6
  71. package/src/features/face-swap/infrastructure/index.ts +0 -5
  72. package/src/features/face-swap/infrastructure/services/face-swap-executor.ts +0 -96
  73. package/src/features/face-swap/infrastructure/services/index.ts +0 -6
  74. package/src/features/hd-touch-up/infrastructure/index.ts +0 -1
  75. package/src/features/hd-touch-up/infrastructure/services/hd-touch-up-executor.ts +0 -97
  76. package/src/features/hd-touch-up/infrastructure/services/index.ts +0 -2
  77. package/src/features/photo-restoration/infrastructure/index.ts +0 -1
  78. package/src/features/photo-restoration/infrastructure/services/index.ts +0 -2
  79. package/src/features/photo-restoration/infrastructure/services/photo-restore-executor.ts +0 -98
  80. package/src/features/remove-background/infrastructure/index.ts +0 -5
  81. package/src/features/remove-background/infrastructure/services/index.ts +0 -6
  82. package/src/features/remove-background/infrastructure/services/remove-background-executor.ts +0 -95
  83. package/src/features/remove-object/infrastructure/index.ts +0 -5
  84. package/src/features/remove-object/infrastructure/services/index.ts +0 -6
  85. package/src/features/remove-object/infrastructure/services/remove-object-executor.ts +0 -99
  86. package/src/features/replace-background/infrastructure/services/index.ts +0 -6
  87. package/src/features/replace-background/infrastructure/services/replace-background-executor.ts +0 -95
  88. package/src/features/upscaling/infrastructure/index.ts +0 -1
  89. package/src/features/upscaling/infrastructure/services/index.ts +0 -2
  90. package/src/features/upscaling/infrastructure/services/upscale-executor.ts +0 -98
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-generation-content",
3
- "version": "1.17.23",
3
+ "version": "1.17.25",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -44,6 +44,46 @@ export interface SubscribeOptions<T = unknown> {
44
44
  onResult?: (result: T) => void;
45
45
  }
46
46
 
47
+ /**
48
+ * Feature types for image processing (output: image)
49
+ */
50
+ export type ImageFeatureType =
51
+ | "upscale"
52
+ | "photo-restore"
53
+ | "face-swap"
54
+ | "anime-selfie"
55
+ | "remove-background"
56
+ | "remove-object"
57
+ | "hd-touch-up"
58
+ | "replace-background";
59
+
60
+ /**
61
+ * Feature types for video generation (output: video)
62
+ */
63
+ export type VideoFeatureType =
64
+ | "ai-hug"
65
+ | "ai-kiss";
66
+
67
+ /**
68
+ * Input data for image features
69
+ */
70
+ export interface ImageFeatureInputData {
71
+ imageBase64: string;
72
+ targetImageBase64?: string;
73
+ prompt?: string;
74
+ options?: Record<string, unknown>;
75
+ }
76
+
77
+ /**
78
+ * Input data for video features
79
+ */
80
+ export interface VideoFeatureInputData {
81
+ sourceImageBase64: string;
82
+ targetImageBase64: string;
83
+ prompt?: string;
84
+ options?: Record<string, unknown>;
85
+ }
86
+
47
87
  /**
48
88
  * AI Provider Interface
49
89
  * All AI providers must implement this interface
@@ -73,4 +113,30 @@ export interface IAIProvider {
73
113
  run<T = unknown>(model: string, input: Record<string, unknown>): Promise<T>;
74
114
 
75
115
  reset(): void;
116
+
117
+ /**
118
+ * Get model ID for an image feature
119
+ */
120
+ getImageFeatureModel(feature: ImageFeatureType): string;
121
+
122
+ /**
123
+ * Build provider-specific input for an image feature
124
+ */
125
+ buildImageFeatureInput(
126
+ feature: ImageFeatureType,
127
+ data: ImageFeatureInputData,
128
+ ): Record<string, unknown>;
129
+
130
+ /**
131
+ * Get model ID for a video feature
132
+ */
133
+ getVideoFeatureModel(feature: VideoFeatureType): string;
134
+
135
+ /**
136
+ * Build provider-specific input for a video feature
137
+ */
138
+ buildVideoFeatureInput(
139
+ feature: VideoFeatureType,
140
+ data: VideoFeatureInputData,
141
+ ): Record<string, unknown>;
76
142
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * AI Hug Feature Types
3
- * Request, Result, Config types for AI hug generation
3
+ * Request, Result, Config types for AI hug video generation
4
4
  */
5
5
 
6
6
  export interface AIHugOptions {
@@ -14,13 +14,13 @@ export interface AIHugRequest {
14
14
  sourceImageBase64?: string;
15
15
  targetImageBase64?: string;
16
16
  userId: string;
17
+ prompt?: string;
17
18
  options?: AIHugOptions;
18
19
  }
19
20
 
20
21
  export interface AIHugResult {
21
22
  success: boolean;
22
- imageUrl?: string;
23
- imageBase64?: string;
23
+ videoUrl?: string;
24
24
  error?: string;
25
25
  requestId?: string;
26
26
  }
@@ -28,7 +28,7 @@ export interface AIHugResult {
28
28
  export interface AIHugFeatureState {
29
29
  sourceImageUri: string | null;
30
30
  targetImageUri: string | null;
31
- processedUrl: string | null;
31
+ processedVideoUrl: string | null;
32
32
  isProcessing: boolean;
33
33
  progress: number;
34
34
  error: string | null;
@@ -49,19 +49,10 @@ export interface AIHugTranslations {
49
49
  tryAnotherText: string;
50
50
  }
51
51
 
52
- export type AIHugInputBuilder = (
53
- sourceBase64: string,
54
- targetBase64: string,
55
- options?: AIHugOptions,
56
- ) => Record<string, unknown>;
57
-
58
52
  export type AIHugResultExtractor = (result: unknown) => string | undefined;
59
53
 
60
54
  export interface AIHugFeatureConfig {
61
- providerId?: string;
62
55
  creditCost?: number;
63
- model: string;
64
- buildInput: AIHugInputBuilder;
65
56
  extractResult?: AIHugResultExtractor;
66
57
  prepareImage: (imageUri: string) => Promise<string>;
67
58
  onSourceImageSelect?: (uri: string) => void;
@@ -8,7 +8,6 @@ export type {
8
8
  AIHugResult,
9
9
  AIHugFeatureState,
10
10
  AIHugTranslations,
11
- AIHugInputBuilder,
12
11
  AIHugResultExtractor,
13
12
  AIHugFeatureConfig,
14
13
  } from "./ai-hug.types";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * AI Hug Feature
3
- * Provider-agnostic AI hug generation feature
3
+ * Provider-agnostic AI hug video generation feature
4
4
  */
5
5
 
6
6
  // Domain Types
@@ -11,14 +11,9 @@ export type {
11
11
  AIHugFeatureState,
12
12
  AIHugTranslations,
13
13
  AIHugFeatureConfig,
14
- AIHugInputBuilder,
15
14
  AIHugResultExtractor,
16
15
  } from "./domain";
17
16
 
18
- // Infrastructure Services
19
- export { executeAIHug, hasAIHugSupport } from "./infrastructure";
20
- export type { ExecuteAIHugOptions } from "./infrastructure";
21
-
22
17
  // Presentation Hooks
23
18
  export { useAIHugFeature } from "./presentation";
24
19
  export type {
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * AIHugFeature Component
3
- * Self-contained AI hug feature UI component
3
+ * Self-contained AI hug video feature UI component
4
4
  * Uses hook internally, only requires config and translations
5
5
  */
6
6
 
7
7
  import React, { useCallback } from "react";
8
- import { View, ScrollView, StyleSheet, Image, Dimensions } from "react-native";
8
+ import { View, ScrollView, StyleSheet, Dimensions } from "react-native";
9
9
  import {
10
10
  useAppDesignTokens,
11
11
  AtomicText,
@@ -22,16 +22,16 @@ import type {
22
22
  export interface AIHugFeatureProps {
23
23
  /** Feature configuration with provider-specific settings */
24
24
  config: AIHugFeatureConfig;
25
- /** User ID for the generation request */
26
- userId: string;
27
25
  /** Translations for all UI text */
28
26
  translations: AIHugTranslations;
29
27
  /** Source image picker callback */
30
28
  onSelectSourceImage: () => Promise<string | null>;
31
29
  /** Target image picker callback */
32
30
  onSelectTargetImage: () => Promise<string | null>;
33
- /** Save image callback */
34
- onSaveImage: (imageUrl: string) => Promise<void>;
31
+ /** Save video callback */
32
+ onSaveVideo: (videoUrl: string) => Promise<void>;
33
+ /** Custom video player renderer - required for video playback */
34
+ renderVideoPlayer: (props: { videoUrl: string; size: number }) => React.ReactNode;
35
35
  /** Optional custom processing modal renderer */
36
36
  renderProcessingModal?: (props: {
37
37
  visible: boolean;
@@ -41,21 +41,20 @@ export interface AIHugFeatureProps {
41
41
 
42
42
  export const AIHugFeature: React.FC<AIHugFeatureProps> = ({
43
43
  config,
44
- userId,
45
44
  translations,
46
45
  onSelectSourceImage,
47
46
  onSelectTargetImage,
48
- onSaveImage,
47
+ onSaveVideo,
48
+ renderVideoPlayer,
49
49
  renderProcessingModal,
50
50
  }) => {
51
51
  const tokens = useAppDesignTokens();
52
52
 
53
53
  const feature = useAIHugFeature({
54
54
  config,
55
- userId,
56
55
  onSelectSourceImage,
57
56
  onSelectTargetImage,
58
- onSaveImage,
57
+ onSaveVideo,
59
58
  });
60
59
 
61
60
  const handleProcess = useCallback(() => {
@@ -76,9 +75,9 @@ export const AIHugFeature: React.FC<AIHugFeatureProps> = ({
76
75
 
77
76
  const canProcess = feature.sourceImageUri && feature.targetImageUri && !feature.isProcessing;
78
77
 
79
- if (feature.processedUrl) {
78
+ if (feature.processedVideoUrl) {
80
79
  const screenWidth = Dimensions.get("window").width;
81
- const imageSize = screenWidth - 48;
80
+ const videoSize = screenWidth - 48;
82
81
 
83
82
  return (
84
83
  <ScrollView
@@ -93,12 +92,8 @@ export const AIHugFeature: React.FC<AIHugFeatureProps> = ({
93
92
  {translations.successText}
94
93
  </AtomicText>
95
94
 
96
- <View style={styles.resultImageContainer}>
97
- <Image
98
- source={{ uri: feature.processedUrl }}
99
- style={[styles.resultImage, { width: imageSize, height: imageSize }]}
100
- resizeMode="contain"
101
- />
95
+ <View style={styles.resultVideoContainer}>
96
+ {renderVideoPlayer({ videoUrl: feature.processedVideoUrl, size: videoSize })}
102
97
  </View>
103
98
 
104
99
  <View style={styles.resultActions}>
@@ -190,14 +185,11 @@ const styles = StyleSheet.create({
190
185
  textAlign: "center",
191
186
  marginBottom: 24,
192
187
  },
193
- resultImageContainer: {
188
+ resultVideoContainer: {
194
189
  alignItems: "center",
195
190
  marginHorizontal: 24,
196
191
  marginBottom: 24,
197
192
  },
198
- resultImage: {
199
- borderRadius: 16,
200
- },
201
193
  resultActions: {
202
194
  marginHorizontal: 24,
203
195
  gap: 12,
@@ -1,24 +1,21 @@
1
1
  /**
2
2
  * useAIHugFeature Hook
3
- * Manages AI hug feature state and actions
3
+ * Manages AI hug video generation state and actions
4
4
  */
5
5
 
6
6
  import { useState, useCallback } from "react";
7
- import { executeAIHug } from "../../infrastructure/services";
7
+ import { executeVideoFeature } from "../../../../infrastructure/services";
8
8
  import type {
9
9
  AIHugFeatureState,
10
10
  AIHugFeatureConfig,
11
11
  AIHugResult,
12
12
  } from "../../domain/types";
13
13
 
14
- declare const __DEV__: boolean;
15
-
16
14
  export interface UseAIHugFeatureProps {
17
15
  config: AIHugFeatureConfig;
18
- userId: string;
19
16
  onSelectSourceImage: () => Promise<string | null>;
20
17
  onSelectTargetImage: () => Promise<string | null>;
21
- onSaveImage: (imageUrl: string) => Promise<void>;
18
+ onSaveVideo: (videoUrl: string) => Promise<void>;
22
19
  }
23
20
 
24
21
  export interface UseAIHugFeatureReturn extends AIHugFeatureState {
@@ -32,7 +29,7 @@ export interface UseAIHugFeatureReturn extends AIHugFeatureState {
32
29
  const initialState: AIHugFeatureState = {
33
30
  sourceImageUri: null,
34
31
  targetImageUri: null,
35
- processedUrl: null,
32
+ processedVideoUrl: null,
36
33
  isProcessing: false,
37
34
  progress: 0,
38
35
  error: null,
@@ -41,7 +38,7 @@ const initialState: AIHugFeatureState = {
41
38
  export function useAIHugFeature(
42
39
  props: UseAIHugFeatureProps,
43
40
  ): UseAIHugFeatureReturn {
44
- const { config, userId, onSelectSourceImage, onSelectTargetImage, onSaveImage } = props;
41
+ const { config, onSelectSourceImage, onSelectTargetImage, onSaveVideo } = props;
45
42
  const [state, setState] = useState<AIHugFeatureState>(initialState);
46
43
 
47
44
  const selectSourceImage = useCallback(async () => {
@@ -86,39 +83,23 @@ export function useAIHugFeature(
86
83
 
87
84
  config.onProcessingStart?.();
88
85
 
89
- if (__DEV__) {
90
- // eslint-disable-next-line no-console
91
- console.log("[useAIHugFeature] Starting AI hug process");
92
- }
93
-
94
86
  const sourceImageBase64 = await config.prepareImage(state.sourceImageUri);
95
87
  const targetImageBase64 = await config.prepareImage(state.targetImageUri);
96
88
 
97
- const result: AIHugResult = await executeAIHug(
98
- {
99
- sourceImageUri: state.sourceImageUri,
100
- targetImageUri: state.targetImageUri,
101
- sourceImageBase64,
102
- targetImageBase64,
103
- userId,
104
- },
105
- {
106
- model: config.model,
107
- buildInput: config.buildInput,
108
- extractResult: config.extractResult,
109
- onProgress: handleProgress,
110
- },
89
+ const result = await executeVideoFeature(
90
+ "ai-hug",
91
+ { sourceImageBase64, targetImageBase64 },
92
+ { extractResult: config.extractResult, onProgress: handleProgress },
111
93
  );
112
94
 
113
- if (result.success && result.imageUrl) {
114
- const url = result.imageUrl;
95
+ if (result.success && result.videoUrl) {
115
96
  setState((prev) => ({
116
97
  ...prev,
117
98
  isProcessing: false,
118
- processedUrl: url,
99
+ processedVideoUrl: result.videoUrl!,
119
100
  progress: 100,
120
101
  }));
121
- config.onProcessingComplete?.(result);
102
+ config.onProcessingComplete?.({ success: true, videoUrl: result.videoUrl });
122
103
  } else {
123
104
  const errorMessage = result.error || "Processing failed";
124
105
  setState((prev) => ({
@@ -129,18 +110,18 @@ export function useAIHugFeature(
129
110
  }));
130
111
  config.onError?.(errorMessage);
131
112
  }
132
- }, [state.sourceImageUri, state.targetImageUri, userId, config, handleProgress]);
113
+ }, [state.sourceImageUri, state.targetImageUri, config, handleProgress]);
133
114
 
134
115
  const save = useCallback(async () => {
135
- if (!state.processedUrl) return;
116
+ if (!state.processedVideoUrl) return;
136
117
 
137
118
  try {
138
- await onSaveImage(state.processedUrl);
119
+ await onSaveVideo(state.processedVideoUrl);
139
120
  } catch (error) {
140
121
  const message = error instanceof Error ? error.message : String(error);
141
122
  setState((prev) => ({ ...prev, error: message }));
142
123
  }
143
- }, [state.processedUrl, onSaveImage]);
124
+ }, [state.processedVideoUrl, onSaveVideo]);
144
125
 
145
126
  const reset = useCallback(() => {
146
127
  setState(initialState);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * AI Kiss Feature Types
3
- * Request, Result, Config types for AI kiss generation
3
+ * Request, Result, Config types for AI kiss video generation
4
4
  */
5
5
 
6
6
  export interface AIKissOptions {
@@ -14,13 +14,13 @@ export interface AIKissRequest {
14
14
  sourceImageBase64?: string;
15
15
  targetImageBase64?: string;
16
16
  userId: string;
17
+ prompt?: string;
17
18
  options?: AIKissOptions;
18
19
  }
19
20
 
20
21
  export interface AIKissResult {
21
22
  success: boolean;
22
- imageUrl?: string;
23
- imageBase64?: string;
23
+ videoUrl?: string;
24
24
  error?: string;
25
25
  requestId?: string;
26
26
  }
@@ -28,7 +28,7 @@ export interface AIKissResult {
28
28
  export interface AIKissFeatureState {
29
29
  sourceImageUri: string | null;
30
30
  targetImageUri: string | null;
31
- processedUrl: string | null;
31
+ processedVideoUrl: string | null;
32
32
  isProcessing: boolean;
33
33
  progress: number;
34
34
  error: string | null;
@@ -49,19 +49,10 @@ export interface AIKissTranslations {
49
49
  tryAnotherText: string;
50
50
  }
51
51
 
52
- export type AIKissInputBuilder = (
53
- sourceBase64: string,
54
- targetBase64: string,
55
- options?: AIKissOptions,
56
- ) => Record<string, unknown>;
57
-
58
52
  export type AIKissResultExtractor = (result: unknown) => string | undefined;
59
53
 
60
54
  export interface AIKissFeatureConfig {
61
- providerId?: string;
62
55
  creditCost?: number;
63
- model: string;
64
- buildInput: AIKissInputBuilder;
65
56
  extractResult?: AIKissResultExtractor;
66
57
  prepareImage: (imageUri: string) => Promise<string>;
67
58
  onSourceImageSelect?: (uri: string) => void;
@@ -8,7 +8,6 @@ export type {
8
8
  AIKissResult,
9
9
  AIKissFeatureState,
10
10
  AIKissTranslations,
11
- AIKissInputBuilder,
12
11
  AIKissResultExtractor,
13
12
  AIKissFeatureConfig,
14
13
  } from "./ai-kiss.types";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * AI Kiss Feature
3
- * Provider-agnostic AI kiss generation feature
3
+ * Provider-agnostic AI kiss video generation feature
4
4
  */
5
5
 
6
6
  // Domain Types
@@ -11,14 +11,9 @@ export type {
11
11
  AIKissFeatureState,
12
12
  AIKissTranslations,
13
13
  AIKissFeatureConfig,
14
- AIKissInputBuilder,
15
14
  AIKissResultExtractor,
16
15
  } from "./domain";
17
16
 
18
- // Infrastructure Services
19
- export { executeAIKiss, hasAIKissSupport } from "./infrastructure";
20
- export type { ExecuteAIKissOptions } from "./infrastructure";
21
-
22
17
  // Presentation Hooks
23
18
  export { useAIKissFeature } from "./presentation";
24
19
  export type {
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * AIKissFeature Component
3
- * Self-contained AI kiss feature UI component
3
+ * Self-contained AI kiss video feature UI component
4
4
  * Uses hook internally, only requires config and translations
5
5
  */
6
6
 
7
7
  import React, { useCallback } from "react";
8
- import { View, ScrollView, StyleSheet, Image, Dimensions } from "react-native";
8
+ import { View, ScrollView, StyleSheet, Dimensions } from "react-native";
9
9
  import {
10
10
  useAppDesignTokens,
11
11
  AtomicText,
@@ -21,11 +21,12 @@ import type {
21
21
 
22
22
  export interface AIKissFeatureProps {
23
23
  config: AIKissFeatureConfig;
24
- userId: string;
25
24
  translations: AIKissTranslations;
26
25
  onSelectSourceImage: () => Promise<string | null>;
27
26
  onSelectTargetImage: () => Promise<string | null>;
28
- onSaveImage: (imageUrl: string) => Promise<void>;
27
+ onSaveVideo: (videoUrl: string) => Promise<void>;
28
+ /** Custom video player renderer - required for video playback */
29
+ renderVideoPlayer: (props: { videoUrl: string; size: number }) => React.ReactNode;
29
30
  renderProcessingModal?: (props: {
30
31
  visible: boolean;
31
32
  progress: number;
@@ -34,21 +35,20 @@ export interface AIKissFeatureProps {
34
35
 
35
36
  export const AIKissFeature: React.FC<AIKissFeatureProps> = ({
36
37
  config,
37
- userId,
38
38
  translations,
39
39
  onSelectSourceImage,
40
40
  onSelectTargetImage,
41
- onSaveImage,
41
+ onSaveVideo,
42
+ renderVideoPlayer,
42
43
  renderProcessingModal,
43
44
  }) => {
44
45
  const tokens = useAppDesignTokens();
45
46
 
46
47
  const feature = useAIKissFeature({
47
48
  config,
48
- userId,
49
49
  onSelectSourceImage,
50
50
  onSelectTargetImage,
51
- onSaveImage,
51
+ onSaveVideo,
52
52
  });
53
53
 
54
54
  const handleProcess = useCallback(() => {
@@ -69,9 +69,9 @@ export const AIKissFeature: React.FC<AIKissFeatureProps> = ({
69
69
 
70
70
  const canProcess = feature.sourceImageUri && feature.targetImageUri && !feature.isProcessing;
71
71
 
72
- if (feature.processedUrl) {
72
+ if (feature.processedVideoUrl) {
73
73
  const screenWidth = Dimensions.get("window").width;
74
- const imageSize = screenWidth - 48;
74
+ const videoSize = screenWidth - 48;
75
75
 
76
76
  return (
77
77
  <ScrollView
@@ -86,12 +86,8 @@ export const AIKissFeature: React.FC<AIKissFeatureProps> = ({
86
86
  {translations.successText}
87
87
  </AtomicText>
88
88
 
89
- <View style={styles.resultImageContainer}>
90
- <Image
91
- source={{ uri: feature.processedUrl }}
92
- style={[styles.resultImage, { width: imageSize, height: imageSize }]}
93
- resizeMode="contain"
94
- />
89
+ <View style={styles.resultVideoContainer}>
90
+ {renderVideoPlayer({ videoUrl: feature.processedVideoUrl, size: videoSize })}
95
91
  </View>
96
92
 
97
93
  <View style={styles.resultActions}>
@@ -183,14 +179,11 @@ const styles = StyleSheet.create({
183
179
  textAlign: "center",
184
180
  marginBottom: 24,
185
181
  },
186
- resultImageContainer: {
182
+ resultVideoContainer: {
187
183
  alignItems: "center",
188
184
  marginHorizontal: 24,
189
185
  marginBottom: 24,
190
186
  },
191
- resultImage: {
192
- borderRadius: 16,
193
- },
194
187
  resultActions: {
195
188
  marginHorizontal: 24,
196
189
  gap: 12,
@@ -1,24 +1,21 @@
1
1
  /**
2
2
  * useAIKissFeature Hook
3
- * Manages AI kiss feature state and actions
3
+ * Manages AI kiss video generation state and actions
4
4
  */
5
5
 
6
6
  import { useState, useCallback } from "react";
7
- import { executeAIKiss } from "../../infrastructure/services";
7
+ import { executeVideoFeature } from "../../../../infrastructure/services";
8
8
  import type {
9
9
  AIKissFeatureState,
10
10
  AIKissFeatureConfig,
11
11
  AIKissResult,
12
12
  } from "../../domain/types";
13
13
 
14
- declare const __DEV__: boolean;
15
-
16
14
  export interface UseAIKissFeatureProps {
17
15
  config: AIKissFeatureConfig;
18
- userId: string;
19
16
  onSelectSourceImage: () => Promise<string | null>;
20
17
  onSelectTargetImage: () => Promise<string | null>;
21
- onSaveImage: (imageUrl: string) => Promise<void>;
18
+ onSaveVideo: (videoUrl: string) => Promise<void>;
22
19
  }
23
20
 
24
21
  export interface UseAIKissFeatureReturn extends AIKissFeatureState {
@@ -32,7 +29,7 @@ export interface UseAIKissFeatureReturn extends AIKissFeatureState {
32
29
  const initialState: AIKissFeatureState = {
33
30
  sourceImageUri: null,
34
31
  targetImageUri: null,
35
- processedUrl: null,
32
+ processedVideoUrl: null,
36
33
  isProcessing: false,
37
34
  progress: 0,
38
35
  error: null,
@@ -41,7 +38,7 @@ const initialState: AIKissFeatureState = {
41
38
  export function useAIKissFeature(
42
39
  props: UseAIKissFeatureProps,
43
40
  ): UseAIKissFeatureReturn {
44
- const { config, userId, onSelectSourceImage, onSelectTargetImage, onSaveImage } = props;
41
+ const { config, onSelectSourceImage, onSelectTargetImage, onSaveVideo } = props;
45
42
  const [state, setState] = useState<AIKissFeatureState>(initialState);
46
43
 
47
44
  const selectSourceImage = useCallback(async () => {
@@ -86,39 +83,23 @@ export function useAIKissFeature(
86
83
 
87
84
  config.onProcessingStart?.();
88
85
 
89
- if (__DEV__) {
90
- // eslint-disable-next-line no-console
91
- console.log("[useAIKissFeature] Starting AI kiss process");
92
- }
93
-
94
86
  const sourceImageBase64 = await config.prepareImage(state.sourceImageUri);
95
87
  const targetImageBase64 = await config.prepareImage(state.targetImageUri);
96
88
 
97
- const result: AIKissResult = await executeAIKiss(
98
- {
99
- sourceImageUri: state.sourceImageUri,
100
- targetImageUri: state.targetImageUri,
101
- sourceImageBase64,
102
- targetImageBase64,
103
- userId,
104
- },
105
- {
106
- model: config.model,
107
- buildInput: config.buildInput,
108
- extractResult: config.extractResult,
109
- onProgress: handleProgress,
110
- },
89
+ const result = await executeVideoFeature(
90
+ "ai-kiss",
91
+ { sourceImageBase64, targetImageBase64 },
92
+ { extractResult: config.extractResult, onProgress: handleProgress },
111
93
  );
112
94
 
113
- if (result.success && result.imageUrl) {
114
- const url = result.imageUrl;
95
+ if (result.success && result.videoUrl) {
115
96
  setState((prev) => ({
116
97
  ...prev,
117
98
  isProcessing: false,
118
- processedUrl: url,
99
+ processedVideoUrl: result.videoUrl!,
119
100
  progress: 100,
120
101
  }));
121
- config.onProcessingComplete?.(result);
102
+ config.onProcessingComplete?.({ success: true, videoUrl: result.videoUrl });
122
103
  } else {
123
104
  const errorMessage = result.error || "Processing failed";
124
105
  setState((prev) => ({
@@ -129,18 +110,18 @@ export function useAIKissFeature(
129
110
  }));
130
111
  config.onError?.(errorMessage);
131
112
  }
132
- }, [state.sourceImageUri, state.targetImageUri, userId, config, handleProgress]);
113
+ }, [state.sourceImageUri, state.targetImageUri, config, handleProgress]);
133
114
 
134
115
  const save = useCallback(async () => {
135
- if (!state.processedUrl) return;
116
+ if (!state.processedVideoUrl) return;
136
117
 
137
118
  try {
138
- await onSaveImage(state.processedUrl);
119
+ await onSaveVideo(state.processedVideoUrl);
139
120
  } catch (error) {
140
121
  const message = error instanceof Error ? error.message : String(error);
141
122
  setState((prev) => ({ ...prev, error: message }));
142
123
  }
143
- }, [state.processedUrl, onSaveImage]);
124
+ }, [state.processedVideoUrl, onSaveVideo]);
144
125
 
145
126
  const reset = useCallback(() => {
146
127
  setState(initialState);