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
|
|