@umituz/react-native-ai-generation-content 1.26.4 → 1.26.6
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 +1 -2
- package/src/domains/generation/application/generation-strategy.factory.ts +1 -1
- package/src/domains/generation/index.ts +3 -8
- package/src/{infrastructure → domains/generation/infrastructure}/executors/image-executor.ts +2 -2
- package/src/{infrastructure → domains/generation/infrastructure}/executors/video-executor.ts +2 -2
- package/src/index.ts +2 -25
- package/src/presentation/components/index.ts +0 -3
- package/src/presentation/hooks/index.ts +0 -7
- package/src/presentation/components/flows/AIGenerateWizardFlow.tsx +0 -231
- package/src/presentation/components/flows/AIGenerateWizardFlow.types.ts +0 -66
- package/src/presentation/components/flows/useAIGenerateWizardFlow.ts +0 -130
- package/src/presentation/hooks/useAIGenerateWizard.ts +0 -164
- /package/src/{infrastructure → domains/generation/infrastructure}/executors/executor-factory.ts +0 -0
- /package/src/{infrastructure → domains/generation/infrastructure}/flow/index.ts +0 -0
- /package/src/{infrastructure → domains/generation/infrastructure}/flow/step-builder.ts +0 -0
- /package/src/{infrastructure → domains/generation/infrastructure}/flow/useFlow.ts +0 -0
- /package/src/{infrastructure → domains/generation/infrastructure}/flow/useFlowStore.ts +0 -0
- /package/src/domains/{wizard → generation/wizard}/domain/entities/wizard-config.types.ts +0 -0
- /package/src/domains/{wizard → generation/wizard}/index.ts +0 -0
- /package/src/domains/{wizard → generation/wizard}/infrastructure/builders/dynamic-step-builder.ts +0 -0
- /package/src/domains/{wizard → generation/wizard}/infrastructure/renderers/step-renderer.tsx +0 -0
- /package/src/domains/{wizard → generation/wizard}/infrastructure/strategies/index.ts +0 -0
- /package/src/domains/{wizard → generation/wizard}/infrastructure/strategies/wizard-strategy.factory.ts +0 -0
- /package/src/domains/{wizard → generation/wizard}/presentation/components/GenericWizardFlow.tsx +0 -0
- /package/src/domains/{wizard → generation/wizard}/presentation/hooks/usePhotoUploadState.ts +0 -0
- /package/src/domains/{wizard → generation/wizard}/presentation/hooks/useWizardGeneration.ts +0 -0
- /package/src/domains/{wizard → generation/wizard}/presentation/screens/GeneratingScreen.tsx +0 -0
- /package/src/domains/{wizard → generation/wizard}/presentation/screens/GenericPhotoUploadScreen.tsx +0 -0
- /package/src/domains/{wizard → generation/wizard}/presentation/steps/PhotoUploadStep.tsx +0 -0
- /package/src/domains/{wizard → generation/wizard}/presentation/steps/SelectionStep.tsx +0 -0
- /package/src/domains/{wizard → generation/wizard}/presentation/steps/TextInputStep.tsx +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.26.
|
|
3
|
+
"version": "1.26.6",
|
|
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",
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"./creations": "./src/domains/creations/index.ts",
|
|
12
12
|
"./face-detection": "./src/domains/face-detection/index.ts",
|
|
13
13
|
"./feature-background": "./src/domains/feature-background/index.ts",
|
|
14
|
-
"./wizard": "./src/domains/wizard/index.ts",
|
|
15
14
|
"./generation": "./src/domains/generation/index.ts"
|
|
16
15
|
},
|
|
17
16
|
"files": [
|
|
@@ -11,7 +11,7 @@ import type {
|
|
|
11
11
|
ImageGenerationOutput,
|
|
12
12
|
VideoGenerationOutput,
|
|
13
13
|
} from "../domain/generation.types";
|
|
14
|
-
import { ExecutorFactory } from "
|
|
14
|
+
import { ExecutorFactory } from "../infrastructure/executors/executor-factory";
|
|
15
15
|
import { featureRegistry } from "./feature-registry";
|
|
16
16
|
|
|
17
17
|
declare const __DEV__: boolean;
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generation Domain
|
|
3
|
-
* Generic, feature-agnostic AI generation system
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Presentation Layer
|
|
7
1
|
export {
|
|
8
2
|
useAIGeneration,
|
|
9
3
|
type UseAIGenerationProps,
|
|
@@ -11,11 +5,9 @@ export {
|
|
|
11
5
|
type AlertMessages,
|
|
12
6
|
} from "./presentation/useAIGeneration.hook";
|
|
13
7
|
|
|
14
|
-
// Application Layer
|
|
15
8
|
export { featureRegistry } from "./application/feature-registry";
|
|
16
9
|
export { createGenerationStrategy } from "./application/generation-strategy.factory";
|
|
17
10
|
|
|
18
|
-
// Domain Layer
|
|
19
11
|
export type {
|
|
20
12
|
FeatureConfig,
|
|
21
13
|
FeatureRegistration,
|
|
@@ -35,3 +27,6 @@ export type {
|
|
|
35
27
|
MemeGenerationInput,
|
|
36
28
|
MemeGenerationOutput,
|
|
37
29
|
} from "./domain/generation.types";
|
|
30
|
+
|
|
31
|
+
export * from "./wizard";
|
|
32
|
+
export * from "./infrastructure/flow";
|
package/src/{infrastructure → domains/generation/infrastructure}/executors/image-executor.ts
RENAMED
|
@@ -9,8 +9,8 @@ import type {
|
|
|
9
9
|
ImageGenerationOutput,
|
|
10
10
|
GenerationOptions,
|
|
11
11
|
GenerationResult,
|
|
12
|
-
} from "../../
|
|
13
|
-
import { providerRegistry } from "
|
|
12
|
+
} from "../../domain/generation.types";
|
|
13
|
+
import { providerRegistry } from "../../../../infrastructure/services/provider-registry.service";
|
|
14
14
|
|
|
15
15
|
declare const __DEV__: boolean;
|
|
16
16
|
|
package/src/{infrastructure → domains/generation/infrastructure}/executors/video-executor.ts
RENAMED
|
@@ -9,8 +9,8 @@ import type {
|
|
|
9
9
|
VideoGenerationOutput,
|
|
10
10
|
GenerationOptions,
|
|
11
11
|
GenerationResult,
|
|
12
|
-
} from "../../
|
|
13
|
-
import { providerRegistry } from "
|
|
12
|
+
} from "../../domain/generation.types";
|
|
13
|
+
import { providerRegistry } from "../../../../infrastructure/services/provider-registry.service";
|
|
14
14
|
|
|
15
15
|
declare const __DEV__: boolean;
|
|
16
16
|
|
package/src/index.ts
CHANGED
|
@@ -74,7 +74,6 @@ export {
|
|
|
74
74
|
useAIGenerateState, AIGenerateStep,
|
|
75
75
|
useGenerationOrchestrator, useImageGeneration, useVideoGeneration, useAIFeatureGeneration,
|
|
76
76
|
createGenerationError, getAlertMessage, parseError,
|
|
77
|
-
useAIGenerateWizard, createWizardTranslations,
|
|
78
77
|
} from "./presentation/hooks";
|
|
79
78
|
|
|
80
79
|
export type {
|
|
@@ -87,7 +86,6 @@ export type {
|
|
|
87
86
|
SingleImageInput, DualImageInput, ImageGenerationInput, ImageGenerationConfig,
|
|
88
87
|
DualImageVideoInput, VideoGenerationConfig,
|
|
89
88
|
UploadedImage,
|
|
90
|
-
AIGenerateWizardConfig, AIGenerateWizardTranslations, UseAIGenerateWizardReturn,
|
|
91
89
|
} from "./presentation/hooks";
|
|
92
90
|
|
|
93
91
|
export {
|
|
@@ -98,7 +96,7 @@ export {
|
|
|
98
96
|
GenerateButton, ResultDisplay, AIGenerationResult, ErrorDisplay, FeatureHeader,
|
|
99
97
|
AIGenScreenHeader, CreditBadge, PhotoUploadCard, SettingsSheet, StyleSelector,
|
|
100
98
|
AspectRatioSelector, DurationSelector, GridSelector, StylePresetsGrid, AIGenerationForm,
|
|
101
|
-
AIGenerationConfig,
|
|
99
|
+
AIGenerationConfig,
|
|
102
100
|
createAspectRatioOptions, createDurationOptions, createStyleOptions, createStyleOptionsFromConfig,
|
|
103
101
|
ASPECT_RATIO_IDS, COMMON_DURATIONS,
|
|
104
102
|
} from "./presentation/components";
|
|
@@ -129,7 +127,7 @@ export type {
|
|
|
129
127
|
AspectRatioSelectorProps, DurationSelectorProps, GridSelectorProps, GridSelectorOption,
|
|
130
128
|
StyleOption, AspectRatioOption, DurationValue, AspectRatioTranslations, DurationOption,
|
|
131
129
|
StyleTranslations, AIGenerationFormProps, AIGenerationFormTranslations,
|
|
132
|
-
AIGenerationConfigProps,
|
|
130
|
+
AIGenerationConfigProps,
|
|
133
131
|
} from "./presentation/components";
|
|
134
132
|
|
|
135
133
|
export { DEFAULT_SINGLE_PHOTO_FLOW, DEFAULT_DUAL_PHOTO_FLOW } from "./presentation/types/flow-config.types";
|
|
@@ -185,25 +183,4 @@ export type {
|
|
|
185
183
|
} from "./presentation/screens/ai-feature";
|
|
186
184
|
|
|
187
185
|
|
|
188
|
-
// Flow System - Dynamic multi-step flow management
|
|
189
|
-
export { createFlowStore, useFlow, resetFlowStore } from "./infrastructure/flow";
|
|
190
|
-
export type { FlowStoreType } from "./infrastructure/flow";
|
|
191
|
-
export { StepType } from "./domain/entities/flow-config.types";
|
|
192
|
-
export type {
|
|
193
|
-
StepDefinition,
|
|
194
|
-
FlowState,
|
|
195
|
-
FlowActions,
|
|
196
|
-
FlowConfiguration,
|
|
197
|
-
FlowCallbacks,
|
|
198
|
-
FlowDataProvider,
|
|
199
|
-
FlowFeatures,
|
|
200
|
-
StepComponentProps,
|
|
201
|
-
StepTransition,
|
|
202
|
-
PartnerConfig,
|
|
203
|
-
FlowVisualStyleData,
|
|
204
|
-
FlowUploadedImageData,
|
|
205
|
-
FlowGenerationStatus,
|
|
206
|
-
} from "./domain/entities/flow-config.types";
|
|
207
|
-
|
|
208
|
-
export * from "./domains/wizard";
|
|
209
186
|
export * from "./domains/generation";
|
|
@@ -10,9 +10,6 @@ export * from "./AIGenerationForm";
|
|
|
10
10
|
export * from "./AIGenerationForm.types";
|
|
11
11
|
export * from "./AIGenerationConfig";
|
|
12
12
|
|
|
13
|
-
export * from "./flows/AIGenerateWizardFlow";
|
|
14
|
-
export * from "./flows/AIGenerateWizardFlow.types";
|
|
15
|
-
|
|
16
13
|
export type { GenerationProgressContentProps } from "./GenerationProgressContent";
|
|
17
14
|
export type { GenerationProgressBarProps } from "./GenerationProgressBar";
|
|
18
15
|
|
|
@@ -63,10 +63,3 @@ export type {
|
|
|
63
63
|
|
|
64
64
|
export { useAIGenerateState, AIGenerateStep } from "./generation/useAIGenerateState";
|
|
65
65
|
export type { UploadedImage } from "./generation/useAIGenerateState";
|
|
66
|
-
|
|
67
|
-
export { useAIGenerateWizard, createWizardTranslations } from "./useAIGenerateWizard";
|
|
68
|
-
export type {
|
|
69
|
-
AIGenerateWizardConfig,
|
|
70
|
-
AIGenerateWizardTranslations,
|
|
71
|
-
UseAIGenerateWizardReturn,
|
|
72
|
-
} from "./useAIGenerateWizard";
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { View, ScrollView, Platform, TouchableOpacity, Image } from "react-native";
|
|
4
|
-
import {
|
|
5
|
-
useAppDesignTokens,
|
|
6
|
-
AtomicText,
|
|
7
|
-
AtomicIcon,
|
|
8
|
-
ScreenLayout,
|
|
9
|
-
AtomicKeyboardAvoidingView,
|
|
10
|
-
} from "@umituz/react-native-design-system";
|
|
11
|
-
|
|
12
|
-
import { AIGenScreenHeader } from "../headers/AIGenScreenHeader";
|
|
13
|
-
import { PartnerStepScreen } from "../../../features/partner-upload/presentation/screens/PartnerStepScreen";
|
|
14
|
-
import { AIGenerationConfig } from "../AIGenerationConfig";
|
|
15
|
-
import { GenerationProgressContent } from "../GenerationProgressContent";
|
|
16
|
-
import { AIGenerationResult } from "../display/AIGenerationResult";
|
|
17
|
-
import { AIGenerateStep } from "../../hooks/generation/useAIGenerateState";
|
|
18
|
-
import { useAIGenerateWizardFlow } from "./useAIGenerateWizardFlow";
|
|
19
|
-
import { AIGenerateWizardFlowProps } from "./AIGenerateWizardFlow.types";
|
|
20
|
-
import { VideoResultPlayer } from "../display/VideoResultPlayer";
|
|
21
|
-
|
|
22
|
-
export const AIGenerateWizardFlow: React.FC<AIGenerateWizardFlowProps> = ({
|
|
23
|
-
featureType,
|
|
24
|
-
translations,
|
|
25
|
-
styleOptions,
|
|
26
|
-
presets,
|
|
27
|
-
durationOptions,
|
|
28
|
-
onGenerate,
|
|
29
|
-
onBack: onBackProp,
|
|
30
|
-
onSave,
|
|
31
|
-
onShare,
|
|
32
|
-
onStepChange,
|
|
33
|
-
t,
|
|
34
|
-
}) => {
|
|
35
|
-
const tokens = useAppDesignTokens();
|
|
36
|
-
|
|
37
|
-
// Transform WizardStyleOption[] to StyleOption[] format
|
|
38
|
-
const transformedStyles = React.useMemo(() =>
|
|
39
|
-
styleOptions.map((style) => ({
|
|
40
|
-
id: style.id,
|
|
41
|
-
name: style.label,
|
|
42
|
-
description: undefined,
|
|
43
|
-
icon: style.icon,
|
|
44
|
-
})),
|
|
45
|
-
[styleOptions]
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
// Transform PresetOption[] to StylePreset[] format
|
|
49
|
-
const transformedPresets = React.useMemo(() =>
|
|
50
|
-
presets.map((preset) => ({
|
|
51
|
-
id: preset.id,
|
|
52
|
-
name: preset.label,
|
|
53
|
-
emoji: preset.icon || "",
|
|
54
|
-
description: preset.prompt || "",
|
|
55
|
-
})),
|
|
56
|
-
[presets]
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
const {
|
|
60
|
-
currentStep,
|
|
61
|
-
setCurrentStep,
|
|
62
|
-
images,
|
|
63
|
-
setStepImage,
|
|
64
|
-
prompt,
|
|
65
|
-
setPrompt,
|
|
66
|
-
selectedStyle,
|
|
67
|
-
setSelectedStyle,
|
|
68
|
-
selectedDuration,
|
|
69
|
-
setSelectedDuration,
|
|
70
|
-
showAdvanced,
|
|
71
|
-
toggleAdvanced,
|
|
72
|
-
isGenerating,
|
|
73
|
-
progress,
|
|
74
|
-
result,
|
|
75
|
-
handleBack,
|
|
76
|
-
handleNext,
|
|
77
|
-
handleGenerate,
|
|
78
|
-
} = useAIGenerateWizardFlow({ featureType, onGenerate, onBack: onBackProp, onStepChange });
|
|
79
|
-
|
|
80
|
-
switch (currentStep) {
|
|
81
|
-
case AIGenerateStep.UPLOAD_1:
|
|
82
|
-
case AIGenerateStep.UPLOAD_2: {
|
|
83
|
-
const isStep2 = currentStep === AIGenerateStep.UPLOAD_2;
|
|
84
|
-
return (
|
|
85
|
-
<PartnerStepScreen
|
|
86
|
-
t={t}
|
|
87
|
-
onBack={handleBack}
|
|
88
|
-
onContinue={(img: { uri: string; previewUrl?: string }) => {
|
|
89
|
-
setStepImage(isStep2 ? 1 : 0, { uri: img.uri, previewUrl: img.previewUrl || img.uri });
|
|
90
|
-
handleNext();
|
|
91
|
-
}}
|
|
92
|
-
translations={{
|
|
93
|
-
title: translations.headerTitle,
|
|
94
|
-
subtitle: isStep2 ? translations.uploadSubtitle2 : translations.uploadSubtitle,
|
|
95
|
-
continue: translations.continue,
|
|
96
|
-
tapToUpload: translations.tapToUpload,
|
|
97
|
-
selectPhoto: translations.selectPhoto,
|
|
98
|
-
change: translations.change,
|
|
99
|
-
analyzing: translations.analyzing,
|
|
100
|
-
fileTooLarge: translations.fileTooLarge,
|
|
101
|
-
maxFileSize: translations.maxFileSize,
|
|
102
|
-
error: translations.error,
|
|
103
|
-
uploadFailed: translations.uploadFailed,
|
|
104
|
-
aiDisclosure: translations.aiDisclosure,
|
|
105
|
-
}}
|
|
106
|
-
initialName=""
|
|
107
|
-
config={{ showFaceDetection: featureType === "face-swap", showNameInput: false, showPhotoTips: true }}
|
|
108
|
-
/>
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
case AIGenerateStep.GENERATING:
|
|
113
|
-
return (
|
|
114
|
-
<ScreenLayout header={<AIGenScreenHeader title={translations.headerTitle} onNavigationPress={handleBack} />}>
|
|
115
|
-
<View style={{ flex: 1, padding: tokens.spacing.xl }}>
|
|
116
|
-
<GenerationProgressContent
|
|
117
|
-
progress={progress}
|
|
118
|
-
title={translations.processingTitle}
|
|
119
|
-
message={translations.processingMessage}
|
|
120
|
-
hint={translations.processingHint}
|
|
121
|
-
/>
|
|
122
|
-
</View>
|
|
123
|
-
</ScreenLayout>
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
case AIGenerateStep.RESULT:
|
|
127
|
-
const isVideo = ["image-to-video", "text-to-video", "ai-hug", "ai-kiss"].includes(featureType);
|
|
128
|
-
return (
|
|
129
|
-
<ScreenLayout header={<AIGenScreenHeader title={translations.headerTitle} onNavigationPress={handleBack} />}>
|
|
130
|
-
<AIGenerationResult
|
|
131
|
-
successText={translations.successTitle}
|
|
132
|
-
primaryAction={{
|
|
133
|
-
label: translations.saveButton,
|
|
134
|
-
onPress: () => result && onSave?.(result),
|
|
135
|
-
icon: "download"
|
|
136
|
-
}}
|
|
137
|
-
secondaryAction={{
|
|
138
|
-
label: translations.tryAgainButton,
|
|
139
|
-
onPress: () => setCurrentStep(AIGenerateStep.CONFIG),
|
|
140
|
-
icon: "refresh",
|
|
141
|
-
}}
|
|
142
|
-
extraActions={[
|
|
143
|
-
{
|
|
144
|
-
label: translations.shareButton,
|
|
145
|
-
onPress: () => result && onShare?.(result),
|
|
146
|
-
icon: "share-variant",
|
|
147
|
-
variant: "outline",
|
|
148
|
-
},
|
|
149
|
-
]}
|
|
150
|
-
>
|
|
151
|
-
{isVideo && result ? (
|
|
152
|
-
<VideoResultPlayer uri={result} />
|
|
153
|
-
) : (
|
|
154
|
-
<Image source={{ uri: result || "" }} style={{ width: "100%", aspectRatio: 2 / 3, borderRadius: 16 }} resizeMode="cover" />
|
|
155
|
-
)}
|
|
156
|
-
</AIGenerationResult>
|
|
157
|
-
</ScreenLayout>
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
default:
|
|
161
|
-
return (
|
|
162
|
-
<AtomicKeyboardAvoidingView offset={Platform.OS === "ios" ? 94 : 0}>
|
|
163
|
-
<ScrollView
|
|
164
|
-
style={{ backgroundColor: tokens.colors.backgroundPrimary }}
|
|
165
|
-
contentContainerStyle={{ paddingBottom: 100 }}
|
|
166
|
-
showsVerticalScrollIndicator={false}
|
|
167
|
-
keyboardShouldPersistTaps="handled"
|
|
168
|
-
>
|
|
169
|
-
<AIGenScreenHeader
|
|
170
|
-
title={translations.headerTitle}
|
|
171
|
-
onNavigationPress={handleBack}
|
|
172
|
-
rightContent={
|
|
173
|
-
<TouchableOpacity
|
|
174
|
-
onPress={handleGenerate}
|
|
175
|
-
disabled={isGenerating || !prompt.trim()}
|
|
176
|
-
activeOpacity={0.7}
|
|
177
|
-
style={{
|
|
178
|
-
flexDirection: "row",
|
|
179
|
-
alignItems: "center",
|
|
180
|
-
backgroundColor: !isGenerating && prompt.trim() ? tokens.colors.primary : tokens.colors.surfaceVariant,
|
|
181
|
-
paddingHorizontal: tokens.spacing.md,
|
|
182
|
-
paddingVertical: tokens.spacing.xs,
|
|
183
|
-
borderRadius: tokens.borders.radius.full,
|
|
184
|
-
opacity: !isGenerating && prompt.trim() ? 1 : 0.5,
|
|
185
|
-
}}
|
|
186
|
-
>
|
|
187
|
-
<AtomicText
|
|
188
|
-
type="bodyMedium"
|
|
189
|
-
style={{
|
|
190
|
-
fontWeight: "800",
|
|
191
|
-
color: !isGenerating && prompt.trim() ? tokens.colors.onPrimary : tokens.colors.textSecondary,
|
|
192
|
-
marginRight: 4,
|
|
193
|
-
}}
|
|
194
|
-
>
|
|
195
|
-
{isGenerating ? translations.generatingButton : translations.generateButton}
|
|
196
|
-
</AtomicText>
|
|
197
|
-
<AtomicIcon
|
|
198
|
-
name={isGenerating ? "refresh" : "sparkles"}
|
|
199
|
-
size="sm"
|
|
200
|
-
color={!isGenerating && prompt.trim() ? "onPrimary" : "textSecondary"}
|
|
201
|
-
/>
|
|
202
|
-
</TouchableOpacity>
|
|
203
|
-
}
|
|
204
|
-
/>
|
|
205
|
-
<AIGenerationConfig
|
|
206
|
-
heroTitle={translations.heroTitle}
|
|
207
|
-
heroSubtitle={translations.heroSubtitle}
|
|
208
|
-
isGenerating={isGenerating}
|
|
209
|
-
progress={progress}
|
|
210
|
-
presets={transformedPresets}
|
|
211
|
-
onPresetPress={() => { void handleGenerate(); }}
|
|
212
|
-
prompt={prompt}
|
|
213
|
-
onPromptChange={setPrompt}
|
|
214
|
-
styles={transformedStyles}
|
|
215
|
-
selectedStyle={selectedStyle}
|
|
216
|
-
onStyleSelect={setSelectedStyle}
|
|
217
|
-
duration={selectedDuration}
|
|
218
|
-
durationOptions={durationOptions}
|
|
219
|
-
onDurationSelect={setSelectedDuration}
|
|
220
|
-
showAdvanced={showAdvanced}
|
|
221
|
-
onAdvancedToggle={toggleAdvanced}
|
|
222
|
-
onGenerate={handleGenerate}
|
|
223
|
-
images={images}
|
|
224
|
-
hideGenerateButton={true}
|
|
225
|
-
translations={translations}
|
|
226
|
-
/>
|
|
227
|
-
</ScrollView>
|
|
228
|
-
</AtomicKeyboardAvoidingView>
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
};
|
|
@@ -1,66 +0,0 @@
|
|
|
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 shareButton: string;
|
|
31
|
-
readonly tryAgainButton: string;
|
|
32
|
-
readonly fileTooLarge: string;
|
|
33
|
-
readonly maxFileSize: string;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface WizardStyleOption {
|
|
37
|
-
readonly id: string;
|
|
38
|
-
readonly label: string;
|
|
39
|
-
readonly icon?: string;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface PresetOption {
|
|
43
|
-
readonly id: string;
|
|
44
|
-
readonly label: string;
|
|
45
|
-
readonly prompt?: string;
|
|
46
|
-
readonly icon?: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface AIGenerateWizardFlowProps {
|
|
50
|
-
readonly featureType: string;
|
|
51
|
-
readonly translations: AIGenerateWizardTranslations;
|
|
52
|
-
readonly styleOptions: WizardStyleOption[];
|
|
53
|
-
readonly presets: PresetOption[];
|
|
54
|
-
readonly durationOptions: number[];
|
|
55
|
-
readonly onGenerate: (data: {
|
|
56
|
-
prompt: string;
|
|
57
|
-
style: string;
|
|
58
|
-
duration: number;
|
|
59
|
-
images: { uri: string }[];
|
|
60
|
-
}) => Promise<string | null | void>;
|
|
61
|
-
readonly onBack?: () => void;
|
|
62
|
-
readonly onSave?: (uri: string) => Promise<void>;
|
|
63
|
-
readonly onShare?: (uri: string) => Promise<void>;
|
|
64
|
-
readonly onStepChange?: (stepId: string) => void;
|
|
65
|
-
readonly t: (key: string) => string;
|
|
66
|
-
}
|
|
@@ -1,130 +0,0 @@
|
|
|
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 GenerationData {
|
|
7
|
-
prompt: string;
|
|
8
|
-
style: string;
|
|
9
|
-
duration: number;
|
|
10
|
-
images: { uri: string; previewUrl?: string }[];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface UseAIGenerateWizardFlowProps {
|
|
14
|
-
featureType: string;
|
|
15
|
-
onGenerate: (data: GenerationData) => Promise<string | null | void>;
|
|
16
|
-
onBack?: () => void;
|
|
17
|
-
onStepChange?: (stepId: string) => void;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function useAIGenerateWizardFlow({
|
|
21
|
-
featureType,
|
|
22
|
-
onGenerate,
|
|
23
|
-
onBack: onBackProp,
|
|
24
|
-
onStepChange,
|
|
25
|
-
}: UseAIGenerateWizardFlowProps) {
|
|
26
|
-
const state = useAIGenerateState();
|
|
27
|
-
const {
|
|
28
|
-
currentStep, setCurrentStep, setIsGenerating,
|
|
29
|
-
setProgress, setResult, images, prompt, selectedStyle,
|
|
30
|
-
selectedDuration
|
|
31
|
-
} = state;
|
|
32
|
-
|
|
33
|
-
// Notify parent app when step changes
|
|
34
|
-
// NOTE: Do NOT include onStepChange in dependencies - causes infinite loop!
|
|
35
|
-
// Parent app re-renders when callback updates state, recreating the callback,
|
|
36
|
-
// which would retrigger this effect in an infinite loop.
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
if (onStepChange) {
|
|
39
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
40
|
-
console.log("[AIGenerateWizardFlow] Step changed", {
|
|
41
|
-
currentStep,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
onStepChange(currentStep);
|
|
45
|
-
}
|
|
46
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
47
|
-
}, [currentStep]);
|
|
48
|
-
|
|
49
|
-
const imageCountRequired = useMemo(() => {
|
|
50
|
-
if (!featureType || !hasAIFeature(featureType)) return 0;
|
|
51
|
-
const config = getAIFeatureConfig(featureType as Parameters<typeof getAIFeatureConfig>[0]);
|
|
52
|
-
if (config.mode === "dual" || config.mode === "dual-video") return 2;
|
|
53
|
-
if (config.mode === "single" || config.mode === "single-with-prompt")
|
|
54
|
-
return 1;
|
|
55
|
-
return 0;
|
|
56
|
-
}, [featureType]);
|
|
57
|
-
|
|
58
|
-
useEffect(() => {
|
|
59
|
-
if (currentStep === AIGenerateStep.INFO) {
|
|
60
|
-
if (imageCountRequired > 0) {
|
|
61
|
-
setCurrentStep(AIGenerateStep.UPLOAD_1);
|
|
62
|
-
} else {
|
|
63
|
-
setCurrentStep(AIGenerateStep.CONFIG);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}, [featureType, imageCountRequired, setCurrentStep, currentStep]);
|
|
67
|
-
|
|
68
|
-
const handleBack = useCallback(() => {
|
|
69
|
-
if (currentStep === AIGenerateStep.UPLOAD_1) {
|
|
70
|
-
onBackProp?.();
|
|
71
|
-
} else if (currentStep === AIGenerateStep.UPLOAD_2) {
|
|
72
|
-
setCurrentStep(AIGenerateStep.UPLOAD_1);
|
|
73
|
-
} else if (currentStep === AIGenerateStep.CONFIG) {
|
|
74
|
-
if (imageCountRequired > 1) {
|
|
75
|
-
setCurrentStep(AIGenerateStep.UPLOAD_2);
|
|
76
|
-
} else if (imageCountRequired > 0) {
|
|
77
|
-
setCurrentStep(AIGenerateStep.UPLOAD_1);
|
|
78
|
-
} else {
|
|
79
|
-
onBackProp?.();
|
|
80
|
-
}
|
|
81
|
-
} else if (currentStep === AIGenerateStep.RESULT) {
|
|
82
|
-
setCurrentStep(AIGenerateStep.CONFIG);
|
|
83
|
-
}
|
|
84
|
-
}, [currentStep, setCurrentStep, imageCountRequired, onBackProp]);
|
|
85
|
-
|
|
86
|
-
const handleNext = useCallback(() => {
|
|
87
|
-
if (currentStep === AIGenerateStep.UPLOAD_1) {
|
|
88
|
-
if (imageCountRequired > 1) {
|
|
89
|
-
setCurrentStep(AIGenerateStep.UPLOAD_2);
|
|
90
|
-
} else {
|
|
91
|
-
setCurrentStep(AIGenerateStep.CONFIG);
|
|
92
|
-
}
|
|
93
|
-
} else if (currentStep === AIGenerateStep.UPLOAD_2) {
|
|
94
|
-
setCurrentStep(AIGenerateStep.CONFIG);
|
|
95
|
-
}
|
|
96
|
-
}, [currentStep, setCurrentStep, imageCountRequired]);
|
|
97
|
-
|
|
98
|
-
const handleGenerate = useCallback(async () => {
|
|
99
|
-
setIsGenerating(true);
|
|
100
|
-
setProgress(10);
|
|
101
|
-
setCurrentStep(AIGenerateStep.GENERATING);
|
|
102
|
-
|
|
103
|
-
try {
|
|
104
|
-
const output = await onGenerate({
|
|
105
|
-
prompt,
|
|
106
|
-
style: selectedStyle,
|
|
107
|
-
duration: selectedDuration,
|
|
108
|
-
images,
|
|
109
|
-
});
|
|
110
|
-
if (output) {
|
|
111
|
-
setResult(output);
|
|
112
|
-
setCurrentStep(AIGenerateStep.RESULT);
|
|
113
|
-
}
|
|
114
|
-
} catch (error) {
|
|
115
|
-
console.error("Generation failed", error);
|
|
116
|
-
setCurrentStep(AIGenerateStep.CONFIG);
|
|
117
|
-
} finally {
|
|
118
|
-
setIsGenerating(false);
|
|
119
|
-
setProgress(0);
|
|
120
|
-
}
|
|
121
|
-
}, [onGenerate, prompt, selectedStyle, selectedDuration, images, setCurrentStep, setIsGenerating, setProgress, setResult]);
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
...state,
|
|
125
|
-
imageCountRequired,
|
|
126
|
-
handleBack,
|
|
127
|
-
handleNext,
|
|
128
|
-
handleGenerate,
|
|
129
|
-
};
|
|
130
|
-
}
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useAIGenerateWizard Hook
|
|
3
|
-
* Provides all necessary logic for AI generation wizard screens
|
|
4
|
-
* Centralizes save, share, and generation handling
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { useCallback, useMemo } from "react";
|
|
8
|
-
import {
|
|
9
|
-
saveMediaToGallery,
|
|
10
|
-
shareMedia,
|
|
11
|
-
type MediaActionTranslations,
|
|
12
|
-
type ToastConfig,
|
|
13
|
-
} from "../../infrastructure/utils/media-actions.util";
|
|
14
|
-
import { useAIFeatureGeneration } from "./generation";
|
|
15
|
-
import type { AlertMessages } from "./generation";
|
|
16
|
-
|
|
17
|
-
export interface AIGenerateWizardConfig {
|
|
18
|
-
readonly featureType: string;
|
|
19
|
-
readonly userId?: string;
|
|
20
|
-
readonly alertMessages?: AlertMessages;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface AIGenerateWizardTranslations {
|
|
24
|
-
readonly headerTitle: string;
|
|
25
|
-
readonly uploadSubtitle: string;
|
|
26
|
-
readonly uploadSubtitle2: string;
|
|
27
|
-
readonly continue: string;
|
|
28
|
-
readonly tapToUpload: string;
|
|
29
|
-
readonly selectPhoto: string;
|
|
30
|
-
readonly change: string;
|
|
31
|
-
readonly analyzing: string;
|
|
32
|
-
readonly error: string;
|
|
33
|
-
readonly uploadFailed: string;
|
|
34
|
-
readonly aiDisclosure: string;
|
|
35
|
-
readonly heroTitle: string;
|
|
36
|
-
readonly heroSubtitle: string;
|
|
37
|
-
readonly presetsTitle: string;
|
|
38
|
-
readonly showAdvancedLabel: string;
|
|
39
|
-
readonly hideAdvancedLabel: string;
|
|
40
|
-
readonly promptTitle: string;
|
|
41
|
-
readonly promptPlaceholder: string;
|
|
42
|
-
readonly styleTitle: string;
|
|
43
|
-
readonly durationTitle: string;
|
|
44
|
-
readonly generateButton: string;
|
|
45
|
-
readonly generatingButton: string;
|
|
46
|
-
readonly processingTitle: string;
|
|
47
|
-
readonly processingMessage: string;
|
|
48
|
-
readonly processingHint: string;
|
|
49
|
-
readonly successTitle: string;
|
|
50
|
-
readonly saveButton: string;
|
|
51
|
-
readonly shareButton: string;
|
|
52
|
-
readonly tryAgainButton: string;
|
|
53
|
-
readonly fileTooLarge: string;
|
|
54
|
-
readonly maxFileSize: string;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface UseAIGenerateWizardReturn {
|
|
58
|
-
readonly generate: (data: {
|
|
59
|
-
prompt: string;
|
|
60
|
-
style: string;
|
|
61
|
-
duration: number;
|
|
62
|
-
images: { uri: string }[];
|
|
63
|
-
}) => Promise<string | null | void>;
|
|
64
|
-
readonly handleSave: (uri: string) => Promise<void>;
|
|
65
|
-
readonly handleShare: (uri: string) => Promise<void>;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Hook that provides all AI generation wizard functionality
|
|
70
|
-
* Handles generation, save, and share operations
|
|
71
|
-
*/
|
|
72
|
-
export function useAIGenerateWizard(
|
|
73
|
-
config: AIGenerateWizardConfig,
|
|
74
|
-
translations: { error?: string; success?: string },
|
|
75
|
-
toast?: ToastConfig
|
|
76
|
-
): UseAIGenerateWizardReturn {
|
|
77
|
-
const { generate } = useAIFeatureGeneration({
|
|
78
|
-
featureType: config.featureType as never,
|
|
79
|
-
alertMessages: config.alertMessages ?? {
|
|
80
|
-
success: translations.success ?? "Generation successful",
|
|
81
|
-
error: translations.error ?? "Error",
|
|
82
|
-
creditLimit: "Insufficient credits",
|
|
83
|
-
},
|
|
84
|
-
userId: config.userId,
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const mediaTranslations: MediaActionTranslations = useMemo(
|
|
88
|
-
() => ({
|
|
89
|
-
success: translations.success,
|
|
90
|
-
error: translations.error,
|
|
91
|
-
permissionDenied: "Permission denied",
|
|
92
|
-
saveFailed: "Failed to save media",
|
|
93
|
-
shareFailed: "Failed to share media",
|
|
94
|
-
shareNotAvailable: "Sharing is not available on this device",
|
|
95
|
-
}),
|
|
96
|
-
[translations]
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
const handleSave = useCallback(
|
|
100
|
-
async (uri: string): Promise<void> => {
|
|
101
|
-
await saveMediaToGallery(uri, mediaTranslations, toast);
|
|
102
|
-
},
|
|
103
|
-
[mediaTranslations, toast]
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
const handleShare = useCallback(
|
|
107
|
-
async (uri: string): Promise<void> => {
|
|
108
|
-
await shareMedia(uri, mediaTranslations, toast);
|
|
109
|
-
},
|
|
110
|
-
[mediaTranslations, toast]
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
generate,
|
|
115
|
-
handleSave,
|
|
116
|
-
handleShare,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Creates translations object from t function
|
|
122
|
-
* @param t - Translation function
|
|
123
|
-
* @param featureType - Feature type for feature-specific keys
|
|
124
|
-
* @returns Translations object for AIGenerateWizardFlow
|
|
125
|
-
*/
|
|
126
|
-
export function createWizardTranslations(
|
|
127
|
-
t: (key: string) => string,
|
|
128
|
-
featureType: string
|
|
129
|
-
): AIGenerateWizardTranslations {
|
|
130
|
-
const featureKey = featureType.replace(/-/g, "_");
|
|
131
|
-
return {
|
|
132
|
-
headerTitle: t(`home.ai_features.${featureKey}.title`),
|
|
133
|
-
uploadSubtitle: t("imageProcessing.upload.subtitle"),
|
|
134
|
-
uploadSubtitle2: t("imageProcessing.upload.subtitle_2"),
|
|
135
|
-
continue: t("common.actions.continue"),
|
|
136
|
-
tapToUpload: t("imageProcessing.upload.tapToUpload"),
|
|
137
|
-
selectPhoto: t("imageProcessing.upload.selectPhoto"),
|
|
138
|
-
change: t("imageProcessing.upload.change"),
|
|
139
|
-
analyzing: t("imageProcessing.upload.analyzing"),
|
|
140
|
-
error: t("common.error"),
|
|
141
|
-
uploadFailed: t("common.errors.upload_failed"),
|
|
142
|
-
aiDisclosure: t("imageProcessing.upload.aiDisclosure"),
|
|
143
|
-
heroTitle: "",
|
|
144
|
-
heroSubtitle: "",
|
|
145
|
-
presetsTitle: t("common.generation.presets.title"),
|
|
146
|
-
showAdvancedLabel: t("common.generation.advanced.show"),
|
|
147
|
-
hideAdvancedLabel: t("common.generation.advanced.hide"),
|
|
148
|
-
promptTitle: t("common.prompts.custom_prompt"),
|
|
149
|
-
promptPlaceholder: t("common.prompts.placeholder"),
|
|
150
|
-
styleTitle: t("common.generation.style_selector.video_title"),
|
|
151
|
-
durationTitle: t("common.generation.duration_selector.title"),
|
|
152
|
-
generateButton: t("common.actions.generate"),
|
|
153
|
-
generatingButton: t("common.actions.generating"),
|
|
154
|
-
processingTitle: t("common.generation.progress.title"),
|
|
155
|
-
processingMessage: t("common.generation.progress.hint"),
|
|
156
|
-
processingHint: t("common.generation.progress.backgroundHint"),
|
|
157
|
-
successTitle: t("common.generation.success"),
|
|
158
|
-
saveButton: t("common.actions.save"),
|
|
159
|
-
shareButton: t("common.actions.share"),
|
|
160
|
-
tryAgainButton: t("common.actions.try_again"),
|
|
161
|
-
fileTooLarge: t("common.errors.file_too_large"),
|
|
162
|
-
maxFileSize: t("common.errors.max_file_size"),
|
|
163
|
-
};
|
|
164
|
-
}
|
/package/src/{infrastructure → domains/generation/infrastructure}/executors/executor-factory.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/domains/{wizard → generation/wizard}/infrastructure/builders/dynamic-step-builder.ts
RENAMED
|
File without changes
|
/package/src/domains/{wizard → generation/wizard}/infrastructure/renderers/step-renderer.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/domains/{wizard → generation/wizard}/presentation/components/GenericWizardFlow.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/domains/{wizard → generation/wizard}/presentation/screens/GenericPhotoUploadScreen.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|