@umituz/react-native-ai-generation-content 1.17.61 → 1.17.62

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.17.61",
3
+ "version": "1.17.62",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -13,6 +13,7 @@ import {
13
13
  } from "@umituz/react-native-design-system";
14
14
  import { DualImagePicker } from "../../../../presentation/components/image-picker/DualImagePicker";
15
15
  import { AIGenerationForm } from "../../../../presentation/components/AIGenerationForm";
16
+ import { AIGenerationResult } from "../../../../presentation/components/display/AIGenerationResult";
16
17
  import { useAIHugFeature } from "../hooks";
17
18
  import type {
18
19
  AIHugTranslations,
@@ -85,31 +86,19 @@ export const AIHugFeature: React.FC<AIHugFeatureProps> = ({
85
86
  contentContainerStyle={styles.content}
86
87
  showsVerticalScrollIndicator={false}
87
88
  >
88
- <AtomicText
89
- type="headlineMedium"
90
- style={[styles.successText, { color: tokens.colors.success }]}
89
+ <AIGenerationResult
90
+ successText={translations.successText}
91
+ primaryAction={{
92
+ label: translations.saveButtonText,
93
+ onPress: handleSave,
94
+ }}
95
+ secondaryAction={{
96
+ label: translations.tryAnotherText,
97
+ onPress: feature.reset,
98
+ }}
91
99
  >
92
- {translations.successText}
93
- </AtomicText>
94
-
95
- <View style={styles.resultVideoContainer}>
96
100
  {renderVideoPlayer({ videoUrl: feature.processedVideoUrl, size: videoSize })}
97
- </View>
98
-
99
- <View style={styles.resultActions}>
100
- <AtomicButton
101
- title={translations.saveButtonText}
102
- onPress={handleSave}
103
- variant="primary"
104
- size="lg"
105
- />
106
- <AtomicButton
107
- title={translations.tryAnotherText}
108
- onPress={feature.reset}
109
- variant="secondary"
110
- size="lg"
111
- />
112
- </View>
101
+ </AIGenerationResult>
113
102
  </ScrollView>
114
103
  );
115
104
  }
@@ -13,6 +13,7 @@ import {
13
13
  } from "@umituz/react-native-design-system";
14
14
  import { DualImagePicker } from "../../../../presentation/components/image-picker/DualImagePicker";
15
15
  import { AIGenerationForm } from "../../../../presentation/components/AIGenerationForm";
16
+ import { AIGenerationResult } from "../../../../presentation/components/display/AIGenerationResult";
16
17
  import { useAIKissFeature } from "../hooks";
17
18
  import type {
18
19
  AIKissTranslations,
@@ -79,31 +80,19 @@ export const AIKissFeature: React.FC<AIKissFeatureProps> = ({
79
80
  contentContainerStyle={styles.content}
80
81
  showsVerticalScrollIndicator={false}
81
82
  >
82
- <AtomicText
83
- type="headlineMedium"
84
- style={[styles.successText, { color: tokens.colors.success }]}
83
+ <AIGenerationResult
84
+ successText={translations.successText}
85
+ primaryAction={{
86
+ label: translations.saveButtonText,
87
+ onPress: handleSave,
88
+ }}
89
+ secondaryAction={{
90
+ label: translations.tryAnotherText,
91
+ onPress: feature.reset,
92
+ }}
85
93
  >
86
- {translations.successText}
87
- </AtomicText>
88
-
89
- <View style={styles.resultVideoContainer}>
90
94
  {renderVideoPlayer({ videoUrl: feature.processedVideoUrl, size: videoSize })}
91
- </View>
92
-
93
- <View style={styles.resultActions}>
94
- <AtomicButton
95
- title={translations.saveButtonText}
96
- onPress={handleSave}
97
- variant="primary"
98
- size="lg"
99
- />
100
- <AtomicButton
101
- title={translations.tryAnotherText}
102
- onPress={feature.reset}
103
- variant="secondary"
104
- size="lg"
105
- />
106
- </View>
95
+ </AIGenerationResult>
107
96
  </ScrollView>
108
97
  );
109
98
  }
@@ -13,6 +13,7 @@ import {
13
13
  } from "@umituz/react-native-design-system";
14
14
  import { PhotoUploadCard } from "../../../../presentation/components/PhotoUploadCard";
15
15
  import { AIGenerationForm } from "../../../../presentation/components/AIGenerationForm";
16
+ import { AIGenerationResult } from "../../../../presentation/components/display/AIGenerationResult";
16
17
  import { useAnimeSelfieFeature } from "../hooks";
17
18
  import type {
18
19
  AnimeSelfieTranslations,
@@ -77,35 +78,23 @@ export const AnimeSelfieFeature: React.FC<AnimeSelfieFeatureProps> = ({
77
78
  contentContainerStyle={styles.content}
78
79
  showsVerticalScrollIndicator={false}
79
80
  >
80
- <AtomicText
81
- type="headlineMedium"
82
- style={[styles.successText, { color: tokens.colors.success }]}
81
+ <AIGenerationResult
82
+ successText={translations.successText}
83
+ primaryAction={{
84
+ label: translations.saveButtonText,
85
+ onPress: handleSave,
86
+ }}
87
+ secondaryAction={{
88
+ label: translations.tryAnotherText,
89
+ onPress: feature.reset,
90
+ }}
83
91
  >
84
- {translations.successText}
85
- </AtomicText>
86
-
87
- <View style={styles.resultImageContainer}>
88
92
  <Image
89
93
  source={{ uri: feature.processedUrl }}
90
94
  style={[styles.resultImage, { width: imageSize, height: imageSize }]}
91
95
  resizeMode="contain"
92
96
  />
93
- </View>
94
-
95
- <View style={styles.resultActions}>
96
- <AtomicButton
97
- title={translations.saveButtonText}
98
- onPress={handleSave}
99
- variant="primary"
100
- size="lg"
101
- />
102
- <AtomicButton
103
- title={translations.tryAnotherText}
104
- onPress={feature.reset}
105
- variant="secondary"
106
- size="lg"
107
- />
108
- </View>
97
+ </AIGenerationResult>
109
98
  </ScrollView>
110
99
  );
111
100
  }
@@ -13,6 +13,7 @@ import {
13
13
  } from "@umituz/react-native-design-system";
14
14
  import { DualImagePicker } from "../../../../presentation/components/image-picker/DualImagePicker";
15
15
  import { AIGenerationForm } from "../../../../presentation/components/AIGenerationForm";
16
+ import { AIGenerationResult } from "../../../../presentation/components/display/AIGenerationResult";
16
17
  import { useFaceSwapFeature } from "../hooks";
17
18
  import type {
18
19
  FaceSwapTranslations,
@@ -76,35 +77,23 @@ export const FaceSwapFeature: React.FC<FaceSwapFeatureProps> = ({
76
77
  contentContainerStyle={styles.content}
77
78
  showsVerticalScrollIndicator={false}
78
79
  >
79
- <AtomicText
80
- type="headlineMedium"
81
- style={[styles.successText, { color: tokens.colors.success }]}
80
+ <AIGenerationResult
81
+ successText={translations.successText}
82
+ primaryAction={{
83
+ label: translations.saveButtonText,
84
+ onPress: handleSave,
85
+ }}
86
+ secondaryAction={{
87
+ label: translations.tryAnotherText,
88
+ onPress: feature.reset,
89
+ }}
82
90
  >
83
- {translations.successText}
84
- </AtomicText>
85
-
86
- <View style={styles.resultImageContainer}>
87
91
  <Image
88
92
  source={{ uri: feature.processedUrl }}
89
93
  style={[styles.resultImage, { width: imageSize, height: imageSize }]}
90
94
  resizeMode="contain"
91
95
  />
92
- </View>
93
-
94
- <View style={styles.resultActions}>
95
- <AtomicButton
96
- title={translations.saveButtonText}
97
- onPress={handleSave}
98
- variant="primary"
99
- size="lg"
100
- />
101
- <AtomicButton
102
- title={translations.tryAnotherText}
103
- onPress={feature.reset}
104
- variant="secondary"
105
- size="lg"
106
- />
107
- </View>
96
+ </AIGenerationResult>
108
97
  </ScrollView>
109
98
  );
110
99
  }
@@ -13,6 +13,7 @@ import {
13
13
  } from "@umituz/react-native-design-system";
14
14
  import { PhotoUploadCard } from "../../../../presentation/components/PhotoUploadCard";
15
15
  import { AIGenerationForm } from "../../../../presentation/components/AIGenerationForm";
16
+ import { AIGenerationResult } from "../../../../presentation/components/display/AIGenerationResult";
16
17
  import { useHDTouchUpFeature } from "../hooks";
17
18
  import type {
18
19
  HDTouchUpTranslations,
@@ -77,35 +78,23 @@ export const HDTouchUpFeature: React.FC<HDTouchUpFeatureProps> = ({
77
78
  contentContainerStyle={styles.content}
78
79
  showsVerticalScrollIndicator={false}
79
80
  >
80
- <AtomicText
81
- type="headlineMedium"
82
- style={[styles.successText, { color: tokens.colors.success }]}
81
+ <AIGenerationResult
82
+ successText={translations.successText}
83
+ primaryAction={{
84
+ label: translations.saveButtonText,
85
+ onPress: handleSave,
86
+ }}
87
+ secondaryAction={{
88
+ label: translations.tryAnotherText,
89
+ onPress: feature.reset,
90
+ }}
83
91
  >
84
- {translations.successText}
85
- </AtomicText>
86
-
87
- <View style={styles.resultImageContainer}>
88
92
  <Image
89
93
  source={{ uri: feature.processedUrl }}
90
94
  style={[styles.resultImage, { width: imageSize, height: imageSize }]}
91
95
  resizeMode="contain"
92
96
  />
93
- </View>
94
-
95
- <View style={styles.resultActions}>
96
- <AtomicButton
97
- title={translations.saveButtonText}
98
- onPress={handleSave}
99
- variant="primary"
100
- size="lg"
101
- />
102
- <AtomicButton
103
- title={translations.tryAnotherText}
104
- onPress={feature.reset}
105
- variant="secondary"
106
- size="lg"
107
- />
108
- </View>
97
+ </AIGenerationResult>
109
98
  </ScrollView>
110
99
  );
111
100
  }
@@ -13,6 +13,7 @@ import {
13
13
  } from "@umituz/react-native-design-system";
14
14
  import { PhotoUploadCard } from "../../../../presentation/components/PhotoUploadCard";
15
15
  import { AIGenerationForm } from "../../../../presentation/components/AIGenerationForm";
16
+ import { AIGenerationResult } from "../../../../presentation/components/display/AIGenerationResult";
16
17
  import { useRemoveBackgroundFeature } from "../hooks";
17
18
  import type {
18
19
  RemoveBackgroundTranslations,
@@ -77,35 +78,23 @@ export const RemoveBackgroundFeature: React.FC<RemoveBackgroundFeatureProps> = (
77
78
  contentContainerStyle={styles.content}
78
79
  showsVerticalScrollIndicator={false}
79
80
  >
80
- <AtomicText
81
- type="headlineMedium"
82
- style={[styles.successText, { color: tokens.colors.success }]}
81
+ <AIGenerationResult
82
+ successText={translations.successText}
83
+ primaryAction={{
84
+ label: translations.saveButtonText,
85
+ onPress: handleSave,
86
+ }}
87
+ secondaryAction={{
88
+ label: translations.tryAnotherText,
89
+ onPress: feature.reset,
90
+ }}
83
91
  >
84
- {translations.successText}
85
- </AtomicText>
86
-
87
- <View style={styles.resultImageContainer}>
88
92
  <Image
89
93
  source={{ uri: feature.processedUrl }}
90
94
  style={[styles.resultImage, { width: imageSize, height: imageSize }]}
91
95
  resizeMode="contain"
92
96
  />
93
- </View>
94
-
95
- <View style={styles.resultActions}>
96
- <AtomicButton
97
- title={translations.saveButtonText}
98
- onPress={handleSave}
99
- variant="primary"
100
- size="lg"
101
- />
102
- <AtomicButton
103
- title={translations.tryAnotherText}
104
- onPress={feature.reset}
105
- variant="secondary"
106
- size="lg"
107
- />
108
- </View>
97
+ </AIGenerationResult>
109
98
  </ScrollView>
110
99
  );
111
100
  }
@@ -13,6 +13,7 @@ import {
13
13
  } from "@umituz/react-native-design-system";
14
14
  import { PhotoUploadCard } from "../../../../presentation/components/PhotoUploadCard";
15
15
  import { AIGenerationForm } from "../../../../presentation/components/AIGenerationForm";
16
+ import { AIGenerationResult } from "../../../../presentation/components/display/AIGenerationResult";
16
17
  import { useRemoveObjectFeature } from "../hooks";
17
18
  import type {
18
19
  RemoveObjectTranslations,
@@ -76,35 +77,23 @@ export const RemoveObjectFeature: React.FC<RemoveObjectFeatureProps> = ({
76
77
  contentContainerStyle={styles.content}
77
78
  showsVerticalScrollIndicator={false}
78
79
  >
79
- <AtomicText
80
- type="headlineMedium"
81
- style={[styles.successText, { color: tokens.colors.success }]}
80
+ <AIGenerationResult
81
+ successText={translations.successText}
82
+ primaryAction={{
83
+ label: translations.saveButtonText,
84
+ onPress: handleSave,
85
+ }}
86
+ secondaryAction={{
87
+ label: translations.tryAnotherText,
88
+ onPress: feature.reset,
89
+ }}
82
90
  >
83
- {translations.successText}
84
- </AtomicText>
85
-
86
- <View style={styles.resultImageContainer}>
87
91
  <Image
88
92
  source={{ uri: feature.processedUrl }}
89
93
  style={[styles.resultImage, { width: imageSize, height: imageSize }]}
90
94
  resizeMode="contain"
91
95
  />
92
- </View>
93
-
94
- <View style={styles.resultActions}>
95
- <AtomicButton
96
- title={translations.saveButtonText}
97
- onPress={handleSave}
98
- variant="primary"
99
- size="lg"
100
- />
101
- <AtomicButton
102
- title={translations.tryAnotherText}
103
- onPress={feature.reset}
104
- variant="secondary"
105
- size="lg"
106
- />
107
- </View>
96
+ </AIGenerationResult>
108
97
  </ScrollView>
109
98
  );
110
99
  }
@@ -0,0 +1,124 @@
1
+ import React, { PropsWithChildren } from "react";
2
+ import { View, StyleSheet, Dimensions } from "react-native";
3
+ import {
4
+ useAppDesignTokens,
5
+ AtomicText,
6
+ AtomicButton,
7
+ } from "@umituz/react-native-design-system";
8
+
9
+ export interface AIGenerationResultAction {
10
+ label: string;
11
+ onPress: () => void;
12
+ variant?: "primary" | "secondary" | "outline";
13
+ icon?: string;
14
+ }
15
+
16
+ export interface AIGenerationResultTranslations {
17
+ successText?: string;
18
+ }
19
+
20
+ export interface AIGenerationResultProps extends PropsWithChildren {
21
+ /** Success message shown at the top */
22
+ successText?: string;
23
+ /** Primary action (usually Save/Download) */
24
+ primaryAction?: AIGenerationResultAction;
25
+ /** Secondary action (usually Try Again/Reset) */
26
+ secondaryAction?: AIGenerationResultAction;
27
+ /** Additional actions */
28
+ extraActions?: AIGenerationResultAction[];
29
+ /** Standard translations */
30
+ translations?: AIGenerationResultTranslations;
31
+ /** Custom style for the content container */
32
+ contentStyle?: any;
33
+ }
34
+
35
+ /**
36
+ * Standardized AI Generation Result View
37
+ * Handles success message, content display (children), and action buttons.
38
+ */
39
+ export const AIGenerationResult: React.FC<AIGenerationResultProps> = ({
40
+ successText,
41
+ primaryAction,
42
+ secondaryAction,
43
+ extraActions = [],
44
+ translations,
45
+ contentStyle,
46
+ children,
47
+ }) => {
48
+ const tokens = useAppDesignTokens();
49
+ const screenWidth = Dimensions.get("window").width;
50
+ const contentSize = screenWidth - 48;
51
+
52
+ const displaySuccessText = successText || translations?.successText;
53
+
54
+ return (
55
+ <View style={styles.container}>
56
+ {displaySuccessText && (
57
+ <AtomicText
58
+ type="headlineMedium"
59
+ style={[styles.successText, { color: tokens.colors.success }]}
60
+ >
61
+ {displaySuccessText}
62
+ </AtomicText>
63
+ )}
64
+
65
+ <View style={[styles.contentContainer, { width: contentSize }, contentStyle]}>
66
+ {children}
67
+ </View>
68
+
69
+ <View style={styles.actionsContainer}>
70
+ {primaryAction && (
71
+ <AtomicButton
72
+ title={primaryAction.label}
73
+ onPress={primaryAction.onPress}
74
+ variant="primary"
75
+ size="lg"
76
+ leftIcon={primaryAction.icon}
77
+ />
78
+ )}
79
+
80
+ {secondaryAction && (
81
+ <AtomicButton
82
+ title={secondaryAction.label}
83
+ onPress={secondaryAction.onPress}
84
+ variant="secondary"
85
+ size="lg"
86
+ leftIcon={secondaryAction.icon}
87
+ />
88
+ )}
89
+
90
+ {extraActions.map((action, index) => (
91
+ <AtomicButton
92
+ key={`extra-action-${index}`}
93
+ title={action.label}
94
+ onPress={action.onPress}
95
+ variant={action.variant || "outline"}
96
+ size="lg"
97
+ leftIcon={action.icon}
98
+ />
99
+ ))}
100
+ </View>
101
+ </View>
102
+ );
103
+ };
104
+
105
+ const styles = StyleSheet.create({
106
+ container: {
107
+ flex: 1,
108
+ paddingVertical: 16,
109
+ },
110
+ successText: {
111
+ textAlign: "center",
112
+ marginBottom: 24,
113
+ },
114
+ contentContainer: {
115
+ alignSelf: "center",
116
+ marginBottom: 24,
117
+ borderRadius: 16,
118
+ overflow: "hidden",
119
+ },
120
+ actionsContainer: {
121
+ marginHorizontal: 24,
122
+ gap: 12,
123
+ },
124
+ });
@@ -3,4 +3,9 @@ export {
3
3
  type ResultDisplayProps,
4
4
  type ResultDisplayAction,
5
5
  } from "./ResultDisplay";
6
+ export {
7
+ AIGenerationResult,
8
+ type AIGenerationResultProps,
9
+ type AIGenerationResultAction,
10
+ } from "./AIGenerationResult";
6
11
  export { ErrorDisplay, type ErrorDisplayProps } from "./ErrorDisplay";