@umituz/react-native-ai-generation-content 1.20.40 → 1.20.42

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.40",
3
+ "version": "1.20.42",
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",
@@ -25,31 +25,8 @@ export interface PartnerConfig {
25
25
  readonly maxNameLength?: number;
26
26
  }
27
27
 
28
- /** Category Data - App provides */
29
- export interface CategoryData {
30
- readonly id: string;
31
- readonly titleKey: string;
32
- readonly descriptionKey?: string;
33
- readonly icon: string;
34
- readonly imageUrl?: string;
35
- readonly subcategories?: readonly CategoryData[];
36
- }
37
-
38
- /** Scenario Data - App provides */
39
- export interface ScenarioData {
40
- readonly id: string;
41
- readonly categoryId?: string;
42
- readonly titleKey: string;
43
- readonly descriptionKey: string;
44
- readonly icon: string;
45
- readonly imageUrl?: string;
46
- readonly previewImageUrl?: string;
47
- readonly aiPrompt: string;
48
- readonly storyTemplate?: string;
49
- }
50
-
51
28
  /** Visual Style Option */
52
- export interface VisualStyleData {
29
+ export interface FlowVisualStyleData {
53
30
  readonly id: string;
54
31
  readonly icon: string;
55
32
  readonly labelKey: string;
@@ -57,7 +34,7 @@ export interface VisualStyleData {
57
34
  }
58
35
 
59
36
  /** Uploaded Image Data */
60
- export interface UploadedImageData {
37
+ export interface FlowUploadedImageData {
61
38
  readonly uri: string;
62
39
  readonly base64: string;
63
40
  readonly mimeType: string;
@@ -88,9 +65,9 @@ export interface FlowState {
88
65
  readonly currentStepId: string;
89
66
  readonly currentStepIndex: number;
90
67
  readonly completedSteps: readonly string[];
91
- readonly selectedCategory?: CategoryData;
92
- readonly selectedScenario?: ScenarioData;
93
- readonly partners: Record<string, UploadedImageData | undefined>;
68
+ readonly selectedCategory?: unknown;
69
+ readonly selectedScenario?: unknown;
70
+ readonly partners: Record<string, FlowUploadedImageData | undefined>;
94
71
  readonly partnerNames: Record<string, string>;
95
72
  readonly textInput?: string;
96
73
  readonly visualStyle?: string;
@@ -107,9 +84,9 @@ export interface FlowActions {
107
84
  goToStep: (stepId: string) => void;
108
85
  nextStep: () => void;
109
86
  previousStep: () => void;
110
- setCategory: (category: CategoryData | undefined) => void;
111
- setScenario: (scenario: ScenarioData | undefined) => void;
112
- setPartnerImage: (partnerId: string, image: UploadedImageData | undefined) => void;
87
+ setCategory: (category: unknown) => void;
88
+ setScenario: (scenario: unknown) => void;
89
+ setPartnerImage: (partnerId: string, image: FlowUploadedImageData | undefined) => void;
113
90
  setPartnerName: (partnerId: string, name: string) => void;
114
91
  setTextInput: (text: string) => void;
115
92
  setVisualStyle: (styleId: string) => void;
@@ -148,9 +125,9 @@ export interface FlowCallbacks {
148
125
 
149
126
  /** Flow Data Provider - App provides data */
150
127
  export interface FlowDataProvider {
151
- readonly categories?: readonly CategoryData[];
152
- readonly scenarios?: readonly ScenarioData[];
153
- readonly visualStyles?: readonly VisualStyleData[];
128
+ readonly categories?: readonly unknown[];
129
+ readonly scenarios?: readonly unknown[];
130
+ readonly visualStyles?: readonly FlowVisualStyleData[];
154
131
  readonly surprisePrompts?: readonly string[];
155
132
  }
156
133
 
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Couple Future Wizard Types
3
+ * Configuration types for the couple future wizard component
4
+ */
5
+
6
+ import type { StepType, FlowCallbacks, FlowUploadedImageData } from "../../../domain/entities/flow-config.types";
7
+
8
+ /** Scenario data structure */
9
+ export interface WizardScenarioData {
10
+ readonly id: string;
11
+ readonly title: string;
12
+ readonly description?: string;
13
+ readonly image?: string;
14
+ readonly aiPrompt?: string;
15
+ readonly category?: string;
16
+ }
17
+
18
+ /** Visual style option */
19
+ export interface WizardVisualStyleOption {
20
+ readonly id: string;
21
+ readonly icon: string;
22
+ readonly labelKey: string;
23
+ }
24
+
25
+ /** Partner upload config */
26
+ export interface WizardPartnerConfig {
27
+ readonly titleKey: string;
28
+ readonly subtitleKey: string;
29
+ readonly showFaceDetection?: boolean;
30
+ readonly showNameInput?: boolean;
31
+ readonly showPhotoTips?: boolean;
32
+ }
33
+
34
+ /** Wizard step config */
35
+ export interface WizardStepConfig {
36
+ readonly id: string;
37
+ readonly type: StepType;
38
+ readonly enabled?: boolean;
39
+ }
40
+
41
+ /** Wizard configuration */
42
+ export interface CoupleFutureWizardConfig {
43
+ readonly steps: readonly WizardStepConfig[];
44
+ readonly customScenarioId?: string;
45
+ readonly partnerA?: WizardPartnerConfig;
46
+ readonly partnerB?: WizardPartnerConfig;
47
+ }
48
+
49
+ /** Wizard translations */
50
+ export interface CoupleFutureWizardTranslations {
51
+ readonly generator: {
52
+ readonly title: string;
53
+ readonly waitMessage: string;
54
+ readonly hint?: string;
55
+ };
56
+ readonly partnerA: {
57
+ readonly title: string;
58
+ readonly subtitle: string;
59
+ readonly continue: string;
60
+ readonly tapToUpload: string;
61
+ readonly selectPhoto: string;
62
+ readonly change: string;
63
+ };
64
+ readonly partnerB: {
65
+ readonly title: string;
66
+ readonly subtitle: string;
67
+ readonly continue: string;
68
+ readonly tapToUpload: string;
69
+ readonly selectPhoto: string;
70
+ readonly change: string;
71
+ };
72
+ readonly scenarioPreview: {
73
+ readonly continue: string;
74
+ readonly back?: string;
75
+ };
76
+ readonly defaultNames: {
77
+ readonly partnerA: string;
78
+ readonly partnerB: string;
79
+ };
80
+ }
81
+
82
+ /** Wizard data providers */
83
+ export interface CoupleFutureWizardData {
84
+ readonly scenarios: readonly WizardScenarioData[];
85
+ readonly visualStyles?: readonly WizardVisualStyleOption[];
86
+ readonly surprisePrompts?: readonly string[];
87
+ }
88
+
89
+ /** Wizard callbacks */
90
+ export interface CoupleFutureWizardCallbacks extends FlowCallbacks {
91
+ readonly onScenarioSelect?: (scenario: WizardScenarioData) => void;
92
+ readonly onPartnerUpload?: (partnerId: "A" | "B", image: FlowUploadedImageData) => void;
93
+ readonly requireFeature?: (callback: () => void) => boolean;
94
+ }
95
+
96
+ /** Wizard props */
97
+ export interface CoupleFutureWizardProps {
98
+ readonly userId?: string;
99
+ readonly config: CoupleFutureWizardConfig;
100
+ readonly translations: CoupleFutureWizardTranslations;
101
+ readonly data: CoupleFutureWizardData;
102
+ readonly callbacks?: CoupleFutureWizardCallbacks;
103
+ readonly t: (key: string) => string;
104
+ }
105
+
106
+ /** Wizard state (exposed to parent) */
107
+ export interface CoupleFutureWizardState {
108
+ readonly currentStepId: string;
109
+ readonly selectedScenario: WizardScenarioData | null;
110
+ readonly partnerA: FlowUploadedImageData | null;
111
+ readonly partnerB: FlowUploadedImageData | null;
112
+ readonly partnerAName: string;
113
+ readonly partnerBName: string;
114
+ readonly customPrompt: string;
115
+ readonly visualStyle: string;
116
+ readonly isGenerating: boolean;
117
+ readonly progress: number;
118
+ }
@@ -47,6 +47,22 @@ export type {
47
47
  } from "./infrastructure/coupleFeatureRegistry";
48
48
  export { enhanceCouplePrompt } from "./infrastructure/couplePromptEnhancer";
49
49
 
50
+ // Wizard Component
51
+ export { CoupleFutureWizard, resetCoupleFutureWizard } from "./presentation/components/CoupleFutureWizard";
52
+ export { GeneratingStepContent } from "./presentation/components/GeneratingStepContent";
53
+ export type {
54
+ CoupleFutureWizardProps,
55
+ CoupleFutureWizardConfig,
56
+ CoupleFutureWizardTranslations,
57
+ CoupleFutureWizardData,
58
+ CoupleFutureWizardCallbacks,
59
+ CoupleFutureWizardState,
60
+ WizardScenarioData,
61
+ WizardVisualStyleOption,
62
+ WizardPartnerConfig,
63
+ WizardStepConfig,
64
+ } from "./domain/wizard.types";
65
+
50
66
  // Generation utilities
51
67
  export {
52
68
  buildGenerationInputFromConfig,
@@ -0,0 +1,160 @@
1
+ /**
2
+ * CoupleFutureWizard
3
+ * Complete wizard component for couple future generation flow
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 type { CoupleFutureWizardProps, WizardScenarioData } from "../../domain/wizard.types";
13
+ import { PartnerStepScreen } from "../../../partner-upload";
14
+ import { ScenarioPreviewScreen } from "../../../scenarios";
15
+ import { GeneratingStepContent } from "./GeneratingStepContent";
16
+
17
+ const createStepDefinitions = (
18
+ config: CoupleFutureWizardProps["config"],
19
+ ): readonly StepDefinition[] => {
20
+ return config.steps.map((step) => ({
21
+ id: step.id,
22
+ type: step.type,
23
+ required: step.enabled !== false,
24
+ }));
25
+ };
26
+
27
+ export const CoupleFutureWizard: React.FC<CoupleFutureWizardProps> = ({
28
+ config,
29
+ translations,
30
+ data,
31
+ callbacks,
32
+ t,
33
+ }) => {
34
+ const tokens = useAppDesignTokens();
35
+
36
+ const stepDefinitions = useMemo(
37
+ () => createStepDefinitions(config),
38
+ [config],
39
+ );
40
+
41
+ const flow = useFlow({ steps: stepDefinitions });
42
+
43
+ const handleScenarioSelect = useCallback(
44
+ (scenario: WizardScenarioData) => {
45
+ flow.setCategory(scenario);
46
+ callbacks?.onScenarioSelect?.(scenario);
47
+ flow.nextStep();
48
+ },
49
+ [flow, callbacks],
50
+ );
51
+
52
+ const handleScenarioPreviewContinue = useCallback(() => {
53
+ const checkFeature = callbacks?.requireFeature;
54
+ if (checkFeature) {
55
+ checkFeature(() => flow.nextStep());
56
+ } else {
57
+ flow.nextStep();
58
+ }
59
+ }, [flow, callbacks]);
60
+
61
+ const handlePartnerAContinue = useCallback(
62
+ (image: { uri: string; base64: string; mimeType: string }, name?: string) => {
63
+ flow.setPartnerImage("A", image);
64
+ if (name) flow.setPartnerName("A", name);
65
+ callbacks?.onPartnerUpload?.("A", image);
66
+ flow.nextStep();
67
+ },
68
+ [flow, callbacks],
69
+ );
70
+
71
+ const handlePartnerBContinue = useCallback(
72
+ (image: { uri: string; base64: string; mimeType: string }, name?: string) => {
73
+ flow.setPartnerImage("B", image);
74
+ if (name) flow.setPartnerName("B", name);
75
+ callbacks?.onPartnerUpload?.("B", image);
76
+ flow.startGeneration();
77
+ callbacks?.onGenerationStart?.();
78
+ },
79
+ [flow, callbacks],
80
+ );
81
+
82
+ const renderCurrentStep = useCallback(() => {
83
+ const step = flow.currentStep;
84
+ if (!step) return null;
85
+
86
+ switch (step.type) {
87
+ case StepType.SCENARIO_SELECTION:
88
+ return null; // Rendered by parent via CategoryNavigationContainer
89
+
90
+ case StepType.SCENARIO_PREVIEW:
91
+ return (
92
+ <ScenarioPreviewScreen
93
+ scenario={flow.selectedCategory as never}
94
+ translations={translations.scenarioPreview as never}
95
+ onBack={flow.previousStep}
96
+ onContinue={handleScenarioPreviewContinue}
97
+ t={t}
98
+ />
99
+ );
100
+
101
+ case StepType.PARTNER_UPLOAD:
102
+ const isPartnerA = step.id.includes("A") || step.id === "PARTNER_A";
103
+ const partnerTranslations = isPartnerA
104
+ ? translations.partnerA
105
+ : translations.partnerB;
106
+ const partnerConfig = isPartnerA ? config.partnerA : config.partnerB;
107
+
108
+ return (
109
+ <PartnerStepScreen
110
+ key={isPartnerA ? "a" : "b"}
111
+ translations={partnerTranslations as never}
112
+ t={t}
113
+ initialName=""
114
+ config={{
115
+ showFaceDetection: partnerConfig?.showFaceDetection ?? false,
116
+ showNameInput: partnerConfig?.showNameInput ?? false,
117
+ showPhotoTips: partnerConfig?.showPhotoTips ?? true,
118
+ maxFileSizeMB: 10,
119
+ maxNameLength: 30,
120
+ }}
121
+ onBack={flow.previousStep}
122
+ onContinue={isPartnerA ? handlePartnerAContinue as never : handlePartnerBContinue as never}
123
+ />
124
+ );
125
+
126
+ case StepType.GENERATING:
127
+ return (
128
+ <GeneratingStepContent
129
+ progress={flow.generationProgress}
130
+ title={translations.generator.title}
131
+ message={translations.generator.waitMessage}
132
+ hint={translations.generator.hint}
133
+ />
134
+ );
135
+
136
+ default:
137
+ return null;
138
+ }
139
+ }, [
140
+ flow,
141
+ config,
142
+ translations,
143
+ t,
144
+ handleScenarioPreviewContinue,
145
+ handlePartnerAContinue,
146
+ handlePartnerBContinue,
147
+ ]);
148
+
149
+ return (
150
+ <View style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}>
151
+ {renderCurrentStep()}
152
+ </View>
153
+ );
154
+ };
155
+
156
+ export { resetFlowStore as resetCoupleFutureWizard };
157
+
158
+ const styles = StyleSheet.create({
159
+ container: { flex: 1 },
160
+ });
@@ -0,0 +1,86 @@
1
+ /**
2
+ * GeneratingStepContent
3
+ * Display component for generation progress
4
+ */
5
+
6
+ import React from "react";
7
+ import { View, StyleSheet } from "react-native";
8
+ import {
9
+ AtomicText,
10
+ useAppDesignTokens,
11
+ } from "@umituz/react-native-design-system";
12
+ import { GenerationProgressBar } from "../../../../presentation/components";
13
+
14
+ interface GeneratingStepContentProps {
15
+ readonly progress: number;
16
+ readonly title: string;
17
+ readonly message: string;
18
+ readonly hint?: string;
19
+ }
20
+
21
+ export const GeneratingStepContent: React.FC<GeneratingStepContentProps> = ({
22
+ progress,
23
+ title,
24
+ message,
25
+ hint,
26
+ }) => {
27
+ const tokens = useAppDesignTokens();
28
+
29
+ return (
30
+ <View style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}>
31
+ <View style={styles.content}>
32
+ <AtomicText type="headlineMedium" style={styles.title}>
33
+ {title}
34
+ </AtomicText>
35
+
36
+ <View style={styles.progressContainer}>
37
+ <GenerationProgressBar progress={progress} />
38
+ </View>
39
+
40
+ <AtomicText
41
+ type="bodyMedium"
42
+ style={[styles.message, { color: tokens.colors.textSecondary }]}
43
+ >
44
+ {message}
45
+ </AtomicText>
46
+
47
+ {hint ? (
48
+ <AtomicText
49
+ type="labelSmall"
50
+ style={[styles.hint, { color: tokens.colors.textTertiary }]}
51
+ >
52
+ {hint}
53
+ </AtomicText>
54
+ ) : null}
55
+ </View>
56
+ </View>
57
+ );
58
+ };
59
+
60
+ const styles = StyleSheet.create({
61
+ container: {
62
+ flex: 1,
63
+ justifyContent: "center",
64
+ alignItems: "center",
65
+ },
66
+ content: {
67
+ width: "100%",
68
+ paddingHorizontal: 24,
69
+ alignItems: "center",
70
+ },
71
+ title: {
72
+ textAlign: "center",
73
+ marginBottom: 32,
74
+ },
75
+ progressContainer: {
76
+ width: "100%",
77
+ marginBottom: 24,
78
+ },
79
+ message: {
80
+ textAlign: "center",
81
+ marginBottom: 16,
82
+ },
83
+ hint: {
84
+ textAlign: "center",
85
+ },
86
+ });
package/src/index.ts CHANGED
@@ -210,9 +210,7 @@ export type {
210
210
  StepComponentProps,
211
211
  StepTransition,
212
212
  PartnerConfig,
213
- CategoryData,
214
- ScenarioData,
215
- VisualStyleData,
216
- UploadedImageData,
213
+ FlowVisualStyleData,
214
+ FlowUploadedImageData,
217
215
  FlowGenerationStatus,
218
216
  } from "./domain/entities/flow-config.types";
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { useRef, useCallback, useMemo } from "react";
7
7
  import { createFlowStore, type FlowStoreType } from "./useFlowStore";
8
- import type { FlowState, FlowActions, StepDefinition } from "../../domain/entities/flow-config.types";
8
+ import type { FlowState, FlowActions, StepDefinition, FlowUploadedImageData } from "../../domain/entities/flow-config.types";
9
9
 
10
10
  interface UseFlowConfig {
11
11
  steps: readonly StepDefinition[];
@@ -20,7 +20,7 @@ interface UseFlowReturn extends FlowState, FlowActions {
20
20
  isFirstStep: boolean;
21
21
  isLastStep: boolean;
22
22
  hasPartner: (partnerId: string) => boolean;
23
- getPartnerImage: (partnerId: string) => FlowState["partners"][string];
23
+ getPartnerImage: (partnerId: string) => FlowUploadedImageData | undefined;
24
24
  getPartnerName: (partnerId: string) => string;
25
25
  }
26
26
 
@@ -7,9 +7,7 @@ import { createStore } from "@umituz/react-native-design-system";
7
7
  import type {
8
8
  FlowState,
9
9
  FlowActions,
10
- CategoryData,
11
- ScenarioData,
12
- UploadedImageData,
10
+ FlowUploadedImageData,
13
11
  StepDefinition,
14
12
  } from "../../domain/entities/flow-config.types";
15
13
 
@@ -84,10 +82,10 @@ export const createFlowStore = (config: FlowStoreConfig) => {
84
82
  }
85
83
  },
86
84
 
87
- setCategory: (category: CategoryData | undefined) => set({ selectedCategory: category }),
88
- setScenario: (scenario: ScenarioData | undefined) => set({ selectedScenario: scenario }),
85
+ setCategory: (category: unknown) => set({ selectedCategory: category }),
86
+ setScenario: (scenario: unknown) => set({ selectedScenario: scenario }),
89
87
 
90
- setPartnerImage: (partnerId: string, image: UploadedImageData | undefined) => {
88
+ setPartnerImage: (partnerId: string, image: FlowUploadedImageData | undefined) => {
91
89
  const { partners } = get();
92
90
  set({ partners: { ...partners, [partnerId]: image } });
93
91
  },