Projekt

Obecné

Profil

Stáhnout (7.43 KB) Statistiky
| Větev: | Tag: | Revize:
1
import { VStack, Box, Text, HStack, ScrollView, Flex, Button, CloseIcon, IconButton, TextArea, useToast } from "native-base";
2
import { Note } from "../../types/note";
3
import NoteView from "./NoteView";
4
import { MessageIcon } from "../general/Icons";
5
import React, { useCallback, useState } from "react";
6
import { updateNote, deleteNote } from "../../stores/actions/notesThunks";
7
import { ConfirmDialog } from "../general/Dialogs";
8
import { AppDispatch, RootState } from "../../stores/store";
9
import { useDispatch, useSelector } from "react-redux";
10
import { InfoToast } from "../toast/InfoToast";
11
import { UserRole } from "../../stores/reducers/userSlice";
12

    
13

    
14

    
15
const NotesListView = (props: { notes: Note[], navigation: any, handleCreateComment: any, requestPending: boolean, height: number }) => {
16
    const notes = props.notes;
17

    
18
    // const userRole = useSelector((state: RootState) => state.user.role)
19
    const userId = useSelector((state: RootState) => state.user.userId)
20
    const userRole = useSelector((state: RootState) => state.user.role)
21

    
22
    console.log(userRole)
23

    
24
    const [newComment, setNewComment] = useState<string>("");
25
    const [replyingTo, setReplyingTo] = useState<{ messageId: string; userName: string } | null>(null);
26

    
27
    const toast = useToast();
28

    
29
    const [renderedNotes, setRenderedNotes] = useState(6);
30

    
31
    const cancelRef = React.useRef(null);
32

    
33
    const dispatch = useDispatch<AppDispatch>();
34

    
35
    const [confirmDialog, setConfirmDialog] = React.useState<{
36
        headerText?: string;
37
        bodyText?: string;
38
        confirmText?: string;
39
        confirmColor?: string;
40
        cancelRef?: any;
41
        onClose?: () => void;
42
        onSubmit?: () => void;
43
    } | null>(null);
44

    
45
    const handleReply = useCallback((messageId: string, userName: string) => {
46
        setReplyingTo({ messageId, userName });
47
    }, [setReplyingTo]);
48

    
49
    const handleEdit = useCallback((note: Note) => {
50
        if (!props.requestPending) {
51
            dispatch(updateNote(note));
52
        }
53
    }, [dispatch, props.requestPending]);
54

    
55
    const handleDelete = useCallback((messageId: string) => {
56
        if (!props.requestPending) {
57
            dispatch(deleteNote({ noteId: messageId }));
58
        }
59
    }, [dispatch, props.requestPending]);
60

    
61

    
62

    
63
    const handleScrollEnd = (event: any) => {
64
        const offsetY = event.nativeEvent.contentOffset.y;
65
        const contentHeight = event.nativeEvent.contentSize.height;
66
        const screenHeight = event.nativeEvent.layoutMeasurement.height;
67

    
68
        if (offsetY + screenHeight >= contentHeight - 20) {
69
            // Load more notes when the user is near the end of the list
70
            const nextBatchSize = 5; // Number of notes to render in the next batch
71

    
72
            if ((renderedNotes + nextBatchSize) > notes.length && (renderedNotes + nextBatchSize) != notes.length) {
73
                toast.closeAll()
74
                toast.show({
75
                    render: ({
76
                        id
77
                    }) => {
78
                        return <InfoToast text={"All notes loaded..."} onClose={() => toast.close(id)} />;
79
                    },
80
                    duration: 3000
81
                });
82
                setRenderedNotes(notes.length);
83

    
84
            }
85
            else if ((renderedNotes + nextBatchSize) != notes.length) {
86
                toast.closeAll()
87
                toast.show({
88
                    render: ({
89
                        id
90
                    }) => {
91
                        return <InfoToast text={"Loading more notes..."} onClose={() => toast.close(id)} />;
92
                    },
93
                    duration: 3000
94
                });
95
                setRenderedNotes(renderedNotes + nextBatchSize);
96

    
97
            }
98
        }
99
    };
100

    
101
    return (
102
        <VStack >
103
            <Box height={props.height - (replyingTo ? 40 : 0) ?? undefined} marginBottom={2}>
104
                {/* Notes */}
105
                <ScrollView contentContainerStyle={{ flexGrow: 1 }} onScrollEndDrag={handleScrollEnd} paddingLeft={2.5} paddingRight={2.5}>
106
                    {
107
                        notes && notes.length > 0 ? (
108
                            <VStack>
109
                                {
110
                                    notes.slice(0, renderedNotes).map((note, index) => {
111

    
112
                                        return <NoteView higlighted={replyingTo?.messageId == note.uuid} key={index} note={note}
113
                                            handleReply={
114
                                                handleReply
115
                                            }
116

    
117
                                            handleDelete={
118
                                                (note.username == userId || userRole == UserRole.Admin) ?
119
                                                    handleDelete
120
                                                    :
121
                                                    undefined
122
                                            }
123

    
124
                                            handleEdit={
125
                                                (note.username == userId || userRole == UserRole.Admin) ?
126
                                                    handleEdit
127
                                                    :
128
                                                    undefined
129
                                            } 
130
                                            setConfirmDialog={setConfirmDialog} navigation={props.navigation} />;
131

    
132
                                    })
133
                                }
134
                            </VStack>
135
                        ) : (
136
                            <Text>There are no notes.</Text>
137
                        )
138
                    }
139
                </ScrollView>
140
            </Box>
141

    
142
            {/* Create comment */}
143
            {
144
                props.handleCreateComment != null &&
145
                <VStack>
146

    
147
                    {/* Replying to */}
148
                    {replyingTo != null &&
149
                        <Flex direction="row" alignItems="center" justify="flex-end" height={10} style={{ backgroundColor: "#FFF8E1" }}>
150
                            <Text>Replying to {replyingTo.userName}</Text>
151
                            <IconButton onPress={() => setReplyingTo(null)} size="sm" icon={<CloseIcon />} marginLeft="-1%" marginRight={20} />
152
                        </Flex>
153
                    }
154

    
155

    
156
                    {/* Add comment */}
157
                    <HStack height={90} marginLeft={1.5} marginRight={1.5}>
158
                        <TextArea
159
                            flex={1}
160
                            placeholder={userRole == UserRole.Unauthorized || userRole == UserRole.User ? "Unathorized to add comment" : "Add comment"}
161
                            isDisabled={userRole == UserRole.Unauthorized || userRole == UserRole.User}
162
                            fontSize={14}
163
                            value={newComment}
164
                            onChangeText={setNewComment}
165
                            autoCompleteType={undefined}
166

    
167

    
168
                        />
169
                        <Flex marginLeft={2} marginBottom={8}>
170
                            <Button disabled={userRole == UserRole.Unauthorized || userRole == UserRole.User} onPress={() => props.handleCreateComment(newComment, replyingTo)} startIcon={<MessageIcon color="#FFF" />} />
171
                        </Flex>
172
                    </HStack>
173
                </VStack>
174
            }
175
            <ConfirmDialog {...confirmDialog} isShown={confirmDialog != null} cancelRef={cancelRef} />
176
        </VStack >
177
    );
178
}
179

    
180
export default NotesListView
(2-2/2)