Projekt

Obecné

Profil

Stáhnout (5.86 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 } from "../../stores/store";
9
import { useDispatch } from "react-redux";
10
import { Dimensions } from "react-native";
11

    
12

    
13

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

    
17
    const toast = useToast();
18

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

    
22
    const [renderedNotes, setRenderedNotes] = useState(6);
23

    
24
    const cancelRef = React.useRef(null);
25

    
26
    const dispatch = useDispatch<AppDispatch>();
27

    
28
    const windowHeight = Dimensions.get('window').height;
29

    
30
    const [confirmDialog, setConfirmDialog] = React.useState<{
31
        headerText?: string;
32
        bodyText?: string;
33
        confirmText?: string;
34
        confirmColor?: string;
35
        cancelRef?: any;
36
        onClose?: () => void;
37
        onSubmit?: () => void;
38
    } | null>(null);
39

    
40
    const handleReply = useCallback((messageId: string, userName: string) => {
41
        setReplyingTo({ messageId, userName });
42
    }, [setReplyingTo]);
43

    
44
    const handleEdit = useCallback((note: Note) => {
45
        if (!props.requestPending) {
46
            dispatch(updateNote(note));
47
        }
48
    }, [dispatch, props.requestPending]);
49

    
50
    const handleDelete = useCallback((messageId: string) => {
51
        if (!props.requestPending) {
52
            dispatch(deleteNote({ noteId: messageId }));
53
        }
54
    }, [dispatch, props.requestPending]);
55

    
56
    const handleScrollEnd = (event: any) => {
57
        const offsetY = event.nativeEvent.contentOffset.y;
58
        const contentHeight = event.nativeEvent.contentSize.height;
59
        const screenHeight = event.nativeEvent.layoutMeasurement.height;
60

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

    
65
            if ((renderedNotes + nextBatchSize) > notes.length && (renderedNotes + nextBatchSize) != notes.length) {
66
                setRenderedNotes(notes.length);
67
                // TODO toast display info all rendered
68
            }
69
            else if ((renderedNotes + nextBatchSize) != notes.length) {
70
                setRenderedNotes(renderedNotes + nextBatchSize);
71
                // TODO toast display loading more notes
72
            }
73
        }
74
    };
75

    
76
    return (
77
        <VStack>
78
            <Box height={windowHeight - 70 - 160 - (replyingTo ? 40 : 0)} marginBottom={2}>
79
                {/* Notes */}
80
                <ScrollView contentContainerStyle={{ flexGrow: 1 }} onScrollEndDrag={handleScrollEnd}>
81
                    {
82
                        notes && notes.length > 0 ? (
83
                            <VStack>
84
                                {
85
                                    notes.slice(0, renderedNotes).map((note, index) => {
86
                                        
87
                                        if(replyingTo?.messageId == note.uuid){
88
                                            return <NoteView higlighted key={index} note={note} handleReply={handleReply} handleDelete={handleDelete} handleEdit={handleEdit} setConfirmDialog={setConfirmDialog} navigation={props.navigation} />
89
                                        }
90
                                        
91
                                        return <NoteView key={index} note={note} handleReply={handleReply} handleDelete={handleDelete} handleEdit={handleEdit} setConfirmDialog={setConfirmDialog} navigation={props.navigation} />;
92
                                        
93
                                    })
94
                                }
95
                            </VStack>
96
                        ) : (
97
                            <Text>There are no notes.</Text>
98
                        )
99
                    }
100
                </ScrollView>
101
            </Box>
102

    
103
            {/* Create comment */}
104
            {
105
                props.handleCreateComment != null &&
106
                <VStack>
107

    
108
                    {/* Replying to */}
109
                    {replyingTo != null &&
110
                        <Flex direction="row" alignItems="center" justify="flex-end" height={10} style={{backgroundColor: "#FFF8E1"}}>
111
                            <Text>Replying to {replyingTo.userName}</Text>
112
                            <IconButton onPress={() => setReplyingTo(null)} size="sm" icon={<CloseIcon />} marginLeft="-1%" marginRight={20 }/>
113
                        </Flex>
114
                    }
115

    
116

    
117
                    {/* Add comment */}
118
                    <HStack height={90} >
119
                        <TextArea
120
                            flex={1}
121
                            placeholder="Add comment"
122
                            fontSize={14}
123
                            value={newComment}
124
                            onChangeText={setNewComment}
125
                            autoCompleteType={undefined}
126
                        />
127
                        <Flex marginLeft={2} marginBottom={8}>
128
                            <Button onPress={() => props.handleCreateComment(newComment, replyingTo)} startIcon={<MessageIcon color="#FFF" />}>
129
                                Send
130
                            </Button>
131
                        </Flex>
132
                    </HStack>
133
                </VStack>
134
            }
135
            <ConfirmDialog {...confirmDialog} isShown={confirmDialog != null} cancelRef={cancelRef} />
136
        </VStack >
137
    );
138
}
139

    
140
export default NotesListView
(2-2/2)