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

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.26",
3
+ "version": "1.37.28",
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",
@@ -3,6 +3,7 @@
3
3
  * Utility functions for creation preview/thumbnail extraction
4
4
  */
5
5
 
6
+ import { isImageUrl } from "@umituz/react-native-design-system";
6
7
  import type { CreationOutput } from "../entities/Creation";
7
8
 
8
9
  // Re-export for convenience
@@ -82,3 +83,21 @@ export function getPrimaryMediaUrl(output?: CreationOutput): string | null {
82
83
  null
83
84
  );
84
85
  }
86
+
87
+ /**
88
+ * Determine if thumbnail URL is valid and should be displayed
89
+ * - Must exist
90
+ * - Must be an image URL (not a video URL)
91
+ * - Content must not be in progress
92
+ */
93
+ export function shouldShowThumbnail(
94
+ thumbnailUrl?: string | null,
95
+ inProgress?: boolean
96
+ ): boolean {
97
+ if (!thumbnailUrl || inProgress) {
98
+ return false;
99
+ }
100
+
101
+ // Thumbnail must be an image, not a video
102
+ return isImageUrl(thumbnailUrl);
103
+ }
@@ -40,6 +40,11 @@ export function CreationCard({
40
40
  creationId: creation.id,
41
41
  hasOnPress: !!callbacks.onPress,
42
42
  callbacksKeys: Object.keys(callbacks),
43
+ status: creation.status,
44
+ type: creation.type,
45
+ output: creation.output,
46
+ hasThumbnailUrl: !!creation.output?.thumbnailUrl,
47
+ thumbnailUrl: creation.output?.thumbnailUrl,
43
48
  });
44
49
  }
45
50
 
@@ -119,6 +124,7 @@ export function CreationCard({
119
124
  <View style={styles.previewContainer} pointerEvents="box-none">
120
125
  <CreationPreview
121
126
  uri={previewUrl}
127
+ thumbnailUrl={creation.output?.thumbnailUrl}
122
128
  status={creation.status}
123
129
  type={creation.type as CreationTypeId}
124
130
  />
@@ -12,6 +12,7 @@ import {
12
12
  } from "@umituz/react-native-design-system";
13
13
  import type { CreationStatus, CreationTypeId } from "../../domain/types";
14
14
  import { isInProgress } from "../../domain/utils";
15
+ import { shouldShowThumbnail } from "../../domain/utils/preview-helpers";
15
16
 
16
17
  export interface CreationVideoPreviewProps {
17
18
  /** Thumbnail image URL (optional) */
@@ -30,14 +31,6 @@ export interface CreationVideoPreviewProps {
30
31
  readonly showLoadingIndicator?: boolean;
31
32
  }
32
33
 
33
- /** Check if URL is a video URL (mp4, mov, etc.) */
34
- function isVideoUrl(url?: string | null): boolean {
35
- if (!url) return false;
36
- const videoExtensions = [".mp4", ".mov", ".avi", ".webm", ".mkv"];
37
- const lowerUrl = url.toLowerCase();
38
- return videoExtensions.some((ext) => lowerUrl.includes(ext));
39
- }
40
-
41
34
  export function CreationVideoPreview({
42
35
  thumbnailUrl,
43
36
  videoUrl: _videoUrl,
@@ -48,9 +41,20 @@ export function CreationVideoPreview({
48
41
  }: CreationVideoPreviewProps) {
49
42
  const tokens = useAppDesignTokens();
50
43
  const inProgress = isInProgress(status);
44
+ const hasThumbnail = shouldShowThumbnail(thumbnailUrl, inProgress);
51
45
 
52
- // Only use thumbnail if it's a real image URL, not a video URL
53
- const hasThumbnail = !!thumbnailUrl && !inProgress && !isVideoUrl(thumbnailUrl);
46
+ // Debug logging
47
+ if (__DEV__) {
48
+ console.log("[CreationVideoPreview]", {
49
+ thumbnailUrl,
50
+ status,
51
+ inProgress,
52
+ hasThumbnail,
53
+ willShowSpinner: inProgress && showLoadingIndicator,
54
+ willShowThumbnail: hasThumbnail,
55
+ willShowPlaceholder: !inProgress && !hasThumbnail,
56
+ });
57
+ }
54
58
 
55
59
  const styles = useMemo(
56
60
  () =>
@@ -119,7 +123,7 @@ export function CreationVideoPreview({
119
123
  }
120
124
 
121
125
  // Show thumbnail with play icon overlay
122
- if (hasThumbnail) {
126
+ if (hasThumbnail && thumbnailUrl) {
123
127
  return (
124
128
  <View style={styles.container}>
125
129
  <Image
@@ -19,10 +19,6 @@ interface GalleryHeaderProps {
19
19
  readonly filterButtons?: FilterButtonConfig[];
20
20
  readonly showFilter?: boolean;
21
21
  readonly style?: ViewStyle;
22
- /** Number of pending/processing jobs to show as badge */
23
- readonly pendingCount?: number;
24
- /** Label for pending badge tooltip */
25
- readonly pendingLabel?: string;
26
22
  }
27
23
 
28
24
  export const GalleryHeader: React.FC<GalleryHeaderProps> = ({
@@ -32,8 +28,6 @@ export const GalleryHeader: React.FC<GalleryHeaderProps> = ({
32
28
  filterButtons = [],
33
29
  showFilter = true,
34
30
  style,
35
- pendingCount = 0,
36
- pendingLabel,
37
31
  }) => {
38
32
  const tokens = useAppDesignTokens();
39
33
  const styles = useStyles(tokens);
@@ -102,18 +96,6 @@ const useStyles = (tokens: DesignTokens) =>
102
96
  fontWeight: "700",
103
97
  color: tokens.colors.textPrimary,
104
98
  },
105
- pendingBadge: {
106
- flexDirection: "row",
107
- alignItems: "center",
108
- gap: 4,
109
- paddingHorizontal: 8,
110
- paddingVertical: 4,
111
- borderRadius: 12,
112
- },
113
- pendingBadgeText: {
114
- fontSize: 12,
115
- fontWeight: "600",
116
- },
117
99
  subtitle: {
118
100
  fontSize: 14,
119
101
  color: tokens.colors.textSecondary,
@@ -120,8 +120,6 @@ export function CreationsGalleryScreen({
120
120
  countLabel={t(config.translations.photoCount)}
121
121
  showFilter={showFilter}
122
122
  filterButtons={filterButtons}
123
- pendingCount={filters.processingCount}
124
- pendingLabel={t("creations.processing")}
125
123
  />
126
124
  </View>
127
125
  );