Projekt

Obecné

Profil

Stáhnout (5.86 KB) Statistiky
| Větev: | Tag: | Revize:
1 8b1106f4 Fantič
import { VStack, Box, Text, HStack, ScrollView, Flex, Button, CloseIcon, IconButton, TextArea, useToast } from "native-base";
2 cb25df10 Fantič
import { Note } from "../../types/note";
3
import NoteView from "./NoteView";
4 2135f53d Fantič
import { MessageIcon } from "../general/Icons";
5 56626a63 Fantič
import React, { useCallback, useState } from "react";
6 2135f53d Fantič
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 b5ac7218 Fantič
import { Dimensions } from "react-native";
11 cb25df10 Fantič
12 8b1106f4 Fantič
13
14 2135f53d Fantič
const NotesListView = (props: { notes: Note[], navigation: any, handleCreateComment: any, requestPending: boolean }) => {
15 cb25df10 Fantič
    const notes = props.notes;
16 2135f53d Fantič
17 8b1106f4 Fantič
    const toast = useToast();
18
19 2135f53d Fantič
    const [newComment, setNewComment] = useState<string>("");
20
    const [replyingTo, setReplyingTo] = useState<{ messageId: string; userName: string } | null>(null);
21
22 bc25708c Fantič
    const [renderedNotes, setRenderedNotes] = useState(6);
23
24 2135f53d Fantič
    const cancelRef = React.useRef(null);
25
26
    const dispatch = useDispatch<AppDispatch>();
27
28 b5ac7218 Fantič
    const windowHeight = Dimensions.get('window').height;
29
30 2135f53d Fantič
    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 56626a63 Fantič
    const handleReply = useCallback((messageId: string, userName: string) => {
41
        setReplyingTo({ messageId, userName });
42
    }, [setReplyingTo]);
43 b5ac7218 Fantič
44 56626a63 Fantič
    const handleEdit = useCallback((note: Note) => {
45
        if (!props.requestPending) {
46 2135f53d Fantič
            dispatch(updateNote(note));
47 56626a63 Fantič
        }
48
    }, [dispatch, props.requestPending]);
49 b5ac7218 Fantič
50 56626a63 Fantič
    const handleDelete = useCallback((messageId: string) => {
51
        if (!props.requestPending) {
52
            dispatch(deleteNote({ noteId: messageId }));
53
        }
54
    }, [dispatch, props.requestPending]);
55 2135f53d Fantič
56 8b1106f4 Fantič
    const handleScrollEnd = (event: any) => {
57 bc25708c Fantič
        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 8b1106f4 Fantič
            if ((renderedNotes + nextBatchSize) > notes.length && (renderedNotes + nextBatchSize) != notes.length) {
66 bc25708c Fantič
                setRenderedNotes(notes.length);
67
                // TODO toast display info all rendered
68
            }
69 8b1106f4 Fantič
            else if ((renderedNotes + nextBatchSize) != notes.length) {
70 bc25708c Fantič
                setRenderedNotes(renderedNotes + nextBatchSize);
71
                // TODO toast display loading more notes
72
            }
73
        }
74
    };
75
76 cb25df10 Fantič
    return (
77 2135f53d Fantič
        <VStack>
78 b5ac7218 Fantič
            <Box height={windowHeight - 70 - 160 - (replyingTo ? 40 : 0)} marginBottom={2}>
79
                {/* Notes */}
80 bc25708c Fantič
                <ScrollView contentContainerStyle={{ flexGrow: 1 }} onScrollEndDrag={handleScrollEnd}>
81 2135f53d Fantič
                    {
82
                        notes && notes.length > 0 ? (
83
                            <VStack>
84 bc25708c Fantič
                                {
85 8b1106f4 Fantič
                                    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 bc25708c Fantič
                                }
95 2135f53d Fantič
                            </VStack>
96
                        ) : (
97
                            <Text>There are no notes.</Text>
98
                        )
99
                    }
100
                </ScrollView>
101
            </Box>
102
103 b5ac7218 Fantič
            {/* Create comment */}
104 cb25df10 Fantič
            {
105 2135f53d Fantič
                props.handleCreateComment != null &&
106 b5ac7218 Fantič
                <VStack>
107
108
                    {/* Replying to */}
109
                    {replyingTo != null &&
110 8b1106f4 Fantič
                        <Flex direction="row" alignItems="center" justify="flex-end" height={10} style={{backgroundColor: "#FFF8E1"}}>
111 b5ac7218 Fantič
                            <Text>Replying to {replyingTo.userName}</Text>
112 8b1106f4 Fantič
                            <IconButton onPress={() => setReplyingTo(null)} size="sm" icon={<CloseIcon />} marginLeft="-1%" marginRight={20 }/>
113 b5ac7218 Fantič
                        </Flex>
114
                    }
115 bc25708c Fantič
116 b5ac7218 Fantič
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 cb25df10 Fantič
            }
135 2135f53d Fantič
            <ConfirmDialog {...confirmDialog} isShown={confirmDialog != null} cancelRef={cancelRef} />
136 b5ac7218 Fantič
        </VStack >
137 cb25df10 Fantič
    );
138
}
139
140
export default NotesListView