Projekt

Obecné

Profil

Stáhnout (11.3 KB) Statistiky
| Větev: | Tag: | Revize:
1
import { Center, Box, VStack, Button, HStack, Text, Image, ScrollView, View, Spacer, Card, Heading, Switch, Flex, ChevronLeftIcon, ChevronRightIcon } from "native-base"
2
import React, { useCallback, useEffect, useState } from "react"
3
import { Item } from "../../types/item"
4
import { Note } from "../../types/note"
5
import LoadingBox from "../loading/LoadingBox"
6
import NotesListView from "../notes/NotesListView"
7
import { IMAGE_URL } from "../../api/constants"
8
import { log } from "../../logging/logger"
9
import { createNote, getAllNotes } from "../../stores/actions/notesThunks"
10
import { AppDispatch, RootState } from "../../stores/store"
11
import { useDispatch, useSelector } from "react-redux"
12
import { getItemNotes } from "../../stores/actions/itemThunks"
13

    
14
import { Dimensions } from "react-native";
15
import { DrawerNavigationProp } from "@react-navigation/drawer"
16
import { RootStackParamList } from "../../pages/Navigation"
17

    
18
interface ItemDetailProps {
19
    item: Item,
20
    itemLoading: boolean,
21
    notes: Note[],
22
    notesLoading: boolean,
23
    navigation: DrawerNavigationProp<RootStackParamList, "Item", undefined>
24
}
25

    
26
const ItemDetail = (props: { item: Item, itemLoading: boolean }) => {
27
    const item = props.item;
28

    
29
    const [selectedImage, setSelectedImage] = useState<number>(0);
30

    
31
    return (<>
32
        {
33
            item && props.itemLoading ?
34
                (<LoadingBox text="Item loading..." />)
35
                :
36
                (
37
                    <ScrollView flex="1">
38
                        <VStack>
39
                            <HStack marginLeft={2.5} alignItems={"center"}>
40
                                <VStack flex={1} marginTop={3.5}>
41
                                    <Text>
42
                                        {item.authorDisplayName ? item.authorDisplayName : item.authorName}
43
                                    </Text>
44
                                    <Heading size="sm">
45
                                        {item.workName}
46
                                    </Heading>
47
                                </VStack>
48
                                <Box marginLeft="auto" marginTop={0}> {/* marginLeft: "auto" pushes the Box to the right */}
49
                                    <Button variant="outline" size="md">
50
                                        {item?.concordances?.[0]?.id}
51
                                    </Button>
52
                                </Box>
53
                            </HStack>
54
                            <Card shadow="1" marginTop={5}>
55
                                {item.inventoryItem &&
56
                                    <VStack>
57
                                        <Text italic>
58
                                            <Text color="light.500">Inventory item: </Text>
59
                                            {item.inventoryItem}
60
                                        </Text>
61
                                        <Text italic marginTop="2.5%">
62
                                            {item.searchSubjects != undefined && item?.searchSubjects?.map((subject, index) => (
63
                                                item.searchSubjects && index < item.searchSubjects.length - 1 ? (subject + ", ") : (subject)
64
                                            ))}
65
                                        </Text>
66
                                    </VStack>}
67
                            </Card>
68
                            {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>
71
                                    <HStack space={4}>
72
                                        <Button variant="ghost" size="lg" onPress={() => {
73
                                            if (item.images && selectedImage - 1 >= 0) {
74
                                                setSelectedImage(selectedImage - 1);
75
                                            }
76
                                        }} leftIcon={<ChevronLeftIcon size="lg" />} />
77
                                        <Image size={250} alt="image" source={{ uri: IMAGE_URL + "/" + item.images[selectedImage].imageUrl }} />
78
                                        <Button variant="ghost" size="lg" onPress={() => {
79
                                            if (item.images && selectedImage + 1 < item.images.length) {
80
                                                setSelectedImage(selectedImage + 1);
81
                                            }
82
                                        }} leftIcon={<ChevronRightIcon size="lg" />} />
83
                                    </HStack>
84
                                </VStack>
85
                            )}
86
                            {item.fullView && (
87
                                <Card shadow={1} marginTop={5} marginBottom={5}>
88
                                    {item.authorName &&
89
                                        <HStack>
90
                                            <Text italic marginTop={2.5}>
91
                                                <Text color="light.500">Author name: </Text>
92
                                                {item.authorName}
93
                                            </Text>
94
                                        </HStack>}
95
                                    {item.title &&
96
                                        <HStack>
97
                                            <Text italic marginTop={2.5}>
98
                                                <Text color="light.500">Title: </Text>
99
                                                {item.title}
100
                                            </Text>
101
                                        </HStack>}
102
                                    {item.institution &&
103
                                        <HStack>
104
                                            <Text italic marginTop={2.5}>
105
                                                <Text color="light.500">Institution: </Text>
106
                                                {item.institution.name}, Inv. No. {item.institution.inventoryNumber}, {item.institution.city} {"(" + item.institution.country + ")"}
107
                                            </Text>
108
                                        </HStack>}
109
                                    {item.repository &&
110
                                        <HStack>
111
                                            <Text italic marginTop={2.5}>
112
                                                <Text color="light.500">Repository: </Text>
113
                                                {item.repository}
114
                                            </Text>
115
                                        </HStack>}
116
                                    {item.provenance &&
117
                                        <HStack>
118
                                            <Text italic marginTop={2.5}>
119
                                                <Text color="light.500">Provenance: </Text>
120
                                                {item.provenance}
121
                                            </Text>
122
                                        </HStack>}
123
                                    {item.description &&
124
                                        <HStack>
125
                                            <Text italic marginTop={2.5}>
126
                                                <Text color="light.500">Description: </Text>
127
                                                {item.description}
128
                                            </Text>
129
                                        </HStack>}
130
                                </Card>)}
131
                        </VStack>
132
                    </ScrollView>
133
                )
134
        }</>
135
    );
