@umituz/react-native-ai-generation-content 1.17.40 → 1.17.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.17.40",
3
+ "version": "1.17.42",
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,10 @@
1
+ import { VideoTypeOption } from "../presentation/components/VideoTypeSelector";
2
+
3
+ export const DEFAULT_VIDEO_TYPES: readonly VideoTypeOption[] = [
4
+ { id: "product", name: "Product Demo", emoji: "📦" },
5
+ { id: "tutorial", name: "Tutorial", emoji: "🎓" },
6
+ { id: "promo", name: "Promo/Ad", emoji: "📣" },
7
+ { id: "story", name: "Storytelling", emoji: "📖" },
8
+ { id: "explainer", name: "Explainer", emoji: "💡" },
9
+ { id: "vlog", name: "Vlog", emoji: "🎥" },
10
+ ];
@@ -1,2 +1,5 @@
1
1
  export * from "./domain/types/script.types";
2
+ export * from "./domain/constants";
2
3
  export * from "./presentation/components";
4
+ export * from "./presentation/hooks";
5
+ export * from "./infrastructure/services/ScriptGenerationService";
@@ -0,0 +1,62 @@
1
+ import {
2
+ ScriptSection,
3
+ ScriptGenerationRequest,
4
+ } from "../domain/types/script.types";
5
+ import { DEFAULT_VIDEO_TYPES } from "../domain/constants";
6
+
7
+ /**
8
+ * ScriptGenerationService
9
+ * Handles building prompts and (eventually) calling AI providers for script generation.
10
+ */
11
+ export class ScriptGenerationService {
12
+ /**
13
+ * Build prompt for script generation
14
+ */
15
+ buildScriptPrompt(request: ScriptGenerationRequest): string {
16
+ const typeInfo = DEFAULT_VIDEO_TYPES.find((t) => t.id === request.videoType);
17
+
18
+ return `Generate a video script for a ${request.duration}-second ${typeInfo?.name || "video"} about: ${request.topic}
19
+
20
+ ${request.targetAudience ? `Target Audience: ${request.targetAudience}` : ""}
21
+ ${request.keyPoints ? `Key Points to Cover: ${request.keyPoints}` : ""}
22
+
23
+ Please create a detailed script with the following structure:
24
+ 1. Hook (3-5 seconds): Attention-grabbing opening
25
+ 2. Introduction (5-10 seconds): Brief intro to the topic
26
+ 3. Main Content (${request.duration - 15} seconds): Core message and value
27
+ 4. Call-to-Action (5 seconds): Clear next step for viewers
28
+
29
+ For each section, provide:
30
+ - Section title
31
+ - Voiceover text
32
+ - Duration in seconds
33
+ - Visual/scene suggestions
34
+
35
+ Format as JSON with this structure:
36
+ {
37
+ "sections": [
38
+ {
39
+ "type": "hook|intro|main|cta",
40
+ "title": "Section title",
41
+ "content": "Voiceover text",
42
+ "duration": 5,
43
+ "notes": "Visual suggestions"
44
+ }
45
+ ],
46
+ "totalDuration": ${request.duration}
47
+ }`;
48
+ }
49
+
50
+ /**
51
+ * Generate script from request
52
+ */
53
+ async generateScript(
54
+ request: ScriptGenerationRequest,
55
+ ): Promise<readonly ScriptSection[] | null> {
56
+ // NOTE: This will be implemented by the app using a specific AI provider (like OpenAI or FAL)
57
+ // The package provides the structure and prompt building.
58
+ return null;
59
+ }
60
+ }
61
+
62
+ export const scriptGenerationService = new ScriptGenerationService();
@@ -0,0 +1 @@
1
+ export * from "./useScriptGenerator";
@@ -0,0 +1,74 @@
1
+ import { useState, useCallback } from "react";
2
+ import {
3
+ ScriptSection,
4
+ ScriptGenerationRequest,
5
+ } from "../../domain/types/script.types";
6
+
7
+ export interface UseScriptGeneratorProps {
8
+ readonly onGenerate: (request: ScriptGenerationRequest) => Promise<readonly ScriptSection[] | null>;
9
+ readonly onUseScript?: (script: readonly ScriptSection[]) => void;
10
+ readonly onAuthRequired?: () => void;
11
+ }
12
+
13
+ export interface UseScriptGeneratorReturn {
14
+ readonly isGenerating: boolean;
15
+ readonly generatedScript: readonly ScriptSection[] | null;
16
+ readonly generateScript: (request: ScriptGenerationRequest) => Promise<void>;
17
+ readonly handleUseScript: () => void;
18
+ readonly resetState: () => void;
19
+ }
20
+
21
+ export function useScriptGenerator({
22
+ onGenerate,
23
+ onUseScript,
24
+ onAuthRequired,
25
+ }: UseScriptGeneratorProps): UseScriptGeneratorReturn {
26
+ const [isGenerating, setIsGenerating] = useState(false);
27
+ const [generatedScript, setGeneratedScript] = useState<readonly ScriptSection[] | null>(null);
28
+
29
+ const generateScript = useCallback(
30
+ async (request: ScriptGenerationRequest) => {
31
+ if (!request.topic.trim()) {
32
+ return;
33
+ }
34
+
35
+ if (onAuthRequired) {
36
+ onAuthRequired();
37
+ }
38
+
39
+ setIsGenerating(true);
40
+
41
+ try {
42
+ const script = await onGenerate(request);
43
+
44
+ if (script) {
45
+ setGeneratedScript(script);
46
+ }
47
+ } catch (error) {
48
+ console.error("Script generation error:", error);
49
+ } finally {
50
+ setIsGenerating(false);
51
+ }
52
+ },
53
+ [onGenerate, onAuthRequired],
54
+ );
55
+
56
+ const handleUseScript = useCallback(() => {
57
+ if (generatedScript && onUseScript) {
58
+ onUseScript(generatedScript);
59
+ }
60
+ }, [generatedScript, onUseScript]);
61
+
62
+ const resetState = useCallback(() => {
63
+ setGeneratedScript(null);
64
+ setIsGenerating(false);
65
+ }, []);
66
+
67
+ return {
68
+ isGenerating,
69
+ generatedScript,
70
+ generateScript,
71
+ handleUseScript,
72
+ resetState,
73
+ };
74
+ }
package/src/index.ts CHANGED
@@ -295,6 +295,7 @@ export {
295
295
  StyleSelector,
296
296
  AspectRatioSelector,
297
297
  DurationSelector,
298
+ StylePresetsGrid,
298
299
  } from "./presentation/components";
