@umituz/react-native-ai-generation-content 1.17.21 → 1.17.23
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/domains/creations/domain/types/creation-filter.ts +16 -18
- package/src/domains/creations/domain/value-objects/CreationsConfig.ts +12 -0
- package/src/domains/creations/presentation/components/FilterSheets.tsx +63 -0
- package/src/domains/creations/presentation/components/GalleryHeader.tsx +95 -93
- package/src/domains/creations/presentation/components/index.ts +1 -0
- package/src/domains/creations/presentation/hooks/index.ts +3 -0
- package/src/domains/creations/presentation/hooks/useCreationsFilter.ts +35 -48
- package/src/domains/creations/presentation/hooks/useGalleryFilters.ts +78 -0
- package/src/domains/creations/presentation/hooks/useMediaFilter.ts +54 -0
- package/src/domains/creations/presentation/hooks/useStatusFilter.ts +54 -0
- package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +81 -156
- package/src/features/image-to-video/index.ts +90 -3
- package/src/features/image-to-video/presentation/components/AnimationStyleSelector.tsx +135 -0
- package/src/features/image-to-video/presentation/components/DurationSelector.tsx +110 -0
- package/src/features/image-to-video/presentation/components/GenerateButton.tsx +95 -0
- package/src/features/image-to-video/presentation/components/HeroSection.tsx +89 -0
- package/src/features/image-to-video/presentation/components/ImageSelectionGrid.tsx +234 -0
- package/src/features/image-to-video/presentation/components/MusicMoodSelector.tsx +181 -0
- package/src/features/image-to-video/presentation/components/index.ts +30 -0
- package/src/features/image-to-video/presentation/hooks/index.ts +22 -0
- package/src/features/image-to-video/presentation/hooks/useFormState.ts +116 -0
- package/src/features/image-to-video/presentation/hooks/useGeneration.ts +85 -0
- package/src/features/image-to-video/presentation/hooks/useImageToVideoForm.ts +93 -0
- package/src/features/image-to-video/presentation/index.ts +4 -0
- package/src/features/text-to-video/domain/types/callback.types.ts +50 -0
- package/src/features/text-to-video/domain/types/component.types.ts +106 -0
- package/src/features/text-to-video/domain/types/config.types.ts +61 -0
- package/src/features/text-to-video/domain/types/index.ts +48 -4
- package/src/features/text-to-video/domain/types/request.types.ts +36 -0
- package/src/features/text-to-video/domain/types/state.types.ts +53 -0
- package/src/features/text-to-video/index.ts +41 -3
- package/src/features/text-to-video/infrastructure/services/text-to-video-executor.ts +1 -1
- package/src/features/text-to-video/presentation/components/FrameSelector.tsx +153 -0
- package/src/features/text-to-video/presentation/components/GenerationTabs.tsx +73 -0
- package/src/features/text-to-video/presentation/components/HeroSection.tsx +67 -0
- package/src/features/text-to-video/presentation/components/HintCarousel.tsx +96 -0
- package/src/features/text-to-video/presentation/components/OptionsPanel.tsx +123 -0
- package/src/features/text-to-video/presentation/components/index.ts +10 -0
- package/src/features/text-to-video/presentation/hooks/index.ts +11 -0
- package/src/features/text-to-video/presentation/hooks/useTextToVideoFeature.ts +77 -20
- package/src/features/text-to-video/presentation/hooks/useTextToVideoForm.ts +134 -0
- package/src/features/text-to-video/presentation/index.ts +6 -0
- package/src/features/text-to-video/domain/types/text-to-video.types.ts +0 -65
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* useTextToVideoFeature Hook
|
|
3
|
+
* Single Responsibility: Orchestrate text-to-video generation with callbacks
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { useState, useCallback } from "react";
|
|
6
|
+
import { useState, useCallback, useMemo } from "react";
|
|
7
7
|
import { executeTextToVideo } from "../../infrastructure/services";
|
|
8
8
|
import type {
|
|
9
9
|
TextToVideoFeatureState,
|
|
10
|
-
|
|
10
|
+
TextToVideoConfig,
|
|
11
|
+
TextToVideoCallbacks,
|
|
11
12
|
TextToVideoResult,
|
|
12
13
|
TextToVideoOptions,
|
|
14
|
+
TextToVideoInputBuilder,
|
|
15
|
+
TextToVideoResultExtractor,
|
|
13
16
|
} from "../../domain/types";
|
|
14
17
|
|
|
18
|
+
declare const __DEV__: boolean;
|
|
19
|
+
|
|
15
20
|
export interface UseTextToVideoFeatureProps {
|
|
16
|
-
config:
|
|
21
|
+
config: TextToVideoConfig;
|
|
22
|
+
callbacks: TextToVideoCallbacks;
|
|
17
23
|
userId: string;
|
|
24
|
+
buildInput: TextToVideoInputBuilder;
|
|
25
|
+
extractResult?: TextToVideoResultExtractor;
|
|
18
26
|
}
|
|
19
27
|
|
|
20
28
|
export interface UseTextToVideoFeatureReturn {
|
|
@@ -23,9 +31,10 @@ export interface UseTextToVideoFeatureReturn {
|
|
|
23
31
|
generate: (options?: TextToVideoOptions) => Promise<TextToVideoResult>;
|
|
24
32
|
reset: () => void;
|
|
25
33
|
isReady: boolean;
|
|
34
|
+
canGenerate: boolean;
|
|
26
35
|
}
|
|
27
36
|
|
|
28
|
-
const
|
|
37
|
+
const INITIAL_STATE: TextToVideoFeatureState = {
|
|
29
38
|
prompt: "",
|
|
30
39
|
videoUrl: null,
|
|
31
40
|
thumbnailUrl: null,
|
|
@@ -37,25 +46,61 @@ const initialState: TextToVideoFeatureState = {
|
|
|
37
46
|
export function useTextToVideoFeature(
|
|
38
47
|
props: UseTextToVideoFeatureProps,
|
|
39
48
|
): UseTextToVideoFeatureReturn {
|
|
40
|
-
const { config, userId } = props;
|
|
41
|
-
const [state, setState] = useState<TextToVideoFeatureState>(
|
|
49
|
+
const { config, callbacks, userId, buildInput, extractResult } = props;
|
|
50
|
+
const [state, setState] = useState<TextToVideoFeatureState>(INITIAL_STATE);
|
|
42
51
|
|
|
43
52
|
const setPrompt = useCallback(
|
|
44
53
|
(prompt: string) => {
|
|
45
54
|
setState((prev) => ({ ...prev, prompt, error: null }));
|
|
46
|
-
|
|
55
|
+
callbacks.onPromptChange?.(prompt);
|
|
47
56
|
},
|
|
48
|
-
[
|
|
57
|
+
[callbacks],
|
|
49
58
|
);
|
|
50
59
|
|
|
51
60
|
const generate = useCallback(
|
|
52
61
|
async (options?: TextToVideoOptions): Promise<TextToVideoResult> => {
|
|
53
|
-
if (!state.prompt) {
|
|
62
|
+
if (!state.prompt.trim()) {
|
|
54
63
|
const error = "Prompt is required";
|
|
55
64
|
setState((prev) => ({ ...prev, error }));
|
|
65
|
+
callbacks.onError?.(error);
|
|
56
66
|
return { success: false, error };
|
|
57
67
|
}
|
|
58
68
|
|
|
69
|
+
if (callbacks.onAuthCheck && !callbacks.onAuthCheck()) {
|
|
70
|
+
return { success: false, error: "Authentication required" };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (callbacks.onCreditCheck && !callbacks.onCreditCheck(config.creditCost)) {
|
|
74
|
+
callbacks.onShowPaywall?.(config.creditCost);
|
|
75
|
+
return { success: false, error: "Insufficient credits" };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (callbacks.onModeration) {
|
|
79
|
+
const moderationResult = await callbacks.onModeration(state.prompt);
|
|
80
|
+
if (!moderationResult.isAllowed && moderationResult.warnings.length > 0) {
|
|
81
|
+
return new Promise((resolve) => {
|
|
82
|
+
callbacks.onShowModerationWarning?.(
|
|
83
|
+
moderationResult.warnings,
|
|
84
|
+
() => {
|
|
85
|
+
setState((prev) => ({ ...prev, isProcessing: false }));
|
|
86
|
+
resolve({ success: false, error: "Content policy violation" });
|
|
87
|
+
},
|
|
88
|
+
async () => {
|
|
89
|
+
const result = await executeGeneration(options);
|
|
90
|
+
resolve(result);
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return executeGeneration(options);
|
|
98
|
+
},
|
|
99
|
+
[state.prompt, callbacks, config.creditCost, buildInput, extractResult, userId],
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const executeGeneration = useCallback(
|
|
103
|
+
async (options?: TextToVideoOptions): Promise<TextToVideoResult> => {
|
|
59
104
|
setState((prev) => ({
|
|
60
105
|
...prev,
|
|
61
106
|
isProcessing: true,
|
|
@@ -63,16 +108,20 @@ export function useTextToVideoFeature(
|
|
|
63
108
|
error: null,
|
|
64
109
|
}));
|
|
65
110
|
|
|
66
|
-
|
|
111
|
+
if (__DEV__) {
|
|
112
|
+
// eslint-disable-next-line no-console
|
|
113
|
+
console.log("[TextToVideoFeature] Starting generation");
|
|
114
|
+
}
|
|
67
115
|
|
|
68
116
|
const result = await executeTextToVideo(
|
|
69
117
|
{ prompt: state.prompt, userId, options },
|
|
70
118
|
{
|
|
71
119
|
model: config.model,
|
|
72
|
-
buildInput
|
|
73
|
-
extractResult
|
|
120
|
+
buildInput,
|
|
121
|
+
extractResult,
|
|
74
122
|
onProgress: (progress) => {
|
|
75
123
|
setState((prev) => ({ ...prev, progress }));
|
|
124
|
+
callbacks.onProgress?.(progress);
|
|
76
125
|
},
|
|
77
126
|
},
|
|
78
127
|
);
|
|
@@ -85,6 +134,7 @@ export function useTextToVideoFeature(
|
|
|
85
134
|
isProcessing: false,
|
|
86
135
|
progress: 100,
|
|
87
136
|
}));
|
|
137
|
+
callbacks.onGenerate?.(result);
|
|
88
138
|
} else {
|
|
89
139
|
const error = result.error || "Generation failed";
|
|
90
140
|
setState((prev) => ({
|
|
@@ -92,20 +142,27 @@ export function useTextToVideoFeature(
|
|
|
92
142
|
isProcessing: false,
|
|
93
143
|
error,
|
|
94
144
|
}));
|
|
95
|
-
|
|
145
|
+
callbacks.onError?.(error);
|
|
96
146
|
}
|
|
97
147
|
|
|
98
|
-
config.onProcessingComplete?.(result);
|
|
99
148
|
return result;
|
|
100
149
|
},
|
|
101
|
-
[state.prompt, userId, config],
|
|
150
|
+
[state.prompt, userId, config.model, buildInput, extractResult, callbacks],
|
|
102
151
|
);
|
|
103
152
|
|
|
104
153
|
const reset = useCallback(() => {
|
|
105
|
-
setState(
|
|
154
|
+
setState(INITIAL_STATE);
|
|
106
155
|
}, []);
|
|
107
156
|
|
|
108
|
-
const isReady =
|
|
157
|
+
const isReady = useMemo(
|
|
158
|
+
() => state.prompt.trim().length > 0 && !state.isProcessing,
|
|
159
|
+
[state.prompt, state.isProcessing],
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
const canGenerate = useMemo(
|
|
163
|
+
() => isReady && !state.error,
|
|
164
|
+
[isReady, state.error],
|
|
165
|
+
);
|
|
109
166
|
|
|
110
|
-
return { state, setPrompt, generate, reset, isReady };
|
|
167
|
+
return { state, setPrompt, generate, reset, isReady, canGenerate };
|
|
111
168
|
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useTextToVideoForm Hook
|
|
3
|
+
* Single Responsibility: Manage text-to-video form state
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useState, useCallback } from "react";
|
|
7
|
+
import type {
|
|
8
|
+
TextToVideoFormState,
|
|
9
|
+
FrameData,
|
|
10
|
+
} from "../../domain/types";
|
|
11
|
+
import { INITIAL_FORM_STATE } from "../../domain/types";
|
|
12
|
+
|
|
13
|
+
declare const __DEV__: boolean;
|
|
14
|
+
|
|
15
|
+
export interface UseTextToVideoFormProps {
|
|
16
|
+
initialValues?: Partial<TextToVideoFormState>;
|
|
17
|
+
onPromptChange?: (prompt: string) => void;
|
|
18
|
+
onStyleChange?: (style: string) => void;
|
|
19
|
+
onTabChange?: (tab: string) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface UseTextToVideoFormReturn {
|
|
23
|
+
state: TextToVideoFormState;
|
|
24
|
+
frames: FrameData[];
|
|
25
|
+
setPrompt: (prompt: string) => void;
|
|
26
|
+
setStyle: (style: string) => void;
|
|
27
|
+
setAspectRatio: (ratio: string) => void;
|
|
28
|
+
setDuration: (duration: number) => void;
|
|
29
|
+
setActiveTab: (tab: string) => void;
|
|
30
|
+
setSoundEnabled: (enabled: boolean) => void;
|
|
31
|
+
setProfessionalMode: (enabled: boolean) => void;
|
|
32
|
+
setFrames: (frames: FrameData[]) => void;
|
|
33
|
+
handleFrameChange: (index: number) => void;
|
|
34
|
+
handleFrameDelete: (index: number) => void;
|
|
35
|
+
selectExamplePrompt: (prompt: string) => void;
|
|
36
|
+
reset: () => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function useTextToVideoForm(
|
|
40
|
+
props: UseTextToVideoFormProps = {},
|
|
41
|
+
): UseTextToVideoFormReturn {
|
|
42
|
+
const { initialValues, onPromptChange, onStyleChange, onTabChange } = props;
|
|
43
|
+
|
|
44
|
+
const [state, setState] = useState<TextToVideoFormState>({
|
|
45
|
+
...INITIAL_FORM_STATE,
|
|
46
|
+
...initialValues,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const [frames, setFrames] = useState<FrameData[]>([]);
|
|
50
|
+
|
|
51
|
+
const setPrompt = useCallback(
|
|
52
|
+
(prompt: string) => {
|
|
53
|
+
setState((prev) => ({ ...prev, prompt }));
|
|
54
|
+
onPromptChange?.(prompt);
|
|
55
|
+
},
|
|
56
|
+
[onPromptChange],
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const setStyle = useCallback(
|
|
60
|
+
(style: string) => {
|
|
61
|
+
setState((prev) => ({ ...prev, style }));
|
|
62
|
+
onStyleChange?.(style);
|
|
63
|
+
},
|
|
64
|
+
[onStyleChange],
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const setAspectRatio = useCallback((aspectRatio: string) => {
|
|
68
|
+
setState((prev) => ({ ...prev, aspectRatio }));
|
|
69
|
+
}, []);
|
|
70
|
+
|
|
71
|
+
const setDuration = useCallback((duration: number) => {
|
|
72
|
+
setState((prev) => ({ ...prev, duration }));
|
|
73
|
+
}, []);
|
|
74
|
+
|
|
75
|
+
const setActiveTab = useCallback(
|
|
76
|
+
(activeTab: string) => {
|
|
77
|
+
setState((prev) => ({ ...prev, activeTab }));
|
|
78
|
+
onTabChange?.(activeTab);
|
|
79
|
+
},
|
|
80
|
+
[onTabChange],
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const setSoundEnabled = useCallback((soundEnabled: boolean) => {
|
|
84
|
+
setState((prev) => ({ ...prev, soundEnabled }));
|
|
85
|
+
}, []);
|
|
86
|
+
|
|
87
|
+
const setProfessionalMode = useCallback((professionalMode: boolean) => {
|
|
88
|
+
setState((prev) => ({ ...prev, professionalMode }));
|
|
89
|
+
}, []);
|
|
90
|
+
|
|
91
|
+
const handleFrameChange = useCallback((index: number) => {
|
|
92
|
+
if (__DEV__) {
|
|
93
|
+
// eslint-disable-next-line no-console
|
|
94
|
+
console.log("[TextToVideoForm] Frame change requested:", index);
|
|
95
|
+
}
|
|
96
|
+
}, []);
|
|
97
|
+
|
|
98
|
+
const handleFrameDelete = useCallback(
|
|
99
|
+
(index: number) => {
|
|
100
|
+
const newFrames = frames.filter((f) => f.order !== index);
|
|
101
|
+
setFrames(newFrames);
|
|
102
|
+
},
|
|
103
|
+
[frames],
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const selectExamplePrompt = useCallback(
|
|
107
|
+
(prompt: string) => {
|
|
108
|
+
setPrompt(prompt);
|
|
109
|
+
},
|
|
110
|
+
[setPrompt],
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const reset = useCallback(() => {
|
|
114
|
+
setState({ ...INITIAL_FORM_STATE, ...initialValues });
|
|
115
|
+
setFrames([]);
|
|
116
|
+
}, [initialValues]);
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
state,
|
|
120
|
+
frames,
|
|
121
|
+
setPrompt,
|
|
122
|
+
setStyle,
|
|
123
|
+
setAspectRatio,
|
|
124
|
+
setDuration,
|
|
125
|
+
setActiveTab,
|
|
126
|
+
setSoundEnabled,
|
|
127
|
+
setProfessionalMode,
|
|
128
|
+
setFrames,
|
|
129
|
+
handleFrameChange,
|
|
130
|
+
handleFrameDelete,
|
|
131
|
+
selectExamplePrompt,
|
|
132
|
+
reset,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Text-to-Video Feature Types
|
|
3
|
-
* Request, Result, Config types for text-to-video generation
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface TextToVideoOptions {
|
|
7
|
-
duration?: number;
|
|
8
|
-
fps?: number;
|
|
9
|
-
guidanceScale?: number;
|
|
10
|
-
aspectRatio?: "16:9" | "9:16" | "1:1";
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface TextToVideoRequest {
|
|
14
|
-
prompt: string;
|
|
15
|
-
userId: string;
|
|
16
|
-
negativePrompt?: string;
|
|
17
|
-
options?: TextToVideoOptions;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface TextToVideoResult {
|
|
21
|
-
success: boolean;
|
|
22
|
-
videoUrl?: string;
|
|
23
|
-
thumbnailUrl?: string;
|
|
24
|
-
error?: string;
|
|
25
|
-
requestId?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface TextToVideoFeatureState {
|
|
29
|
-
prompt: string;
|
|
30
|
-
videoUrl: string | null;
|
|
31
|
-
thumbnailUrl: string | null;
|
|
32
|
-
isProcessing: boolean;
|
|
33
|
-
progress: number;
|
|
34
|
-
error: string | null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface TextToVideoTranslations {
|
|
38
|
-
promptPlaceholder: string;
|
|
39
|
-
generateButtonText: string;
|
|
40
|
-
processingText: string;
|
|
41
|
-
successText: string;
|
|
42
|
-
saveButtonText: string;
|
|
43
|
-
tryAnotherText: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export type TextToVideoInputBuilder = (
|
|
47
|
-
prompt: string,
|
|
48
|
-
options?: TextToVideoOptions,
|
|
49
|
-
) => Record<string, unknown>;
|
|
50
|
-
|
|
51
|
-
export type TextToVideoResultExtractor = (
|
|
52
|
-
result: unknown,
|
|
53
|
-
) => { videoUrl?: string; thumbnailUrl?: string } | undefined;
|
|
54
|
-
|
|
55
|
-
export interface TextToVideoFeatureConfig {
|
|
56
|
-
providerId?: string;
|
|
57
|
-
creditCost?: number;
|
|
58
|
-
model: string;
|
|
59
|
-
buildInput: TextToVideoInputBuilder;
|
|
60
|
-
extractResult?: TextToVideoResultExtractor;
|
|
61
|
-
onPromptChange?: (prompt: string) => void;
|
|
62
|
-
onProcessingStart?: () => void;
|
|
63
|
-
onProcessingComplete?: (result: TextToVideoResult) => void;
|
|
64
|
-
onError?: (error: string) => void;
|
|
65
|
-
}
|