@umituz/react-native-ai-generation-content 1.17.78 → 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 +1 -1
- package/src/features/meme-generator/index.ts +1 -0
- package/src/features/meme-generator/presentation/screens/MemeGeneratorScreen.tsx +169 -0
- package/src/features/meme-generator/presentation/screens/index.ts +1 -0
- package/src/index.ts +6 -0
- package/src/infrastructure/utils/feature-utils.ts +2 -0
- package/src/infrastructure/utils/video-helpers.ts +3 -0
package/package.json
CHANGED
|
@@ -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
|
|