@umituz/react-native-ai-generation-content 1.12.32 → 1.12.34

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.12.32",
3
+ "version": "1.12.34",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -45,6 +45,7 @@
45
45
  "@umituz/react-native-firebase": "*",
46
46
  "@umituz/react-native-image": "*",
47
47
  "@umituz/react-native-offline": "*",
48
+ "@umituz/react-native-timezone": "*",
48
49
  "@umituz/react-native-uuid": "*",
49
50
  "expo-linear-gradient": ">=15.0.0",
50
51
  "firebase": ">=10.0.0",
@@ -71,6 +72,7 @@
71
72
  "@umituz/react-native-haptics": "^1.0.2",
72
73
  "@umituz/react-native-image": "*",
73
74
  "@umituz/react-native-offline": "*",
75
+ "@umituz/react-native-timezone": "^1.3.4",
74
76
  "@umituz/react-native-uuid": "*",
75
77
  "eslint": "^8.57.0",
76
78
  "expo-application": "^7.0.8",
@@ -12,6 +12,7 @@ export interface Creation {
12
12
  readonly originalUri?: string;
13
13
  readonly createdAt: Date;
14
14
  readonly isShared: boolean;
15
+ readonly isFavorite: boolean;
15
16
  }
16
17
 
17
18
  export interface CreationDocument {
@@ -26,6 +27,7 @@ export interface CreationDocument {
26
27
  readonly type?: string;
27
28
  readonly status?: string;
28
29
  readonly isShared: boolean;
30
+ readonly isFavorite?: boolean;
29
31
  readonly createdAt: FirebaseTimestamp | Date; // Allow Date for writing
30
32
  readonly completedAt?: FirebaseTimestamp | Date;
31
33
  }
@@ -56,5 +58,6 @@ export function mapDocumentToCreation(
56
58
  originalUri: data.originalImageUrl || data.originalImage,
57
59
  createdAt: creationDate,
58
60
  isShared: data.isShared ?? false,
61
+ isFavorite: data.isFavorite ?? false,
59
62
  };
60
63
  }
@@ -20,4 +20,9 @@ export interface ICreationsRepository {
20
20
  creationId: string,
21
21
  isShared: boolean,
22
22
  ): Promise<boolean>;
23
+ updateFavorite(
24
+ userId: string,
25
+ creationId: string,
26
+ isFavorite: boolean,
27
+ ): Promise<boolean>;
23
28
  }
@@ -238,4 +238,20 @@ export class CreationsRepository
238
238
  return false;
239
239
  }
240
240
  }
241
+
242
+ async updateFavorite(
243
+ userId: string,
244
+ creationId: string,
245
+ isFavorite: boolean,
246
+ ): Promise<boolean> {
247
+ const docRef = this.getDocRef(userId, creationId);
248
+ if (!docRef) return false;
249
+
250
+ try {
251
+ await updateDoc(docRef, { isFavorite });
252
+ return true;
253
+ } catch {
254
+ return false;
255
+ }
256
+ }
241
257
  }
@@ -1,8 +1,3 @@
1
- /**
2
- * CreationCard Component
3
- * Displays a creation item with actions
4
- */
5
-
6
1
  import React, { useMemo, useCallback } from "react";
7
2
  import { View, Image, TouchableOpacity, StyleSheet } from "react-native";
