@umituz/react-native-ai-generation-content 1.17.242 → 1.17.243

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.17.242",
3
+ "version": "1.17.243",
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",
@@ -38,7 +38,6 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@umituz/react-native-auth": "latest",
41
- "@umituz/react-native-design-system": "latest",
42
41
  "@umituz/react-native-filesystem": "latest",
43
42
  "@umituz/react-native-firebase": "latest",
44
43
  "@umituz/react-native-tanstack": "latest"
@@ -63,7 +62,7 @@
63
62
  "@types/react": "~19.1.10",
64
63
  "@typescript-eslint/eslint-plugin": "^8.0.0",
65
64
  "@typescript-eslint/parser": "^8.0.0",
66
- "@umituz/react-native-design-system": "latest",
65
+ "@umituz/react-native-design-system": "^2.6.126",
67
66
  "@umituz/react-native-filesystem": "latest",
68
67
  "@umituz/react-native-firebase": "latest",
69
68
  "@umituz/react-native-haptics": "latest",
@@ -80,6 +79,7 @@
80
79
  "expo-haptics": "^15.0.8",
81
80
  "expo-image": "^3.0.11",
82
81
  "expo-localization": "^17.0.8",
82
+ "expo-media-library": "^18.2.1",
83
83
  "expo-network": "^8.0.8",
84
84
  "expo-sharing": "^14.0.8",
