forked from ReactTraining/hooks-workshop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNewPost.js
119 lines (104 loc) · 3.17 KB
/
NewPost.js
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
import React, { useState, useRef, useEffect } from "react"
import { useAppState } from "app/app-state"
import { createPost, DATE_FORMAT } from "app/utils"
import { format as formatDate } from "date-fns"
import Avatar from "app/Avatar"
import Minutes from "app/Minutes"
import { FaDumbbell } from "react-icons/fa"
import RecentPostsDropdown from "app/RecentPostsDropdown"
const MAX_MESSAGE_LENGTH = 200
export default function NewPost({ takeFocus, date, onSuccess, showAvatar }) {
const [{ auth }] = useAppState()
const [message, setMessage] = useState(
getLocalStorageValue(makeNewPostKey(date)) || ""
)
const [saving, setSaving] = useState(false)
const formRef = useRef()
const messageRef = useRef()
useEffect(() => {
setLocalStorage(makeNewPostKey(date), message)
})
useEffect(() => {
if (takeFocus) {
messageRef.current.focus()
}
}, [takeFocus])
const handleAboutChange = event => {
setMessage(event.target.value)
}
const tooMuchText = message.length > MAX_MESSAGE_LENGTH
const submit = event => {
setSaving(true)
// eslint-disable-next-line
createPost({
message: messageRef.current.value,
// We specifically want to avoid refs for Minutes because it would
// require ref forwarding and not all Minutes components (lectures)
// will use ref forwarding (because they don't need it)
minutes: parseInt(event.target.elements[3].value, 10),
date: formatDate(date, DATE_FORMAT),
uid: auth.uid
}).then(post => {
setSaving(false)
setMessage("")
onSuccess(post)
})
}
const handleSubmit = event => {
event.preventDefault()
submit(event)
}
const handleMessageKeyDown = event => {
if (event.metaKey && event.key === "Enter") {
submit(event)
}
}
const handleRecentSelect = text => {
setMessage(text)
}
return (
<div
className={"NewPost" + (tooMuchText ? " NewPost_error" : "")}
style={{ opacity: saving ? 0.25 : 1 }}
>
{showAvatar && <Avatar uid={auth.uid} size={70} />}
<form ref={formRef} className="NewPost_form" onSubmit={handleSubmit}>
<textarea
ref={messageRef}
className="NewPost_input"
placeholder="Tell us about your workout!"
value={message}
onChange={handleAboutChange}
onKeyDown={handleMessageKeyDown}
/>
<div className="NewPost_char_count">
{message.length}/{MAX_MESSAGE_LENGTH}
</div>
<RecentPostsDropdown uid={auth.uid} onSelect={handleRecentSelect} />
<div className="NewPost_buttons">
<Minutes date={date} />
<div>
<button disabled={saving} type="submit" className="icon_button cta">
<FaDumbbell /> <span>Post</span>
</button>
</div>
</div>
</form>
</div>
)
}
function makeNewPostKey(date) {
return `newPost:${formatDate(date, DATE_FORMAT)}`
}
function getLocalStorageValue(key) {
const val = localStorage.getItem(key)
if (!val) return null
try {
return JSON.parse(val)
} catch (e) {
return null
}
}
function setLocalStorage(key, value) {
localStorage.setItem(key, JSON.stringify(value))
}