Revize f4af30c8
Přidáno uživatelem Fantič před více než 1 rok
src/components/item/ItemView.tsx | ||
---|---|---|
1 |
import { Center, Box, VStack, Button, HStack, Text, Image, ScrollView, View, Spacer, Card, Heading, Switch, Flex, ChevronLeftIcon, ChevronRightIcon } from "native-base" |
|
1 |
import { Center, Box, VStack, Button, HStack, Text, Image, ScrollView, View, Spacer, Card, Heading, Switch, Flex, ChevronLeftIcon, ChevronRightIcon, Divider, Pressable } from "native-base"
|
|
2 | 2 |
import React, { useCallback, useEffect, useState } from "react" |
3 | 3 |
import { Item } from "../../types/item" |
4 | 4 |
import { Note } from "../../types/note" |
... | ... | |
14 | 14 |
import { Dimensions } from "react-native"; |
15 | 15 |
import { DrawerNavigationProp } from "@react-navigation/drawer" |
16 | 16 |
import { RootStackParamList } from "../../pages/Navigation" |
17 |
import { select } from "d3" |
|
17 | 18 |
|
18 | 19 |
interface ItemDetailProps { |
19 | 20 |
item: Item, |
... | ... | |
23 | 24 |
navigation: DrawerNavigationProp<RootStackParamList, "Item", undefined> |
24 | 25 |
} |
25 | 26 |
|
26 |
const ItemDetail = (props: { item: Item, itemLoading: boolean }) => {
|
|
27 |
const ItemDetail = (props: ItemDetailProps) => {
|
|
27 | 28 |
const item = props.item; |
28 | 29 |
|
29 | 30 |
const [selectedImage, setSelectedImage] = useState<number>(0); |
30 | 31 |
|
32 |
const [images, setImages] = useState<{ imageUrl: string, title: string }[]>([]); |
|
33 |
|
|
34 |
|
|
35 |
useEffect(() => { |
|
36 |
if (item.images?.[0]) { |
|
37 |
setImages([item.images[0], item.images[0], item.images[0], item.images[0], item.images[0], item.images[0], item.images[0]]) |
|
38 |
} |
|
39 |
}, [item]) |
|
40 |
|
|
31 | 41 |
return (<> |
32 | 42 |
{ |
33 | 43 |
item && props.itemLoading ? |
34 | 44 |
(<LoadingBox text="Item loading..." />) |
35 | 45 |
: |
36 | 46 |
( |
37 |
<ScrollView flex="1"> |
|
47 |
<ScrollView flex="1" paddingLeft={2.5} paddingRight={2.5}>
|
|
38 | 48 |
<VStack> |
39 | 49 |
<HStack marginLeft={2.5} alignItems={"center"}> |
40 | 50 |
<VStack flex={1} marginTop={3.5}> |
41 |
<Text> |
|
51 |
<Text fontSize={13} color="#4D4D4D">
|
|
42 | 52 |
{item.authorDisplayName ? item.authorDisplayName : item.authorName} |
43 | 53 |
</Text> |
44 |
<Heading size="sm">
|
|
54 |
<Heading marginTop={1} fontSize={18} color="#4D4D4D">
|
|
45 | 55 |
{item.workName} |
46 | 56 |
</Heading> |
57 |
|
|
47 | 58 |
</VStack> |
48 | 59 |
<Box marginLeft="auto" marginTop={0}> {/* marginLeft: "auto" pushes the Box to the right */} |
49 |
<Button variant="outline" size="md"> |
|
50 |
{item?.concordances?.[0]?.id} |
|
60 |
<Button variant="outline" backgroundColor={"#F4DFAB"} borderRadius={8} size="sm" padding={1.5} > |
|
61 |
<Text color="#654B07" fontSize={14}> |
|
62 |
{item?.concordances?.[0]?.id} |
|
63 |
</Text> |
|
51 | 64 |
</Button> |
52 | 65 |
</Box> |
53 | 66 |
</HStack> |
54 |
<Card shadow="1" marginTop={5}> |
|
67 |
|
|
68 |
|
|
69 |
<View marginTop={5} backgroundColor="#F5F4F1" borderRadius={10} borderColor="#F5F4F1" padding={2}> |
|
55 | 70 |
{item.inventoryItem && |
56 | 71 |
<VStack> |
57 | 72 |
<Text italic> |
58 |
<Text color="light.500">Inventory item: </Text>
|
|
73 |
<Text color="#654B07" italic fontWeight={"semibold"}>Inventory item: </Text>
|
|
59 | 74 |
{item.inventoryItem} |
60 | 75 |
</Text> |
61 | 76 |
<Text italic marginTop="2.5%"> |
62 | 77 |
{item.searchSubjects != undefined && item?.searchSubjects?.map((subject, index) => ( |
63 |
item.searchSubjects && index < item.searchSubjects.length - 1 ? (subject + ", ") : (subject) |
|
78 |
subject != "" ? |
|
79 |
item.searchSubjects && index < item.searchSubjects.length - 1 ? (subject + ", ") : (subject) |
|
80 |
: |
|
81 |
"" |
|
64 | 82 |
))} |
65 | 83 |
</Text> |
66 | 84 |
</VStack>} |
67 |
</Card>
|
|
85 |
</View>
|
|
68 | 86 |
{item.fullView && item.images && item.images.length > 0 && ( |
69 |
<VStack background="primary.100" marginTop={5} alignItems="center" justifyContent="center"> |
|
70 |
<Text marginBottom={2}>Resembling objects {selectedImage + 1 + "/" + item.images.length}</Text> |
|
87 |
<VStack marginTop={5} alignItems="center" justifyContent="center" backgroundColor="#F5F4F1" borderRadius={10} borderColor="#F5F4F1" padding={2}> |
|
88 |
|
|
89 |
<Box marginTop={2.5} borderWidth={1} width={Dimensions.get('window').width - 110} alignItems="center" backgroundColor="red" borderTopRadius={10} > |
|
90 |
<Text marginBottom={2}>{"Resembling objects"} |
|
91 |
{selectedImage + 1 + "/" + item.images.length + item.images[selectedImage].cert + item.images[selectedImage].relationship_type} |
|
92 |
</Text> |
|
93 |
</Box> |
|
94 |
|
|
71 | 95 |
<HStack space={4}> |
72 | 96 |
<Button variant="ghost" size="lg" onPress={() => { |
73 | 97 |
if (item.images && selectedImage - 1 >= 0) { |
74 | 98 |
setSelectedImage(selectedImage - 1); |
75 | 99 |
} |
76 | 100 |
}} leftIcon={<ChevronLeftIcon size="lg" />} /> |
77 |
<Image size={250} alt="image" source={{ uri: IMAGE_URL + "/" + item.images[selectedImage].imageUrl }} />
|
|
101 |
<Image size={Dimensions.get('window').width - 110} alt="image" source={{ uri: IMAGE_URL + "/" + item.images[selectedImage].imageUrl }} />
|
|
78 | 102 |
<Button variant="ghost" size="lg" onPress={() => { |
79 | 103 |
if (item.images && selectedImage + 1 < item.images.length) { |
80 | 104 |
setSelectedImage(selectedImage + 1); |
81 | 105 |
} |
82 | 106 |
}} leftIcon={<ChevronRightIcon size="lg" />} /> |
83 | 107 |
</HStack> |
108 |
<ScrollView horizontal marginBottom={2.5} marginTop={5}> |
|
109 |
|
|
110 |
{item.images.map((image, index) => ( |
|
111 |
<Pressable |
|
112 |
onPress={() => { setSelectedImage(index); }}> |
|
113 |
<Image marginLeft={2.5} size={90} alt="image" source={{ uri: IMAGE_URL + "/" + image.imageUrl }} |
|
114 |
borderColor={selectedImage == index ? "#1782FF" : undefined} |
|
115 |
borderWidth={3} |
|
116 |
/> |
|
117 |
</Pressable> |
|
118 |
|
|
119 |
))} |
|
120 |
</ScrollView> |
|
84 | 121 |
</VStack> |
85 | 122 |
)} |
86 | 123 |
{item.fullView && ( |
87 |
<Card shadow={1} marginTop={5} marginBottom={5}>
|
|
124 |
<View marginTop={5} backgroundColor="#F5F4F1" borderRadius={10} borderColor="#F5F4F1" padding={2} marginBottom={5}>
|
|
88 | 125 |
{item.authorName && |
89 | 126 |
<HStack> |
90 |
<Text italic marginTop={2.5}>
|
|
91 |
<Text color="light.500">Author name: </Text>
|
|
127 |
<Text marginTop={2.5}> |
|
128 |
<Text color="#654B07" italic fontWeight={"semibold"}>Author name: </Text>
|
|
92 | 129 |
{item.authorName} |
93 | 130 |
</Text> |
94 | 131 |
</HStack>} |
95 | 132 |
{item.title && |
96 | 133 |
<HStack> |
97 |
<Text italic marginTop={2.5}>
|
|
98 |
<Text color="light.500">Title: </Text>
|
|
134 |
<Text marginTop={2.5}> |
|
135 |
<Text color="#654B07" italic fontWeight={"semibold"}>Title: </Text>
|
|
99 | 136 |
{item.title} |
100 | 137 |
</Text> |
101 | 138 |
</HStack>} |
102 | 139 |
{item.institution && |
103 | 140 |
<HStack> |
104 |
<Text italic marginTop={2.5}>
|
|
105 |
<Text color="light.500">Institution: </Text>
|
|
141 |
<Text marginTop={2.5}> |
|
142 |
<Text color="#654B07" italic fontWeight={"semibold"}>Institution: </Text>
|
|
106 | 143 |
{item.institution.name}, Inv. No. {item.institution.inventoryNumber}, {item.institution.city} {"(" + item.institution.country + ")"} |
107 | 144 |
</Text> |
108 | 145 |
</HStack>} |
109 | 146 |
{item.repository && |
110 | 147 |
<HStack> |
111 |
<Text italic marginTop={2.5}>
|
|
112 |
<Text color="light.500">Repository: </Text>
|
|
148 |
<Text marginTop={2.5}> |
|
149 |
<Text color="#654B07" italic fontWeight={"semibold"}>Repository: </Text>
|
|
113 | 150 |
{item.repository} |
114 | 151 |
</Text> |
115 | 152 |
</HStack>} |
116 | 153 |
{item.provenance && |
117 | 154 |
<HStack> |
118 |
<Text italic marginTop={2.5}>
|
|
119 |
<Text color="light.500">Provenance: </Text>
|
|
155 |
<Text marginTop={2.5}> |
|
156 |
<Text color="#654B07" italic fontWeight={"semibold"}>Provenance: </Text>
|
|
120 | 157 |
{item.provenance} |
121 | 158 |
</Text> |
122 | 159 |
</HStack>} |
123 | 160 |
{item.description && |
124 | 161 |
<HStack> |
125 |
<Text italic marginTop={2.5}>
|
|
126 |
<Text color="light.500">Description: </Text>
|
|
162 |
<Text marginTop={2.5}> |
|
163 |
<Text color="#654B07" italic fontWeight={"semibold"}>Description: </Text>
|
|
127 | 164 |
{item.description} |
128 | 165 |
</Text> |
129 | 166 |
</HStack>} |
130 |
</Card>)} |
|
167 |
</View>)} |
|
168 |
|
|
169 |
{ |
|
170 |
item.room && item.room.id && |
|
171 |
<Flex direction="row" alignItems="center" justify="flex-end"> |
|
172 |
<Button |
|
173 |
onPress={() => props.navigation.navigate("Plan", { roomId: item?.room?.id, placeId: undefined })} |
|
174 |
variant={"link"} |
|
175 |
backgroundColor={"#F4DFAB"} |
|
176 |
borderRadius={7} |
|
177 |
marginTop={0} |
|
178 |
marginBottom={5} |
|
179 |
width={125} |
|
180 |
rightIcon={<ChevronRightIcon size="xs" />}> |
|
181 |
Show in map |
|
182 |
</Button> |
|
183 |
</Flex> |
|
184 |
|
|
185 |
} |
|
186 |
|
|
131 | 187 |
</VStack> |
132 |
</ScrollView> |
|
188 |
</ScrollView >
|
|
133 | 189 |
) |
134 | 190 |
}</> |
135 | 191 |
); |
... | ... | |
152 | 208 |
dispatch(getItemNotes({ item: props.item, relatedComments: showRelatedComments })); |
153 | 209 |
} |
154 | 210 |
}, [triggerRefresh]) |
155 |
|
|
211 |
|
|
156 | 212 |
const toggleRelatedComments = useCallback(() => { |
157 | 213 |
if (!props.notesLoading) { |
158 | 214 |
|
... | ... | |
161 | 217 |
setShowRelatedComments(value); |
162 | 218 |
dispatch(getItemNotes({ item: props.item, relatedComments: value })); |
163 | 219 |
} |
164 |
}, [showRelatedComments]);
|
|
220 |
}, [showRelatedComments]); |
|
165 | 221 |
|
166 | 222 |
|
167 | 223 |
const handleCreateItemComment = useCallback( |
... | ... | |
183 | 239 |
props.notesLoading ? |
184 | 240 |
(<LoadingBox text="Notes loading..." />) |
185 | 241 |
: |
186 |
(<VStack> |
|
242 |
(<VStack paddingLeft={2.5} paddingRight={2.5}>
|
|
187 | 243 |
<Flex direction="row" alignItems="center" justify="flex-end"> |
188 | 244 |
<Text fontSize={"12"}>Show related comments</Text> |
189 | 245 |
<Switch value={showRelatedComments} onChange={toggleRelatedComments} size="md" /> |
... | ... | |
213 | 269 |
} |
214 | 270 |
|
215 | 271 |
return ( |
216 |
<Box marginLeft={2.5} marginRight={2.5}>
|
|
272 |
<Box> |
|
217 | 273 |
|
218 | 274 |
<Box height={Dimensions.get('window').height - 210}> |
219 | 275 |
{itemShown ? ( |
220 |
<ItemDetail itemLoading={itemLoading} item={props.item} />
|
|
276 |
<ItemDetail itemLoading={props.itemLoading} item={props.item} notesLoading={props.notesLoading} notes={props.notes} navigation={props.navigation} />
|
|
221 | 277 |
) : ( |
222 | 278 |
<ItemNotes item={props.item} notesLoading={props.notesLoading} notes={props.notes} navigation={props.navigation} /> |
223 | 279 |
)} |
... | ... | |
226 | 282 |
{/* item notes switch tab */} |
227 | 283 |
<HStack alignItems="center"> |
228 | 284 |
<Button |
229 |
variant={itemShown ? "subtle" : "outline"}
|
|
285 |
variant={"unstyled"}
|
|
230 | 286 |
w="50%" |
231 | 287 |
onPress={handleItemClick} |
232 | 288 |
> |
233 |
Item |
|
289 |
<VStack alignItems={"center"}> |
|
290 |
<Text color="primary" bold={itemShown} mb={itemShown ? undefined : 2}> |
|
291 |
Item |
|
292 |
</Text> |
|
293 |
{itemShown && <Divider borderWidth={1} width={60} mt={2} color="primary" />} |
|
294 |
</VStack> |
|
234 | 295 |
</Button> |
235 | 296 |
<Button |
236 |
variant={itemShown ? "outline" : "subtle"}
|
|
297 |
variant={"unstyled"}
|
|
237 | 298 |
w="50%" |
238 | 299 |
onPress={handleNotesClick} |
239 | 300 |
> |
240 |
Notes |
|
301 |
<VStack alignItems={"center"}> |
|
302 |
<Text color="primary" bold={!itemShown} mb={!itemShown ? undefined : 2}> |
|
303 |
Notes |
|
304 |
</Text> |
|
305 |
{!itemShown && <Divider borderWidth={1} width={60} mt={2} color="primary" />} |
|
306 |
</VStack> |
|
241 | 307 |
</Button> |
242 | 308 |
</HStack> |
243 | 309 |
</Box> |
Také k dispozici: Unified diff
re #10895: ItemView redesign, refactor