@umituz/react-native-ai-generation-content 1.17.0 → 1.17.2

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 (156) hide show
  1. package/package.json +13 -14
  2. package/src/domains/creations/domain/entities/Creation.ts +33 -2
  3. package/src/domains/creations/domain/entities/index.ts +1 -1
  4. package/src/domains/creations/domain/types/creation-categories.ts +133 -0
  5. package/src/domains/creations/domain/types/creation-filter.ts +131 -0
  6. package/src/domains/creations/domain/types/creation-types.ts +63 -0
  7. package/src/domains/creations/domain/types/index.ts +44 -0
  8. package/src/domains/creations/domain/utils/creation-helpers.ts +134 -0
  9. package/src/domains/creations/domain/utils/index.ts +8 -0
  10. package/src/domains/creations/domain/utils/preview-helpers.ts +84 -0
  11. package/src/domains/creations/domain/utils/status-helpers.ts +90 -0
  12. package/src/domains/creations/index.ts +95 -21
  13. package/src/domains/creations/infrastructure/repositories/CreationsRepository.ts +14 -1
  14. package/src/domains/creations/presentation/components/CreationActions.tsx +120 -0
  15. package/src/domains/creations/presentation/components/CreationBadges.tsx +111 -0
  16. package/src/domains/creations/presentation/components/CreationCard.tsx +201 -102
  17. package/src/domains/creations/presentation/components/CreationPreview.tsx +117 -0
  18. package/src/domains/creations/presentation/components/CreationsFilterBar.tsx +254 -0
  19. package/src/domains/creations/presentation/components/CreationsGrid.tsx +121 -68
  20. package/src/domains/creations/presentation/components/CreationsHomeCard.tsx +1 -1
  21. package/src/domains/creations/presentation/components/index.ts +23 -3
  22. package/src/domains/creations/presentation/hooks/index.ts +1 -0
  23. package/src/domains/creations/presentation/hooks/useAdvancedFilter.ts +261 -0
  24. package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +8 -6
  25. package/src/domains/face-detection/infrastructure/validators/faceValidator.ts +1 -1
  26. package/src/domains/prompts/infrastructure/services/PromptGenerationService.ts +1 -1
  27. package/src/domains/prompts/presentation/hooks/useFaceSwap.ts +2 -2
  28. package/src/domains/prompts/presentation/hooks/usePromptGeneration.ts +4 -4
  29. package/src/features/ai-hug/domain/index.ts +5 -0
  30. package/src/features/ai-hug/domain/types/ai-hug.types.ts +72 -0
  31. package/src/features/ai-hug/domain/types/index.ts +14 -0
  32. package/src/features/ai-hug/index.ts +27 -0
  33. package/src/features/ai-hug/infrastructure/index.ts +5 -0
  34. package/src/features/ai-hug/infrastructure/services/ai-hug-executor.ts +96 -0
  35. package/src/features/ai-hug/infrastructure/services/index.ts +6 -0
  36. package/src/features/ai-hug/presentation/hooks/index.ts +9 -0
  37. package/src/features/ai-hug/presentation/hooks/useAIHugFeature.ts +157 -0
  38. package/src/features/ai-hug/presentation/index.ts +5 -0
  39. package/src/features/ai-kiss/domain/index.ts +5 -0
  40. package/src/features/ai-kiss/domain/types/ai-kiss.types.ts +72 -0
  41. package/src/features/ai-kiss/domain/types/index.ts +14 -0
  42. package/src/features/ai-kiss/index.ts +27 -0
  43. package/src/features/ai-kiss/infrastructure/index.ts +5 -0
  44. package/src/features/ai-kiss/infrastructure/services/ai-kiss-executor.ts +96 -0
  45. package/src/features/ai-kiss/infrastructure/services/index.ts +6 -0
  46. package/src/features/ai-kiss/presentation/hooks/index.ts +9 -0
  47. package/src/features/ai-kiss/presentation/hooks/useAIKissFeature.ts +157 -0
  48. package/src/features/ai-kiss/presentation/index.ts +5 -0
  49. package/src/features/anime-selfie/domain/index.ts +5 -0
  50. package/src/features/anime-selfie/domain/types/anime-selfie.types.ts +72 -0
  51. package/src/features/anime-selfie/domain/types/index.ts +15 -0
  52. package/src/features/anime-selfie/index.ts +28 -0
  53. package/src/features/anime-selfie/infrastructure/index.ts +5 -0
  54. package/src/features/anime-selfie/infrastructure/services/anime-selfie-executor.ts +95 -0
  55. package/src/features/anime-selfie/infrastructure/services/index.ts +6 -0
  56. package/src/features/anime-selfie/presentation/hooks/index.ts +9 -0
  57. package/src/features/anime-selfie/presentation/hooks/useAnimeSelfieFeature.ts +138 -0
  58. package/src/features/anime-selfie/presentation/index.ts +5 -0
  59. package/src/features/background/domain/types/index.ts +15 -0
  60. package/src/features/background/domain/types/replace-background.types.ts +82 -0
  61. package/src/features/background/index.ts +31 -3
  62. package/src/features/background/infrastructure/index.ts +5 -0
  63. package/src/features/background/infrastructure/services/index.ts +6 -0
  64. package/src/features/background/infrastructure/services/replace-background-executor.ts +95 -0
  65. package/src/features/background/presentation/hooks/index.ts +6 -1
  66. package/src/features/background/presentation/hooks/useReplaceBackgroundFeature.ts +160 -0
  67. package/src/features/face-swap/domain/index.ts +5 -0
  68. package/src/features/face-swap/domain/types/face-swap.types.ts +72 -0
  69. package/src/features/face-swap/domain/types/index.ts +14 -0
  70. package/src/features/face-swap/index.ts +27 -1
  71. package/src/features/face-swap/infrastructure/index.ts +5 -0
  72. package/src/features/face-swap/infrastructure/services/face-swap-executor.ts +96 -0
  73. package/src/features/face-swap/infrastructure/services/index.ts +6 -0
  74. package/src/features/face-swap/presentation/hooks/index.ts +9 -0
  75. package/src/features/face-swap/presentation/hooks/useFaceSwapFeature.ts +157 -0
  76. package/src/features/face-swap/presentation/index.ts +5 -0
  77. package/src/features/image-to-video/domain/index.ts +1 -0
  78. package/src/features/image-to-video/domain/types/image-to-video.types.ts +71 -0
  79. package/src/features/image-to-video/domain/types/index.ts +10 -0
  80. package/src/features/image-to-video/index.ts +27 -0
  81. package/src/features/image-to-video/infrastructure/index.ts +1 -0
  82. package/src/features/image-to-video/infrastructure/services/image-to-video-executor.ts +112 -0
  83. package/src/features/image-to-video/infrastructure/services/index.ts +5 -0
  84. package/src/features/image-to-video/presentation/hooks/index.ts +5 -0
  85. package/src/features/image-to-video/presentation/hooks/useImageToVideoFeature.ts +121 -0
  86. package/src/features/image-to-video/presentation/index.ts +1 -0
  87. package/src/features/photo-restoration/domain/types/index.ts +2 -5
  88. package/src/features/photo-restoration/domain/types/photo-restore.types.ts +14 -0
  89. package/src/features/photo-restoration/index.ts +3 -8
  90. package/src/features/photo-restoration/infrastructure/services/index.ts +1 -6
  91. package/src/features/photo-restoration/infrastructure/services/photo-restore-executor.ts +64 -30
  92. package/src/features/photo-restoration/presentation/hooks/usePhotoRestoreFeature.ts +11 -6
  93. package/src/features/remove-background/domain/index.ts +5 -0
  94. package/src/features/remove-background/domain/types/index.ts +14 -0
  95. package/src/features/remove-background/domain/types/remove-background.types.ts +69 -0
  96. package/src/features/remove-background/index.ts +27 -0
  97. package/src/features/remove-background/infrastructure/index.ts +5 -0
  98. package/src/features/remove-background/infrastructure/services/index.ts +6 -0
  99. package/src/features/remove-background/infrastructure/services/remove-background-executor.ts +95 -0
  100. package/src/features/remove-background/presentation/hooks/index.ts +9 -0
  101. package/src/features/remove-background/presentation/hooks/useRemoveBackgroundFeature.ts +137 -0
  102. package/src/features/remove-background/presentation/index.ts +5 -0
  103. package/src/features/remove-object/domain/index.ts +5 -0
  104. package/src/features/remove-object/domain/types/index.ts +14 -0
  105. package/src/features/remove-object/domain/types/remove-object.types.ts +77 -0
  106. package/src/features/remove-object/index.ts +27 -0
  107. package/src/features/remove-object/infrastructure/index.ts +5 -0
  108. package/src/features/remove-object/infrastructure/services/index.ts +6 -0
  109. package/src/features/remove-object/infrastructure/services/remove-object-executor.ts +99 -0
  110. package/src/features/remove-object/presentation/hooks/index.ts +9 -0
  111. package/src/features/remove-object/presentation/hooks/useRemoveObjectFeature.ts +168 -0
  112. package/src/features/remove-object/presentation/index.ts +5 -0
  113. package/src/features/text-to-image/domain/index.ts +1 -0
  114. package/src/features/text-to-image/domain/types/index.ts +10 -0
  115. package/src/features/text-to-image/domain/types/text-to-image.types.ts +66 -0
  116. package/src/features/text-to-image/index.ts +27 -1
  117. package/src/features/text-to-image/infrastructure/index.ts +1 -0
  118. package/src/features/text-to-image/infrastructure/services/index.ts +5 -0
  119. package/src/features/text-to-image/infrastructure/services/text-to-image-executor.ts +113 -0
  120. package/src/features/text-to-image/presentation/hooks/index.ts +5 -0
  121. package/src/features/text-to-image/presentation/hooks/useTextToImageFeature.ts +111 -0
  122. package/src/features/text-to-image/presentation/index.ts +1 -0
  123. package/src/features/text-to-video/domain/index.ts +1 -0
  124. package/src/features/text-to-video/domain/types/index.ts +10 -0
  125. package/src/features/text-to-video/domain/types/text-to-video.types.ts +65 -0
  126. package/src/features/text-to-video/index.ts +27 -1
  127. package/src/features/text-to-video/infrastructure/index.ts +1 -0
  128. package/src/features/text-to-video/infrastructure/services/index.ts +5 -0
  129. package/src/features/text-to-video/infrastructure/services/text-to-video-executor.ts +108 -0
  130. package/src/features/text-to-video/presentation/hooks/index.ts +5 -0
  131. package/src/features/text-to-video/presentation/hooks/useTextToVideoFeature.ts +111 -0
  132. package/src/features/text-to-video/presentation/index.ts +1 -0
  133. package/src/features/text-to-voice/domain/index.ts +1 -0
  134. package/src/features/text-to-voice/domain/types/index.ts +10 -0
  135. package/src/features/text-to-voice/domain/types/text-to-voice.types.ts +65 -0
  136. package/src/features/text-to-voice/index.ts +27 -0
  137. package/src/features/text-to-voice/infrastructure/index.ts +1 -0
  138. package/src/features/text-to-voice/infrastructure/services/index.ts +5 -0
  139. package/src/features/text-to-voice/infrastructure/services/text-to-voice-executor.ts +111 -0
  140. package/src/features/text-to-voice/presentation/hooks/index.ts +5 -0
  141. package/src/features/text-to-voice/presentation/hooks/useTextToVoiceFeature.ts +105 -0
  142. package/src/features/text-to-voice/presentation/index.ts +1 -0
  143. package/src/features/upscaling/domain/types/index.ts +0 -1
  144. package/src/features/upscaling/domain/types/upscale.types.ts +14 -0
  145. package/src/features/upscaling/index.ts +3 -11
  146. package/src/features/upscaling/infrastructure/services/index.ts +1 -6
  147. package/src/features/upscaling/infrastructure/services/upscale-executor.ts +64 -30
  148. package/src/features/upscaling/presentation/hooks/useUpscaleFeature.ts +12 -7
  149. package/src/index.ts +63 -0
  150. package/src/features/face-swap/domain/entities.ts +0 -48
  151. package/src/features/photo-restoration/domain/types/provider.types.ts +0 -23
  152. package/src/features/photo-restoration/infrastructure/services/photo-restore-provider-registry.ts +0 -77
  153. package/src/features/text-to-image/domain/entities.ts +0 -58
  154. package/src/features/text-to-video/domain/entities.ts +0 -52
  155. package/src/features/upscaling/domain/types/provider.types.ts +0 -23
  156. package/src/features/upscaling/infrastructure/services/upscale-provider-registry.ts +0 -77
