Skip to content

Commit ca0770c

Browse files
authored
Merge pull request #7 from craig-dsilva/likes
Likes and Dislikes
2 parents c88ed3b + bb698f3 commit ca0770c

9 files changed

Lines changed: 214 additions & 86 deletions

File tree

chat-app/client/src/components/Chat/Chat.jsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useState } from "react";
22
import Message from "../Message/Message";
33
import "./Chat.css";
44

5-
const Chat = ({ messages, sendMessage }) => {
5+
const Chat = ({ messages, sendMessage, reactToMessage }) => {
66
const [input, setInput] = useState("");
77

88
const handleSend = () => {
@@ -14,8 +14,17 @@ const Chat = ({ messages, sendMessage }) => {
1414
return (
1515
<div className="container">
1616
<ul className="messages">
17-
{messages.map((message) => (
18-
<Message message={message.text} messageTime={message.time} />
17+
{messages.map((message, i) => (
18+
<Message
19+
key={i}
20+
i={i}
21+
index={message.index}
22+
message={message.text}
23+
messageTime={message.time}
24+
likes={message.likes}
25+
dislikes={message.dislikes}
26+
reactToMessage={reactToMessage}
27+
/>
1928
))}
2029
</ul>
2130
<div className="chat-box">

chat-app/client/src/components/Message/Message.css

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,26 @@
66
}
77

88
.message-text,
9-
.message-time {
9+
.message-info {
1010
margin: 0;
1111
}
1212

1313
.message-text {
1414
font-size: large;
1515
}
1616

17-
.message-time {
17+
.message-info {
1818
font-size: small;
19+
display: flex;
20+
justify-content: space-around;
21+
}
22+
23+
.message-like {
24+
display: flex;
25+
}
26+
27+
.like-button {
28+
border: none;
29+
background-color: #fff;
30+
font-size: 1.5rem;
1931
}

chat-app/client/src/components/Message/Message.jsx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,40 @@
11
import formatTime from "../../utils/formatTime";
22
import "./Message.css";
33

4-
const Message = ({ message, messageTime }) => {
4+
const Message = ({
5+
message,
6+
messageTime,
7+
likes,
8+
dislikes,
9+
reactToMessage,
10+
i,
11+
}) => {
512
const { date, time } = formatTime(messageTime);
613

714
return (
815
<div className="message">
916
<p className="message-text">{message}</p>
10-
<p className="message-time">{`${date} ${time}`}</p>
17+
<div className="message-info">
18+
<p>{`${date} ${time}`}</p>
19+
<div className="message-like">
20+
<button
21+
className="like-button"
22+
onClick={() => reactToMessage(i, "likes")}
23+
>
24+
&#128077;
25+
</button>
26+
<p>Likes: {likes}</p>
27+
</div>
28+
<div className="message-like">
29+
<button
30+
className="like-button"
31+
onClick={() => reactToMessage(i, "dislikes")}
32+
>
33+
&#128078;
34+
</button>
35+
<p>Dislikes: {dislikes}</p>
36+
</div>
37+
</div>
1138
</div>
1239
);
1340
};
Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,35 @@
11
import { useEffect, useRef, useState } from "react";
22

3-
const usePoll = (url) => {
3+
const useLongPoll = (url) => {
44
const [messages, setMessages] = useState([]);
55
const cursorRef = useRef(0);
66
const activeRef = useRef(true);
77

88
useEffect(() => {
9+
fetch(`${url}/poll/history`)
10+
.then((r) => r.json())
11+
.then((history) => {
12+
setMessages(history);
13+
cursorRef.current = history.length;
14+
});
15+
916
const poll = async () => {
1017
while (activeRef.current) {
1118
try {
1219
const res = await fetch(`${url}/poll?since=${cursorRef.current}`);
1320
const data = await res.json();
1421

1522
if (data.messages.length > 0) {
16-
cursorRef.current = data.cursor;
17-
setMessages((prev) => [...prev, ...data.messages]);
23+
data.messages.forEach((msg) => {
24+
if (msg.index !== undefined) {
25+
setMessages((prev) =>
26+
prev.map((m, i) => (i === msg.index ? { ...m, ...msg } : m)),
27+
);
28+
} else {
29+
cursorRef.current = data.cursor;
30+
setMessages((prev) => [...prev, msg]);
31+
}
32+
});
1833
}
1934
} catch {
2035
await new Promise((r) => setTimeout(r, 2000));
@@ -29,17 +44,25 @@ const usePoll = (url) => {
2944
}, [url]);
3045

3146
const sendMessage = async (text) => {
32-
const message = { text, time: new Date().toISOString() };
33-
setMessages((prev) => [...prev, { ...message }]);
34-
35-
await fetch(`${url}/message`, {
47+
const msg = { text, time: new Date().toISOString(), likes: 0, dislikes: 0 };
48+
setMessages((prev) => [...prev, { ...msg, self: true }]);
49+
await fetch(`${url}/poll/message`, {
3650
method: "POST",
3751
headers: { "Content-Type": "application/json" },
38-
body: JSON.stringify(message),
52+
body: JSON.stringify(msg),
3953
});
4054
};
4155

42-
return { messages, sendMessage };
56+
const reactToMessage = async (index, type) => {
57+
setMessages((prev) =>
58+
prev.map((msg, i) =>
59+
i === index ? { ...msg, [type]: msg[type] + 1 } : msg,
60+
),
61+
);
62+
await fetch(`${url}/poll/message/${index}/${type}`, { method: "PATCH" });
63+
};
64+
65+
return { messages, sendMessage, reactToMessage };
4366
};
4467

45-
export default usePoll;
68+
export default useLongPoll;

chat-app/client/src/hooks/useSocket.jsx

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,38 @@ const useSocket = (url) => {
99
socketRef.current = io(url);
1010

1111
socketRef.current.on("history", (history) => {
12-
setMessages(history.map((message) => ({ ...message })));
12+
setMessages(history);
1313
});
1414

15-
socketRef.current.on("message", (message) => {
16-
setMessages((prev) => [...prev, message]);
15+
socketRef.current.on("message", (msg) => {
16+
setMessages((prev) => [...prev, msg]);
17+
});
18+
19+
socketRef.current.on("react", ({ index, type, value }) => {
20+
setMessages((prev) =>
21+
prev.map((msg, i) => (i === index ? { ...msg, [type]: value } : msg)),
22+
);
1723
});
1824

1925
return () => socketRef.current.disconnect();
2026
}, [url]);
2127

2228
const sendMessage = (text) => {
23-
const message = {
24-
text,
25-
time: new Date().toISOString(),
26-
};
27-
socketRef.current.emit("message", message);
28-
setMessages((prev) => [...prev, { ...message }]);
29+
const msg = { text, time: new Date().toISOString(), likes: 0, dislikes: 0 };
30+
socketRef.current.emit("message", msg);
31+
setMessages((prev) => [...prev, { ...msg, self: true }]);
32+
};
33+
34+
const reactToMessage = (index, type) => {
35+
setMessages((prev) =>
36+
prev.map((msg, i) =>
37+
i === index ? { ...msg, [type]: msg[type] + 1 } : msg,
38+
),
39+
);
40+
socketRef.current.emit("react", { index, type });
2941
};
3042

31-
return { messages, sendMessage };
43+
return { messages, sendMessage, reactToMessage };
3244
};
3345

3446
export default useSocket;

chat-app/client/src/pages/Poll.jsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,16 @@ import usePoll from "../hooks/usePoll";
22
import Chat from "../components/Chat/Chat";
33

44
const Poll = () => {
5-
const { messages, sendMessage } = usePoll("http://localhost:3000");
6-
return <Chat messages={messages} sendMessage={sendMessage} />;
5+
const { messages, sendMessage, reactToMessage } = usePoll(
6+
"http://localhost:3000",
7+
);
8+
return (
9+
<Chat
10+
messages={messages}
11+
sendMessage={sendMessage}
12+
reactToMessage={reactToMessage}
13+
/>
14+
);
715
};
816

917
export default Poll;

chat-app/client/src/pages/Socket.jsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,16 @@ import useSocket from "../hooks/useSocket";
22
import Chat from "../components/Chat/Chat";
33

44
const Socket = () => {
5-
const { messages, sendMessage } = useSocket("http://localhost:3000");
6-
return <Chat messages={messages} sendMessage={sendMessage} />;
5+
const { messages, sendMessage, reactToMessage } = useSocket(
6+
"http://localhost:3000",
7+
);
8+
return (
9+
<Chat
10+
messages={messages}
11+
sendMessage={sendMessage}
12+
reactToMessage={reactToMessage}
13+
/>
14+
);
715
};
816

917
export default Socket;

chat-app/server/data/chat.json

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
[
22
{
33
"text": "Hello",
4-
"time": "2026-05-22T14:53:00.281Z"
4+
"time": "2026-05-22T14:53:00.281Z",
5+
"likes": 0,
6+
"dislikes": 0
57
},
68
{
79
"text": "How are you?",
8-
"time": "2026-05-22T14:54:49.729Z"
10+
"time": "2026-05-22T14:54:49.729Z",
11+
"likes": 0,
12+
"dislikes": 0
913
},
1014
{
1115
"text": "I'm good. How are you?",
12-
"time": "2026-05-22T14:55:22.839Z"
16+
"time": "2026-05-22T14:55:22.839Z",
17+
"likes": 0,
18+
"dislikes": 0
1319
},
1420
{
1521
"text": "I'm not too bad",
16-
"time": "2026-05-22T14:55:54.424Z"
22+
"time": "2026-05-22T14:55:54.424Z",
23+
"likes": 0,
24+
"dislikes": 0
1725
}
1826
]

0 commit comments

Comments
 (0)