@umituz/react-native-ai-generation-content 1.12.38 → 1.12.40
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 +1 -1
- package/src/domains/creations/domain/value-objects/CreationsConfig.ts +1 -1
- package/src/domains/creations/presentation/components/index.ts +0 -1
- package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +25 -5
- package/src/domains/creations/presentation/utils/filterUtils.ts +2 -2
- package/src/domains/creations/presentation/components/FilterBottomSheet.tsx +0 -171
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { Creation, CreationDocument } from "../entities/Creation";
|
|
7
|
-
import type { FilterCategory } from "
|
|
7
|
+
import type { FilterCategory } from "@umituz/react-native-design-system";
|
|
8
8
|
|
|
9
9
|
export interface CreationType {
|
|
10
10
|
readonly id: string;
|
|
@@ -11,7 +11,6 @@ export { CreationCard } from "./CreationCard";
|
|
|
11
11
|
export { CreationThumbnail } from "./CreationThumbnail";
|
|
12
12
|
export { CreationImageViewer } from "./CreationImageViewer";
|
|
13
13
|
export { CreationsGrid } from "./CreationsGrid";
|
|
14
|
-
export { FilterBottomSheet, type FilterCategory, type FilterOption } from "./FilterBottomSheet";
|
|
15
14
|
|
|
16
15
|
// Detail Components
|
|
17
16
|
export { DetailHeader } from "./CreationDetail/DetailHeader";
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
+
declare const __DEV__: boolean;
|
|
2
|
+
|
|
1
3
|
import React, { useMemo, useCallback, useState } from "react";
|
|
2
4
|
import { View, StyleSheet, type LayoutChangeEvent } from "react-native";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
+
import {
|
|
6
|
+
useAppDesignTokens,
|
|
7
|
+
useAlert,
|
|
8
|
+
AlertType,
|
|
9
|
+
AlertMode,
|
|
10
|
+
useSharing,
|
|
11
|
+
FilterBottomSheet,
|
|
12
|
+
type DesignTokens,
|
|
13
|
+
type BottomSheetModalRef
|
|
14
|
+
} from "@umituz/react-native-design-system";
|
|
5
15
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
6
16
|
import { useFocusEffect } from "@react-navigation/native";
|
|
7
17
|
import { useCreations } from "../hooks/useCreations";
|
|
8
18
|
import { useDeleteCreation } from "../hooks/useDeleteCreation";
|
|
9
19
|
import { useCreationsFilter } from "../hooks/useCreationsFilter";
|
|
10
|
-
import { GalleryHeader, CreationsGrid,
|
|
20
|
+
import { GalleryHeader, CreationsGrid, CreationImageViewer, GalleryEmptyStates } from "../components";
|
|
11
21
|
import { getTranslatedTypes, getFilterCategoriesFromConfig } from "../utils/filterUtils";
|
|
12
22
|
import type { Creation } from "../../domain/entities/Creation";
|
|
13
23
|
import type { CreationsConfig } from "../../domain/value-objects/CreationsConfig";
|
|
@@ -45,7 +55,7 @@ export function CreationsGalleryScreen({
|
|
|
45
55
|
const [viewerVisible, setViewerVisible] = useState(false);
|
|
46
56
|
const [viewerIndex, setViewerIndex] = useState(0);
|
|
47
57
|
const [selectedCreation, setSelectedCreation] = useState<Creation | null>(null);
|
|
48
|
-
const filterSheetRef = React.useRef<
|
|
58
|
+
const filterSheetRef = React.useRef<BottomSheetModalRef>(null);
|
|
49
59
|
|
|
50
60
|
const { data: creationsData, isLoading, refetch } = useCreations({ userId, repository });
|
|
51
61
|
const creations = creationsData;
|
|
@@ -151,7 +161,17 @@ export function CreationsGalleryScreen({
|
|
|
151
161
|
countLabel={t(config.translations.photoCount) || 'photos'}
|
|
152
162
|
isFiltered={isFiltered}
|
|
153
163
|
filterLabel={t(config.translations.filterLabel) || 'Filter'}
|
|
154
|
-
onFilterPress={() =>
|
|
164
|
+
onFilterPress={() => {
|
|
165
|
+
if (__DEV__) {
|
|
166
|
+
// eslint-disable-next-line no-console
|
|
167
|
+
console.log('[CreationsGallery] Filter button pressed');
|
|
168
|
+
// eslint-disable-next-line no-console
|
|
169
|
+
console.log('[CreationsGallery] filterSheetRef.current:', filterSheetRef.current);
|
|
170
|
+
// eslint-disable-next-line no-console
|
|
171
|
+
console.log('[CreationsGallery] allCategories:', allCategories);
|
|
172
|
+
}
|
|
173
|
+
filterSheetRef.current?.present();
|
|
174
|
+
}}
|
|
155
175
|
style={{ paddingTop: insets.top + tokens.spacing.md }}
|
|
156
176
|
/>
|
|
157
177
|
)}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CreationsConfig } from "../../domain/value-objects/CreationsConfig";
|
|
2
|
-
import { FilterCategory } from "
|
|
1
|
+
import type { CreationsConfig } from "../../domain/value-objects/CreationsConfig";
|
|
2
|
+
import type { FilterCategory } from "@umituz/react-native-design-system";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Transforms the creations configuration into filter categories for the UI.
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import React, { forwardRef, useCallback, useMemo } from 'react';
|
|
2
|
-
import { View, StyleSheet, TouchableOpacity, ScrollView } from 'react-native';
|
|
3
|
-
import { useAppDesignTokens, AtomicText, AtomicIcon, type DesignTokens } from '@umituz/react-native-design-system';
|
|
4
|
-
import { BottomSheetModal } from '@gorhom/bottom-sheet';
|
|
5
|
-
|
|
6
|
-
export interface FilterOption {
|
|
7
|
-
id: string;
|
|
8
|
-
label: string;
|
|
9
|
-
icon?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface FilterCategory {
|
|
13
|
-
id: string;
|
|
14
|
-
title: string;
|
|
15
|
-
multiSelect?: boolean;
|
|
16
|
-
options: FilterOption[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
interface FilterBottomSheetProps {
|
|
20
|
-
categories: FilterCategory[];
|
|
21
|
-
selectedIds: string[];
|
|
22
|
-
onFilterPress: (id: string, categoryId: string) => void;
|
|
23
|
-
onClearFilters: () => void;
|
|
24
|
-
title: string;
|
|
25
|
-
snapPoints?: string[];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const FilterBottomSheet = forwardRef<BottomSheetModal, FilterBottomSheetProps>((props, ref) => {
|
|
29
|
-
const { categories, selectedIds, onFilterPress, onClearFilters, title, snapPoints: propSnapPoints } = props;
|
|
30
|
-
const tokens = useAppDesignTokens();
|
|
31
|
-
const styles = useStyles(tokens);
|
|
32
|
-
|
|
33
|
-
const snapPoints = useMemo(() => propSnapPoints || ['50%', '75%'], [propSnapPoints]);
|
|
34
|
-
|
|
35
|
-
const renderOption = useCallback((option: FilterOption, category: FilterCategory) => {
|
|
36
|
-
const isSelected = selectedIds.includes(option.id);
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<TouchableOpacity
|
|
40
|
-
key={option.id}
|
|
41
|
-
style={[styles.option, isSelected && styles.optionSelected]}
|
|
42
|
-
onPress={() => onFilterPress(option.id, category.id)}
|
|
43
|
-
>
|
|
44
|
-
<View style={styles.optionContent}>
|
|
45
|
-
{option.icon && (
|
|
46
|
-
<View style={styles.optionIcon}>
|
|
47
|
-
<AtomicIcon
|
|
48
|
-
name={option.icon}
|
|
49
|
-
size="sm"
|
|
50
|
-
color={isSelected ? "primary" : "onSurface"}
|
|
51
|
-
/>
|
|
52
|
-
</View>
|
|
53
|
-
)}
|
|
54
|
-
<AtomicText
|
|
55
|
-
style={[styles.optionLabel, isSelected && styles.optionLabelSelected]}
|
|
56
|
-
>
|
|
57
|
-
{option.label}
|
|
58
|
-
</AtomicText>
|
|
59
|
-
</View>
|
|
60
|
-
{isSelected && (
|
|
61
|
-
<AtomicIcon name="checkmark" size="sm" color="primary" />
|
|
62
|
-
)}
|
|
63
|
-
</TouchableOpacity>
|
|
64
|
-
);
|
|
65
|
-
}, [onFilterPress, selectedIds, styles]);
|
|
66
|
-
|
|
67
|
-
const backgroundStyle = useMemo(() => ({
|
|
68
|
-
backgroundColor: tokens.colors.surface,
|
|
69
|
-
}), [tokens.colors.surface]);
|
|
70
|
-
|
|
71
|
-
const handleIndicatorStyle = useMemo(() => ({
|
|
72
|
-
backgroundColor: tokens.colors.outline,
|
|
73
|
-
}), [tokens.colors.outline]);
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
<BottomSheetModal
|
|
77
|
-
ref={ref}
|
|
78
|
-
snapPoints={snapPoints}
|
|
79
|
-
backgroundStyle={backgroundStyle}
|
|
80
|
-
handleIndicatorStyle={handleIndicatorStyle}
|
|
81
|
-
enablePanDownToClose
|
|
82
|
-
>
|
|
83
|
-
<View style={styles.header}>
|
|
84
|
-
<AtomicText style={styles.headerTitle}>{title}</AtomicText>
|
|
85
|
-
<TouchableOpacity onPress={onClearFilters}>
|
|
86
|
-
<AtomicText style={styles.clearButton}>Clear</AtomicText>
|
|
87
|
-
</TouchableOpacity>
|
|
88
|
-
</View>
|
|
89
|
-
|
|
90
|
-
<ScrollView contentContainerStyle={styles.content}>
|
|
91
|
-
{categories.map(category => (
|
|
92
|
-
<View key={category.id} style={styles.categoryContainer}>
|
|
93
|
-
<AtomicText style={styles.categoryTitle}>{category.title}</AtomicText>
|
|
94
|
-
<View style={styles.optionsContainer}>
|
|
95
|
-
{category.options.map(option => renderOption(option, category))}
|
|
96
|
-
</View>
|
|
97
|
-
</View>
|
|
98
|
-
))}
|
|
99
|
-
</ScrollView>
|
|
100
|
-
</BottomSheetModal>
|
|
101
|
-
);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
FilterBottomSheet.displayName = 'FilterBottomSheet';
|
|
105
|
-
|
|
106
|
-
const useStyles = (tokens: DesignTokens) => StyleSheet.create({
|
|
107
|
-
content: {
|
|
108
|
-
padding: tokens.spacing.md,
|
|
109
|
-
paddingBottom: tokens.spacing.xl,
|
|
110
|
-
},
|
|
111
|
-
header: {
|
|
112
|
-
flexDirection: 'row',
|
|
113
|
-
justifyContent: 'space-between',
|
|
114
|
-
alignItems: 'center',
|
|
115
|
-
paddingHorizontal: tokens.spacing.md,
|
|
116
|
-
paddingBottom: tokens.spacing.sm,
|
|
117
|
-
borderBottomWidth: 1,
|
|
118
|
-
borderBottomColor: tokens.colors.outline,
|
|
119
|
-
},
|
|
120
|
-
headerTitle: {
|
|
121
|
-
fontSize: 20,
|
|
122
|
-
fontWeight: '700',
|
|
123
|
-
color: tokens.colors.textPrimary,
|
|
124
|
-
},
|
|
125
|
-
clearButton: {
|
|
126
|
-
color: tokens.colors.primary,
|
|
127
|
-
fontSize: 14,
|
|
128
|
-
fontWeight: '600',
|
|
129
|
-
},
|
|
130
|
-
categoryContainer: {
|
|
131
|
-
marginTop: tokens.spacing.md,
|
|
132
|
-
},
|
|
133
|
-
categoryTitle: {
|
|
134
|
-
marginBottom: tokens.spacing.xs,
|
|
135
|
-
color: tokens.colors.textSecondary,
|
|
136
|
-
fontSize: 16,
|
|
137
|
-
fontWeight: '600',
|
|
138
|
-
},
|
|
139
|
-
optionsContainer: {
|
|
140
|
-
backgroundColor: tokens.colors.background,
|
|
141
|
-
borderRadius: tokens.borders.radius.md,
|
|
142
|
-
overflow: 'hidden',
|
|
143
|
-
},
|
|
144
|
-
option: {
|
|
145
|
-
flexDirection: 'row',
|
|
146
|
-
alignItems: 'center',
|
|
147
|
-
justifyContent: 'space-between',
|
|
148
|
-
padding: tokens.spacing.md,
|
|
149
|
-
backgroundColor: tokens.colors.background,
|
|
150
|
-
borderBottomWidth: 1,
|
|
151
|
-
borderBottomColor: tokens.colors.surface,
|
|
152
|
-
},
|
|
153
|
-
optionSelected: {
|
|
154
|
-
backgroundColor: tokens.colors.surface,
|
|
155
|
-
},
|
|
156
|
-
optionContent: {
|
|
157
|
-
flexDirection: 'row',
|
|
158
|
-
alignItems: 'center',
|
|
159
|
-
},
|
|
160
|
-
optionIcon: {
|
|
161
|
-
marginRight: tokens.spacing.sm,
|
|
162
|
-
},
|
|
163
|
-
optionLabel: {
|
|
164
|
-
color: tokens.colors.textPrimary,
|
|
165
|
-
fontSize: 14,
|
|
166
|
-
},
|
|
167
|
-
optionLabelSelected: {
|
|
168
|
-
color: tokens.colors.primary,
|
|
169
|
-
fontWeight: 'bold',
|
|
170
|
-
},
|
|
171
|
-
});
|