@umituz/react-native-ai-generation-content 1.20.43 → 1.20.45

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-generation-content",
3
- "version": "1.20.43",
3
+ "version": "1.20.45",
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",
@@ -79,3 +79,76 @@ export interface WizardActions {
79
79
  }
80
80
 
81
81
  export type WizardStore = WizardState & WizardActions;
82
+
83
+ /** Feature mode determines the wizard variant */
84
+ export type FeatureMode = "single_image" | "dual_image" | "text_to_media" | "image_to_video";
85
+
86
+ /** Pre-built step type */
87
+ export type PrebuiltStepType =
88
+ | "image_upload"
89
+ | "partner_a_upload"
90
+ | "partner_b_upload"
91
+ | "prompt_input"
92
+ | "style_selector"
93
+ | "duration_selector"
94
+ | "scenario_selection"
95
+ | "scenario_preview"
96
+ | "generating"
97
+ | "result";
98
+
99
+ /** Feature wizard config */
100
+ export interface FeatureWizardConfig {
101
+ readonly featureId: string;
102
+ readonly mode: FeatureMode;
103
+ readonly creditCost?: number;
104
+ readonly showPrompt?: boolean;
105
+ readonly showStyleSelector?: boolean;
106
+ readonly showDurationSelector?: boolean;
107
+ readonly showScenarioSelection?: boolean;
108
+ }
109
+
110
+ /** Pre-configured step flows */
111
+ export const FEATURE_FLOWS: Record<FeatureMode, readonly PrebuiltStepType[]> = {
112
+ single_image: ["image_upload", "generating"],
113
+ dual_image: ["partner_a_upload", "partner_b_upload", "generating"],
114
+ text_to_media: ["prompt_input", "generating"],
115
+ image_to_video: ["image_upload", "prompt_input", "generating"],
116
+ } as const;
117
+
118
+ /** Feature mode by feature ID */
119
+ export const FEATURE_MODES: Record<string, FeatureMode> = {
120
+ // Single Image Features
121
+ "anime-selfie": "single_image",
122
+ "hd-touch-up": "single_image",
123
+ "photo-restoration": "single_image",
124
+ "remove-background": "single_image",
125
+ "remove-object": "single_image",
126
+ "upscaling": "single_image",
127
+ // Single Image with Prompt
128
+ "image-to-image": "single_image",
129
+ "replace-background": "single_image",
130
+ // Dual Image Features
131
+ "ai-hug": "dual_image",
132
+ "ai-kiss": "dual_image",
133
+ "face-swap": "dual_image",
134
+ "couple-future": "dual_image",
135
+ // Text to Media Features
136
+ "text-to-image": "text_to_media",
137
+ "text-to-video": "text_to_media",
138
+ "text-to-voice": "text_to_media",
139
+ "meme-generator": "text_to_media",
140
+ "script-generator": "text_to_media",
141
+ "love-message": "text_to_media",
142
+ // Image to Video Features
143
+ "image-to-video": "image_to_video",
144
+ } as const;
145
+
146
+ /** Get feature mode by feature ID */
147
+ export const getFeatureMode = (featureId: string): FeatureMode => {
148
+ return FEATURE_MODES[featureId] ?? "single_image";
149
+ };
150
+
151
+ /** Get flow steps for feature mode */
152
+ export const getFeatureFlow = (mode: FeatureMode): readonly PrebuiltStepType[] => {
153
+ return FEATURE_FLOWS[mode];
154
+ };
@@ -3,8 +3,14 @@
3
3
  * Generic wizard for all AI generation flows
4
4
  */
5
5
 
6
- // Component
6
+ // Components
7
7
  export { AIGenerationWizard, default as AIGenerationWizardDefault } from "./presentation/components/AIGenerationWizard";
8
+ export { AIFeatureWizard, resetAIFeatureWizard } from "./presentation/components/AIFeatureWizard";
9
+ export type {
10
+ AIFeatureWizardProps,
11
+ AIFeatureWizardTranslations,
12
+ AIFeatureWizardCallbacks,
13
+ } from "./presentation/components/AIFeatureWizard";
8
14
 
9
15
  // Hooks
10
16
  export { useWizard, resetWizardStore } from "./presentation/hooks/useWizard";
@@ -12,7 +18,7 @@ export { useWizard, resetWizardStore } from "./presentation/hooks/useWizard";
12
18
  // Store
13
19
  export { createWizardStore, type WizardStoreType } from "./presentation/store/useWizardStore";
14
20
 
