@umituz/react-native-ai-generation-content 1.37.28 → 1.37.30

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.37.28",
3
+ "version": "1.37.30",
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",
@@ -21,31 +21,25 @@ export const IMAGE_CREATION_TYPES: CreationTypeId[] = [
21
21
  "background-replacement",
22
22
  "ai-brush",
23
23
  "hd-touch-up",
24
- "ai-hug",
25
- "ai-kiss",
26
24
  "anime-selfie",
27
25
  ];
28
26
 
29
27
  /**
30
- * Video-related creation types
28
+ * Video-related creation types (core types only)
29
+ * NOTE: All other video types (scenarios, ai-hug, ai-kiss, etc.)
30
+ * are dynamically determined by output content via isVideoUrl()
31
31
  */
32
32
  export const VIDEO_CREATION_TYPES: CreationTypeId[] = [
33
33
  "text-to-video",
34
34
  "image-to-video",
35
35
  ];
36
36
 
37
- /**
38
- * Voice-related creation types
39
- */
40
- export const VOICE_CREATION_TYPES: CreationTypeId[] = ["text-to-voice"];
41
-
42
37
  /**
43
38
  * All creation types
44
39
  */
45
40
  export const ALL_CREATION_TYPES: CreationTypeId[] = [
46
41
  ...IMAGE_CREATION_TYPES,
47
42
  ...VIDEO_CREATION_TYPES,
48
- ...VOICE_CREATION_TYPES,
49
43
  ];
50
44
 
51
45
  /**
@@ -59,15 +53,15 @@ export function getTypesForCategory(
59
53
  return IMAGE_CREATION_TYPES;
60
54
  case "video":
61
55
  return VIDEO_CREATION_TYPES;
62
- case "voice":
63
- return VOICE_CREATION_TYPES;
64
56
  case "all":
65
57
  return ALL_CREATION_TYPES;
58
+ default:
59
+ return ALL_CREATION_TYPES;
66
60
  }
67
61
  }
68
62
 
69
63
  /**
70
- * Get category for a creation type
64
+ * Get category for a creation type (type-based fallback only)
71
65
  */