85
85
  "expo-video": "^3.0.15",
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Recent Creations Section Component
3
+ * Displays recent creations in a grid layout
4
+ */
5
+
6
+ import React, { useMemo, useCallback } from "react";
7
+ import { StyleSheet, View, TouchableOpacity, FlatList } from "react-native";
8
+ import {
9
+ AtomicText,
10
+ AtomicImage,
11
+ AtomicIcon,
12
+ useAppDesignTokens,
13
+ } from "@umituz/react-native-design-system";
14
+ import type { RecentCreation } from "../types/result-preview.types";
15
+
16
+ interface RecentCreationsSectionProps {
17
+ readonly recentCreations: readonly RecentCreation[];
18
+ readonly onViewAll?: () => void;
19
+ readonly onCreationPress?: (creation: RecentCreation) => void;
20
+ readonly title: string;
21
+ readonly viewAllLabel: string;
22
+ }
23
+
24
+ export const RecentCreationsSection: React.FC<RecentCreationsSectionProps> = ({
25
+ recentCreations,
26
+ onViewAll,
27
+ onCreationPress,
28
+ title,
29
+ viewAllLabel,
30
+ }) => {
31
+ const tokens = useAppDesignTokens();
32
+
33
+ const styles = useMemo(
34
+ () =>
35
+ StyleSheet.create({
36
+ container: {
37
+ marginTop: tokens.spacing.xl,
38
+ paddingHorizontal: tokens.spacing.md,
39
+ },
40
+ header: {
41
+ flexDirection: "row",
42
+ justifyContent: "space-between",
43
+ alignItems: "center",
44
+ marginBottom: tokens.spacing.md,
45
+ },
46
+ title: {
47
+ fontSize: 20,
48
+ fontWeight: "700",
49
+ color: tokens.colors.textPrimary,
50
+ },
51
+ viewAllButton: {
52
+ paddingHorizontal: tokens.spacing.sm,
53
+ paddingVertical: tokens.spacing.xs,
54
+ },
55
+ viewAllText: {
56
+ fontSize: 12,
57
+ fontWeight: "700",
58
+ color: tokens.colors.primary,
59
+ textTransform: "uppercase",
60
+ letterSpacing: 0.5,
61
+ },
62
+ grid: {
63
+ gap: tokens.spacing.md,
64
+ },
65
+ creationItem: {
66
+ flex: 1,
67
+ marginHorizontal: tokens.spacing.xs,
68
+ },
69
+ imageContainer: {
70
+ width: "100%",
71
+ aspectRatio: 4 / 5,
72
+ borderRadius: tokens.borders.radius.md,
73
+ overflow: "hidden",
74
+ backgroundColor: tokens.colors.backgroundSecondary,
75
+ position: "relative",
76
+ },
77
+ image: {
78
+ width: "100%",
79
+ height: "100%",
80
+ },
81
+ favoriteIcon: {
82
+ position: "absolute",
83
+ bottom: 8,
84
+ right: 8,
85
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
86
+ borderRadius: tokens.borders.radius.full,
87
+ padding: 6,
88
+ },
89
+ creationInfo: {
90
+ marginTop: tokens.spacing.xs,
91
+ },
92
+ creationTitle: {
93
+ fontSize: 14,
94
+ fontWeight: "700",
95
+ color: tokens.colors.textPrimary,
96
+ marginBottom: 2,
97
+ },
98
+ creationDate: {
99
+ fontSize: 12,
100
+ color: tokens.colors.textSecondary,
101
+ },
102
+ divider: {
103
+ height: 1,
104
+ backgroundColor: tokens.colors.border,
105
+ marginBottom: tokens.spacing.lg,
106
+ marginHorizontal: tokens.spacing.lg,
107
+ },
108
+ columnWrapper: {
109
+ justifyContent: "space-between",
110
+ },
111
+ }),
112
+ [tokens],
113
+ );
114
+
115
+ const handleCreationPress = useCallback((creation: RecentCreation) => {
116
+ onCreationPress?.(creation);
117
+ }, [onCreationPress]);
118
+
119
+ const renderItem = useCallback(({ item }: { item: RecentCreation }) => (
120
+ <TouchableOpacity
121
+ style={styles.creationItem}
122
+ onPress={() => handleCreationPress(item)}
123
+ activeOpacity={0.7}
124
+ >
125
+ <View style={styles.imageContainer}>
126
+ <AtomicImage
127
+ source={{ uri: item.imageUrl }}
128
+ style={styles.image}
129
+ rounded
130
+ />
131
+ {item.isFavorite && (
132
+ <View style={styles.favoriteIcon}>
133
+ <AtomicIcon name="heart" size="xs" color="error" />
134
+ </View>
135
+ )}
136
+ </View>
137
+ <View style={styles.creationInfo}>
138
+ <AtomicText style={styles.creationTitle} numberOfLines={1}>
139
+ {item.title}
140
+ </AtomicText>
141
+ <AtomicText style={styles.creationDate}>
142
+ {item.date}
143
+ </AtomicText>
144
+ </View>
145
+ </TouchableOpacity>
146
+ ), [styles, handleCreationPress]);
147
+
148
+ if (!recentCreations || recentCreations.length === 0) {
149
+ return null;
150
+ }
151
+
152
+ return (
153
+ <>
154
+ <View style={styles.divider} />
155
+ <View style={styles.container}>
156
+ <View style={styles.header}>
157
+ <AtomicText style={styles.title}>{title}</AtomicText>
158
+ {onViewAll && (
159
+ <TouchableOpacity
160
+ style={styles.viewAllButton}
161
+ onPress={onViewAll}
162
+ activeOpacity={0.7}
163
+ >
164
+ <AtomicText style={styles.viewAllText}>{viewAllLabel}</AtomicText>
165
+ </TouchableOpacity>
166
+ )}
167
+ </View>
168
+ <FlatList
169
+ data={recentCreations}
170
+ renderItem={renderItem}
171
+ keyExtractor={(item) => item.id}
172
+ numColumns={2}
173
+ columnWrapperStyle={styles.columnWrapper}
174
+ scrollEnabled={false}
175
+ showsVerticalScrollIndicator={false}
176
+ />
177
+ </View>
178
+ </>
179
+ );
180
+ };
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import React, { useMemo } from "react";
7
- import { StyleSheet, View, ViewStyle } from "react-native";
7
+ import { StyleSheet, View } from "react-native";
8
8
  import { AtomicImage, useAppDesignTokens } from "@umituz/react-native-design-system";
9
9
  import type { ResultImageCardProps } from "../types/result-preview.types";
10
10
 
