-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathApp.jsx
134 lines (123 loc) · 4.39 KB
/
App.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import React from "react"
import Sidebar from "./components/Sidebar"
import Editor from "./components/Editor"
import Split from "react-split"
import { notesCollection, db } from "./firebase.js"
import { onSnapshot, addDoc, deleteDoc } from "firebase/firestore"
import { doc, setDoc } from "@firebase/firestore"
export default function App() {
const [notes, setNotes] = React.useState([])
const [currentNoteId, setCurrentNoteId] = React.useState("")
const [tempNoteText, setTempNoteText] = React.useState("")
const currentNote =
notes.find(note => note.id === currentNoteId)
|| notes[0]
const sortedNotes = notes.sort(
(objA, objB) => Number(objB.updatedAt) - Number(objA.updatedAt),
);
React.useEffect(() => {
// Sync up local notes array with the Snapshot (Firebase) Data
const unsubscribe = onSnapshot(notesCollection, function(snapshot){
const notesArray = snapshot.docs.map(doc => ({
...doc.data() ,
id: doc.id
}))
setNotes(notesArray);
})
return unsubscribe
}, [])
//Only for the 1st time
React.useEffect(() => {
if(!currentNoteId){
setCurrentNoteId(notes[0]?.id)
}
}, [notes])
//For Debouncing: tempNote State instead of updateNote
React.useEffect(() => {
if (currentNote) {
setTempNoteText(prev => currentNote.body)
}
}, [currentNote])
//DEBOUCING LOGIC
// * Create an effect that runs any time the tempNoteText changes
// * Delay the sending of the request to Firebase
// * uses setTimeout
// * use clearTimeout to cancel the timeout
React.useEffect(() => {
const timeoutID = setTimeout(() => {
if(tempNoteText !== currentNote.body){
updateNote(tempNoteText)
}
}, 500)
return () => clearTimeout(timeoutID)
}, [tempNoteText])
async function createNewNote() {
const newNote = {
body: "# Type your markdown note's title here",
createdAt: Date.now(),
updatedAt: Date.now()
}
const noteRef = await addDoc(notesCollection, newNote)
setCurrentNoteId(noteRef.id)
}
async function updateNote(text) {
// WITH DATABASE
const docRef = doc(db, "notes", currentNoteId)
await setDoc(docRef,
{body: text, updatedAt: Date.now()},
{merge: true})
// WITHOUT DATABASE
// setNotes(oldNotes => {
// const newArray = []
// for (let i = 0; i < oldNotes.length; i++) {
// const oldNote = oldNotes[i]
// if (oldNote.id === currentNoteId) {
// // Put the most recently-modified note at the top
// newArray.unshift({ ...oldNote, body: text })
// } else {
// newArray.push(oldNote)
// }
// }
// return newArray
// })
}
async function deleteNote(noteId) {
const docRef = doc(db,"notes", noteId);
await deleteDoc(docRef)
}
return (
<main>
{
notes.length > 0
?
<Split
sizes={[30, 70]}
direction="horizontal"
className="split"
>
<Sidebar
notes={sortedNotes}
currentNote={currentNote}
setCurrentNoteId={setCurrentNoteId}
newNote={createNewNote}
deleteNote={deleteNote}
/>
<Editor
currentNote={tempNoteText}
updateNote={setTempNoteText}
/>
</Split>
:
<div className="no-notes">
<h1>You have no notes</h1>
<button
className="first-note"
onClick={createNewNote}
>
Create one now
</button>
</div>
}
</main>
)
}