72
66
  export function getCategoryForType(type: CreationTypeId): CreationCategory {
73
67
  if (IMAGE_CREATION_TYPES.includes(type)) {
@@ -76,12 +70,46 @@ export function getCategoryForType(type: CreationTypeId): CreationCategory {
76
70
  if (VIDEO_CREATION_TYPES.includes(type)) {
77
71
  return "video";
78
72
  }
79
- if (VOICE_CREATION_TYPES.includes(type)) {
80
- return "voice";
81
- }
82
73
  return "image"; // Default fallback
83
74
  }
84
75
 
76
+ /**
77
+ * Get category for a creation based on its output content
78
+ * This is the PRIMARY method for categorization - OUTPUT determines category, not type
79
+ * Handles all scenarios (solo_martial_artist, ski_resort, ai-hug, ai-kiss, etc.)
80
+ *
81
+ * Strategy: API response already tells us the type via field names:
82
+ * - output.videoUrl exists → video
83
+ * - output.imageUrl exists → image
84
+ * No need to parse URLs or check extensions!
85
+ */
86
+ export function getCategoryForCreation(creation: {
87
+ type?: string;
88
+ output?: {
89
+ videoUrl?: string;
90
+ imageUrl?: string;
91
+ imageUrls?: string[];
92
+ };
93
+ uri?: string;
94
+ }): CreationCategory {
95
+ // PRIORITY 1: Check output field names (most reliable)
96
+ if (creation.output?.videoUrl) {
97
+ return "video";
98
+ }
99
+
100
+ if (creation.output?.imageUrl || creation.output?.imageUrls?.length) {
101
+ return "image";
102
+ }
103
+
104
+ // PRIORITY 2: Fallback to type-based (for known types)
105
+ if (creation.type) {
106
+ return getCategoryForType(creation.type as CreationTypeId);
107
+ }
108
+
109
+ // Final fallback
110
+ return "image";
111
+ }
112
+
85
113
  /**
86
114
  * Check if a type belongs to a category
87
115
  */
@@ -110,24 +138,3 @@ export function isImageCreationType(type?: string): boolean {
110
138
  if (!type) return false;
111
139
  return IMAGE_CREATION_TYPES.includes(type as CreationTypeId);
112
140
  }
113
-
114
- /**
115
- * Check if creation type is voice
116
- */
117
- export function isVoiceCreationType(type?: string): boolean {
118
- if (!type) return false;
119
- return VOICE_CREATION_TYPES.includes(type as CreationTypeId);
120
- }
121
-
122
- /**
123
- * Get media type (image/video/audio) for a creation type
124
- */
125
- export function getMediaTypeForCreation(
126
- type?: string
127
- ): "image" | "video" | "audio" | "unknown" {
128
- if (!type) return "unknown";
129
- if (isVideoCreationType(type)) return "video";
130
- if (isVoiceCreationType(type)) return "audio";
131
- if (isImageCreationType(type)) return "image";
132
- return "unknown";
133
- }
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import type { CreationTypeId, CreationStatus, CreationCategory } from "./creation-types";
7
- import { IMAGE_CREATION_TYPES, VIDEO_CREATION_TYPES, VOICE_CREATION_TYPES } from "./creation-categories";
8
7
 
9
8
  /**
10
9
  * Filter options for querying creations
@@ -61,7 +60,6 @@ export const MEDIA_FILTER_OPTIONS: FilterOption[] = [
61
60
  { id: "all", label: "All", labelKey: "creations.filter.all", icon: "grid-outline" },
62
61
  { id: "image", label: "Images", labelKey: "creations.filter.images", icon: "image-outline" },
63
62
  { id: "video", label: "Videos", labelKey: "creations.filter.videos", icon: "videocam-outline" },
64
- { id: "voice", label: "Voice", labelKey: "creations.filter.voice", icon: "mic-outline" },
65
63
  ];
66
64
 
67
65
  /**
@@ -89,11 +87,16 @@ export interface CreationStats {
89
87
  * Calculate stats from creations array
90
88
  */
91
89
  export function calculateCreationStats(
92
- creations: Array<{ type?: string; status?: string }>
90
+ creations: Array<{
91
+ type?: string;
92
+ status?: string;
93
+ output?: { videoUrl?: string; imageUrl?: string; imageUrls?: string[] };
94
+ uri?: string;
95
+ }>
93
96
  ): CreationStats {
94
97
  const stats: CreationStats = {
95
98
  total: creations.length,
96
- byCategory: { all: creations.length, image: 0, video: 0, voice: 0 },
99
+ byCategory: { all: creations.length, image: 0, video: 0 },
97
100
  byStatus: { pending: 0, queued: 0, processing: 0, completed: 0, failed: 0 },
98
101
  byType: {},
99
102
  };
@@ -114,15 +117,11 @@ export function calculateCreationStats(
114
117
  }
115
118
  }
116
119
 
117
- // Calculate category counts from type counts
118
- for (const [typeId, count] of Object.entries(stats.byType)) {
119
- if ((IMAGE_CREATION_TYPES as string[]).includes(typeId)) {
120
- stats.byCategory.image += count as number;
121
- } else if ((VIDEO_CREATION_TYPES as string[]).includes(typeId)) {
122
- stats.byCategory.video += count as number;
123
- } else if ((VOICE_CREATION_TYPES as string[]).includes(typeId)) {
124
- stats.byCategory.voice += count as number;
125
- }
120
+ // Calculate category counts based on OUTPUT content (most reliable)
121
+ const { getCategoryForCreation } = require("./creation-categories");
122
+ for (const creation of creations) {
123
+ const category = getCategoryForCreation(creation) as Exclude<CreationCategory, "all">;
124
+ stats.byCategory[category]++;
126
125
  }
127
126
 
128
127
  return stats;
@@ -10,7 +10,6 @@ export type CreationTypeId =
10
10
  | "text-to-image"
11
11
  | "text-to-video"
12
12
  | "image-to-video"
13
- | "text-to-voice"
14
13
  | "upscale"
15
14
  | "remove-background"
16
15
  | "photo-restore"
@@ -39,7 +38,7 @@ export type CreationStatus =
39
38
  /**
40
39
  * Creation category for grouping types
41
40
  */
42
- export type CreationCategory = "image" | "video" | "voice" | "all";
41
+ export type CreationCategory = "image" | "video" | "all";
43
42
 
44
43
  /**
45
44
  * All status values as array for iteration
@@ -59,5 +58,4 @@ export const ALL_CREATION_CATEGORIES: CreationCategory[] = [
59
58
  "all",
60
59
  "image",
61
60
  "video",
62
- "voice",
63
61
  ];
@@ -18,15 +18,13 @@ export {
18
18
  export {
19
19
  IMAGE_CREATION_TYPES,
20
20
  VIDEO_CREATION_TYPES,
21
- VOICE_CREATION_TYPES,
22
21
  ALL_CREATION_TYPES,
23
22
  getTypesForCategory,
24
23
  getCategoryForType,
24
+ getCategoryForCreation,
25
25
  isTypeInCategory,
26
26
  isVideoCreationType,
27
27
  isImageCreationType,
28
- isVoiceCreationType,
29
- getMediaTypeForCreation,
30
28
  } from "./creation-categories";
31
29
 
32
30
  // Filter types
@@ -26,8 +26,6 @@ export function getTypeIcon(type: CreationTypeId): IconName {
26
26
  case "text-to-video":
27
27
  case "image-to-video":
28
28
  return "film";
29
- case "text-to-voice":
30
- return "mic";
31
29
  case "style-transfer":
32
30
  case "colorization":
33
31
  return "color-palette";
@@ -25,17 +25,15 @@ export {
25
25
  ALL_CREATION_TYPES,
26
26
  IMAGE_CREATION_TYPES,
27
27
  VIDEO_CREATION_TYPES,
28
- VOICE_CREATION_TYPES,
29
28
  DEFAULT_CREATION_FILTER,
30
29
  MEDIA_FILTER_OPTIONS,
31
30
  STATUS_FILTER_OPTIONS,
32
31
  getTypesForCategory,
33
32
  getCategoryForType,
33
+ getCategoryForCreation,
34
34
  isTypeInCategory,
35
35
  isVideoCreationType,
36
36
  isImageCreationType,
37
- isVoiceCreationType,
38
- getMediaTypeForCreation,
39
37
  calculateCreationStats,
40
38
  } from "./domain/types";
41
39
 
@@ -1,22 +1,15 @@
1
1
  /**
2
2
  * CreationPreview Component
3
3
  * Smart wrapper that delegates to CreationImagePreview or CreationVideoPreview
4
- * based on creation type
4
+ * based on output content type (not creation type)
5
5
  */
6
6
 
7
7
  import React from "react";
8
+ import { isVideoUrl } from "@umituz/react-native-design-system";
8
9
  import type { CreationStatus, CreationTypeId } from "../../domain/types";
9
10
  import { CreationImagePreview } from "./CreationImagePreview";
10
11
  import { CreationVideoPreview } from "./CreationVideoPreview";
11
12
 
12
- /** Video creation types */
13
- const VIDEO_TYPES: CreationTypeId[] = ["text-to-video", "image-to-video"];
14
-
15
- /** Check if creation type is a video type */
16
- function isVideoType(type?: CreationTypeId | string): boolean {
17
- return VIDEO_TYPES.includes(type as CreationTypeId);
18
- }
19
-
20
13
  interface CreationPreviewProps {
21
14
  /** Preview image/thumbnail URL */
22
15
  readonly uri?: string | null;
@@ -43,11 +36,15 @@ export function CreationPreview({
43
36
  height,
44
37
  showLoadingIndicator = true,
45
38
  }: CreationPreviewProps) {
46
- // For video types, use CreationVideoPreview
47
- if (isVideoType(type)) {
39
+ // Determine preview type based on URI content, not creation type
40
+ // This handles scenario-based videos (solo_martial_artist, ski_resort, etc.)
41
+ const hasVideoContent = uri && isVideoUrl(uri);
42
+
43
+ // For video content, use CreationVideoPreview
44
+ if (hasVideoContent) {
48
45
  return (
49
46
  <CreationVideoPreview
50
- thumbnailUrl={thumbnailUrl || uri}
47
+ thumbnailUrl={thumbnailUrl}
51
48
  videoUrl={uri}
52
49
  status={status}
53
50
  type={type as CreationTypeId}
@@ -58,7 +55,7 @@ export function CreationPreview({
58
55
  );
59
56
  }
60
57
 
61
- // For image types, use CreationImagePreview
58
+ // For image content, use CreationImagePreview
62
59
  return (
63
60
  <CreationImagePreview
64
61
  uri={uri}