@@ -20,8 +20,8 @@ export const ResultImageCard: React.FC<ResultImageCardProps> = ({
20
20
  StyleSheet.create({
21
21
  container: {
22
22
  width: "100%",
23
- aspectRatio: 1,
24
- borderRadius: rounded ? tokens.borders.radius.md : 0,
23
+ aspectRatio: 3 / 4,
24
+ borderRadius: rounded ? tokens.borders.radius.xl : 0,
25
25
  overflow: "hidden",
26
26
  backgroundColor: tokens.colors.backgroundSecondary,
27
27
  },
@@ -13,6 +13,7 @@ import {
13
13
  } from "@umituz/react-native-design-system";
14
14
  import { ResultImageCard } from "./ResultImageCard";
15
15
  import { ResultActionBar } from "./ResultActionBar";
16
+ import { RecentCreationsSection } from "./RecentCreationsSection";
16
17
  import type { ResultPreviewScreenProps } from "../types/result-preview.types";
17
18
 
18
19
  export const ResultPreviewScreen: React.FC<ResultPreviewScreenProps> = ({
@@ -24,6 +25,9 @@ export const ResultPreviewScreen: React.FC<ResultPreviewScreenProps> = ({
24
25
  onTryAgain,
25
26
  onNavigateBack,
26
27
  onRate,
28
+ recentCreations,
29
+ onViewAll,
30
+ onCreationPress,
27
31
  translations,
28
32
  style,
29
33
  }) => {
@@ -98,6 +102,15 @@ export const ResultPreviewScreen: React.FC<ResultPreviewScreenProps> = ({
98
102
  rateButtonText={translations.rateButton}
99
103
  />
100
104
  </View>
105
+ {recentCreations && recentCreations.length > 0 && translations.recentCreations && translations.viewAll && (
106
+ <RecentCreationsSection
107
+ recentCreations={recentCreations}
108
+ onViewAll={onViewAll}
109
+ onCreationPress={onCreationPress}
110
+ title={translations.recentCreations}
111
+ viewAllLabel={translations.viewAll}
112
+ />
113
+ )}
101
114
  </View>
102
115
  </ScreenLayout>
103
116
  );
@@ -5,3 +5,4 @@
5
5
  export { ResultPreviewScreen } from "./ResultPreviewScreen";
6
6
  export { ResultImageCard } from "./ResultImageCard";
7
7
  export { ResultActionBar } from "./ResultActionBar";
8
+ export { RecentCreationsSection } from "./RecentCreationsSection";
@@ -79,6 +79,17 @@ export interface ResultActionBarProps {
79
79
  rateButtonText?: string;
80
80
  }
81
81
 
82
+ /**
83
+ * Recent creation item
84
+ */
85
+ export interface RecentCreation {
86
+ readonly id: string;
87
+ readonly imageUrl: string;
88
+ readonly title: string;
89
+ readonly date: string;
90
+ readonly isFavorite?: boolean;
91
+ }
92
+
82
93
  /**
83
94
  * Result preview screen props
84
95
  */
@@ -94,6 +105,12 @@ export interface ResultPreviewScreenProps {
94
105
  onTryAgain: () => void;
95
106
  onNavigateBack: () => void;
96
107
  onRate?: () => void;
108
+ /** Recent creations to display */
109
+ recentCreations?: readonly RecentCreation[];
110
+ /** Navigate to all creations */
111
+ onViewAll?: () => void;
112
+ /** View a specific creation */
113
+ onCreationPress?: (creation: RecentCreation) => void;
97
114
  /** Translations */
98
115
  translations: ResultPreviewTranslations;
99
116
  /** Optional custom style */
@@ -118,8 +135,12 @@ export interface ResultPreviewTranslations {
118
135
  sharing: string;
119
136
  /** Try again button */
120
137
  tryAnother: string;
121
- /** Rate button (optional) */
138
+ /** Rate button */
122
139
  rateButton?: string;
140
+ /** Recent creations section title */
141
+ recentCreations?: string;
142
+ /** View all button */
143
+ viewAll?: string;
123
144
  }
124
145
 
125
146
  /**