+141
-4
client/src/pages/Chat.jsx
+141
-4
client/src/pages/Chat.jsx
···
1
-
function Chat() {
1
+
import { useEffect, useState, useRef } from "react";
2
+
3
+
export default function Chat() {
4
+
5
+
const [messages, setMessages] = useState([]);
6
+
const [terminated, setTerminated] = useState(false);
7
+
const [currMessage, setCurrMessage] = useState("");
8
+
const [isConnected, setIsConnected] = useState(false);
9
+
const [isSearching, setIsSearching] = useState(false);
10
+
const [matched, setMatched] = useState(false);
11
+
const [receiver, setReceiver] = useState(localStorage.getItem("receiver"));
12
+
const socketRef = useRef(null);
13
+
14
+
const handleChange = (e) => setCurrMessage(e.target.value);
15
+
16
+
const handleKeyPress = (e) => {
17
+
if (e.key === "Enter" && currMessage.trim() !== "" && matched) {
18
+
const payload = {
19
+
id: localStorage.getItem("userId"),
20
+
message: currMessage
21
+
};
22
+
socketRef.current.send(JSON.stringify(payload));
23
+
setCurrMessage("");
24
+
}
25
+
};
26
+
27
+
const handleClick = () => {
28
+
if (isConnected) return;
29
+
30
+
const userId = localStorage.getItem("userId");
31
+
if (!userId) {
32
+
alert("Please login first");
33
+
return;
34
+
}
35
+
36
+
setIsSearching(true);
37
+
socketRef.current = new WebSocket(`ws://localhost:3000/?userId=${userId}`);
38
+
39
+
socketRef.current.onopen = () => {
40
+
console.log("Connected to WebSocket");
41
+
setIsConnected(true);
42
+
};
43
+
44
+
socketRef.current.onmessage = (e) => {
45
+
try {
46
+
const data = JSON.parse(e.data);
47
+
48
+
if (data.type === "matched") {
49
+
setIsSearching(false);
50
+
setMatched(true);
51
+
setReceiver(data.with);
52
+
localStorage.setItem("receiver", data.with);
53
+
console.log("Matched with:", data.with);
54
+
} else if (data.type === "disconnected") {
55
+
setMatched(false);
56
+
setReceiver(null);
57
+
localStorage.removeItem("receiver");
58
+
setIsSearching(true);
59
+
console.log("Partner disconnected, searching for new match...");
60
+
} else if (data.type === "no_match") {
61
+
setIsSearching(false);
62
+
setMatched(false);
63
+
setReceiver(null);
64
+
localStorage.removeItem("receiver");
65
+
console.log("No match found");
66
+
} else {
67
+
setMessages((prev) => [...prev, data]);
68
+
}
69
+
} catch (err) {
70
+
console.error("Error parsing message:", err);
71
+
setMessages((prev) => [...prev, e.data]);
72
+
}
73
+
};
74
+
75
+
socketRef.current.onclose = () => {
76
+
setTerminated(true);
77
+
setIsConnected(false);
78
+
setIsSearching(false);
79
+
};
80
+
81
+
socketRef.current.onerror = (err) => {
82
+
console.error("WebSocket Error:", err);
83
+
setIsSearching(false);
84
+
};
85
+
};
86
+
87
+
useEffect(() => {
88
+
return () => {
89
+
if (socketRef.current) {
90
+
socketRef.current.close();
91
+
}
92
+
};
93
+
}, []);
94
+
95
+
if (terminated) return <h1>Chat Terminated</h1>;
96
+
2
97
return (
3
-
<h1>Chat</h1>
4
-
)
98
+
<div>
99
+
{!isConnected ? (
100
+
<button onClick={handleClick}>I want a friend</button>
101
+
) : isSearching ? (
102
+
<div>
103
+
<p>Searching for a friend...</p>
104
+
<button onClick={() => {
105
+
socketRef.current?.close();
106
+
setIsConnected(false);
107
+
setIsSearching(false);
108
+
}}>Cancel</button>
109
+
</div>
110
+
) : matched && receiver ? (
111
+
<div>
112
+
<h2>Chat with {receiver}</h2>
113
+
<input
114
+
type="text"
115
+
value={currMessage}
116
+
onChange={handleChange}
117
+
onKeyDown={handleKeyPress}
118
+
placeholder="Type a message..."
119
+
/>
120
+
<ul>
121
+
{messages.map((msg, i) => (
122
+
<li key={i}>
123
+
{typeof msg === 'string' ? msg : `${msg.id}: ${msg.message}`}
124
+
</li>
125
+
))}
126
+
</ul>
127
+
</div>
128
+
) : isConnected && !isSearching ? (
129
+
<div>
130
+
<p>No match found. Try again later.</p>
131
+
<button onClick={() => {
132
+
socketRef.current?.close();
133
+
setIsConnected(false);
134
+
setIsSearching(false);
135
+
setMatched(false);
136
+
setReceiver(null);
137
+
localStorage.removeItem("receiver");
138
+
}}>Try Again</button>
139
+
</div>
140
+
) : null}
141
+
</div>
142
+
);
5
143
}
6
144
7
-
export default Chat;