136
}
137

    
138

    
139

    
140
const ItemNotes = (props: { item: Item, notes: Note[], notesLoading: boolean, navigation: DrawerNavigationProp<RootStackParamList, "Item", undefined> }) => {
141

    
142
    const [showRelatedComments, setShowRelatedComments] = useState(true);
143

    
144
    const { requestPending, triggerRefresh } = useSelector((state: RootState) => state.noteViewState)
145

    
146
    const dispatch = useDispatch<AppDispatch>();
147

    
148
    // trigger refresh on triggerRefresh increment
149
    useEffect(() => {
150
        if (triggerRefresh > 0) {
151
            log.debug("NotesViewPage", "useEffect", "getNotes");
152
            dispatch(getItemNotes({ item: props.item, relatedComments: showRelatedComments }));
153
        }
154
    }, [triggerRefresh])
155
    
156
    const toggleRelatedComments = useCallback(() => {
157
        if (!props.notesLoading) {
158

    
159
            let value = !showRelatedComments;
160

    
161
            setShowRelatedComments(value);
162
            dispatch(getItemNotes({ item: props.item, relatedComments: value }));
163
        }
164
      }, [showRelatedComments]);
165

    
166

    
167
    const handleCreateItemComment = useCallback(
168
        (newComment: string, replyingTo: { messageId: string; userName: string } | null) => {
169
            if (!requestPending) {
170
                // creating new comment
171
                if (replyingTo != null) {
172
                    dispatch(createNote({ newNote: { note: newComment, reply_to: replyingTo.messageId } as Note }));
173
                } else {
174
                    dispatch(createNote({ newNote: { note: newComment, items: props.item.id } as any }));
175
                }
176
            }
177
        },
178
        [props.item.id]
179
    );
180

    
181
    return (
182

    
183
        props.notesLoading ?
184
            (<LoadingBox text="Notes loading..." />)
185
            :
186
            (<VStack>
187
                <Flex direction="row" alignItems="center" justify="flex-end">
188
                    <Text fontSize={"12"}>Show related comments</Text>
189
                    <Switch value={showRelatedComments} onChange={toggleRelatedComments} size="md" />
190
                </Flex>
191
                <Box >
192
                    <NotesListView height={Dimensions.get('window').height - 355} requestPending={requestPending} notes={props.notes} navigation={props.navigation} handleCreateComment={handleCreateItemComment} />
193
                </Box>
194
            </VStack>)
195
    );
196
}
197

    
198

    
199

    
200
const ItemView = (props: ItemDetailProps) => {
201

    
202
    // item shown / note shown
203
    const [itemShown, setItemShown] = React.useState(true);
204

    
205
    const { itemLoading, notesLoading, navigation } = props;
206

    
207
    const handleItemClick = () => {
208
        setItemShown(true);
209
    }
210

    
211
    const handleNotesClick = () => {
212
        setItemShown(false);
213
    }
214

    
215
    return (
216
        <Box marginLeft={2.5} marginRight={2.5}>
217

    
218
            <Box height={Dimensions.get('window').height - 210}>
219
                {itemShown ? (
220
                    <ItemDetail itemLoading={itemLoading} item={props.item} />
221
                ) : (
222
                    <ItemNotes item={props.item} notesLoading={props.notesLoading} notes={props.notes} navigation={props.navigation} />
223
                )}
224
            </Box>
225

    
226
            {/* item notes switch tab */}
227
            <HStack alignItems="center">
228
                <Button
229
                    variant={itemShown ? "subtle" : "outline"}
230
                    w="50%"
231
                    onPress={handleItemClick}
232
                >
233
                    Item
234
                </Button>
235
                <Button
236
                    variant={itemShown ? "outline" : "subtle"}
237
                    w="50%"
238
                    onPress={handleNotesClick}
239
                >
240
                    Notes
241
                </Button>
242
            </HStack>
243
        </Box>
244
    )
245
}
246

    
247
export default ItemView
(2-2/2)