@umituz/react-native-ai-generation-content 1.12.4 → 1.12.5

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.
Files changed (67) hide show
  1. package/package.json +29 -6
  2. package/src/domains/creations/application/services/CreationsService.ts +71 -0
  3. package/src/domains/creations/domain/entities/Creation.ts +51 -0
  4. package/src/domains/creations/domain/entities/index.ts +6 -0
  5. package/src/domains/creations/domain/repositories/ICreationsRepository.ts +23 -0
  6. package/src/domains/creations/domain/repositories/index.ts +5 -0
  7. package/src/domains/creations/domain/services/ICreationsStorageService.ts +13 -0
  8. package/src/domains/creations/domain/value-objects/CreationsConfig.ts +76 -0
  9. package/src/domains/creations/domain/value-objects/index.ts +12 -0
  10. package/src/domains/creations/index.ts +84 -0
  11. package/src/domains/creations/infrastructure/adapters/createRepository.ts +54 -0
  12. package/src/domains/creations/infrastructure/adapters/index.ts +5 -0
  13. package/src/domains/creations/infrastructure/repositories/CreationsRepository.ts +233 -0
  14. package/src/domains/creations/infrastructure/repositories/index.ts +8 -0
  15. package/src/domains/creations/infrastructure/services/CreationsStorageService.ts +48 -0
  16. package/src/domains/creations/presentation/components/CreationCard.tsx +136 -0
  17. package/src/domains/creations/presentation/components/CreationDetail/DetailActions.tsx +76 -0
  18. package/src/domains/creations/presentation/components/CreationDetail/DetailHeader.tsx +81 -0
  19. package/src/domains/creations/presentation/components/CreationDetail/DetailImage.tsx +41 -0
  20. package/src/domains/creations/presentation/components/CreationDetail/DetailStory.tsx +67 -0
  21. package/src/domains/creations/presentation/components/CreationDetail/index.ts +4 -0
  22. package/src/domains/creations/presentation/components/CreationImageViewer.tsx +43 -0
  23. package/src/domains/creations/presentation/components/CreationThumbnail.tsx +63 -0
  24. package/src/domains/creations/presentation/components/CreationsGrid.tsx +75 -0
  25. package/src/domains/creations/presentation/components/CreationsHomeCard.tsx +176 -0
  26. package/src/domains/creations/presentation/components/EmptyState.tsx +75 -0
  27. package/src/domains/creations/presentation/components/FilterBottomSheet.tsx +158 -0
  28. package/src/domains/creations/presentation/components/FilterChips.tsx +105 -0
  29. package/src/domains/creations/presentation/components/GalleryHeader.tsx +106 -0
  30. package/src/domains/creations/presentation/components/index.ts +19 -0
  31. package/src/domains/creations/presentation/hooks/index.ts +7 -0
  32. package/src/domains/creations/presentation/hooks/useCreations.ts +33 -0
  33. package/src/domains/creations/presentation/hooks/useCreationsFilter.ts +70 -0
  34. package/src/domains/creations/presentation/hooks/useDeleteCreation.ts +51 -0
  35. package/src/domains/creations/presentation/screens/CreationDetailScreen.tsx +71 -0
  36. package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +217 -0
  37. package/src/domains/creations/presentation/screens/index.ts +5 -0
  38. package/src/domains/creations/presentation/utils/filterUtils.ts +52 -0
  39. package/src/domains/creations/types.d.ts +107 -0
  40. package/src/domains/face-detection/domain/constants/faceDetectionConstants.ts +16 -0
  41. package/src/domains/face-detection/domain/entities/FaceDetection.ts +19 -0
  42. package/src/domains/face-detection/index.ts +26 -0
  43. package/src/domains/face-detection/infrastructure/analyzers/faceAnalyzer.ts +36 -0
  44. package/src/domains/face-detection/infrastructure/validators/faceValidator.ts +52 -0
  45. package/src/domains/face-detection/presentation/components/FaceValidationStatus.tsx +111 -0
  46. package/src/domains/face-detection/presentation/hooks/useFaceDetection.ts +58 -0
  47. package/src/domains/feature-background/domain/entities/background.types.ts +77 -0
  48. package/src/domains/feature-background/domain/entities/component.types.ts +96 -0
  49. package/src/domains/feature-background/domain/entities/config.types.ts +41 -0
  50. package/src/domains/feature-background/domain/entities/index.ts +31 -0
  51. package/src/domains/feature-background/index.ts +72 -0
  52. package/src/domains/feature-background/infrastructure/constants/index.ts +5 -0
  53. package/src/domains/feature-background/infrastructure/constants/prompts.constants.ts +15 -0
  54. package/src/domains/feature-background/presentation/components/BackgroundFeature.tsx +145 -0
  55. package/src/domains/feature-background/presentation/components/ComparisonSlider.tsx +199 -0
  56. package/src/domains/feature-background/presentation/components/ErrorDisplay.tsx +58 -0
  57. package/src/domains/feature-background/presentation/components/FeatureHeader.tsx +80 -0
  58. package/src/domains/feature-background/presentation/components/GenerateButton.tsx +86 -0
  59. package/src/domains/feature-background/presentation/components/ImagePicker.tsx +136 -0
  60. package/src/domains/feature-background/presentation/components/ModeSelector.tsx +78 -0
  61. package/src/domains/feature-background/presentation/components/ProcessingModal.tsx +113 -0
  62. package/src/domains/feature-background/presentation/components/PromptInput.tsx +142 -0
  63. package/src/domains/feature-background/presentation/components/ResultDisplay.tsx +123 -0
  64. package/src/domains/feature-background/presentation/components/index.ts +16 -0
  65. package/src/domains/feature-background/presentation/hooks/index.ts +7 -0
  66. package/src/domains/feature-background/presentation/hooks/useBackgroundFeature.ts +118 -0
  67. package/src/index.ts +18 -0
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Image Picker Component
3
+ * @description Image selection component with placeholder state
4
+ */
5
+
6
+ import React, { memo } from "react";
7
+ import { View, StyleSheet, TouchableOpacity, Image } from "react-native";
8
+ import {
9
+ AtomicText,
10
+ AtomicIcon,
11
+ useAppDesignTokens,
12
+ } from "@umituz/react-native-design-system";
13
+ import type { ImagePickerProps } from "../../domain/entities";
14
+
15
+ export const ImagePicker: React.FC<ImagePickerProps> = memo(
16
+ function ImagePicker({
17
+ imageUri,
18
+ isProcessing,
19
+ onSelectImage,
20
+ placeholderText,
21
+ }) {
22
+ const tokens = useAppDesignTokens();
23
+
24
+ return (
25
+ <View style={styles.container}>
26
+ <TouchableOpacity
27
+ style={[
28
+ styles.imagePickerBox,
29
+ { backgroundColor: tokens.colors.surface },
30
+ ]}
31
+ onPress={onSelectImage}
32
+ disabled={isProcessing}
33
+ activeOpacity={0.8}
34
+ >
35
+ {imageUri ? (
36
+ <View style={styles.imageContainer}>
37
+ <Image source={{ uri: imageUri }} style={styles.image} />
38
+ <View style={styles.imageOverlay}>
39
+ <View
40
+ style={[
41
+ styles.editBadge,
42
+ { backgroundColor: tokens.colors.primary },
43
+ ]}
44
+ >
45
+ <AtomicIcon
46
+ name="image-plus"
47
+ size={20}
48
+ color="onPrimary"
49
+ />
50
+ </View>
51
+ </View>
52
+ </View>
53
+ ) : (
54
+ <View
55
+ style={[
56
+ styles.placeholderContainer,
57
+ { backgroundColor: tokens.colors.surface },
58
+ ]}
59
+ >
60
+ <View
61
+ style={[
62
+ styles.uploadIconContainer,
63
+ { backgroundColor: tokens.colors.surfaceSecondary },
64
+ ]}
65
+ >
66
+ <AtomicIcon
67
+ name="upload"
68
+ size={40}
69
+ color="primary"
70
+ />
71
+ </View>
72
+ <AtomicText
73
+ type="bodyLarge"
74
+ style={[
75
+ styles.placeholderText,
76
+ { color: tokens.colors.primary },
77
+ ]}
78
+ >
79
+ {placeholderText}
80
+ </AtomicText>
81
+ </View>
82
+ )}
83
+ </TouchableOpacity>
84
+ </View>
85
+ );
86
+ }
87
+ );
88
+
89
+ const styles = StyleSheet.create({
90
+ container: {
91
+ marginVertical: 16,
92
+ alignItems: "center",
93
+ },
94
+ imagePickerBox: {
95
+ width: "100%",
96
+ aspectRatio: 1,
97
+ borderRadius: 20,
98
+ overflow: "hidden",
99
+ },
100
+ imageContainer: {
101
+ flex: 1,
102
+ position: "relative",
103
+ },
104
+ image: {
105
+ width: "100%",
106
+ height: "100%",
107
+ },
108
+ imageOverlay: {
109
+ position: "absolute",
110
+ bottom: 0,
111
+ left: 0,
112
+ right: 0,
113
+ height: "25%",
114
+ justifyContent: "flex-end",
115
+ alignItems: "flex-end",
116
+ padding: 16,
117
+ },
118
+ editBadge: {
119
+ borderRadius: 20,
120
+ padding: 10,
121
+ },
122
+ placeholderContainer: {
123
+ flex: 1,
124
+ justifyContent: "center",
125
+ alignItems: "center",
126
+ },
127
+ uploadIconContainer: {
128
+ borderRadius: 50,
129
+ padding: 24,
130
+ marginBottom: 16,
131
+ },
132
+ placeholderText: {
133
+ textAlign: "center",
134
+ fontWeight: "600",
135
+ },
136
+ });
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Mode Selector Component
3
+ * @description Horizontal scrollable mode selection toolbar
4
+ */
5
+
6
+ import React, { memo } from "react";
7
+ import { View, StyleSheet, ScrollView, TouchableOpacity } from "react-native";
8
+ import {
9
+ AtomicText,
10
+ AtomicIcon,
11
+ useAppDesignTokens,
12
+ } from "@umituz/react-native-design-system";
13
+ import type { ModeSelectorProps } from "../../domain/entities";
14
+
15
+ export const ModeSelector: React.FC<ModeSelectorProps> = memo(
16
+ function ModeSelector({ activeMode, onModeChange, isProcessing, modes }) {
17
+ const tokens = useAppDesignTokens();
18
+
19
+ return (
20
+ <View
21
+ style={[
22
+ styles.container,
23
+ { backgroundColor: tokens.colors.surface },
24
+ ]}
25
+ >
26
+ <ScrollView
27
+ horizontal
28
+ showsHorizontalScrollIndicator={false}
29
+ contentContainerStyle={styles.scrollContent}
30
+ >
31
+ {modes.map((mode) => {
32
+ const isActive = activeMode === mode.id;
33
+ return (
34
+ <TouchableOpacity
35
+ key={mode.id}
36
+ style={[
37
+ styles.modeButton,
38
+ isActive && {
39
+ backgroundColor: tokens.colors.primary,
40
+ },
41
+ ]}
42
+ onPress={() => !isProcessing && onModeChange(mode.id)}
43
+ disabled={isProcessing}
44
+ activeOpacity={0.7}
45
+ >
46
+ <AtomicIcon
47
+ name={mode.icon}
48
+ size={20}
49
+ color={isActive ? "onPrimary" : "onSurface"}
50
+ />
51
+ </TouchableOpacity>
52
+ );
53
+ })}
54
+ </ScrollView>
55
+ </View>
56
+ );
57
+ }
58
+ );
59
+
60
+ const styles = StyleSheet.create({
61
+ container: {
62
+ borderRadius: 24,
63
+ paddingVertical: 8,
64
+ paddingHorizontal: 4,
65
+ },
66
+ scrollContent: {
67
+ flexDirection: "row",
68
+ gap: 8,
69
+ paddingHorizontal: 8,
70
+ },
71
+ modeButton: {
72
+ width: 48,
73
+ height: 48,
74
+ borderRadius: 16,
75
+ justifyContent: "center",
76
+ alignItems: "center",
77
+ },
78
+ });
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Processing Modal Component
3
+ * @description Modal shown during processing with progress
4
+ */
5
+
6
+ import React, { memo } from "react";
7
+ import { Modal, View, StyleSheet, ActivityIndicator } from "react-native";
8
+ import {
9
+ AtomicText,
10
+ useAppDesignTokens,
11
+ } from "@umituz/react-native-design-system";
12
+ import type { ProcessingModalProps } from "../../domain/entities";
13
+
14
+ export const ProcessingModal: React.FC<ProcessingModalProps> = memo(
15
+ function ProcessingModal({ visible, progress = 0, title }) {
16
+ const tokens = useAppDesignTokens();
17
+
18
+ return (
19
+ <Modal
20
+ visible={visible}
21
+ transparent
22
+ animationType="fade"
23
+ statusBarTranslucent
24
+ >
25
+ <View style={styles.overlay}>
26
+ <View
27
+ style={[
28
+ styles.content,
29
+ { backgroundColor: tokens.colors.surface },
30
+ ]}
31
+ >
32
+ <ActivityIndicator
33
+ size="large"
34
+ color={tokens.colors.primary}
35
+ />
36
+ {title && (
37
+ <AtomicText
38
+ type="bodyLarge"
39
+ style={[
40
+ styles.title,
41
+ { color: tokens.colors.textPrimary },
42
+ ]}
43
+ >
44
+ {title}
45
+ </AtomicText>
46
+ )}
47
+ {progress > 0 && (
48
+ <View style={styles.progressContainer}>
49
+ <View
50
+ style={[
51
+ styles.progressBar,
52
+ { backgroundColor: tokens.colors.surfaceSecondary },
53
+ ]}
54
+ >
55
+ <View
56
+ style={[
57
+ styles.progressFill,
58
+ {
59
+ backgroundColor: tokens.colors.primary,
60
+ width: `${Math.min(progress, 100)}%`,
61
+ },
62
+ ]}
63
+ />
64
+ </View>
65
+ <AtomicText
66
+ type="bodySmall"
67
+ style={{ color: tokens.colors.textSecondary }}
68
+ >
69
+ {Math.round(progress)}%
70
+ </AtomicText>
71
+ </View>
72
+ )}
73
+ </View>
74
+ </View>
75
+ </Modal>
76
+ );
77
+ }
78
+ );
79
+
80
+ const styles = StyleSheet.create({
81
+ overlay: {
82
+ flex: 1,
83
+ backgroundColor: "rgba(0, 0, 0, 0.7)",
84
+ justifyContent: "center",
85
+ alignItems: "center",
86
+ },
87
+ content: {
88
+ padding: 32,
89
+ borderRadius: 20,
90
+ alignItems: "center",
91
+ minWidth: 200,
92
+ },
93
+ title: {
94
+ marginTop: 16,
95
+ textAlign: "center",
96
+ },
97
+ progressContainer: {
98
+ marginTop: 16,
99
+ alignItems: "center",
100
+ width: "100%",
101
+ },
102
+ progressBar: {
103
+ width: "100%",
104
+ height: 6,
105
+ borderRadius: 3,
106
+ overflow: "hidden",
107
+ marginBottom: 8,
108
+ },
109
+ progressFill: {
110
+ height: "100%",
111
+ borderRadius: 3,
112
+ },
113
+ });
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Prompt Input Component
3
+ * @description Text input with sample prompt chips
4
+ */
5
+
6
+ import React, { memo } from "react";
7
+ import { View, TextInput, StyleSheet, TouchableOpacity } from "react-native";
8
+ import {
9
+ AtomicText,
10
+ useAppDesignTokens,
11
+ } from "@umituz/react-native-design-system";
12
+ import type { PromptInputProps } from "../../domain/entities";
13
+ import { DEFAULT_SAMPLE_PROMPTS } from "../../infrastructure/constants";
14
+
15
+ export const PromptInput: React.FC<PromptInputProps> = memo(
16
+ function PromptInput({
17
+ value,
18
+ onChangeText,
19
+ isProcessing,
20
+ label,
21
+ placeholder,
22
+ samplePrompts = DEFAULT_SAMPLE_PROMPTS,
23
+ samplePromptsLabel,
24
+ }) {
25
+ const tokens = useAppDesignTokens();
26
+
27
+ return (
28
+ <View style={styles.container}>
29
+ {label && (
30
+ <AtomicText
31
+ type="labelLarge"
32
+ style={[
33
+ styles.label,
34
+ {
35
+ color: tokens.colors.textPrimary,
36
+ marginBottom: tokens.spacing.sm,
37
+ },
38
+ ]}
39
+ >
40
+ {label}
41
+ </AtomicText>
42
+ )}
43
+
44
+ <TextInput
45
+ value={value}
46
+ onChangeText={onChangeText}
47
+ placeholder={placeholder}
48
+ placeholderTextColor={tokens.colors.textTertiary}
49
+ multiline
50
+ numberOfLines={4}
51
+ editable={!isProcessing}
52
+ style={[
53
+ styles.input,
54
+ {
55
+ backgroundColor: tokens.colors.surface,
56
+ borderColor: tokens.colors.border,
57
+ color: tokens.colors.textPrimary,
58
+ },
59
+ ]}
60
+ />
61
+
62
+ {samplePrompts.length > 0 && (
63
+ <>
64
+ {samplePromptsLabel && (
65
+ <AtomicText
66
+ type="labelMedium"
67
+ style={[
68
+ styles.sampleLabel,
69
+ {
70
+ color: tokens.colors.textSecondary,
71
+ marginTop: tokens.spacing.md,
72
+ marginBottom: tokens.spacing.sm,
73
+ },
74
+ ]}
75
+ >
76
+ {samplePromptsLabel}
77
+ </AtomicText>
78
+ )}
79
+
80
+ <View style={styles.sampleContainer}>
81
+ {samplePrompts.map((prompt) => (
82
+ <TouchableOpacity
83
+ key={prompt.id}
84
+ style={[
85
+ styles.sampleChip,
86
+ {
87
+ backgroundColor: tokens.colors.surfaceSecondary,
88
+ borderColor: tokens.colors.border,
89
+ },
90
+ ]}
91
+ onPress={() => onChangeText(prompt.text)}
92
+ disabled={isProcessing}
93
+ >
94
+ <AtomicText
95
+ type="bodySmall"
96
+ style={{ color: tokens.colors.textSecondary }}
97
+ numberOfLines={1}
98
+ >
99
+ {prompt.text}
100
+ </AtomicText>
101
+ </TouchableOpacity>
102
+ ))}
103
+ </View>
104
+ </>
105
+ )}
106
+ </View>
107
+ );
108
+ }
109
+ );
110
+
111
+ const styles = StyleSheet.create({
112
+ container: {
113
+ marginVertical: 16,
114
+ },
115
+ label: {
116
+ fontWeight: "600",
117
+ },
118
+ input: {
119
+ minHeight: 120,
120
+ borderWidth: 1,
121
+ borderRadius: 16,
122
+ paddingHorizontal: 16,
123
+ paddingVertical: 14,
124
+ fontSize: 16,
125
+ textAlignVertical: "top",
126
+ lineHeight: 24,
127
+ },
128
+ sampleLabel: {
129
+ fontWeight: "500",
130
+ },
131
+ sampleContainer: {
132
+ flexDirection: "row",
133
+ flexWrap: "wrap",
134
+ gap: 8,
135
+ },
136
+ sampleChip: {
137
+ paddingHorizontal: 12,
138
+ paddingVertical: 8,
139
+ borderRadius: 20,
140
+ borderWidth: 1,
141
+ },
142
+ });
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Result Display Component
3
+ * @description Displays processed image with save/reset actions
4
+ */
5
+
6
+ import React, { memo } from "react";
7
+ import { View, StyleSheet, Image, TouchableOpacity } from "react-native";
8
+ import {
9
+ AtomicText,
10
+ AtomicIcon,
11
+ useAppDesignTokens,
12
+ } from "@umituz/react-native-design-system";
13
+ import type { ResultDisplayProps } from "../../domain/entities";
14
+
15
+ export const ResultDisplay: React.FC<ResultDisplayProps> = memo(
16
+ function ResultDisplay({
17
+ imageUrl,
18
+ isProcessing,
19
+ onSave,
20
+ onReset,
21
+ saveButtonText,
22
+ resetButtonText,
23
+ }) {
24
+ const tokens = useAppDesignTokens();
25
+
26
+ if (!imageUrl || isProcessing) {
27
+ return null;
28
+ }
29
+
30
+ return (
31
+ <View style={styles.container}>
32
+ <View style={styles.resultContainer}>
33
+ <Image
34
+ source={{ uri: imageUrl }}
35
+ style={styles.resultImage}
36
+ resizeMode="cover"
37
+ />
38
+ </View>
39
+
40
+ <View style={styles.actionsContainer}>
41
+ <TouchableOpacity
42
+ style={[
43
+ styles.actionButton,
44
+ { backgroundColor: tokens.colors.backgroundSecondary },
45
+ ]}
46
+ onPress={onReset}
47
+ >
48
+ <AtomicIcon
49
+ name="refresh-cw"
50
+ size={20}
51
+ color="onSurface"
52
+ />
53
+ <AtomicText
54
+ type="labelLarge"
55
+ style={[styles.actionText, { color: tokens.colors.textPrimary }]}
56
+ >
57
+ {resetButtonText}
58
+ </AtomicText>
59
+ </TouchableOpacity>
60
+
61
+ <TouchableOpacity
62
+ style={[
63
+ styles.actionButton,
64
+ { backgroundColor: tokens.colors.success },
65
+ ]}
66
+ onPress={onSave}
67
+ >
68
+ <AtomicIcon
69
+ name="download"
70
+ size={20}
71
+ color="onPrimary"
72
+ />
73
+ <AtomicText
74
+ type="labelLarge"
75
+ style={[
76
+ styles.actionText,
77
+ { color: tokens.colors.backgroundPrimary },
78
+ ]}
79
+ >
80
+ {saveButtonText}
81
+ </AtomicText>
82
+ </TouchableOpacity>
83
+ </View>
84
+ </View>
85
+ );
86
+ }
87
+ );
88
+
89
+ const styles = StyleSheet.create({
90
+ container: {
91
+ marginTop: 24,
92
+ marginBottom: 16,
93
+ },
94
+ resultContainer: {
95
+ width: "100%",
96
+ aspectRatio: 1,
97
+ borderRadius: 24,
98
+ overflow: "hidden",
99
+ marginBottom: 16,
100
+ borderWidth: 1,
101
+ borderColor: "rgba(255,255,255,0.1)",
102
+ },
103
+ resultImage: {
104
+ width: "100%",
105
+ height: "100%",
106
+ },
107
+ actionsContainer: {
108
+ flexDirection: "row",
109
+ gap: 12,
110
+ },
111
+ actionButton: {
112
+ flex: 1,
113
+ flexDirection: "row",
114
+ alignItems: "center",
115
+ justifyContent: "center",
116
+ paddingVertical: 14,
117
+ borderRadius: 16,
118
+ gap: 8,
119
+ },
120
+ actionText: {
121
+ fontWeight: "600",
122
+ },
123
+ });
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Presentation Components Export
3
+ */
4
+
5
+ export { BackgroundFeature } from "./BackgroundFeature";
6
+ export type { BackgroundFeatureProps } from "./BackgroundFeature";
7
+
8
+ export { ImagePicker } from "./ImagePicker";
9
+ export { PromptInput } from "./PromptInput";
10
+ export { GenerateButton } from "./GenerateButton";
11
+ export { ResultDisplay } from "./ResultDisplay";
12
+ export { ErrorDisplay } from "./ErrorDisplay";
13
+ export { ProcessingModal } from "./ProcessingModal";
14
+ export { FeatureHeader } from "./FeatureHeader";
15
+ export { ComparisonSlider } from "./ComparisonSlider";
16
+ export { ModeSelector } from "./ModeSelector";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Presentation Hooks Export
3
+ */
4
+
5
+ export { useBackgroundFeature } from "./useBackgroundFeature";
6
+
7
+ export type { UseBackgroundFeatureReturn } from "./useBackgroundFeature";