@umituz/react-native-ai-generation-content 1.61.4 → 1.61.6

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.61.4",
3
+ "version": "1.61.6",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
package/src/index.ts CHANGED
@@ -64,7 +64,6 @@ export {
64
64
  extractAudioUrl, extractImageUrls, cleanBase64, addBase64Prefix, preparePhoto, preparePhotos,
65
65
  isValidBase64, getBase64Size, getBase64SizeMB, prepareImage, createDevCallbacks, createFeatureUtils,
66
66
  showVideoGenerationSuccess, handleGenerationError, showContentModerationWarning,
67
- saveMediaToGallery, shareMedia, createSaveHandler, createShareHandler, createMediaHandlers,
68
67
  mapJobStatusToGenerationStatus,
69
68
  } from "./infrastructure/utils";
70
69
 
@@ -73,7 +72,6 @@ export { distinctBy } from "./utils/arrayUtils";
73
72
  export type {
74
73
  IntervalOptions, StatusCheckResult, ResultValidation, ValidateResultOptions,
75
74
  PhotoInput, PreparedImage, ImageSelector, VideoSaver, AlertFunction, FeatureUtilsConfig, VideoAlertFunction,
76
- MediaActionResult, MediaActionTranslations, ToastConfig,
77
75
  } from "./infrastructure/utils";
78
76
 
