@umituz/react-native-ai-generation-content 1.12.21 → 1.12.23
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 +33 -15
- package/src/domains/content-moderation/infrastructure/services/content-moderation.service.ts +4 -32
- package/src/domains/content-moderation/infrastructure/services/moderators/base.moderator.ts +1 -1
- package/src/domains/face-detection/infrastructure/validators/faceValidator.ts +1 -1
- package/src/domains/face-detection/presentation/components/FaceValidationStatus.tsx +3 -3
- package/src/domains/feature-background/presentation/components/BackgroundFeature.tsx +5 -4
- package/src/domains/feature-background/presentation/components/ComparisonSlider.tsx +45 -51
- package/src/domains/feature-background/presentation/components/ErrorDisplay.tsx +5 -3
- package/src/domains/feature-background/presentation/components/ModeSelector.tsx +2 -2
- package/src/domains/feature-background/presentation/hooks/useBackgroundFeature.ts +3 -2
- package/src/domains/prompts/domain/entities/FuturePredictionConfig.ts +2 -1
- package/src/domains/prompts/domain/entities/GeneratedPrompt.ts +0 -1
- package/src/domains/prompts/domain/repositories/IAIPromptServices.ts +6 -12
- package/src/domains/prompts/infrastructure/repositories/PromptHistoryRepository.ts +42 -42
- package/src/domains/prompts/infrastructure/repositories/TemplateRepository.ts +42 -42
- package/src/domains/prompts/infrastructure/services/BackgroundRemovalService.ts +7 -7
- package/src/domains/prompts/infrastructure/services/ColorizationService.ts +7 -7
- package/src/domains/prompts/infrastructure/services/FaceSwapService.ts +19 -20
- package/src/domains/prompts/infrastructure/services/FuturePredictionService.ts +11 -31
- package/src/domains/prompts/infrastructure/services/ImageEnhancementService.ts +7 -7
- package/src/domains/prompts/infrastructure/services/PhotoRestorationService.ts +7 -7
- package/src/domains/prompts/infrastructure/services/PromptGenerationService.ts +13 -13
- package/src/domains/prompts/infrastructure/services/StyleTransferService.ts +8 -8
- package/src/domains/prompts/infrastructure/services/TextGenerationService.ts +7 -7
- package/src/domains/prompts/presentation/hooks/useAIServices.ts +30 -28
- package/src/domains/prompts/presentation/hooks/useFaceSwap.ts +1 -2
- package/src/domains/prompts/presentation/hooks/usePromptGeneration.ts +4 -5
- package/src/domains/prompts/presentation/hooks/useStyleTransfer.ts +1 -1
- package/src/domains/prompts/presentation/hooks/useTemplateRepository.ts +3 -3
- package/src/domains/prompts/presentation/theme/utils.ts +1 -1
- package/src/index.ts +0 -5
- package/src/infrastructure/utils/status-checker.util.ts +4 -4
- package/src/infrastructure/wrappers/synchronous-generation.wrapper.ts +3 -3
- package/src/presentation/components/result/GenerationResultContent.tsx +21 -22
- package/src/presentation/components/result/ResultActions.tsx +51 -52
- package/src/presentation/components/result/ResultHeader.tsx +24 -25
- package/src/presentation/components/result/ResultImageCard.tsx +19 -20
- package/src/presentation/components/result/ResultStoryCard.tsx +23 -24
- package/src/presentation/hooks/photo-generation.types.ts +4 -4
- package/src/presentation/hooks/usePhotoGeneration.ts +18 -13
- package/src/domains/creations/application/services/CreationsService.ts +0 -72
- package/src/domains/creations/domain/entities/Creation.ts +0 -54
- package/src/domains/creations/domain/entities/index.ts +0 -6
- package/src/domains/creations/domain/repositories/ICreationsRepository.ts +0 -25
- package/src/domains/creations/domain/repositories/index.ts +0 -5
- package/src/domains/creations/domain/services/ICreationsStorageService.ts +0 -13
- package/src/domains/creations/domain/value-objects/CreationsConfig.ts +0 -77
- package/src/domains/creations/domain/value-objects/index.ts +0 -12
- package/src/domains/creations/index.ts +0 -84
- package/src/domains/creations/infrastructure/adapters/createRepository.ts +0 -54
- package/src/domains/creations/infrastructure/adapters/index.ts +0 -5
- package/src/domains/creations/infrastructure/repositories/CreationsRepository.ts +0 -263
- package/src/domains/creations/infrastructure/repositories/index.ts +0 -8
- package/src/domains/creations/infrastructure/services/CreationsStorageService.ts +0 -48
- package/src/domains/creations/presentation/components/CreationCard.tsx +0 -196
- package/src/domains/creations/presentation/components/CreationDetail/DetailActions.tsx +0 -76
- package/src/domains/creations/presentation/components/CreationDetail/DetailHeader.tsx +0 -81
- package/src/domains/creations/presentation/components/CreationDetail/DetailImage.tsx +0 -41
- package/src/domains/creations/presentation/components/CreationDetail/DetailStory.tsx +0 -67
- package/src/domains/creations/presentation/components/CreationDetail/index.ts +0 -4
- package/src/domains/creations/presentation/components/CreationImageViewer.tsx +0 -101
- package/src/domains/creations/presentation/components/CreationThumbnail.tsx +0 -63
- package/src/domains/creations/presentation/components/CreationsGalleryEmptyState.tsx +0 -77
- package/src/domains/creations/presentation/components/CreationsGrid.tsx +0 -87
- package/src/domains/creations/presentation/components/CreationsHomeCard.tsx +0 -176
- package/src/domains/creations/presentation/components/EmptyState.tsx +0 -75
- package/src/domains/creations/presentation/components/FilterBottomSheet.tsx +0 -157
- package/src/domains/creations/presentation/components/FilterChips.tsx +0 -105
- package/src/domains/creations/presentation/components/GalleryHeader.tsx +0 -157
- package/src/domains/creations/presentation/components/index.ts +0 -20
- package/src/domains/creations/presentation/hooks/index.ts +0 -9
- package/src/domains/creations/presentation/hooks/useCreations.ts +0 -33
- package/src/domains/creations/presentation/hooks/useCreationsFilter.ts +0 -90
- package/src/domains/creations/presentation/hooks/useDeleteCreation.ts +0 -51
- package/src/domains/creations/presentation/hooks/useDeleteMultipleCreations.ts +0 -57
- package/src/domains/creations/presentation/hooks/useToggleFavorite.ts +0 -59
- package/src/domains/creations/presentation/screens/CreationDetailScreen.tsx +0 -71
- package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +0 -264
- package/src/domains/creations/presentation/screens/index.ts +0 -5
- package/src/domains/creations/presentation/utils/filterUtils.ts +0 -52
- package/src/domains/creations/types.d.ts +0 -107
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useToggleFavorite Hook
|
|
3
|
-
* Handles favoriting/unfavoriting of user creations with optimistic update
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
7
|
-
import type { ICreationsRepository } from "../../domain/repositories/ICreationsRepository";
|
|
8
|
-
import type { Creation } from "../../domain/entities/Creation";
|
|
9
|
-
|
|
10
|
-
interface UseToggleFavoriteProps {
|
|
11
|
-
readonly userId: string | null;
|
|
12
|
-
readonly repository: ICreationsRepository;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function useToggleFavorite({
|
|
16
|
-
userId,
|
|
17
|
-
repository,
|
|
18
|
-
}: UseToggleFavoriteProps) {
|
|
19
|
-
const queryClient = useQueryClient();
|
|
20
|
-
|
|
21
|
-
return useMutation({
|
|
22
|
-
mutationFn: async (creationId: string) => {
|
|
23
|
-
if (!userId) return false;
|
|
24
|
-
return repository.toggleFavorite(userId, creationId);
|
|
25
|
-
},
|
|
26
|
-
onMutate: async (creationId) => {
|
|
27
|
-
if (!userId) return;
|
|
28
|
-
|
|
29
|
-
await queryClient.cancelQueries({
|
|
30
|
-
queryKey: ["creations", userId],
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const previous = queryClient.getQueryData<Creation[]>([
|
|
34
|
-
"creations",
|
|
35
|
-
userId,
|
|
36
|
-
]);
|
|
37
|
-
|
|
38
|
-
queryClient.setQueryData<Creation[]>(
|
|
39
|
-
["creations", userId],
|
|
40
|
-
(old) =>
|
|
41
|
-
old?.map((c) =>
|
|
42
|
-
c.id === creationId ? { ...c, isFavorite: !c.isFavorite } : c,
|
|
43
|
-
) ?? [],
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
return { previous };
|
|
47
|
-
},
|
|
48
|
-
onError: (_err, _id, rollback) => {
|
|
49
|
-
if (userId && rollback?.previous) {
|
|
50
|
-
queryClient.setQueryData(["creations", userId], rollback.previous);
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
onSettled: () => {
|
|
54
|
-
if (userId) {
|
|
55
|
-
queryClient.invalidateQueries({ queryKey: ["creations", userId] });
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { View, StyleSheet, ScrollView } from 'react-native';
|
|
4
|
-
import { useAppDesignTokens } from "@umituz/react-native-design-system";
|
|
5
|
-
import type { Creation } from '../../domain/entities/Creation';
|
|
6
|
-
import { DetailHeader } from '../components/CreationDetail/DetailHeader';
|
|
7
|
-
import { DetailImage } from '../components/CreationDetail/DetailImage';
|
|
8
|
-
import { DetailStory } from '../components/CreationDetail/DetailStory';
|
|
9
|
-
import { DetailActions } from '../components/CreationDetail/DetailActions';
|
|
10
|
-
|
|
11
|
-
interface CreationDetailScreenProps {
|
|
12
|
-
readonly creation: Creation;
|
|
13
|
-
readonly onClose: () => void;
|
|
14
|
-
readonly onShare: (creation: Creation) => void;
|
|
15
|
-
readonly onDelete: (creation: Creation) => void;
|
|
16
|
-
readonly t: (key: string) => string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const CreationDetailScreen: React.FC<CreationDetailScreenProps> = ({
|
|
20
|
-
creation,
|
|
21
|
-
onClose,
|
|
22
|
-
onShare,
|
|
23
|
-
onDelete,
|
|
24
|
-
t
|
|
25
|
-
}) => {
|
|
26
|
-
const tokens = useAppDesignTokens();
|
|
27
|
-
|
|
28
|
-
// Extract data
|
|
29
|
-
const metadata = (creation as any).metadata || {};
|
|
30
|
-
const title = metadata.names || creation.type;
|
|
31
|
-
const story = metadata.story || metadata.description || "";
|
|
32
|
-
const date = metadata.date || new Date(creation.createdAt).toLocaleDateString();
|
|
33
|
-
|
|
34
|
-
const styles = useStyles(tokens);
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<View style={styles.container}>
|
|
38
|
-
<DetailHeader
|
|
39
|
-
title={title}
|
|
40
|
-
date={date}
|
|
41
|
-
onClose={onClose}
|
|
42
|
-
/>
|
|
43
|
-
|
|
44
|
-
<ScrollView
|
|
45
|
-
contentContainerStyle={styles.scrollContent}
|
|
46
|
-
showsVerticalScrollIndicator={false}
|
|
47
|
-
>
|
|
48
|
-
<DetailImage uri={creation.uri} />
|
|
49
|
-
|
|
50
|
-
<DetailStory story={story} />
|
|
51
|
-
|
|
52
|
-
<DetailActions
|
|
53
|
-
onShare={() => onShare(creation)}
|
|
54
|
-
onDelete={() => onDelete(creation)}
|
|
55
|
-
shareLabel={t("result.shareButton") || "Share"}
|
|
56
|
-
deleteLabel={t("common.delete") || "Delete"}
|
|
57
|
-
/>
|
|
58
|
-
</ScrollView>
|
|
59
|
-
</View>
|
|
60
|
-
);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const useStyles = (tokens: any) => StyleSheet.create({
|
|
64
|
-
container: {
|
|
65
|
-
flex: 1,
|
|
66
|
-
backgroundColor: tokens.colors.backgroundPrimary,
|
|
67
|
-
},
|
|
68
|
-
scrollContent: {
|
|
69
|
-
paddingBottom: tokens.spacing.xxl,
|
|
70
|
-
},
|
|
71
|
-
});
|
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
import React, { useMemo, useCallback, useState } from "react";
|
|
2
|
-
import { View, TouchableOpacity } from "react-native";
|
|
3
|
-
import {
|
|
4
|
-
useAppDesignTokens,
|
|
5
|
-
useSharing,
|
|
6
|
-
ScreenLayout,
|
|
7
|
-
ScreenHeader,
|
|
8
|
-
useAlert,
|
|
9
|
-
AlertMode,
|
|
10
|
-
AtomicIcon,
|
|
11
|
-
type BottomSheetModalRef
|
|
12
|
-
} from "@umituz/react-native-design-system";
|
|
13
|
-
import { useCreations } from "../hooks/useCreations";
|
|
14
|
-
import { useDeleteCreation } from "../hooks/useDeleteCreation";
|
|
15
|
-
import { useCreationsFilter } from "../hooks/useCreationsFilter";
|
|
16
|
-
import { useToggleFavorite } from "../hooks/useToggleFavorite";
|
|
17
|
-
import { useDeleteMultipleCreations } from "../hooks/useDeleteMultipleCreations";
|
|
18
|
-
import {
|
|
19
|
-
GalleryHeader,
|
|
20
|
-
CreationsGrid,
|
|
21
|
-
FilterBottomSheet,
|
|
22
|
-
CreationImageViewer,
|
|
23
|
-
CreationsGalleryEmptyState
|
|
24
|
-
} from "../components";
|
|
25
|
-
import { SearchBar } from "@umituz/react-native-design-system";
|
|
26
|
-
import { getTranslatedTypes, getFilterCategoriesFromConfig } from "../utils/filterUtils";
|
|
27
|
-
import type { Creation } from "../../domain/entities/Creation";
|
|
28
|
-
import type { CreationsConfig } from "../../domain/value-objects/CreationsConfig";
|
|
29
|
-
import type { ICreationsRepository } from "../../domain/repositories/ICreationsRepository";
|
|
30
|
-
|
|
31
|
-
interface CreationsGalleryScreenProps {
|
|
32
|
-
readonly userId: string | null;
|
|
33
|
-
readonly repository: ICreationsRepository;
|
|
34
|
-
readonly config: CreationsConfig;
|
|
35
|
-
readonly t: (key: string, options?: any) => string;
|
|
36
|
-
readonly enableEditing?: boolean;
|
|
37
|
-
readonly onImageEdit?: (uri: string, creationId: string) => void | Promise<void>;
|
|
38
|
-
readonly onEmptyAction?: () => void;
|
|
39
|
-
readonly emptyActionLabel?: string;
|
|
40
|
-
readonly onBackPress?: () => void;
|
|
41
|
-
readonly headerTitle?: string;
|
|
42
|
-
readonly showCount?: boolean;
|
|
43
|
-
readonly enableSearch?: boolean;
|
|
44
|
-
readonly enableFilter?: boolean;
|
|
45
|
-
readonly showGalleryHeader?: boolean;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function CreationsGalleryScreen({
|
|
49
|
-
userId,
|
|
50
|
-
repository,
|
|
51
|
-
config,
|
|
52
|
-
t,
|
|
53
|
-
enableEditing = false,
|
|
54
|
-
onImageEdit,
|
|
55
|
-
onEmptyAction,
|
|
56
|
-
emptyActionLabel,
|
|
57
|
-
onBackPress,
|
|
58
|
-
headerTitle,
|
|
59
|
-
showCount = true,
|
|
60
|
-
enableSearch = true,
|
|
61
|
-
enableFilter = false,
|
|
62
|
-
showGalleryHeader = true,
|
|
63
|
-
}: CreationsGalleryScreenProps) {
|
|
64
|
-
const tokens = useAppDesignTokens();
|
|
65
|
-
const { share } = useSharing();
|
|
66
|
-
const alert = useAlert();
|
|
67
|
-
|
|
68
|
-
const [viewerVisible, setViewerVisible] = useState(false);
|
|
69
|
-
const [viewerIndex, setViewerIndex] = useState(0);
|
|
70
|
-
const [selectedCreation, setSelectedCreation] = useState<Creation | null>(null);
|
|
71
|
-
const filterSheetRef = React.useRef<BottomSheetModalRef>(null);
|
|
72
|
-
|
|
73
|
-
const { data: creationsData, isLoading, refetch } = useCreations({ userId, repository });
|
|
74
|
-
const creations = creationsData as Creation[] | undefined;
|
|
75
|
-
|
|
76
|
-
const deleteMutation = useDeleteCreation({ userId, repository });
|
|
77
|
-
const toggleFavoriteMutation = useToggleFavorite({ userId, repository });
|
|
78
|
-
const deleteMultipleMutation = useDeleteMultipleCreations({ userId, repository });
|
|
79
|
-
|
|
80
|
-
const {
|
|
81
|
-
filtered,
|
|
82
|
-
selectedIds: selectedCategoryIds,
|
|
83
|
-
searchQuery,
|
|
84
|
-
setSearchQuery,
|
|
85
|
-
showOnlyFavorites,
|
|
86
|
-
setShowOnlyFavorites,
|
|
87
|
-
toggleFilter,
|
|
88
|
-
clearFilters,
|
|
89
|
-
isFiltered
|
|
90
|
-
} = useCreationsFilter({ creations });
|
|
91
|
-
|
|
92
|
-
const [selectedItemIds, setSelectedItemIds] = useState<string[]>([]);
|
|
93
|
-
const [isSelectionMode, setIsSelectionMode] = useState(false);
|
|
94
|
-
|
|
95
|
-
// Prepare data for UI using utils
|
|
96
|
-
const translatedTypes = useMemo(() => getTranslatedTypes(config, t), [config, t]);
|
|
97
|
-
const allCategories = useMemo(() => getFilterCategoriesFromConfig(config, t), [config, t]);
|
|
98
|
-
|
|
99
|
-
const handleShare = useCallback(async (creation: Creation) => {
|
|
100
|
-
share(creation.uri, { dialogTitle: t("common.share") });
|
|
101
|
-
}, [share, t]);
|
|
102
|
-
|
|
103
|
-
const handleDelete = useCallback(async (creation: Creation) => {
|
|
104
|
-
alert.showWarning(
|
|
105
|
-
t(config.translations.deleteTitle),
|
|
106
|
-
t(config.translations.deleteMessage),
|
|
107
|
-
{
|
|
108
|
-
mode: AlertMode.MODAL,
|
|
109
|
-
actions: [
|
|
110
|
-
{ id: 'cancel', label: t("common.cancel"), onPress: () => { } },
|
|
111
|
-
{
|
|
112
|
-
id: 'delete', label: t("common.delete"), style: 'destructive', onPress: async () => {
|
|
113
|
-
const success = await deleteMutation.mutateAsync(creation.id);
|
|
114
|
-
if (success) setSelectedCreation(null);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
]
|
|
118
|
-
}
|
|
119
|
-
);
|
|
120
|
-
}, [alert, config, deleteMutation, t]);
|
|
121
|
-
|
|
122
|
-
const handleToggleFavorite = useCallback((creation: Creation) => {
|
|
123
|
-
toggleFavoriteMutation.mutate(creation.id);
|
|
124
|
-
}, [toggleFavoriteMutation]);
|
|
125
|
-
|
|
126
|
-
const toggleSelection = useCallback((creation: Creation) => {
|
|
127
|
-
setSelectedItemIds(prev => {
|
|
128
|
-
const isSelected = prev.includes(creation.id);
|
|
129
|
-
const next = isSelected ? prev.filter(id => id !== creation.id) : [...prev, creation.id];
|
|
130
|
-
if (next.length === 0) setIsSelectionMode(false);
|
|
131
|
-
else setIsSelectionMode(true);
|
|
132
|
-
return next;
|
|
133
|
-
});
|
|
134
|
-
}, []);
|
|
135
|
-
|
|
136
|
-
const handleDeleteSelected = useCallback(() => {
|
|
137
|
-
if (selectedItemIds.length === 0) return;
|
|
138
|
-
|
|
139
|
-
alert.showWarning(
|
|
140
|
-
t(config.translations.deleteTitle),
|
|
141
|
-
t("common.delete_selected_confirm") || `Are you sure you want to delete ${selectedItemIds.length} items?`,
|
|
142
|
-
{
|
|
143
|
-
mode: AlertMode.MODAL,
|
|
144
|
-
actions: [
|
|
145
|
-
{ id: 'cancel', label: t("common.cancel"), onPress: () => { } },
|
|
146
|
-
{
|
|
147
|
-
id: 'delete', label: t("common.delete"), style: 'destructive', onPress: async () => {
|
|
148
|
-
const success = await deleteMultipleMutation.mutateAsync(selectedItemIds);
|
|
149
|
-
if (success) {
|
|
150
|
-
setSelectedItemIds([]);
|
|
151
|
-
setIsSelectionMode(false);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
]
|
|
156
|
-
}
|
|
157
|
-
);
|
|
158
|
-
}, [alert, config, deleteMultipleMutation, selectedItemIds, t]);
|
|
159
|
-
|
|
160
|
-
// Handle viewing a creation - shows detail screen
|
|
161
|
-
const handleView = useCallback((creation: Creation) => {
|
|
162
|
-
setSelectedCreation(creation);
|
|
163
|
-
setViewerIndex(filtered.findIndex(c => c.id === creation.id));
|
|
164
|
-
setViewerVisible(true);
|
|
165
|
-
}, [filtered]);
|
|
166
|
-
|
|
167
|
-
const screenTitle = headerTitle || t(config.translations.title) || 'My Creations';
|
|
168
|
-
const showScreenHeader = !!onBackPress;
|
|
169
|
-
|
|
170
|
-
return (
|
|
171
|
-
<ScreenLayout
|
|
172
|
-
edges={['top']}
|
|
173
|
-
scrollable={false}
|
|
174
|
-
header={
|
|
175
|
-
<View>
|
|
176
|
-
{showScreenHeader && (
|
|
177
|
-
<ScreenHeader
|
|
178
|
-
title={isSelectionMode ? `${selectedItemIds.length} Selected` : screenTitle}
|
|
179
|
-
onBackPress={isSelectionMode ? () => { setIsSelectionMode(false); setSelectedItemIds([]); } : onBackPress}
|
|
180
|
-
rightAction={isSelectionMode ? (
|
|
181
|
-
<TouchableOpacity onPress={handleDeleteSelected}>
|
|
182
|
-
<AtomicIcon name="trash" color="error" size="md" />
|
|
183
|
-
</TouchableOpacity>
|
|
184
|
-
) : undefined}
|
|
185
|
-
/>
|
|
186
|
-
)}
|
|
187
|
-
{!isSelectionMode && enableSearch && (
|
|
188
|
-
<View style={{ paddingHorizontal: tokens.spacing.md, paddingBottom: tokens.spacing.xs }}>
|
|
189
|
-
<SearchBar
|
|
190
|
-
placeholder={t("common.search") || "Search Prompt..."}
|
|
191
|
-
value={searchQuery}
|
|
192
|
-
onChangeText={setSearchQuery}
|
|
193
|
-
/>
|
|
194
|
-
</View>
|
|
195
|
-
)}
|
|
196
|
-
</View>
|
|
197
|
-
}
|
|
198
|
-
contentContainerStyle={{ paddingHorizontal: 0 }}
|
|
199
|
-
>
|
|
200
|
-
{creations && creations.length > 0 && showGalleryHeader && (
|
|
201
|
-
<GalleryHeader
|
|
202
|
-
title={showScreenHeader || isSelectionMode ? '' : screenTitle}
|
|
203
|
-
count={filtered.length}
|
|
204
|
-
countLabel=''
|
|
205
|
-
subtitle={showCount ? t(config.translations.photoCount, { count: filtered.length }) : undefined}
|
|
206
|
-
isFiltered={isFiltered}
|
|
207
|
-
filterLabel={t(config.translations.filterLabel) || 'Filter'}
|
|
208
|
-
onFilterPress={() => filterSheetRef.current?.present()}
|
|
209
|
-
onFavoritesPress={() => setShowOnlyFavorites(!showOnlyFavorites)}
|
|
210
|
-
showOnlyFavorites={showOnlyFavorites}
|
|
211
|
-
isFilterEnabled={enableFilter}
|
|
212
|
-
showCount={showCount}
|
|
213
|
-
/>
|
|
214
|
-
)}
|
|
215
|
-
|
|
216
|
-
{/* Main Content Grid - handles empty/loading via ListEmptyComponent */}
|
|
217
|
-
<CreationsGrid
|
|
218
|
-
creations={filtered}
|
|
219
|
-
types={translatedTypes}
|
|
220
|
-
isLoading={isLoading}
|
|
221
|
-
onRefresh={refetch}
|
|
222
|
-
onView={handleView}
|
|
223
|
-
onShare={handleShare}
|
|
224
|
-
onDelete={handleDelete}
|
|
225
|
-
onToggleFavorite={handleToggleFavorite}
|
|
226
|
-
isSelectionMode={isSelectionMode}
|
|
227
|
-
selectedIds={selectedItemIds}
|
|
228
|
-
onSelect={toggleSelection}
|
|
229
|
-
contentContainerStyle={{ paddingBottom: tokens.spacing.xl }}
|
|
230
|
-
ListEmptyComponent={
|
|
231
|
-
<CreationsGalleryEmptyState
|
|
232
|
-
isLoading={isLoading}
|
|
233
|
-
hasCreations={!!creations && creations.length > 0}
|
|
234
|
-
config={config}
|
|
235
|
-
t={t}
|
|
236
|
-
emptyActionLabel={emptyActionLabel}
|
|
237
|
-
onEmptyAction={onEmptyAction}
|
|
238
|
-
clearFilters={clearFilters}
|
|
239
|
-
/>
|
|
240
|
-
}
|
|
241
|
-
/>
|
|
242
|
-
|
|
243
|
-
<CreationImageViewer
|
|
244
|
-
creations={filtered}
|
|
245
|
-
visible={viewerVisible}
|
|
246
|
-
index={viewerIndex}
|
|
247
|
-
onDismiss={() => setViewerVisible(false)}
|
|
248
|
-
onIndexChange={setViewerIndex}
|
|
249
|
-
enableEditing={enableEditing}
|
|
250
|
-
onImageEdit={onImageEdit}
|
|
251
|
-
selectedCreationId={(selectedCreation as Creation | null)?.id}
|
|
252
|
-
/>
|
|
253
|
-
|
|
254
|
-
<FilterBottomSheet
|
|
255
|
-
ref={filterSheetRef}
|
|
256
|
-
categories={allCategories}
|
|
257
|
-
selectedIds={selectedCategoryIds}
|
|
258
|
-
onFilterPress={(id, catId) => toggleFilter(id, allCategories.find(c => c.id === catId)?.multiSelect)}
|
|
259
|
-
onClearFilters={clearFilters}
|
|
260
|
-
title={t(config.translations.filterTitle) || t("common.filter")}
|
|
261
|
-
/>
|
|
262
|
-
</ScreenLayout>
|
|
263
|
-
);
|
|
264
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { CreationsConfig } from "../../domain/value-objects/CreationsConfig";
|
|
2
|
-
import { FilterCategory } from "../components/FilterBottomSheet";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Transforms the creations configuration into filter categories for the UI.
|
|
6
|
-
*
|
|
7
|
-
* @param config The creations configuration object
|
|
8
|
-
* @param t Translation function
|
|
9
|
-
* @returns Array of FilterCategory
|
|
10
|
-
*/
|
|
11
|
-
export const getFilterCategoriesFromConfig = (
|
|
12
|
-
config: CreationsConfig,
|
|
13
|
-
t: (key: string) => string
|
|
14
|
-
): FilterCategory[] => {
|
|
15
|
-
const categories: FilterCategory[] = [];
|
|
16
|
-
|
|
17
|
-
if (config.types.length > 0) {
|
|
18
|
-
categories.push({
|
|
19
|
-
id: 'type',
|
|
20
|
-
title: t(config.translations.filterTitle),
|
|
21
|
-
multiSelect: false,
|
|
22
|
-
options: config.types.map(type => ({
|
|
23
|
-
id: type.id,
|
|
24
|
-
label: t(type.labelKey),
|
|
25
|
-
icon: type.icon || 'image'
|
|
26
|
-
}))
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (config.filterCategories) {
|
|
31
|
-
categories.push(...config.filterCategories);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return categories;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Translates the creation types for display.
|
|
39
|
-
*
|
|
40
|
-
* @param config The creations configuration object
|
|
41
|
-
* @param t Translation function
|
|
42
|
-
* @returns Array of types with translated labels
|
|
43
|
-
*/
|
|
44
|
-
export const getTranslatedTypes = (
|
|
45
|
-
config: CreationsConfig,
|
|
46
|
-
t: (key: string) => string
|
|
47
|
-
) => {
|
|
48
|
-
return config.types.map(type => ({
|
|
49
|
-
...type,
|
|
50
|
-
labelKey: t(type.labelKey)
|
|
51
|
-
}));
|
|
52
|
-
};
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type declarations for external modules
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
declare module "@umituz/react-native-firestore" {
|
|
6
|
-
import type { Firestore } from "firebase/firestore";
|
|
7
|
-
|
|
8
|
-
export class BaseRepository {
|
|
9
|
-
protected getDb(): Firestore | null;
|
|
10
|
-
protected getDbOrThrow(): Firestore;
|
|
11
|
-
protected isDbInitialized(): boolean;
|
|
12
|
-
protected isQuotaError(error: unknown): boolean;
|
|
13
|
-
protected handleQuotaError(error: unknown): never;
|
|
14
|
-
protected executeWithQuotaHandling<T>(
|
|
15
|
-
operation: () => Promise<T>,
|
|
16
|
-
): Promise<T>;
|
|
17
|
-
protected trackRead(
|
|
18
|
-
collection: string,
|
|
19
|
-
count: number,
|
|
20
|
-
cached: boolean,
|
|
21
|
-
): void;
|
|
22
|
-
protected trackWrite(
|
|
23
|
-
collection: string,
|
|
24
|
-
docId: string,
|
|
25
|
-
count: number,
|
|
26
|
-
): void;
|
|
27
|
-
protected trackDelete(
|
|
28
|
-
collection: string,
|
|
29
|
-
docId: string,
|
|
30
|
-
count: number,
|
|
31
|
-
): void;
|
|
32
|
-
destroy(): void;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function getFirestore(): Firestore | null;
|
|
36
|
-
export function initializeFirestore(app: unknown): void;
|
|
37
|
-
export function isFirestoreInitialized(): boolean;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
declare module "@umituz/react-native-design-system" {
|
|
41
|
-
import type { FC, ReactNode } from "react";
|
|
42
|
-
import type { StyleProp, ViewStyle, TextStyle } from "react-native";
|
|
43
|
-
|
|
44
|
-
export interface DesignTokens {
|
|
45
|
-
colors: {
|
|
46
|
-
primary: string;
|
|
47
|
-
secondary: string;
|
|
48
|
-
error: string;
|
|
49
|
-
warning: string;
|
|
50
|
-
success: string;
|
|
51
|
-
backgroundPrimary: string;
|
|
52
|
-
backgroundSecondary: string;
|
|
53
|
-
surface: string;
|
|
54
|
-
textPrimary: string;
|
|
55
|
-
textSecondary: string;
|
|
56
|
-
textInverse: string;
|
|
57
|
-
border: string;
|
|
58
|
-
[key: string]: string;
|
|
59
|
-
};
|
|
60
|
-
spacing: {
|
|
61
|
-
xs: number;
|
|
62
|
-
sm: number;
|
|
63
|
-
md: number;
|
|
64
|
-
lg: number;
|
|
65
|
-
xl: number;
|
|
66
|
-
xxl: number;
|
|
67
|
-
[key: string]: number;
|
|
68
|
-
};
|
|
69
|
-
typography: {
|
|
70
|
-
headingLarge: TextStyle;
|
|
71
|
-
headingMedium: TextStyle;
|
|
72
|
-
headingSmall: TextStyle;
|
|
73
|
-
bodyLarge: TextStyle;
|
|
74
|
-
bodyMedium: TextStyle;
|
|
75
|
-
bodySmall: TextStyle;
|
|
76
|
-
[key: string]: TextStyle;
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function useAppDesignTokens(): DesignTokens;
|
|
81
|
-
|
|
82
|
-
export interface AtomicTextProps {
|
|
83
|
-
children?: ReactNode;
|
|
84
|
-
style?: StyleProp<TextStyle>;
|
|
85
|
-
}
|
|
86
|
-
export const AtomicText: FC<AtomicTextProps>;
|
|
87
|
-
|
|
88
|
-
export interface AtomicIconProps {
|
|
89
|
-
name: string;
|
|
90
|
-
size?: "xs" | "sm" | "md" | "lg" | "xl";
|
|
91
|
-
color?: string;
|
|
92
|
-
}
|
|
93
|
-
export const AtomicIcon: FC<AtomicIconProps>;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
declare module "@umituz/react-native-sharing" {
|
|
97
|
-
export interface ShareOptions {
|
|
98
|
-
dialogTitle?: string;
|
|
99
|
-
mimeType?: string;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export interface UseSharingResult {
|
|
103
|
-
share: (uri: string, options?: ShareOptions) => Promise<void>;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function useSharing(): UseSharingResult;
|
|
107
|
-
}
|