15
- // Types (UploadedImage is already exported from partner-upload)
21
+ // Types
16
22
  export type {
17
23
  WizardStepId,
18
24
  WizardStep,
@@ -23,4 +29,15 @@ export type {
23
29
  AIGenerationWizardConfig,
24
30
  AIGenerationWizardCallbacks,
25
31
  AIGenerationWizardProps,
32
+ FeatureMode,
33
+ PrebuiltStepType,
34
+ FeatureWizardConfig,
35
+ } from "./domain/types";
36
+
37
+ // Feature mode utilities
38
+ export {
39
+ FEATURE_MODES,
40
+ FEATURE_FLOWS,
41
+ getFeatureMode,
42
+ getFeatureFlow,
26
43
  } from "./domain/types";
@@ -0,0 +1,231 @@
1
+ /**
2
+ * AIFeatureWizard
3
+ * Auto-configured wizard based on feature mode
4
+ */
5
+
6
+ import React, { useCallback, useMemo } from "react";
7
+ import { View, StyleSheet } from "react-native";
8
+ import { useAppDesignTokens } from "@umituz/react-native-design-system";
9
+ import { useFlow, resetFlowStore } from "../../../../infrastructure/flow";
10
+ import { StepType } from "../../../../domain/entities/flow-config.types";
11
+ import type { StepDefinition } from "../../../../domain/entities/flow-config.types";
12
+ import { PartnerStepScreen } from "../../../partner-upload";
13
+ import { GeneratingStepContent } from "../../../couple-future/presentation/components/GeneratingStepContent";
14
+ import {
15
+ getFeatureMode,
16
+ getFeatureFlow,
17
+ type FeatureMode,
18
+ type PrebuiltStepType,
19
+ type FeatureWizardConfig,
20
+ } from "../../domain/types";
21
+
22
+ /** Wizard translations interface */
23
+ export interface AIFeatureWizardTranslations {
24
+ readonly generator: {
25
+ readonly title: string;
26
+ readonly waitMessage: string;
27
+ readonly hint?: string;
28
+ };
29
+ readonly imageUpload?: {
30
+ readonly title: string;
31
+ readonly subtitle: string;
32
+ readonly continue: string;
33
+ readonly tapToUpload: string;
34
+ readonly selectPhoto: string;
35
+ readonly change: string;
36
+ };
37
+ readonly partnerA?: {
38
+ readonly title: string;
39
+ readonly subtitle: string;
40
+ readonly continue: string;
41
+ readonly tapToUpload: string;
42
+ readonly selectPhoto: string;
43
+ readonly change: string;
44
+ };
45
+ readonly partnerB?: {
46
+ readonly title: string;
47
+ readonly subtitle: string;
48
+ readonly continue: string;
49
+ readonly tapToUpload: string;
50
+ readonly selectPhoto: string;
51
+ readonly change: string;
52
+ };
53
+ readonly prompt?: {
54
+ readonly title?: string;
55
+ readonly placeholder: string;
56
+ readonly label?: string;
57
+ };
58
+ }
59
+
60
+ /** Wizard callbacks */
61
+ export interface AIFeatureWizardCallbacks {
62
+ readonly onGenerationStart?: () => void;
63
+ readonly onGenerationSuccess?: (result: unknown) => void;
64
+ readonly onGenerationError?: (error: string) => void;
65
+ readonly onImageUpload?: (image: { uri: string; base64: string; mimeType: string }) => void;
66
+ readonly onPartnerAUpload?: (image: { uri: string; base64: string; mimeType: string }) => void;
67
+ readonly onPartnerBUpload?: (image: { uri: string; base64: string; mimeType: string }) => void;
68
+ readonly requireFeature?: (callback: () => void) => boolean;
69
+ }
70
+
71
+ /** Wizard props */
72
+ export interface AIFeatureWizardProps {
73
+ readonly featureId: string;
74
+ readonly config?: Partial<FeatureWizardConfig>;
75
+ readonly translations: AIFeatureWizardTranslations;
76
+ readonly callbacks?: AIFeatureWizardCallbacks;
77
+ readonly t: (key: string) => string;
78
+ }
79
+
80
+ const mapPrebuiltStepToStepType = (step: PrebuiltStepType): StepType => {
81
+ const mapping: Record<PrebuiltStepType, StepType> = {
82
+ image_upload: StepType.PARTNER_UPLOAD,
83
+ partner_a_upload: StepType.PARTNER_UPLOAD,
84
+ partner_b_upload: StepType.PARTNER_UPLOAD,
85
+ prompt_input: StepType.TEXT_INPUT,
86
+ style_selector: StepType.FEATURE_SELECTION,
87
+ duration_selector: StepType.FEATURE_SELECTION,
88
+ scenario_selection: StepType.SCENARIO_SELECTION,
89
+ scenario_preview: StepType.SCENARIO_PREVIEW,
90
+ generating: StepType.GENERATING,
91
+ result: StepType.RESULT_PREVIEW,
92
+ };
93
+ return mapping[step];
94
+ };
95
+
96
+ const createStepDefinitions = (
97
+ featureId: string,
98
+ mode: FeatureMode,
99
+ ): readonly StepDefinition[] => {
100
+ const flow = getFeatureFlow(mode);
101
+ return flow.map((step) => ({
102
+ id: step.toUpperCase(),
103
+ type: mapPrebuiltStepToStepType(step),
104
+ required: true,
105
+ }));
106
+ };
107
+
108
+ export const AIFeatureWizard: React.FC<AIFeatureWizardProps> = ({
109
+ featureId,
110
+ config,
111
+ translations,
112
+ callbacks,
113
+ t,
114
+ }) => {
115
+ const tokens = useAppDesignTokens();
116
+ const mode = config?.mode ?? getFeatureMode(featureId);
117
+
118
+ const stepDefinitions = useMemo(
119
+ () => createStepDefinitions(featureId, mode),
120
+ [featureId, mode],
121
+ );
122
+
123
+ const flow = useFlow({ steps: stepDefinitions });
124
+
125
+ const handleImageContinue = useCallback(
126
+ (image: { uri: string; base64: string; mimeType: string }, _name?: string) => {
127
+ flow.setPartnerImage("single", image);
128
+ callbacks?.onImageUpload?.(image);
129
+ flow.startGeneration();
130
+ callbacks?.onGenerationStart?.();
131
+ },
132
+ [flow, callbacks],
133
+ );
134
+
135
+ const handlePartnerAContinue = useCallback(
136
+ (image: { uri: string; base64: string; mimeType: string }, _name?: string) => {
137
+ flow.setPartnerImage("A", image);
138
+ callbacks?.onPartnerAUpload?.(image);
139
+ flow.nextStep();
140
+ },
141
+ [flow, callbacks],
142
+ );
143
+
144
+ const handlePartnerBContinue = useCallback(
145
+ (image: { uri: string; base64: string; mimeType: string }, _name?: string) => {
146
+ flow.setPartnerImage("B", image);
147
+ callbacks?.onPartnerBUpload?.(image);
148
+ flow.startGeneration();
149
+ callbacks?.onGenerationStart?.();
150
+ },
151
+ [flow, callbacks],
152
+ );
153
+
154
+ const renderCurrentStep = useCallback(() => {
155
+ const step = flow.currentStep;
156
+ if (!step) return null;
157
+
158
+ switch (step.id) {
159
+ case "IMAGE_UPLOAD":
160
+ return (
161
+ <PartnerStepScreen
162
+ key="image"
163
+ translations={translations.imageUpload as never}
164
+ t={t}
165
+ initialName=""
166
+ config={{ showPhotoTips: true, maxFileSizeMB: 10, maxNameLength: 30 }}
167
+ onBack={flow.previousStep}
168
+ onContinue={handleImageContinue as never}
169
+ />
170
+ );
171
+
172
+ case "PARTNER_A_UPLOAD":
173
+ return (
174
+ <PartnerStepScreen
175
+ key="a"
176
+ translations={translations.partnerA as never}
177
+ t={t}
178
+ initialName=""
179
+ config={{ showPhotoTips: true, maxFileSizeMB: 10, maxNameLength: 30 }}
180
+ onBack={flow.previousStep}
181
+ onContinue={handlePartnerAContinue as never}
182
+ />
183
+ );
184
+
185
+ case "PARTNER_B_UPLOAD":
186
+ return (
187
+ <PartnerStepScreen
188
+ key="b"
189
+ translations={translations.partnerB as never}
190
+ t={t}
191
+ initialName=""
192
+ config={{ showPhotoTips: true, maxFileSizeMB: 10, maxNameLength: 30 }}
193
+ onBack={flow.previousStep}
194
+ onContinue={handlePartnerBContinue as never}
195
+ />
196
+ );
197
+
198
+ case "GENERATING":
199
+ return (
200
+ <GeneratingStepContent
201
+ progress={flow.generationProgress}
202
+ title={translations.generator.title}
203
+ message={translations.generator.waitMessage}
204
+ hint={translations.generator.hint}
205
+ />
206
+ );
207
+
208
+ default:
209
+ return null;
210
+ }
211
+ }, [
212
+ flow,
213
+ translations,
214
+ t,
215
+ handleImageContinue,
216
+ handlePartnerAContinue,
217
+ handlePartnerBContinue,
218
+ ]);
219
+
220
+ return (
221
+ <View style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}>
222
+ {renderCurrentStep()}
223
+ </View>
224
+ );
225
+ };
226
+
227
+ export { resetFlowStore as resetAIFeatureWizard };
228
+
229
+ const styles = StyleSheet.create({
230
+ container: { flex: 1 },
231
+ });