@umituz/react-native-ai-generation-content 1.17.77 → 1.17.79

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.77",
3
+ "version": "1.17.79",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -0,0 +1 @@
1
+ export * from "./presentation/screens";
@@ -0,0 +1,169 @@
1
+ import React, { useState } from "react";
2
+ import {
3
+ View,
4
+ StyleSheet,
5
+ Image,
6
+ ActivityIndicator,
7
+ Alert,
8
+ } from "react-native";
9
+ import {
10
+ AtomicButton,
11
+ useAppDesignTokens,
12
+ AtomicIcon,
13
+ AtomicInput,
14
+ ScreenLayout,
15
+ ScreenHeader,
16
+ } from "@umituz/react-native-design-system";
17
+ import { useLocalization } from "@umituz/react-native-localization";
18
+
19
+ export interface MemeGeneratorScreenProps {
20
+ onGenerate: (prompt: string) => Promise<string>;
21
+ onSave: (imageUrl: string) => Promise<void>;
22
+ onBackPress: () => void;
23
+ title?: string;
24
+ }
25
+
26
+ export const MemeGeneratorScreen: React.FC<MemeGeneratorScreenProps> = ({
27
+ onGenerate,
28
+ onSave,
29
+ onBackPress,
30
+ title,
31
+ }) => {
32
+ const { t } = useLocalization();
33
+ const tokens = useAppDesignTokens();
34
+
35
+ const [prompt, setPrompt] = useState("");
36
+ const [generatedImage, setGeneratedImage] = useState<string | null>(null);
37
+ const [isGenerating, setIsGenerating] = useState(false);
38
+ const [isSaving, setIsSaving] = useState(false);
39
+
40
+ const handleGenerate = async () => {
41
+ if (!prompt.trim()) return;
42
+ setIsGenerating(true);
43
+ try {
44
+ const url = await onGenerate(prompt);
45
+ setGeneratedImage(url);
46
+ } catch (error: unknown) {
47
+ const errorMessage = error instanceof Error ? error.message : "Failed to generate";
48
+ Alert.alert(t("common.error"), errorMessage);
49
+ } finally {
50
+ setIsGenerating(false);
51
+ }
52
+ };
53
+
54
+ const handleSave = async () => {
55
+ if (!generatedImage) return;
56
+ setIsSaving(true);
57
+ try {
58
+ await onSave(generatedImage);
59
+ setGeneratedImage(null);
60
+ setPrompt("");
61
+ } catch (error: unknown) {
62
+ const errorMessage = error instanceof Error ? error.message : "Failed to save";
63
+ Alert.alert(t("common.error"), errorMessage);
64
+ } finally {
65
+ setIsSaving(false);
66
+ }
67
+ };
68
+
69
+ const styles = StyleSheet.create({
70
+ content: {
71
+ flex: 1,
72
+ padding: tokens.spacing.lg,
73
+ },
74
+ previewContainer: {
75
+ aspectRatio: 1,
76
+ width: "100%",
77
+ backgroundColor: tokens.colors.backgroundSecondary,
78
+ borderRadius: tokens.borderRadius.lg,
79
+ justifyContent: "center",
80
+ alignItems: "center",
81
+ marginBottom: tokens.spacing.xl,
82
+ overflow: "hidden",
83
+ borderWidth: 1,
84
+ borderColor: tokens.colors.border,
85
+ },
86
+ previewImage: {
87
+ width: "100%",
88
+ height: "100%",
89
+ },
90
+ inputSection: {
91
+ gap: tokens.spacing.lg,
92
+ paddingBottom: tokens.spacing.xxl,
93
+ },
94
+ });
95
+
96
+ return (
97
+ <ScreenLayout
98
+ header={
99
+ <ScreenHeader
100
+ title={title || t("home.create_title")}
101
+ onBackPress={onBackPress}
102
+ />
103
+ }
104
+ scrollable={true}
105
+ responsiveEnabled={false}
106
+ contentContainerStyle={{ paddingHorizontal: 0 }}
107
+ keyboardAvoiding={true}
108
+ >
109
+ <View style={styles.content}>
110
+ <View style={styles.previewContainer}>
111
+ {isGenerating ? (
112
+ <ActivityIndicator size="large" color={tokens.colors.primary} />
113
+ ) : generatedImage ? (
114
+ <Image
115
+ source={{ uri: generatedImage }}
116
+ style={styles.previewImage}
117
+ resizeMode="contain"
118
+ />
119
+ ) : (
120
+ <AtomicIcon
121
+ name="color-wand-outline"
122
+ size={80}
123
+ color="secondary"
124
+ style={{ opacity: 0.3 }}
125
+ />
126
+ )}
127
+ </View>
128
+
129
+ <View style={styles.inputSection}>
130
+ <AtomicInput
131
+ label={t("wizard.prompt_label")}
132
+ placeholder={t("wizard.prompt_placeholder")}
133
+ value={prompt}
134
+ onChangeText={setPrompt}
135
+ multiline
136
+ numberOfLines={3}
137
+ />
138
+
139
+ {!generatedImage ? (
140
+ <AtomicButton
141
+ onPress={handleGenerate}
142
+ disabled={isGenerating}
143
+ fullWidth
144
+ >
145
+ {isGenerating ? t("common.loading") : t("wizard.generate_button")}
146
+ </AtomicButton>
147
+ ) : (
148
+ <View style={{ flexDirection: "row", gap: tokens.spacing.md }}>
149
+ <AtomicButton
150
+ variant="secondary"
151
+ onPress={() => setGeneratedImage(null)}
152
+ style={{ flex: 1 }}
153
+ >
154
+ {t("common.reset")}
155
+ </AtomicButton>
156
+ <AtomicButton
157
+ onPress={handleSave}
158
+ disabled={isSaving}
159
+ style={{ flex: 2 }}
160
+ >
161
+ {t("common.save")}
162
+ </AtomicButton>
163
+ </View>
164
+ )}
165
+ </View>
166
+ </View>
167
+ </ScreenLayout>
168
+ );
169
+ };
@@ -0,0 +1 @@
1
+ export * from "./MemeGeneratorScreen";
package/src/index.ts CHANGED
@@ -532,6 +532,12 @@ export * from "./features/text-to-voice";
532
532
 
