@umituz/react-native-ai-generation-content 1.17.78 → 1.17.80

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.78",
3
+ "version": "1.17.80",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -37,6 +37,6 @@ declare module "@umituz/react-native-firestore" {
37
37
  export function isFirestoreInitialized(): boolean;
38
38
  }
39
39
 
40
- declare module "@umituz/react-native-sentry";
40
+
41
41
  declare module "expo-apple-authentication";
42
42
  declare module "@umituz/react-native-filesystem";
@@ -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
  },
@@ -29,6 +29,7 @@ export function showVideoGenerationSuccess(
29
29
  onEditVideo?: VideoNavigationFunction,
30
30
  ): void {
31
31
  if (typeof __DEV__ !== "undefined" && __DEV__) {
32
+ // eslint-disable-next-line no-console
32
33
  console.log("[VideoGeneration] Success");
33
34
  }
34
35
 
@@ -56,6 +57,7 @@ export function handleGenerationError(
56
57
  const message = error instanceof Error ? error.message : "An error occurred";
57
58
 
58
59
  if (typeof __DEV__ !== "undefined" && __DEV__) {
60
+ // eslint-disable-next-line no-console
59
61
  console.error("[VideoGeneration] Error:", error);
60
62
  }
61
63
 
@@ -70,6 +72,7 @@ export function showContentModerationWarning(
70
72
  reason?: string
71
73
  ): void {
72
74
  if (typeof __DEV__ !== "undefined" && __DEV__) {
75
+ // eslint-disable-next-line no-console
73
76
  console.warn("[VideoGeneration] Content moderation warning:", reason);
74
77
  }
75
78