8
3
  import {
@@ -10,6 +5,7 @@ import {
10
5
  AtomicIcon,
11
6
  useAppDesignTokens,
12
7
  } from "@umituz/react-native-design-system";
8
+ import { timezoneService } from "@umituz/react-native-timezone";
13
9
  import type { Creation } from "../../domain/entities/Creation";
14
10
  import type { CreationType } from "../../domain/value-objects/CreationsConfig";
15
11
 
@@ -19,6 +15,8 @@ interface CreationCardProps {
19
15
  readonly onView?: (creation: Creation) => void;
20
16
  readonly onShare: (creation: Creation) => void;
21
17
  readonly onDelete: (creation: Creation) => void;
18
+ readonly onFavorite?: (creation: Creation, isFavorite: boolean) => void;
19
+ readonly locale?: string;
22
20
  }
23
21
 
24
22
  export function CreationCard({
@@ -27,11 +25,13 @@ export function CreationCard({
27
25
  onView,
28
26
  onShare,
29
27
  onDelete,
28
+ onFavorite,
29
+ locale = "en-US",
30
30
  }: CreationCardProps) {
31
31
  const tokens = useAppDesignTokens();
32
32
 
33
33
  const typeConfig = types.find((t) => t.id === creation.type);
34
- const icon = typeConfig?.icon || "🎨";
34
+ const icon = typeConfig?.icon;
35
35
  const label = typeConfig?.labelKey || creation.type;
36
36
 
37
37
  const handleView = useCallback(() => onView?.(creation), [creation, onView]);
@@ -40,19 +40,24 @@ export function CreationCard({
40
40
  () => onDelete(creation),
41
41
  [creation, onDelete],
42
42
  );
43
+ const handleFavorite = useCallback(
44
+ () => onFavorite?.(creation, !creation.isFavorite),
45
+ [creation, onFavorite],
46
+ );
43
47
 
44
48
  const formattedDate = useMemo(() => {
45
49
  const date =
46
50
  creation.createdAt instanceof Date
47
51
  ? creation.createdAt
48
52
  : new Date(creation.createdAt);
49
- return date.toLocaleDateString(undefined, {
50
- day: "numeric",
53
+
54
+ return timezoneService.formatDateTime(date, locale, {
51
55
  month: "short",
56
+ day: "numeric",
52
57
  hour: "2-digit",
53
58
  minute: "2-digit",
54
59
  });
55
- }, [creation.createdAt]);
60
+ }, [creation.createdAt, locale]);
56
61
 
57
62
  const styles = useMemo(
58
63
  () =>
@@ -112,7 +117,7 @@ export function CreationCard({
112
117
  <View style={styles.content}>
113
118
  <View>
114
119
  <View style={styles.typeRow}>
115
- <AtomicText style={styles.icon}>{icon}</AtomicText>
120
+ <AtomicIcon name={icon} size="sm" color="primary" />
116
121
  <AtomicText style={styles.typeText}>{label}</AtomicText>
117
122
  </View>
118
123
  <AtomicText style={styles.dateText}>{formattedDate}</AtomicText>
@@ -123,6 +128,15 @@ export function CreationCard({
123
128
  <AtomicIcon name="eye" size="sm" color="primary" />
124
129
  </TouchableOpacity>
125
130
  )}
131
+ {onFavorite && (
132
+ <TouchableOpacity style={styles.actionBtn} onPress={handleFavorite}>
133
+ <AtomicIcon
134
+ name={creation.isFavorite ? "heart" : "heart-outline"}
135
+ size="sm"
136
+ color={creation.isFavorite ? "error" : "primary"}
137
+ />
138
+ </TouchableOpacity>
139
+ )}
126
140
  <TouchableOpacity style={styles.actionBtn} onPress={handleShare}>
127
141
  <AtomicIcon name="share-social" size="sm" color="primary" />
128
142
  </TouchableOpacity>
@@ -13,6 +13,8 @@ interface CreationsGridProps {
13
13
  readonly onView: (creation: Creation) => void;
14
14
  readonly onShare: (creation: Creation) => void;
15
15
  readonly onDelete: (creation: Creation) => void;
16
+ readonly onFavorite?: (creation: Creation, isFavorite: boolean) => void;
17
+ readonly locale?: string;
16
18
  readonly contentContainerStyle?: ViewStyle;
17
19
  readonly ListEmptyComponent?: React.ReactElement | null;
18
20
  readonly ListHeaderComponent?: React.ComponentType<unknown> | React.ReactElement | null;
@@ -26,6 +28,8 @@ export const CreationsGrid: React.FC<CreationsGridProps> = ({
26
28
  onView,
27
29
  onShare,
28
30
  onDelete,
31
+ onFavorite,
32
+ locale,
29
33
  contentContainerStyle,
30
34
  ListEmptyComponent,
31
35
  ListHeaderComponent,
@@ -40,6 +44,8 @@ export const CreationsGrid: React.FC<CreationsGridProps> = ({
40
44
  onView={() => onView(item)}
41
45
  onShare={() => onShare(item)}
42
46
  onDelete={() => onDelete(item)}
47
+ onFavorite={onFavorite ? (creation, isFavorite) => onFavorite(creation, isFavorite) : undefined}
48
+ locale={locale}
43
49
  />
44
50
  );
45
51
 
@@ -19,6 +19,7 @@ interface CreationsGalleryScreenProps {
19
19
  readonly repository: ICreationsRepository;
20
20
  readonly config: CreationsConfig;
21
21
  readonly t: (key: string) => string;
22
+ readonly locale?: string;
22
23
  readonly enableEditing?: boolean;
23
24
  readonly onImageEdit?: (uri: string, creationId: string) => void | Promise<void>;
24
25
  readonly onEmptyAction?: () => void;
@@ -30,6 +31,7 @@ export function CreationsGalleryScreen({
30
31
  repository,
31
32
  config,
32
33
  t,
34
+ locale = "en-US",
33
35
  enableEditing = false,
34
36
  onImageEdit,
35
37
  onEmptyAction,
@@ -95,6 +97,15 @@ export function CreationsGalleryScreen({
95
97
  setSelectedCreation(creation);
96
98
  }, []);
97
99
 
100
+ // Handle favorite toggle
101
+ const handleFavorite = useCallback(async (creation: Creation, isFavorite: boolean) => {
102
+ if (!userId) return;
103
+ const success = await repository.updateFavorite(userId, creation.id, isFavorite);
104
+ if (success) {
105
+ void refetch();
106
+ }
107
+ }, [userId, repository, refetch]);
108
+
98
109
  const styles = useStyles(tokens);
99
110
 
100
111
  const renderEmptyComponent = useMemo(() => (
@@ -152,6 +163,8 @@ export function CreationsGalleryScreen({
152
163
  onView={handleView}
153
164
  onShare={handleShare}
154
165
  onDelete={handleDelete}
166
+ onFavorite={handleFavorite}
167
+ locale={locale}
155
168
  contentContainerStyle={{ paddingBottom: insets.bottom + tokens.spacing.xl }}
156
169
  ListEmptyComponent={renderEmptyComponent}
157
170
  />