533
533
  export * from "./features/hd-touch-up";
534
534
 
535
+ // =============================================================================
536
+ // FEATURES - Meme Generator
537
+ // =============================================================================
538
+
539
+ export * from "./features/meme-generator";
540
+
535
541
  // =============================================================================
536
542
  // INFRASTRUCTURE - Orchestration
537
543
  // =============================================================================
@@ -49,11 +49,13 @@ export function createDevCallbacks(featureName: string) {
49
49
  return {
50
50
  onSuccess: (result: unknown) => {
51
51
  if (typeof __DEV__ !== "undefined" && __DEV__) {
52
+ // eslint-disable-next-line no-console
52
53
  console.log(`[${featureName}] Success:`, result);
53
54
  }
54
55
  },
55
56
  onError: (error: unknown) => {
56
57
  if (typeof __DEV__ !== "undefined" && __DEV__) {
58
+ // eslint-disable-next-line no-console
57
59
  console.error(`[${featureName}] Error:`, error);
58
60
  }
59
61
  },
@@ -8,6 +8,11 @@
8
8
  */
9
9
  export type VideoAlertFunction = (title: string, message: string) => void;
10
10
 
11
+ /**
12
+ * Navigation function type for success actions
13
+ */
14
+ export type VideoNavigationFunction = () => void;
15
+
11
16
  /**
12
17
  * Default no-op alert function
13
18
  */
@@ -17,14 +22,29 @@ const noOpAlert: VideoAlertFunction = () => {
17
22
 
18
23
  /**
19
24
  * Show video generation success
25
+ * Supports both alert-based and navigation-based success handling
20
26
  */
21
27
  export function showVideoGenerationSuccess(
22
- showAlert: VideoAlertFunction = noOpAlert
28
+ onViewProjects?: VideoNavigationFunction | VideoAlertFunction,
29
+ onEditVideo?: VideoNavigationFunction,
23
30
  ): void {
24
31
  if (typeof __DEV__ !== "undefined" && __DEV__) {
32
+ // eslint-disable-next-line no-console
25
33
  console.log("[VideoGeneration] Success");
26
34
  }
27
- showAlert("Success", "Your video has been generated successfully!");
35
+
36
+ // If both callbacks are provided, they're navigation functions
37
+ if (onViewProjects && onEditVideo) {
38
+ // This is the navigation pattern - no alert needed
39
+ // The app will handle navigation
40
+ return;
41
+ }
42
+
43
+ // If only one callback is provided, treat it as an alert function
44
+ if (onViewProjects && typeof onViewProjects === "function") {
45
+ const showAlert = onViewProjects as VideoAlertFunction;
46
+ showAlert("Success", "Your video has been generated successfully!");
47
+ }
28
48
  }
29
49
 
30
50
  /**
@@ -37,6 +57,7 @@ export function handleGenerationError(
37
57
  const message = error instanceof Error ? error.message : "An error occurred";
38
58
 
39
59
  if (typeof __DEV__ !== "undefined" && __DEV__) {
60
+ // eslint-disable-next-line no-console
40
61
  console.error("[VideoGeneration] Error:", error);
41
62
  }
42
63
 
@@ -51,6 +72,7 @@ export function showContentModerationWarning(
51
72
  reason?: string
52
73
  ): void {
53
74
  if (typeof __DEV__ !== "undefined" && __DEV__) {
75
+ // eslint-disable-next-line no-console
54
76
  console.warn("[VideoGeneration] Content moderation warning:", reason);
55
77
  }
56
78