@@ -0,0 +1,160 @@
1
+ /**
2
+ * useReplaceBackgroundFeature Hook
3
+ * Manages replace background feature state and actions
4
+ */
5
+
6
+ import { useState, useCallback } from "react";
7
+ import { executeReplaceBackground } from "../../infrastructure/services";
8
+ import type {
9
+ ReplaceBackgroundFeatureState,
10
+ ReplaceBackgroundFeatureConfig,
11
+ ReplaceBackgroundResult,
12
+ ReplaceBackgroundMode,
13
+ } from "../../domain/types";
14
+
15
+ declare const __DEV__: boolean;
16
+
17
+ export interface UseReplaceBackgroundFeatureProps {
18
+ config: ReplaceBackgroundFeatureConfig;
19
+ userId: string;
20
+ onSelectImage: () => Promise<string | null>;
21
+ onSaveImage: (imageUrl: string) => Promise<void>;
22
+ }
23
+
24
+ export interface UseReplaceBackgroundFeatureReturn extends ReplaceBackgroundFeatureState {
25
+ selectImage: () => Promise<void>;
26
+ setPrompt: (prompt: string) => void;
27
+ setMode: (mode: ReplaceBackgroundMode) => void;
28
+ process: () => Promise<void>;
29
+ save: () => Promise<void>;
30
+ reset: () => void;
31
+ }
32
+
33
+ const initialState: ReplaceBackgroundFeatureState = {
34
+ imageUri: null,
35
+ prompt: "",
36
+ processedUrl: null,
37
+ isProcessing: false,
38
+ progress: 0,
39
+ error: null,
40
+ mode: "replace",
41
+ };
42
+
43
+ export function useReplaceBackgroundFeature(
44
+ props: UseReplaceBackgroundFeatureProps,
45
+ ): UseReplaceBackgroundFeatureReturn {
46
+ const { config, userId, onSelectImage, onSaveImage } = props;
47
+ const [state, setState] = useState<ReplaceBackgroundFeatureState>({
48
+ ...initialState,
49
+ mode: config.defaultMode || "replace",
50
+ });
51
+
52
+ const selectImage = useCallback(async () => {
53
+ try {
54
+ const uri = await onSelectImage();
55
+ if (uri) {
56
+ setState((prev) => ({ ...prev, imageUri: uri, error: null }));
57
+ config.onImageSelect?.(uri);
58
+ }
59
+ } catch (error) {
60
+ const message = error instanceof Error ? error.message : String(error);
61
+ setState((prev) => ({ ...prev, error: message }));
62
+ }
63
+ }, [onSelectImage, config]);
64
+
65
+ const setPrompt = useCallback((prompt: string) => {
66
+ setState((prev) => ({ ...prev, prompt }));
67
+ }, []);
68
+
69
+ const setMode = useCallback((mode: ReplaceBackgroundMode) => {
70
+ setState((prev) => ({ ...prev, mode }));
71
+ }, []);
72
+
73
+ const handleProgress = useCallback((progress: number) => {
74
+ setState((prev) => ({ ...prev, progress }));
75
+ }, []);
76
+
77
+ const process = useCallback(async () => {
78
+ if (!state.imageUri) return;
79
+
80
+ setState((prev) => ({
81
+ ...prev,
82
+ isProcessing: true,
83
+ progress: 0,
84
+ error: null,
85
+ }));
86
+
87
+ config.onProcessingStart?.();
88
+
89
+ if (__DEV__) {
90
+ // eslint-disable-next-line no-console
91
+ console.log("[useReplaceBackgroundFeature] Starting background replacement process");
92
+ }
93
+
94
+ const imageBase64 = await config.prepareImage(state.imageUri);
95
+
96
+ const result: ReplaceBackgroundResult = await executeReplaceBackground(
97
+ {
98
+ imageUri: state.imageUri,
99
+ imageBase64,
100
+ userId,
101
+ prompt: state.prompt || undefined,
102
+ options: { mode: state.mode },
103
+ },
104
+ {
105
+ model: config.model,
106
+ buildInput: config.buildInput,
107
+ extractResult: config.extractResult,
108
+ onProgress: handleProgress,
109
+ },
110
+ );
111
+
112
+ if (result.success && result.imageUrl) {
113
+ const url = result.imageUrl;
114
+ setState((prev) => ({
115
+ ...prev,
116
+ isProcessing: false,
117
+ processedUrl: url,
118
+ progress: 100,
119
+ }));
120
+ config.onProcessingComplete?.(result);
121
+ } else {
122
+ const errorMessage = result.error || "Processing failed";
123
+ setState((prev) => ({
124
+ ...prev,
125
+ isProcessing: false,
126
+ error: errorMessage,
127
+ progress: 0,
128
+ }));
129
+ config.onError?.(errorMessage);
130
+ }
131
+ }, [state.imageUri, state.prompt, state.mode, userId, config, handleProgress]);
132
+
133
+ const save = useCallback(async () => {
134
+ if (!state.processedUrl) return;
135
+
136
+ try {
137
+ await onSaveImage(state.processedUrl);
138
+ } catch (error) {
139
+ const message = error instanceof Error ? error.message : String(error);
140
+ setState((prev) => ({ ...prev, error: message }));
141
+ }
142
+ }, [state.processedUrl, onSaveImage]);
143
+
144
+ const reset = useCallback(() => {
145
+ setState({
146
+ ...initialState,
147
+ mode: config.defaultMode || "replace",
148
+ });
149
+ }, [config.defaultMode]);
150
+
151
+ return {
152
+ ...state,
153
+ selectImage,
154
+ setPrompt,
155
+ setMode,
156
+ process,
157
+ save,
158
+ reset,
159
+ };
160
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Face Swap Domain Index
3
+ */
4
+
5
+ export * from "./types";
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Face Swap Feature Types
3
+ * Request, Result, Config types for face swap generation
4
+ */
5
+
6
+ export interface FaceSwapOptions {
7
+ enhanceFace?: boolean;
8
+ preserveSkinTone?: boolean;
9
+ }
10
+
11
+ export interface FaceSwapRequest {
12
+ sourceImageUri: string;
13
+ targetImageUri: string;
14
+ sourceImageBase64?: string;
15
+ targetImageBase64?: string;
16
+ userId: string;
17
+ options?: FaceSwapOptions;
18
+ }
19
+
20
+ export interface FaceSwapResult {
21
+ success: boolean;
22
+ imageUrl?: string;
23
+ imageBase64?: string;
24
+ error?: string;
25
+ requestId?: string;
26
+ }
27
+
28
+ export interface FaceSwapFeatureState {
29
+ sourceImageUri: string | null;
30
+ targetImageUri: string | null;
31
+ processedUrl: string | null;
32
+ isProcessing: boolean;
33
+ progress: number;
34
+ error: string | null;
35
+ }
36
+
37
+ export interface FaceSwapTranslations {
38
+ sourceUploadTitle: string;
39
+ sourceUploadSubtitle: string;
40
+ targetUploadTitle: string;
41
+ targetUploadSubtitle: string;
42
+ uploadChange: string;
43
+ uploadAnalyzing: string;
44
+ description: string;
45
+ processingText: string;
46
+ processButtonText: string;
47
+ successText: string;
48
+ saveButtonText: string;
49
+ tryAnotherText: string;
50
+ }
51
+
52
+ export type FaceSwapInputBuilder = (
53
+ sourceBase64: string,
54
+ targetBase64: string,
55
+ options?: FaceSwapOptions,
56
+ ) => Record<string, unknown>;
57
+
58
+ export type FaceSwapResultExtractor = (result: unknown) => string | undefined;
59
+
60
+ export interface FaceSwapFeatureConfig {
61
+ providerId?: string;
62
+ creditCost?: number;
63
+ model: string;
64
+ buildInput: FaceSwapInputBuilder;
65
+ extractResult?: FaceSwapResultExtractor;
66
+ prepareImage: (imageUri: string) => Promise<string>;
67
+ onSourceImageSelect?: (uri: string) => void;
68
+ onTargetImageSelect?: (uri: string) => void;
69
+ onProcessingStart?: () => void;
70
+ onProcessingComplete?: (result: FaceSwapResult) => void;
71
+ onError?: (error: string) => void;
72
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Face Swap Domain Types Index
3
+ */
4
+
5
+ export type {
6
+ FaceSwapOptions,
7
+ FaceSwapRequest,
8
+ FaceSwapResult,
9
+ FaceSwapFeatureState,
10
+ FaceSwapTranslations,
11
+ FaceSwapInputBuilder,
12
+ FaceSwapResultExtractor,
13
+ FaceSwapFeatureConfig,
14
+ } from "./face-swap.types";
@@ -1 +1,27 @@
1
- export * from './domain/entities';
1
+ /**
2
+ * Face Swap Feature
3
+ * Provider-agnostic face swap generation feature
4
+ */
5
+
6
+ // Domain Types
7
+ export type {
8
+ FaceSwapOptions,
9
+ FaceSwapRequest,
10
+ FaceSwapResult,
11
+ FaceSwapFeatureState,
12
+ FaceSwapTranslations,
13
+ FaceSwapFeatureConfig,
14
+ FaceSwapInputBuilder,
15
+ FaceSwapResultExtractor,
16
+ } from "./domain";
17
+
18
+ // Infrastructure Services
19
+ export { executeFaceSwap, hasFaceSwapSupport } from "./infrastructure";
20
+ export type { ExecuteFaceSwapOptions } from "./infrastructure";
21
+
22
+ // Presentation Hooks
23
+ export { useFaceSwapFeature } from "./presentation";
24
+ export type {
25
+ UseFaceSwapFeatureProps,
26
+ UseFaceSwapFeatureReturn,
27
+ } from "./presentation";
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Face Swap Infrastructure Index
3
+ */
4
+
5
+ export * from "./services";
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Face Swap Executor
3
+ * Provider-agnostic face swap execution using active AI provider
4
+ * Model and input format are provided via options from app level
5
+ */
6
+
7
+ import { providerRegistry } from "../../../../infrastructure/services";
8
+ import { cleanBase64 } from "../../../../infrastructure/utils";
9
+ import type {
10
+ FaceSwapRequest,
11
+ FaceSwapResult,
12
+ FaceSwapInputBuilder,
13
+ FaceSwapResultExtractor,
14
+ } from "../../domain/types";
15
+
16
+ declare const __DEV__: boolean;
17
+
18
+ export interface ExecuteFaceSwapOptions {
19
+ model: string;
20
+ buildInput: FaceSwapInputBuilder;
21
+ extractResult?: FaceSwapResultExtractor;
22
+ onProgress?: (progress: number) => void;
23
+ }
24
+
25
+ function defaultExtractResult(result: unknown): string | undefined {
26
+ if (typeof result !== "object" || result === null) return undefined;
27
+
28
+ const r = result as Record<string, unknown>;
29
+
30
+ if (typeof r.image === "string") return r.image;
31
+ if (Array.isArray(r.images) && r.images[0]?.url) return r.images[0].url;
32
+
33
+ return undefined;
34
+ }
35
+
36
+ export async function executeFaceSwap(
37
+ request: FaceSwapRequest,
38
+ options: ExecuteFaceSwapOptions,
39
+ ): Promise<FaceSwapResult> {
40
+ const provider = providerRegistry.getActiveProvider();
41
+
42
+ if (!provider) {
43
+ return { success: false, error: "No AI provider configured" };
44
+ }
45
+
46
+ if (!provider.isInitialized()) {
47
+ return { success: false, error: "AI provider not initialized" };
48
+ }
49
+
50
+ if (!request.sourceImageBase64 || !request.targetImageBase64) {
51
+ return { success: false, error: "Both source and target image base64 are required" };
52
+ }
53
+
54
+ const { model, buildInput, extractResult, onProgress } = options;
55
+
56
+ if (__DEV__) {
57
+ // eslint-disable-next-line no-console
58
+ console.log(`[FaceSwap] Provider: ${provider.providerId}, Model: ${model}`);
59
+ }
60
+
61
+ try {
62
+ onProgress?.(10);
63
+
64
+ const sourceBase64 = cleanBase64(request.sourceImageBase64);
65
+ const targetBase64 = cleanBase64(request.targetImageBase64);
66
+ onProgress?.(30);
67
+
68
+ const input = buildInput(sourceBase64, targetBase64, request.options);
69
+ onProgress?.(40);
70
+
71
+ const result = await provider.run(model, input);
72
+ onProgress?.(90);
73
+
74
+ const extractor = extractResult || defaultExtractResult;
75
+ const imageUrl = extractor(result);
76
+ onProgress?.(100);
77
+
78
+ if (!imageUrl) {
79
+ return { success: false, error: "No image in response" };
80
+ }
81
+
82
+ return { success: true, imageUrl };
83
+ } catch (error) {
84
+ const message = error instanceof Error ? error.message : String(error);
85
+ if (__DEV__) {
86
+ // eslint-disable-next-line no-console
87
+ console.error("[FaceSwap] Error:", message);
88
+ }
89
+ return { success: false, error: message };
90
+ }
91
+ }
92
+
93
+ export function hasFaceSwapSupport(): boolean {
94
+ const provider = providerRegistry.getActiveProvider();
95
+ return provider !== null && provider.isInitialized();
96
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Face Swap Infrastructure Services Index
3
+ */
4
+
5
+ export { executeFaceSwap, hasFaceSwapSupport } from "./face-swap-executor";
6
+ export type { ExecuteFaceSwapOptions } from "./face-swap-executor";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Face Swap Presentation Hooks Index
3
+ */
4
+
5
+ export { useFaceSwapFeature } from "./useFaceSwapFeature";
6
+ export type {
7
+ UseFaceSwapFeatureProps,
8
+ UseFaceSwapFeatureReturn,
9
+ } from "./useFaceSwapFeature";
@@ -0,0 +1,157 @@
1
+ /**
2
+ * useFaceSwapFeature Hook
3
+ * Manages face swap feature state and actions
4
+ */
5
+
6
+ import { useState, useCallback } from "react";
7
+ import { executeFaceSwap } from "../../infrastructure/services";
8
+ import type {
9
+ FaceSwapFeatureState,
10
+ FaceSwapFeatureConfig,
11
+ FaceSwapResult,
12
+ } from "../../domain/types";
13
+
14
+ declare const __DEV__: boolean;
15
+
16
+ export interface UseFaceSwapFeatureProps {
17
+ config: FaceSwapFeatureConfig;
18
+ userId: string;
19
+ onSelectSourceImage: () => Promise<string | null>;
20
+ onSelectTargetImage: () => Promise<string | null>;
21
+ onSaveImage: (imageUrl: string) => Promise<void>;
22
+ }
23
+
24
+ export interface UseFaceSwapFeatureReturn extends FaceSwapFeatureState {
25
+ selectSourceImage: () => Promise<void>;
26
+ selectTargetImage: () => Promise<void>;
27
+ process: () => Promise<void>;
28
+ save: () => Promise<void>;
29
+ reset: () => void;
30
+ }
31
+
32
+ const initialState: FaceSwapFeatureState = {
33
+ sourceImageUri: null,
34
+ targetImageUri: null,
35
+ processedUrl: null,
36
+ isProcessing: false,
37
+ progress: 0,
38
+ error: null,
39
+ };
40
+
41
+ export function useFaceSwapFeature(
42
+ props: UseFaceSwapFeatureProps,
43
+ ): UseFaceSwapFeatureReturn {
44
+ const { config, userId, onSelectSourceImage, onSelectTargetImage, onSaveImage } = props;
45
+ const [state, setState] = useState<FaceSwapFeatureState>(initialState);
46
+
47
+ const selectSourceImage = useCallback(async () => {
48
+ try {
49
+ const uri = await onSelectSourceImage();
50
+ if (uri) {
51
+ setState((prev) => ({ ...prev, sourceImageUri: uri, error: null }));
52
+ config.onSourceImageSelect?.(uri);
53
+ }
54
+ } catch (error) {
55
+ const message = error instanceof Error ? error.message : String(error);
56
+ setState((prev) => ({ ...prev, error: message }));
57
+ }
58
+ }, [onSelectSourceImage, config]);
59
+
60
+ const selectTargetImage = useCallback(async () => {
61
+ try {
62
+ const uri = await onSelectTargetImage();
63
+ if (uri) {
64
+ setState((prev) => ({ ...prev, targetImageUri: uri, error: null }));
65
+ config.onTargetImageSelect?.(uri);
66
+ }
67
+ } catch (error) {
68
+ const message = error instanceof Error ? error.message : String(error);
69
+ setState((prev) => ({ ...prev, error: message }));
70
+ }
71
+ }, [onSelectTargetImage, config]);
72
+
73
+ const handleProgress = useCallback((progress: number) => {
74
+ setState((prev) => ({ ...prev, progress }));
75
+ }, []);
76
+
77
+ const process = useCallback(async () => {
78
+ if (!state.sourceImageUri || !state.targetImageUri) return;
79
+
80
+ setState((prev) => ({
81
+ ...prev,
82
+ isProcessing: true,
83
+ progress: 0,
84
+ error: null,
85
+ }));
86
+
87
+ config.onProcessingStart?.();
88
+
89
+ if (__DEV__) {
90
+ // eslint-disable-next-line no-console
91
+ console.log("[useFaceSwapFeature] Starting face swap process");
92
+ }
93
+
94
+ const sourceImageBase64 = await config.prepareImage(state.sourceImageUri);
95
+ const targetImageBase64 = await config.prepareImage(state.targetImageUri);
96
+
97
+ const result: FaceSwapResult = await executeFaceSwap(
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
+ },
111
+ );
112
+
113
+ if (result.success && result.imageUrl) {
114
+ const url = result.imageUrl;
115
+ setState((prev) => ({
116
+ ...prev,
117
+ isProcessing: false,
118
+ processedUrl: url,
119
+ progress: 100,
120
+ }));
121
+ config.onProcessingComplete?.(result);
122
+ } else {
123
+ const errorMessage = result.error || "Processing failed";
124
+ setState((prev) => ({
125
+ ...prev,
126
+ isProcessing: false,
127
+ error: errorMessage,
128
+ progress: 0,
129
+ }));
130
+ config.onError?.(errorMessage);
131
+ }
132
+ }, [state.sourceImageUri, state.targetImageUri, userId, config, handleProgress]);
133
+
134
+ const save = useCallback(async () => {
135
+ if (!state.processedUrl) return;
136
+
137
+ try {
138
+ await onSaveImage(state.processedUrl);
139
+ } catch (error) {
140
+ const message = error instanceof Error ? error.message : String(error);
141
+ setState((prev) => ({ ...prev, error: message }));
142
+ }
143
+ }, [state.processedUrl, onSaveImage]);
144
+
145
+ const reset = useCallback(() => {
146
+ setState(initialState);
147
+ }, []);
148
+
149
+ return {
150
+ ...state,
151
+ selectSourceImage,
152
+ selectTargetImage,
153
+ process,
154
+ save,
155
+ reset,
156
+ };
157
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Face Swap Presentation Index
3
+ */
4
+
5
+ export * from "./hooks";
@@ -0,0 +1 @@
1
+ export * from "./types";
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Image-to-Video Feature Types
3
+ * Request, Result, Config types for image-to-video generation
4
+ */
5
+
6
+ export interface ImageToVideoOptions {
7
+ duration?: number;
8
+ motionStrength?: number;
9
+ aspectRatio?: "16:9" | "9:16" | "1:1";
10
+ fps?: number;
11
+ }
12
+
13
+ export interface ImageToVideoRequest {
14
+ imageUri: string;
15
+ imageBase64?: string;
16
+ userId: string;
17
+ motionPrompt?: string;
18
+ options?: ImageToVideoOptions;
19
+ }
20
+
21
+ export interface ImageToVideoResult {
22
+ success: boolean;
23
+ videoUrl?: string;
24
+ thumbnailUrl?: string;
25
+ error?: string;
26
+ requestId?: string;
27
+ }
28
+
29
+ export interface ImageToVideoFeatureState {
30
+ imageUri: string | null;
31
+ motionPrompt: string;
32
+ videoUrl: string | null;
33
+ thumbnailUrl: string | null;
34
+ isProcessing: boolean;
35
+ progress: number;
36
+ error: string | null;
37
+ }
38
+
39
+ export interface ImageToVideoTranslations {
40
+ uploadTitle: string;
41
+ uploadSubtitle: string;
42
+ motionPromptPlaceholder: string;
43
+ generateButtonText: string;
44
+ processingText: string;
45
+ successText: string;
46
+ saveButtonText: string;
47
+ tryAnotherText: string;
48
+ }
49
+
50
+ export type ImageToVideoInputBuilder = (
51
+ imageBase64: string,
52
+ motionPrompt?: string,
53
+ options?: ImageToVideoOptions,
54
+ ) => Record<string, unknown>;
55
+
56
+ export type ImageToVideoResultExtractor = (
57
+ result: unknown,
58
+ ) => { videoUrl?: string; thumbnailUrl?: string } | undefined;
59
+
60
+ export interface ImageToVideoFeatureConfig {
61
+ providerId?: string;
62
+ creditCost?: number;
63
+ model: string;
64
+ buildInput: ImageToVideoInputBuilder;
65
+ extractResult?: ImageToVideoResultExtractor;
66
+ prepareImage: (imageUri: string) => Promise<string>;
67
+ onImageSelect?: (uri: string) => void;
68
+ onProcessingStart?: () => void;
69
+ onProcessingComplete?: (result: ImageToVideoResult) => void;
70
+ onError?: (error: string) => void;
71
+ }
@@ -0,0 +1,10 @@
1
+ export type {
2
+ ImageToVideoOptions,
3
+ ImageToVideoRequest,
4
+ ImageToVideoResult,
5
+ ImageToVideoFeatureState,
6
+ ImageToVideoTranslations,
7
+ ImageToVideoInputBuilder,
8
+ ImageToVideoResultExtractor,
9
+ ImageToVideoFeatureConfig,
10
+ } from "./image-to-video.types";
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Image-to-Video Feature
3
+ * Provider-agnostic image-to-video generation feature
4
+ */
5
+
6
+ // Domain Types
7
+ export type {
8
+ ImageToVideoOptions,
9
+ ImageToVideoRequest,
10
+ ImageToVideoResult,
11
+ ImageToVideoFeatureState,
12
+ ImageToVideoTranslations,
13
+ ImageToVideoInputBuilder,
14
+ ImageToVideoResultExtractor,
15
+ ImageToVideoFeatureConfig,
16
+ } from "./domain";
17
+
18
+ // Infrastructure Services
19
+ export { executeImageToVideo, hasImageToVideoSupport } from "./infrastructure";
20
+ export type { ExecuteImageToVideoOptions } from "./infrastructure";
21
+
22
+ // Presentation Hooks
23
+ export { useImageToVideoFeature } from "./presentation";
24
+ export type {
25
+ UseImageToVideoFeatureProps,
26
+ UseImageToVideoFeatureReturn,
27
+ } from "./presentation";
@@ -0,0 +1 @@
1
+ export * from "./services";