Projekt

Obecné

Profil

Stáhnout (7.86 KB) Statistiky
| Větev: | Tag: | Revize:
1
import {
2
    HStack,
3
    Box,
4
    Text,
5
    Image,
6
    VStack,
7
    Flex,
8
    Pressable,
9
    DeleteIcon,
10
    Button,
11
    Center,
12
    Avatar,
13
    TextArea,
14
    AlertDialog,
15
    ScrollView,
16
    KeyboardAvoidingView
17
} from "native-base";
18
import { Note } from "../../types/note";
19
import { EditIcon } from "../general/Icons";
20
import { AVATAR_URL } from "../../api/constants";
21
import { useState } from "react";
22
import React from "react";
23
import NotesListView from "./NotesListView";
24
import {Platform} from "react-native"
25

    
26
const NoteView = React.memo((props: { note: Note, handleReply: any, handleDelete: any, handleEdit: any, setConfirmDialog: any, navigation: any, parentId?: string, higlighted?: boolean }) => {
27
    const note = props.note;
28

    
29
    const [isEdited, setIsEdited] = useState(false);
30

    
31
    const [showReplies, setShowReplies] = useState(false);
32

    
33
    const [text, setText] = useState(note.note);
34

    
35
    console.log("rerender");
36

    
37
    const getDateString = (timestamp: Date): string => {
38
        return new Date(timestamp).toLocaleString("en-US",
39
            { year: "numeric", month: "short", day: "2-digit", hour: "2-digit", minute: "2-digit", hour12: false }
40
        ).replace(/,/g, "").replace(/ /g, "-").replace(/-(?!.*-)/, " ");
41
    }
42

    
43
    const getUsernameInitials = (username: string): string => {
44
        if (username) {
45
            const words = username.split(" ");
46
            const initials = words.map(word => word.charAt(0).toUpperCase());
47
            return initials.join("");
48
        }
49
        return "UK"; // Unknown
50
    }
51

    
52

    
53
    const toggleShowReplies = () => {
54
        console.log("Toggle showReplies");
55
        setShowReplies(!showReplies)
56
    }
57

    
58
    const toggleEdited = () => {
59
        console.log("Toggle edit");
60
        if (isEdited) {
61
            if (text == note.note) {
62
                setIsEdited(false);
63
            }
64
            else {
65
                // confirm dialog
66
                props.setConfirmDialog({
67
                    headerText: "Cancel Edit",
68
                    bodyText: "Are you sure you want to revert changes on this note?",
69
                    confirmText: "Revert Changes",
70
                    confirmColor: "danger",
71
                    onClose: () => { props.setConfirmDialog(null) },
72
                    onSubmit: () => { setText(note.note); setIsEdited(false); props.setConfirmDialog(null) }
73
                });
74
            }
75
        }
76
        else {
77
            setIsEdited(true);
78
        }
79
    }
80

    
81
    const deleteClicked = () => {
82
        props.setConfirmDialog({
83
            headerText: "Delete Note",
84
            bodyText: "Are you sure you want to delete selected note?",
85
            confirmText: "Delete",
86
            confirmColor: "danger",
87
            onClose: () => { props.setConfirmDialog(null) },
88
            onSubmit: () => { props.handleDelete(note.uuid); props.setConfirmDialog(null) }
89
        });
90
    }
91

    
92
    const saveEdit = () => {
93
        if (note.note == text) {
94
            setIsEdited(false);
95
        }
96
        else {
97
            props.handleEdit({ ...note, note: text });
98
            setIsEdited(false);
99
        }
100
    }
101

    
102
    return (
103

    
104
        <HStack backgroundColor={props.higlighted ? "secondary.50" : "white"} borderBottomColor={props.higlighted ? "secondary.800" : ""}
105
                borderBottomWidth={props.higlighted ? 1.5 : 0} paddingBottom={props.higlighted ? 10 : 0} marginTop={5}>
106
            <Box width="12" height="12" marginTop="2">
107
                <Avatar bg={note.noteColor} width={10} height={10} source={{
108
                    uri: AVATAR_URL + "/" + note.avatarUrl
109
                        // TODO bude zde nebo v atributu ta připona?
110
                        + ".png"
111
                }}>
112
                    {getUsernameInitials(note.username)}
113
                </Avatar>
114
            </Box>
115
            <VStack flex={1} marginLeft="0.5">
116

    
117
                {/* Top section */}
118
                <Text bold>
119
                    {note.username}
120
                </Text>
121

    
122
                <Text italic color="trueGray.500" fontSize="xs">
123
                    {getDateString(note.createdTime)}
124
                </Text>
125

    
126
                {/* Middle section */}
127
                <HStack justifyContent={"space-between"} marginTop={2}>
128
                    {isEdited ?
129
                        <TextArea flex={1} fontSize="14" autoCompleteType={undefined} value={text} onChangeText={setText} />
130
                        :
131
                        <Text flex={1} >
132
                            {text}
133
                        </Text>
134
                    }
135

    
136
                    {note.items && note.items.length > 0 &&
137
                        <Flex marginLeft={1} flex={0}>
138
                            <Button p={1} variant="solid" backgroundColor="secondary.500" borderRadius={8} size="sm" onPress={() => props.navigation.navigate("Item", { itemId: note.items[0] })}>
139
                                <Text color="primary.500" fontSize={12}>
140
                                    {note.items[0]}
141
                                </Text>
142
                            </Button>
143
                        </Flex>
144

    
145
                    }
146
                </HStack>
147

    
148
                {/* Bottom section */}
149
                <HStack justifyContent={"space-between"} marginTop={2}>
150
                    {/* () => props.handleEdit(note.uuid, text) */}
151
                    <Flex direction="row" alignItems="center">
152
                        {props.handleReply != null &&
153
                            <Pressable onPress={() => props.handleReply(note.uuid, note.username)}>
154
                                <Text color="trueGray.500">Reply</Text>
155
                            </Pressable>}
156
                        {!props.parentId && note.replies && note.replies.length > 0 &&
157
                            <Pressable marginLeft={3} onPress={() => toggleShowReplies()}>
158
                                {!showReplies ?
159
                                    <Text color="trueGray.500">{note.replies.length} replies</Text>
160
                                    :
161
                                    <Text color="trueGray.500">Hide</Text>
162
                                }
163

    
164
                            </Pressable>}
165
                    </Flex>
166

    
167
                    <Flex direction="row" alignItems="center" justify="flex-end">
168
                        {props.handleEdit &&
169
                            isEdited &&
170
                            <>
171
                                < Pressable onPress={saveEdit} marginRight={5}>
172
                                    <Text color="trueGray.500">Save</Text>
173
                                </Pressable>
174
                                <Pressable onPress={toggleEdited} marginRight={6}>
175
                                    <Text color="trueGray.500">Cancel</Text>
176
                                </Pressable>
177
                            </>}
178
                        {props.handleEdit &&
179
                            !isEdited &&
180
                            <Pressable onPress={toggleEdited} marginRight={5}>
181
                                <EditIcon color="trueGray.500" />
182
                            </Pressable>}
183
                        {props.handleDelete &&
184
                            <Pressable onPress={deleteClicked}>
185
                                <DeleteIcon />
186
                            </Pressable>
187
                        }
188

    
189
                    </Flex>
190
                </HStack>
191
                {
192
                    showReplies &&
193
                    <VStack style={{ borderLeftColor: '#FFC107', borderLeftWidth: 1, paddingLeft: 5, marginTop: 5 }}>
194
                        {note.replies?.map((note, index) => {
195
                            return (
196
                                <NoteView key={index} note={note} handleReply={null} handleDelete={props.handleDelete} handleEdit={props.handleEdit} setConfirmDialog={props.setConfirmDialog} navigation={props.navigation} />
197
                            )
198
                        })}
199
                    </VStack>
200
                }
201
            </VStack >
202
        </HStack >
203
    );
204
})
205

    
206
export default NoteView
207

    
(1-1/2)