79
77
  export {
@@ -12,5 +12,4 @@ export * from "./url-extractor.util";
12
12
  export * from "./photo-generation";
13
13
  export * from "./feature-utils";
14
14
  export * from "./video-helpers";
15
- export * from "./media-actions.util";
16
15
  export * from "./provider-validator.util";
@@ -34,6 +34,7 @@ export const AIGenerationForm: React.FC<AIGenerationFormProps> = ({
34
34
  onGenerate,
35
35
  isGenerating,
36
36
  hideGenerateButton,
37
+ isDisabled,
37
38
  generateButtonProps,
38
39
  showAdvanced,
39
40
  onAdvancedToggle,
@@ -48,7 +49,9 @@ export const AIGenerationForm: React.FC<AIGenerationFormProps> = ({
48
49
 
49
50
  const tokens = useAppDesignTokens();
50
51
  const isAdvancedVisible = showAdvanced !== undefined ? showAdvanced : true;
51
- const buttonIsDisabled = onPromptChange ? !prompt?.trim() : false;
52
+ // Button is disabled if: external isDisabled is true, OR prompt validation fails (when prompt is used)
53
+ const promptInvalid = onPromptChange ? !prompt?.trim() : false;
54
+ const buttonIsDisabled = isDisabled || promptInvalid;
52
55
 
53
56
  useEffect(() => {
54
57
  if (__DEV__) {
@@ -55,6 +55,8 @@ export interface AIGenerationFormProps extends PropsWithChildren {
55
55
  onGenerate: () => void;
56
56
  isGenerating: boolean;
57
57
  hideGenerateButton?: boolean;
58
+ /** External control to disable the generate button (e.g., when images are not selected) */
59
+ isDisabled?: boolean;
58
60
 
59
61
  // Optional: Generation Progress
60
62
  progress?: number;
@@ -9,11 +9,11 @@ import {
9
9
  MediaPickerService,
10
10
  MediaQuality,
11
11
  useAlert,
12
+ saveImageToGallery,
12
13
  } from "@umituz/react-native-design-system";
13
14
  import { useGenerationOrchestrator } from "./orchestrator";
14
15
  import { executeMultiImageGeneration } from "../../../infrastructure/services/multi-image-generation.executor";
15
16
  import { prepareImage } from "../../../infrastructure/utils/feature-utils";
16
- import { saveMediaToGallery } from "../../../infrastructure/utils/media-actions.util";
17
17
  import type { GenerationStrategy, AlertMessages } from "./types";
18
18
 
19
19
  declare const __DEV__: boolean;
@@ -172,11 +172,11 @@ export const useDualImageGeneration = (
172
172
  }
173
173
  }, [sourceBase64, targetBase64, orchestrator, showError]);
174
174
 
175
- // Save handler
175
+ // Save handler - uses design-system saveImageToGallery
176
176
  const save = useCallback(async () => {
177
177
  if (!orchestrator.result) return;
178
178
 
179
- const result = await saveMediaToGallery(orchestrator.result);
179
+ const result = await saveImageToGallery(orchestrator.result);
180
180
  if (result.success) {
181
181
  showSuccess("Success", "Image saved to gallery");
182
182
  } else {
@@ -121,6 +121,7 @@ export const DualImageFeatureLayout: React.FC<DualImageFeatureLayoutProps> = ({
121
121
  <AIGenerationForm
122
122
  onGenerate={handleProcess}
123
123
  isGenerating={feature.isProcessing}
124
+ isDisabled={!feature.sourceImageUri || !feature.targetImageUri}
124
125
  progress={feature.progress}
125
126
  translations={{
126
127
  generateButton: translations.processButtonText,
@@ -1,200 +0,0 @@
1
- /**
2
- * Media Actions Utilities
3
- * Provides save to gallery and share functionality for generated media
4
- */
5
-
6
- declare const __DEV__: boolean;
7
-
8
- export interface MediaActionResult {
9
- readonly success: boolean;
10
- readonly error?: string;
11
- }
12
-
13
- export interface MediaActionTranslations {
14
- readonly success?: string;
15
- readonly error?: string;
16
- readonly permissionDenied?: string;
17
- readonly saveFailed?: string;
18
- readonly shareFailed?: string;
19
- readonly shareNotAvailable?: string;
20
- }
21
-
22
- export interface ToastConfig {
23
- readonly show: (config: {
24
- type: "success" | "error";
25
- text1: string;
26
- text2?: string;
27
- }) => void;
28
- }
29
-
30
- /**
31
- * Downloads a file from URL to local storage
32
- * @param uri - URL or local path
33
- * @param prefix - File name prefix
34
- * @returns Local file path
35
- */
36
- const downloadToLocal = async (
37
- uri: string,
38
- prefix: string = "media"
39
- ): Promise<string> => {
40
- if (!uri.startsWith("http")) {
41
- return uri;
42
- }
43
-
44
- const FileSystem = require("expo-file-system");
45
- const fileExt = uri.split(".").pop()?.split("?")[0] || "jpg";
46
- const fileRef =
47
- FileSystem.documentDirectory + `${prefix}_${Date.now()}.${fileExt}`;
48
- const { uri: downloadedUri } = await FileSystem.downloadAsync(uri, fileRef);
49
- return downloadedUri;
50
- };
51
-
52
- /**
53
- * Saves media to device gallery
54
- * @param uri - URL or local path of the media
55
- * @param translations - Optional translated messages
56
- * @param toast - Optional toast instance for notifications
57
- * @returns Result with success status
58
- */
59
- export const saveMediaToGallery = async (
60
- uri: string,
61
- translations?: MediaActionTranslations,
62
- toast?: ToastConfig
63
- ): Promise<MediaActionResult> => {
64
- try {
65
- const MediaLibrary = require("expo-media-library");
66
-
67
- const { status } = await MediaLibrary.requestPermissionsAsync();
68
- if (status !== "granted") {
69
- const errorMsg = translations?.permissionDenied || "Permission denied";
70
- toast?.show({
71
- type: "error",
72
- text1: translations?.error || "Error",
73
- text2: errorMsg,
74
- });
75
- return { success: false, error: errorMsg };
76
- }
77
-
78
- const localUri = await downloadToLocal(uri, "download");
79
- await MediaLibrary.saveToLibraryAsync(localUri);
80
-
81
- toast?.show({
82
- type: "success",
83
- text1: translations?.success || "Success",
84
- text2: "Saved to gallery",
85
- });
86
-
87
- return { success: true };
88
- } catch (error) {
89
- // Debug logging in development
90
- if (typeof __DEV__ !== "undefined" && __DEV__) {
91
- console.error("[MediaActions] Save failed:", error);
92
- }
93
- const errorMsg = translations?.saveFailed || "Failed to save media";
94
- toast?.show({
95
- type: "error",
96
- text1: translations?.error || "Error",
97
- text2: errorMsg,
98
- });
99
- return {
100
- success: false,
101
- error: error instanceof Error ? error.message : errorMsg,
102
- };
103
- }
104
- };
105
-
106
- /**
107
- * Shares media using device share sheet
108
- * @param uri - URL or local path of the media
109
- * @param translations - Optional translated messages
110
- * @param toast - Optional toast instance for notifications
111
- * @returns Result with success status
112
- */
113
- export const shareMedia = async (
114
- uri: string,
115
- translations?: MediaActionTranslations,
116
- toast?: ToastConfig
117
- ): Promise<MediaActionResult> => {
118
- try {
119
- const Sharing = require("expo-sharing");
120
-
121
- const isAvailable = await Sharing.isAvailableAsync();
122
- if (!isAvailable) {
123
- const errorMsg =
124
- translations?.shareNotAvailable ||
125
- "Sharing is not available on this device";
126
- toast?.show({
127
- type: "error",
128
- text1: translations?.error || "Error",
129
- text2: errorMsg,
130
- });
131
- return { success: false, error: errorMsg };
132
- }
133
-
134
- const localUri = await downloadToLocal(uri, "share");
135
- await Sharing.shareAsync(localUri);
136
-
137
- return { success: true };
138
- } catch (error) {
139
- // Debug logging in development
140
- if (typeof __DEV__ !== "undefined" && __DEV__) {
141
- console.error("[MediaActions] Share failed:", error);
142
- }
143
- const errorMsg = translations?.shareFailed || "Failed to share media";
144
- toast?.show({
145
- type: "error",
146
- text1: translations?.error || "Error",
147
- text2: errorMsg,
148
- });
149
- return {
150
- success: false,
151
- error: error instanceof Error ? error.message : errorMsg,
152
- };
153
- }
154
- };
155
-
156
- /**
157
- * Creates save handler for use in wizard flows
158
- * @param translations - Translated messages
159
- * @param toast - Toast instance for notifications
160
- * @returns Save handler function
161
- */
162
- export const createSaveHandler = (
163
- translations?: MediaActionTranslations,
164
- toast?: ToastConfig
165
- ) => {
166
- return async (uri: string): Promise<void> => {
167
- await saveMediaToGallery(uri, translations, toast);
168
- };
169
- };
170
-
171
- /**
172
- * Creates share handler for use in wizard flows
173
- * @param translations - Translated messages
174
- * @param toast - Toast instance for notifications
175
- * @returns Share handler function
176
- */
177
- export const createShareHandler = (
178
- translations?: MediaActionTranslations,
179
- toast?: ToastConfig
180
- ) => {
181
- return async (uri: string): Promise<void> => {
182
- await shareMedia(uri, translations, toast);
183
- };
184
- };
185
-
186
- /**
187
- * Creates both save and share handlers
188
- * @param translations - Translated messages
189
- * @param toast - Toast instance for notifications
190
- * @returns Object with onSave and onShare handlers
191
- */
192
- export const createMediaHandlers = (
193
- translations?: MediaActionTranslations,
194
- toast?: ToastConfig
195
- ) => {
196
- return {
197
- onSave: createSaveHandler(translations, toast),
198
- onShare: createShareHandler(translations, toast),
199
- };
200
- };