299
300
 
300
301
  export type {
@@ -326,6 +327,8 @@ export type {
326
327
  AIGenerationProgressInlineProps,
327
328
  PromptInputProps,
328
329
  AIGenerationHeroProps,
330
+ StylePresetsGridProps,
331
+ StylePreset,
329
332
  // Buttons
330
333
  GenerateButtonProps,
331
334
  // Display
@@ -0,0 +1,131 @@
1
+ /**
2
+ * StylePresetsGrid Component
3
+ * Generic grid of preset styles with emojis, names, and optional duration badges.
4
+ */
5
+
6
+ import React from "react";
7
+ import { View, TouchableOpacity, Text, StyleSheet } from "react-native";
8
+ import {
9
+ AtomicText,
10
+ useAppDesignTokens,
11
+ } from "@umituz/react-native-design-system";
12
+
13
+ export interface StylePreset {
14
+ readonly id: string;
15
+ readonly name: string;
16
+ readonly emoji: string;
17
+ readonly description: string;
18
+ readonly duration?: number;
19
+ }
20
+
21
+ export interface StylePresetsGridProps {
22
+ readonly presets: readonly StylePreset[];
23
+ readonly onPresetPress: (preset: StylePreset) => void;
24
+ readonly disabled?: boolean;
25
+ readonly title?: string;
26
+ }
27
+
28
+ export const StylePresetsGrid: React.FC<StylePresetsGridProps> = ({
29
+ presets,
30
+ onPresetPress,
31
+ disabled = false,
32
+ title = "Quick Start - Choose a Style",
33
+ }) => {
34
+ const tokens = useAppDesignTokens();
35
+
36
+ return (
37
+ <View style={styles.section}>
38
+ <AtomicText
39
+ type="bodyMedium"
40
+ style={[styles.title, { color: tokens.colors.textPrimary }]}
41
+ >
42
+ ⚡ {title}
43
+ </AtomicText>
44
+ <View style={styles.grid}>
45
+ {presets.map((preset) => (
46
+ <TouchableOpacity
47
+ key={preset.id}
48
+ style={[
49
+ styles.card,
50
+ { backgroundColor: tokens.colors.surface },
51
+ ]}
52
+ onPress={() => onPresetPress(preset)}
53
+ disabled={disabled}
54
+ >
55
+ <View style={styles.cardHeader}>
56
+ <Text style={styles.emoji}>{preset.emoji}</Text>
57
+ {preset.duration !== undefined && (
58
+ <View
59
+ style={[
60
+ styles.badge,
61
+ { backgroundColor: tokens.colors.primary + "20" },
62
+ ]}
63
+ >
64
+ <AtomicText
65
+ type="labelSmall"
66
+ style={{ color: tokens.colors.primary, fontSize: 10 }}
67
+ >
68
+ {preset.duration}s
69
+ </AtomicText>
70
+ </View>
71
+ )}
72
+ </View>
73
+ <AtomicText
74
+ type="bodyMedium"
75
+ style={[styles.cardTitle, { color: tokens.colors.textPrimary }]}
76
+ >
77
+ {preset.name}
78
+ </AtomicText>
79
+ <AtomicText
80
+ type="labelSmall"
81
+ style={{ color: tokens.colors.textSecondary, marginTop: 4 }}
82
+ >
83
+ {preset.description}
84
+ </AtomicText>
85
+ </TouchableOpacity>
86
+ ))}
87
+ </View>
88
+ </View>
89
+ );
90
+ };
91
+
92
+ const styles = StyleSheet.create({
93
+ section: {
94
+ padding: 16,
95
+ width: "100%",
96
+ },
97
+ title: {
98
+ fontWeight: "600",
99
+ marginBottom: 16,
100
+ },
101
+ grid: {
102
+ flexDirection: "row",
103
+ flexWrap: "wrap",
104
+ gap: 12,
105
+ },
106
+ card: {
107
+ flex: 1,
108
+ minWidth: "47%",
109
+ padding: 16,
110
+ borderRadius: 16,
111
+ borderWidth: 1,
112
+ borderColor: "rgba(0,0,0,0.05)",
113
+ },
114
+ cardHeader: {
115
+ flexDirection: "row",
116
+ alignItems: "center",
117
+ justifyContent: "space-between",
118
+ },
119
+ emoji: {
120
+ fontSize: 40,
121
+ },
122
+ badge: {
123
+ paddingHorizontal: 8,
124
+ paddingVertical: 4,
125
+ borderRadius: 12,
126
+ },
127
+ cardTitle: {
128
+ fontWeight: "600",
129
+ marginTop: 8,
130
+ },
131
+ });
@@ -7,6 +7,7 @@ export { PendingJobCardActions } from "./PendingJobCardActions";
7
7
  export { AIGenerationProgressInline } from "./AIGenerationProgressInline";
8
8
  export { PromptInput } from "./PromptInput";
9
9
  export { AIGenerationHero } from "./AIGenerationHero";
10
+ export * from "./StylePresetsGrid";
10
11
 
11
12
  export type {
12
13
  GenerationProgressModalProps,