@umituz/react-native-ai-generation-content 1.20.22 → 1.20.24

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.22",
3
+ "version": "1.20.24",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
package/src/index.ts CHANGED
@@ -94,7 +94,7 @@ export {
94
94
  GenerateButton, ResultDisplay, AIGenerationResult, ErrorDisplay, FeatureHeader,
95
95
  AIGenScreenHeader, CreditBadge, PhotoUploadCard, SettingsSheet, StyleSelector,
96
96
  AspectRatioSelector, DurationSelector, GridSelector, StylePresetsGrid, AIGenerationForm,
97
- AIGenerationConfig,
97
+ AIGenerationConfig, AIGenerateWizardFlow,
98
98
  createAspectRatioOptions, createDurationOptions, createStyleOptions, createStyleOptionsFromConfig,
99
99
  ASPECT_RATIO_IDS, COMMON_DURATIONS,
100
100
  } from "./presentation/components";
@@ -125,7 +125,7 @@ export type {
125
125
  AspectRatioSelectorProps, DurationSelectorProps, GridSelectorProps, GridSelectorOption,
126
126
  StyleOption, AspectRatioOption, DurationValue, AspectRatioTranslations, DurationOption,
127
127
  StyleTranslations, AIGenerationFormProps, AIGenerationFormTranslations,
128
- AIGenerationConfigProps,
128
+ AIGenerationConfigProps, AIGenerateWizardFlowProps,
129
129
  } from "./presentation/components";
130
130
 
131
131
  export { DEFAULT_SINGLE_PHOTO_FLOW, DEFAULT_DUAL_PHOTO_FLOW } from "./presentation/types/flow-config.types";
@@ -1,5 +1,5 @@
1
1
 
2
- import React, { useMemo, useCallback, useEffect } from "react";
2
+ import React from "react";
3
3
  import { View, ScrollView, Platform, TouchableOpacity, Image } from "react-native";
