Projekt

Obecné

Profil

Stáhnout (7.39 KB) Statistiky
| Větev: | Tag: | Revize:
1
import { HStack, Box, Text, Image, VStack, Flex, Pressable, DeleteIcon, Button, Center, Avatar, TextArea, AlertDialog, ScrollView } from "native-base";
2
import { Note } from "../../types/note";
3
import { EditIcon } from "../general/Icons";
4
import { AVATAR_URL } from "../../api/constants";
5
import { useState } from "react";
6
import React from "react";
7
import NotesListView from "./NotesListView";
8

    
9
const NoteView = React.memo((props: { note: Note, handleReply: any, handleDelete: any, handleEdit: any, setConfirmDialog: any, navigation: any, parentId?: string }) => {
10
    const note = props.note;
11

    
12
    const [isEdited, setIsEdited] = useState(false);
13

    
14
    const [showReplies, setShowReplies] = useState(false);
15

    
16
    const [text, setText] = useState(note.note);
17

    
18

    
19
    const getDateString = (timestamp: Date): string => {
20
        return new Date(timestamp).toLocaleString("en-US",
21
            { year: "numeric", month: "short", day: "2-digit", hour: "2-digit", minute: "2-digit", hour12: false }
22
        ).replace(/,/g, "").replace(/ /g, "-").replace(/-(?!.*-)/, " ");
23
    }
24

    
25
    const getUsernameInitials = (username: string): string => {
26
        if (username) {
27
            const words = username.split(" ");
28
            const initials = words.map(word => word.charAt(0).toUpperCase());
29
            return initials.join("");
30
        }
31
        return "UK"; // Unknown
32
    }
33

    
34

    
35
    const toggleShowReplies = () => {
36
        console.log("Toggle showReplies");
37
        setShowReplies(!showReplies)
38
    }
39

    
40
    const toggleEdited = () => {
41
        console.log("Toggle edit");
42
        if (isEdited) {
43
            if (text == note.note) {
44
                setIsEdited(false);
45
            }
46
            else {
47
                // confirm dialog
48
                props.setConfirmDialog({
49
                    headerText: "Cancel Edit",
50
                    bodyText: "Are you sure you want to revert changes on this note?",
51
                    confirmText: "Revert Changes",
52
                    confirmColor: "danger",
53
                    onClose: () => { props.setConfirmDialog(null) },
54
                    onSubmit: () => { setText(note.note); setIsEdited(false); props.setConfirmDialog(null) }
55
                });
56
            }
57
        }
58
        else {
59
            setIsEdited(true);
60
        }
61
    }
62

    
63
    const deleteClicked = () => {
64
        props.setConfirmDialog({
65
            headerText: "Delete Note",
66
            bodyText: "Are you sure you want to delete selected note?",
67
            confirmText: "Delete",
68
            confirmColor: "danger",
69
            onClose: () => { props.setConfirmDialog(null) },
70
            onSubmit: () => { props.handleDelete(note.uuid); props.setConfirmDialog(null) }
71
        });
72
    }
73

    
74
    const saveEdit = () => {
75
        if (note.note == text) {
76
            setIsEdited(false);
77
        }
78
        else {
79
            props.handleEdit({ ...note, note: text });
80
            setIsEdited(false);
81
        }
82
    }
83

    
84
    return (
85
        <HStack marginTop={5}>
86
            <Box width="10" height="10" marginTop="2">
87
                <Avatar bg={note.noteColor} size="sm" source={{
88
                    uri: AVATAR_URL + "/" + note.avatarUrl
89
                        // TODO bude zde nebo v atributu ta připona?
90
                        + ".png"
91
                }}>
92
                    {getUsernameInitials(note.username)}
93
                </Avatar>
94
            </Box>
95
            <VStack flex={1} marginLeft="0.5">
96

    
97
                {/* Top section */}
98
                <HStack justifyContent={"space-between"}>
99
                    <Text bold>
100
                        {note.username}
101
                    </Text>
102
                    <Flex direction="row" alignItems="center" justify="flex-end" >
103
                        <Text italic color="light.500">
104
                            {getDateString(note.createdTime)}
105
                        </Text>
106
                    </Flex>
107
                </HStack>
108

    
109
                {/* Middle section */}
110
                <HStack justifyContent={"space-between"} marginTop={2}>
111
                    {isEdited ?
112
                        <TextArea flex={1} fontSize="14" autoCompleteType={undefined} value={text} onChangeText={setText} />
113
                        :
114
                        <Text flex={1} >
115
                            {text}
116
                        </Text>
117
                    }
118

    
119
                    {note.items && note.items.length > 0 &&
120
                        <Flex marginLeft={1} flex={0}>
121
                            <Button p={1} variant="outline" size="sm" onPress={() => props.navigation.navigate("Item", { itemId: note.items[0] })}>
122
                                {note.items[0]}
123
                            </Button>
124
                        </Flex>
125

    
126
                    }
127
                </HStack>
128

    
129
                {/* Bottom section */}
130
                <HStack justifyContent={"space-between"} marginTop={2}>
131
                    {/* () => props.handleEdit(note.uuid, text) */}
132
                    <Flex direction="row" alignItems="center">
133
                        {props.handleReply != null &&
134
                            <Pressable onPress={() => props.handleReply(note.uuid, note.username)}>
135
                                <Text color="light.500">Reply</Text>
136
                            </Pressable>}
137
                        {!props.parentId && note.replies && note.replies.length > 0 &&
138
                            <Pressable marginLeft={3} onPress={() => toggleShowReplies()}>
139
                                {!showReplies ?
140
                                    <Text color="light.500">{note.replies.length} replies</Text>
141
                                    :
142
                                    <Text color="light.500">Hide</Text>
143
                                }
144

    
145
                            </Pressable>}
146
                    </Flex>
147

    
148
                    <Flex direction="row" alignItems="center" justify="flex-end">
149
                        {props.handleEdit != null &&
150
                            isEdited ?
151
                            <>
152
                                <Pressable onPress={saveEdit} marginRight={5}>
153
                                    <Text color="light.500">Save</Text>
154
                                </Pressable>
155
                                <Pressable onPress={toggleEdited} marginRight={6}>
156
                                    <Text color="light.500">Cancel</Text>
157
                                </Pressable>
158
                            </>
159
                            :
160
                            <Pressable onPress={toggleEdited} marginRight={5}>
161
                                <EditIcon color="light.500" />
162
                            </Pressable>}
163
                        {props.handleDelete != null &&
164
                            <Pressable onPress={deleteClicked}>
165
                                <DeleteIcon />
166
                            </Pressable>}
167
                    </Flex>
168
                </HStack>
169
                {showReplies &&
170
                    <VStack style={{borderLeftColor: '#FFC107', borderLeftWidth: 1, paddingLeft: 5, marginTop: 5}}>
171
                        {note.replies?.map((note, index) => {
172
                            return (
173
                                <NoteView key={index} note={note} handleReply={null} handleDelete={props.handleDelete} handleEdit={props.handleEdit} setConfirmDialog={props.setConfirmDialog} navigation={props.navigation} />
174
                            )
175
                        })}
176
                    </VStack>
177
                }
178
            </VStack>
179
        </HStack>
180
    );
181
})
182

    
183
export default NoteView
184

    
(1-1/2)