Skip to content

Commit c88ed3b

Browse files
authored
Merge pull request #6 from craig-dsilva/poll
Pollling
2 parents c68b736 + 4ac4c62 commit c88ed3b

15 files changed

Lines changed: 320 additions & 37 deletions

File tree

chat-app/client/package-lock.json

Lines changed: 88 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chat-app/client/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"dependencies": {
1313
"react": "^19.2.6",
1414
"react-dom": "^19.2.6",
15+
"react-router-dom": "^7.16.0",
1516
"socket.io-client": "^4.8.3"
1617
},
1718
"devDependencies": {

chat-app/client/src/App.jsx

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,17 @@
1-
import { useState } from "react";
2-
import useSocket from "./hooks/useSocket";
3-
import Message from "./components/Message";
4-
import "./App.css";
1+
import { BrowserRouter, Routes, Route } from "react-router-dom";
2+
import Nav from "./components/Nav/Nav";
3+
import Socket from "./pages/Socket";
4+
import Poll from "./pages/Poll";
55

66
const App = () => {
7-
const { messages, sendMessage } = useSocket(
8-
"https://craig-dsilva-chat-app-server.hosting.codeyourfuture.io/",
9-
);
10-
const [input, setInput] = useState("");
11-
12-
const handleSend = () => {
13-
if (!input.trim()) return;
14-
sendMessage(input.trim());
15-
setInput("");
16-
};
17-
187
return (
19-
<div className="container">
20-
<ul className="messages">
21-
{messages.map((message) => (
22-
<Message message={message.text} messageTime={message.time} />
23-
))}
24-
</ul>
25-
<div className="chat-box">
26-
<input
27-
className="chat-input"
28-
value={input}
29-
onChange={(e) => setInput(e.target.value)}
30-
/>
31-
<button className="send-button" onClick={handleSend}>
32-
Send
33-
</button>
34-
</div>
35-
</div>
8+
<BrowserRouter>
9+
<Nav />
10+
<Routes>
11+
<Route path="/socket" element={<Socket />} />
12+
<Route path="/poll" element={<Poll />} />
13+
</Routes>
14+
</BrowserRouter>
3615
);
3716
};
3817

File renamed without changes.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { useState } from "react";
2+
import Message from "../Message/Message";
3+
import "./Chat.css";
4+
5+
const Chat = ({ messages, sendMessage }) => {
6+
const [input, setInput] = useState("");
7+
8+
const handleSend = () => {
9+
if (!input.trim()) return;
10+
sendMessage(input.trim());
11+
setInput("");
12+
};
13+
14+
return (
15+
<div className="container">
16+
<ul className="messages">
17+
{messages.map((message) => (
18+
<Message message={message.text} messageTime={message.time} />
19+
))}
20+
</ul>
21+
<div className="chat-box">
22+
<input
23+
className="chat-input"
24+
value={input}
25+
onChange={(e) => setInput(e.target.value)}
26+
/>
27+
<button className="send-button" onClick={handleSend}>
28+
Send
29+
</button>
30+
</div>
31+
</div>
32+
);
33+
};
34+
35+
export default Chat;
File renamed without changes.

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

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

44
const Message = ({ message, messageTime }) => {
55
const { date, time } = formatTime(messageTime);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.nav {
2+
text-align: center;
3+
}
4+
5+
.nav a {
6+
color: #000;
7+
text-decoration: none;
8+
}
9+
10+
.box {
11+
display: flex;
12+
flex-direction: column;
13+
font-size: 2rem;
14+
margin: 10% 25%;
15+
}
16+
17+
.bar {
18+
font-size: 2rem;
19+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Link, useMatch } from "react-router-dom";
2+
import "./Nav.css";
3+
4+
const Nav = () => {
5+
const isHome = useMatch("/");
6+
return (
7+
<div className={`nav ${isHome ? "box" : "bar"}`}>
8+
{!isHome ? (
9+
<Link
10+
style={isHome ? { marginBottom: "1rem" } : { marginRight: "1rem" }}
11+
to="/"
12+
>
13+
Home
14+
</Link>
15+
) : (
16+
<p>
17+
This chat application uses 2 different protocols.
18+
<br /> Please select a protocol below.
19+
</p>
20+
)}
21+
<Link
22+
to="/socket"
23+
style={isHome ? { marginBottom: "1rem" } : { marginRight: "1rem" }}
24+
>
25+
WebSocket
26+
</Link>
27+
<Link
28+
to="/poll"
29+
style={isHome ? { marginBottom: "1rem" } : { marginRight: "1rem" }}
30+
>
31+
Long Polling
32+
</Link>
33+
</div>
34+
);
35+
};
36+
37+
export default Nav;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { useEffect, useRef, useState } from "react";
2+
3+
const usePoll = (url) => {
4+
const [messages, setMessages] = useState([]);
5+
const cursorRef = useRef(0);
6+
const activeRef = useRef(true);
7+
8+
useEffect(() => {
9+
const poll = async () => {
10+
while (activeRef.current) {
11+
try {
12+
const res = await fetch(`${url}/poll?since=${cursorRef.current}`);
13+
const data = await res.json();
14+
15+
if (data.messages.length > 0) {
16+
cursorRef.current = data.cursor;
17+
setMessages((prev) => [...prev, ...data.messages]);
18+
}
19+
} catch {
20+
await new Promise((r) => setTimeout(r, 2000));
21+
}
22+
}
23+
};
24+
25+
poll();
26+
return () => {
27+
activeRef.current = false;
28+
};
29+
}, [url]);
30+
31+
const sendMessage = async (text) => {
32+
const message = { text, time: new Date().toISOString() };
33+
setMessages((prev) => [...prev, { ...message }]);
34+
35+
await fetch(`${url}/message`, {
36+
method: "POST",
37+
headers: { "Content-Type": "application/json" },
38+
body: JSON.stringify(message),
39+
});
40+
};
41+
42+
return { messages, sendMessage };
43+
};
44+
45+
export default usePoll;

0 commit comments

Comments
 (0)