4
4
  import {
5
5
  useAppDesignTokens,
@@ -14,55 +14,9 @@ import { PartnerStepScreen } from "../../../features/partner-upload/presentation
14
14
  import { AIGenerationConfig } from "../AIGenerationConfig";
15
15
  import { GenerationProgressContent } from "../GenerationProgressContent";
16
16
  import { AIGenerationResult } from "../display/AIGenerationResult";
17
- import { useAIGenerateState, AIGenerateStep } from "../../hooks/generation/useAIGenerateState";
18
- import { getAIFeatureConfig, hasAIFeature } from "../../screens/ai-feature/registry";
19
-
20
- export interface AIGenerateWizardFlowProps {
21
- readonly featureType: string;
22
- readonly translations: {
23
- headerTitle: string;
24
- uploadSubtitle: string;
25
- uploadSubtitle2: string;
26
- continue: string;
27
- tapToUpload: string;
28
- selectPhoto: string;
29
- change: string;
30
- analyzing: string;
31
- error: string;
32
- uploadFailed: string;
33
- aiDisclosure: string;
34
- heroTitle: string;
35
- heroSubtitle: string;
36
- presetsTitle: string;
37
- showAdvancedLabel: string;
38
- hideAdvancedLabel: string;
39
- promptTitle: string;
40
- promptPlaceholder: string;
41
- styleTitle: string;
42
- durationTitle: string;
43
- generateButton: string;
44
- generatingButton: string;
45
- processingTitle: string;
46
- processingMessage: string;
47
- processingHint: string;
48
- successTitle: string;
49
- saveButton: string;
50
- tryAgainButton: string;
51
- fileTooLarge: string;
52
- maxFileSize: string;
53
- };
54
- readonly styleOptions: any[];
55
- readonly presets: any[];
56
- readonly durationOptions: number[];
57
- readonly onGenerate: (data: {
58
- prompt: string;
59
- style: string;
60
- duration: number;
61
- images: { uri: string }[];
62
- }) => Promise<string | null>;
63
- readonly onBack?: () => void;
64
- readonly t: (key: string) => string;
65
- }
17
+ import { AIGenerateStep } from "../../hooks/generation/useAIGenerateState";
18
+ import { useAIGenerateWizardFlow } from "./useAIGenerateWizardFlow";
19
+ import { AIGenerateWizardFlowProps } from "./AIGenerateWizardFlow.types";
66
20
 
67
21
  export const AIGenerateWizardFlow: React.FC<AIGenerateWizardFlowProps> = ({
68
22
  featureType,
@@ -89,85 +43,12 @@ export const AIGenerateWizardFlow: React.FC<AIGenerateWizardFlowProps> = ({
89
43
  showAdvanced,
90
44
  toggleAdvanced,
91
45
  isGenerating,
92
- setIsGenerating,
93
46
  progress,
94
- setProgress,
95
47
  result,
96
- setResult,
97
- } = useAIGenerateState();
98
-
99
- const imageCountRequired = useMemo(() => {
100
- if (!featureType || !hasAIFeature(featureType)) return 0;
101
- const config = getAIFeatureConfig(featureType as any);
102
- if (config.mode === "dual" || config.mode === "dual-video") return 2;
103
- if (config.mode === "single" || config.mode === "single-with-prompt")
104
- return 1;
105
- return 0;
106
- }, [featureType]);
107
-
108
- useEffect(() => {
109
- if (currentStep === AIGenerateStep.INFO) {
110
- if (imageCountRequired > 0) {
111
- setCurrentStep(AIGenerateStep.UPLOAD_1);
112
- } else {
113
- setCurrentStep(AIGenerateStep.CONFIG);
114
- }
115
- }
116
- }, [featureType, imageCountRequired, setCurrentStep, currentStep]);
117
-
118
- const handleBack = useCallback(() => {
119
- if (currentStep === AIGenerateStep.UPLOAD_1) {
120
- onBackProp?.();
121
- } else if (currentStep === AIGenerateStep.UPLOAD_2) {
122
- setCurrentStep(AIGenerateStep.UPLOAD_1);
123
- } else if (currentStep === AIGenerateStep.CONFIG) {
124
- if (imageCountRequired > 1) {
125
- setCurrentStep(AIGenerateStep.UPLOAD_2);
126
- } else if (imageCountRequired > 0) {
127
- setCurrentStep(AIGenerateStep.UPLOAD_1);
128
- } else {
129
- onBackProp?.();
130
- }
131
- } else if (currentStep === AIGenerateStep.RESULT) {
132
- setCurrentStep(AIGenerateStep.CONFIG);
133
- }
134
- }, [currentStep, setCurrentStep, imageCountRequired, onBackProp]);
135
-
136
- const handleNext = useCallback(() => {
137
- if (currentStep === AIGenerateStep.UPLOAD_1) {
138
- if (imageCountRequired > 1) {
139
- setCurrentStep(AIGenerateStep.UPLOAD_2);
140
- } else {
141
- setCurrentStep(AIGenerateStep.CONFIG);
142
- }
143
- } else if (currentStep === AIGenerateStep.UPLOAD_2) {
144
- setCurrentStep(AIGenerateStep.CONFIG);
145
- }
146
- }, [currentStep, setCurrentStep, imageCountRequired]);
147
-
148
- const handleGenerate = useCallback(async () => {
149
- setIsGenerating(true);
150
- setProgress(10);
151
- setCurrentStep(AIGenerateStep.GENERATING);
152
-
153
- try {
154
- const output = await onGenerate({
155
- prompt,
156
- style: selectedStyle,
157
- duration: selectedDuration,
158
- images,
159
- });
160
- setResult(output);
161
- setCurrentStep(AIGenerateStep.RESULT);
162
- } catch (error) {
163
- // Error handling should be added here
164
- console.error("Generation failed", error);
165
- setCurrentStep(AIGenerateStep.CONFIG);
166
- } finally {
167
- setIsGenerating(false);
168
- setProgress(0);
169
- }
170
- }, [onGenerate, prompt, selectedStyle, selectedDuration, images, setCurrentStep, setIsGenerating, setProgress, setResult]);
48
+ handleBack,
49
+ handleNext,
50
+ handleGenerate,
51
+ } = useAIGenerateWizardFlow({ featureType, onGenerate, onBack: onBackProp });
171
52
 
172
53
  switch (currentStep) {
173
54
  case AIGenerateStep.UPLOAD_1:
@@ -178,10 +59,7 @@ export const AIGenerateWizardFlow: React.FC<AIGenerateWizardFlowProps> = ({
178
59
  t={t}
179
60
  onBack={handleBack}
180
61
  onContinue={(img: any) => {
181
- setStepImage(isStep2 ? 1 : 0, {
182
- uri: img.uri,
183
- previewUrl: img.previewUrl || img.uri,
184
- });
62
+ setStepImage(isStep2 ? 1 : 0, { uri: img.uri, previewUrl: img.previewUrl || img.uri });
185
63
  handleNext();
186
64
  }}
187
65
  translations={{
@@ -199,25 +77,14 @@ export const AIGenerateWizardFlow: React.FC<AIGenerateWizardFlowProps> = ({
199
77
  aiDisclosure: translations.aiDisclosure,
200
78
  }}
201
79
  initialName=""
202
- config={{
203
- showFaceDetection: featureType === "face-swap",
204
- showNameInput: false,
205
- showPhotoTips: true,
206
- }}
80
+ config={{ showFaceDetection: featureType === "face-swap", showNameInput: false, showPhotoTips: true }}
207
81
  />
208
82
  );
209
83
  }
210
84
 
211
85
  case AIGenerateStep.GENERATING:
212
86
  return (
213
- <ScreenLayout
214
- header={
215
- <AIGenScreenHeader
216
- title={translations.headerTitle}
217
- onNavigationPress={handleBack}
218
- />
219
- }
220
- >
87
+ <ScreenLayout header={<AIGenScreenHeader title={translations.headerTitle} onNavigationPress={handleBack} />}>
221
88
  <View style={{ flex: 1, padding: tokens.spacing.xl }}>
222
89
  <GenerationProgressContent
223
90
  progress={progress}
@@ -231,41 +98,24 @@ export const AIGenerateWizardFlow: React.FC<AIGenerateWizardFlowProps> = ({
231
98
 
232
99
  case AIGenerateStep.RESULT:
233
100
  return (
234
- <ScreenLayout
235
- header={
236
- <AIGenScreenHeader
237
- title={translations.headerTitle}
238
- onNavigationPress={handleBack}
239
- />
240
- }
241
- >
101
+ <ScreenLayout header={<AIGenScreenHeader title={translations.headerTitle} onNavigationPress={handleBack} />}>
242
102
  <AIGenerationResult
243
103
  successText={translations.successTitle}
244
- primaryAction={{
245
- label: translations.saveButton,
246
- onPress: () => {},
247
- icon: "download",
248
- }}
104
+ primaryAction={{ label: translations.saveButton, onPress: () => {}, icon: "download" }}
249
105
  secondaryAction={{
250
106
  label: translations.tryAgainButton,
251
107
  onPress: () => setCurrentStep(AIGenerateStep.CONFIG),
252
108
  icon: "refresh",
253
109
  }}
254
110
  >
255
- <Image
256
- source={{ uri: result || "" }}
257
- style={{ width: "100%", aspectRatio: 2 / 3, borderRadius: 16 }}
258
- resizeMode="cover"
259
- />
111
+ <Image source={{ uri: result || "" }} style={{ width: "100%", aspectRatio: 2 / 3, borderRadius: 16 }} resizeMode="cover" />
260
112
  </AIGenerationResult>
261
113
  </ScreenLayout>
262
114
  );
263
115
 
264
116
  default:
265
117
  return (
266
- <AtomicKeyboardAvoidingView
267
- offset={Platform.OS === "ios" ? 94 : 0}
268
- >
118
+ <AtomicKeyboardAvoidingView offset={Platform.OS === "ios" ? 94 : 0}>
269
119
  <ScrollView
270
120
  style={{ backgroundColor: tokens.colors.backgroundPrimary }}
271
121
  contentContainerStyle={{ paddingBottom: 100 }}
@@ -328,17 +178,7 @@ export const AIGenerateWizardFlow: React.FC<AIGenerateWizardFlowProps> = ({
328
178
  onGenerate={handleGenerate}
329
179
  images={images}
330
180
  hideGenerateButton={true}
331
- translations={{
332
- presetsTitle: translations.presetsTitle,
333
- showAdvancedLabel: translations.showAdvancedLabel,
334
- hideAdvancedLabel: translations.hideAdvancedLabel,
335
- promptTitle: translations.promptTitle,
336
- promptPlaceholder: translations.promptPlaceholder,
337
- styleTitle: translations.styleTitle,
338
- durationTitle: translations.durationTitle,
339
- generateButton: translations.generateButton,
340
- generatingButton: translations.generatingButton,
341
- }}
181
+ translations={translations}
342
182
  />
343
183
  </ScrollView>
344
184
  </AtomicKeyboardAvoidingView>
@@ -0,0 +1,49 @@
1
+
2
+ export interface AIGenerateWizardTranslations {
3
+ readonly headerTitle: string;
4
+ readonly uploadSubtitle: string;
5
+ readonly uploadSubtitle2: string;
6
+ readonly continue: string;
7
+ readonly tapToUpload: string;
8
+ readonly selectPhoto: string;
9
+ readonly change: string;
10
+ readonly analyzing: string;
11
+ readonly error: string;
12
+ readonly uploadFailed: string;
13
+ readonly aiDisclosure: string;
14
+ readonly heroTitle: string;
15
+ readonly heroSubtitle: string;
16
+ readonly presetsTitle: string;
17
+ readonly showAdvancedLabel: string;
18
+ readonly hideAdvancedLabel: string;
19
+ readonly promptTitle: string;
20
+ readonly promptPlaceholder: string;
21
+ readonly styleTitle: string;
22
+ readonly durationTitle: string;
23
+ readonly generateButton: string;
24
+ readonly generatingButton: string;
25
+ readonly processingTitle: string;
26
+ readonly processingMessage: string;
27
+ readonly processingHint: string;
28
+ readonly successTitle: string;
29
+ readonly saveButton: string;
30
+ readonly tryAgainButton: string;
31
+ readonly fileTooLarge: string;
32
+ readonly maxFileSize: string;
33
+ }
34
+
35
+ export interface AIGenerateWizardFlowProps {
36
+ readonly featureType: string;
37
+ readonly translations: AIGenerateWizardTranslations;
38
+ readonly styleOptions: any[];
39
+ readonly presets: any[];
40
+ readonly durationOptions: number[];
41
+ readonly onGenerate: (data: {
42
+ prompt: string;
43
+ style: string;
44
+ duration: number;
45
+ images: { uri: string }[];
46
+ }) => Promise<string | null>;
47
+ readonly onBack?: () => void;
48
+ readonly t: (key: string) => string;
49
+ }
@@ -0,0 +1,103 @@
1
+
2
+ import { useMemo, useCallback, useEffect } from "react";
3
+ import { useAIGenerateState, AIGenerateStep } from "../../hooks/generation/useAIGenerateState";
4
+ import { getAIFeatureConfig, hasAIFeature } from "../../screens/ai-feature/registry";
5
+
6
+ interface UseAIGenerateWizardFlowProps {
7
+ featureType: string;
8
+ onGenerate: (data: any) => Promise<string | null>;
9
+ onBack?: () => void;
10
+ }
11
+
12
+ export function useAIGenerateWizardFlow({
13
+ featureType,
14
+ onGenerate,
15
+ onBack: onBackProp,
16
+ }: UseAIGenerateWizardFlowProps) {
17
+ const state = useAIGenerateState();
18
+ const {
19
+ currentStep, setCurrentStep, isGenerating, setIsGenerating,
20
+ setProgress, setResult, images, prompt, selectedStyle,
21
+ selectedDuration, setStepImage
22
+ } = state;
23
+
24
+ const imageCountRequired = useMemo(() => {
25
+ if (!featureType || !hasAIFeature(featureType)) return 0;
26
+ const config = getAIFeatureConfig(featureType as any);
27
+ if (config.mode === "dual" || config.mode === "dual-video") return 2;
28
+ if (config.mode === "single" || config.mode === "single-with-prompt")
29
+ return 1;
30
+ return 0;
31
+ }, [featureType]);
32
+
33
+ useEffect(() => {
34
+ if (currentStep === AIGenerateStep.INFO) {
35
+ if (imageCountRequired > 0) {
36
+ setCurrentStep(AIGenerateStep.UPLOAD_1);
37
+ } else {
38
+ setCurrentStep(AIGenerateStep.CONFIG);
39
+ }
40
+ }
41
+ }, [featureType, imageCountRequired, setCurrentStep, currentStep]);
42
+
43
+ const handleBack = useCallback(() => {
44
+ if (currentStep === AIGenerateStep.UPLOAD_1) {
45
+ onBackProp?.();
46
+ } else if (currentStep === AIGenerateStep.UPLOAD_2) {
47
+ setCurrentStep(AIGenerateStep.UPLOAD_1);
48
+ } else if (currentStep === AIGenerateStep.CONFIG) {
49
+ if (imageCountRequired > 1) {
50
+ setCurrentStep(AIGenerateStep.UPLOAD_2);
51
+ } else if (imageCountRequired > 0) {
52
+ setCurrentStep(AIGenerateStep.UPLOAD_1);
53
+ } else {
54
+ onBackProp?.();
55
+ }
56
+ } else if (currentStep === AIGenerateStep.RESULT) {
57
+ setCurrentStep(AIGenerateStep.CONFIG);
58
+ }
59
+ }, [currentStep, setCurrentStep, imageCountRequired, onBackProp]);
60
+
61
+ const handleNext = useCallback(() => {
62
+ if (currentStep === AIGenerateStep.UPLOAD_1) {
63
+ if (imageCountRequired > 1) {
64
+ setCurrentStep(AIGenerateStep.UPLOAD_2);
65
+ } else {
66
+ setCurrentStep(AIGenerateStep.CONFIG);
67
+ }
68
+ } else if (currentStep === AIGenerateStep.UPLOAD_2) {
69
+ setCurrentStep(AIGenerateStep.CONFIG);
70
+ }
71
+ }, [currentStep, setCurrentStep, imageCountRequired]);
72
+
73
+ const handleGenerate = useCallback(async () => {
74
+ setIsGenerating(true);
75
+ setProgress(10);
76
+ setCurrentStep(AIGenerateStep.GENERATING);
77
+
78
+ try {
79
+ const output = await onGenerate({
80
+ prompt,
81
+ style: selectedStyle,
82
+ duration: selectedDuration,
83
+ images,
84
+ });
85
+ setResult(output);
86
+ setCurrentStep(AIGenerateStep.RESULT);
87
+ } catch (error) {
88
+ console.error("Generation failed", error);
89
+ setCurrentStep(AIGenerateStep.CONFIG);
90
+ } finally {
91
+ setIsGenerating(false);
92
+ setProgress(0);
93
+ }
94
+ }, [onGenerate, prompt, selectedStyle, selectedDuration, images, setCurrentStep, setIsGenerating, setProgress, setResult]);
95
+
96
+ return {
97
+ ...state,
98
+ imageCountRequired,
99
+ handleBack,
100
+ handleNext,
101
+ handleGenerate,
102
+ };
103
+ }