Skip to content

Commit febb737

Browse files
committed
Start adding online indicator for collab editor
1 parent f162037 commit febb737

File tree

1 file changed

+69
-4
lines changed

1 file changed

+69
-4
lines changed

peerprep/components/questionpage/CollabEditor.tsx

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ import CommsPanel from "./CommsPanel";
1818

1919
import { diff_match_patch } from "diff-match-patch";
2020
import { callFormatter } from "@/app/api/internal/formatter/helper";
21+
import { connect } from "http2";
2122

23+
const PING_INTERVAL_MILLISECONDS = 3000;
2224
const languages: Language[] = ["javascript", "python", "c_cpp"];
2325

2426
const themes = [
@@ -50,7 +52,7 @@ interface Props {
5052
}
5153

5254
interface Message {
53-
type: "content_change" | "auth" | "close_session";
55+
type: "content_change" | "auth" | "close_session" | "ping";
5456
data?: string;
5557
userId?: string | undefined;
5658
token?: string;
@@ -73,6 +75,8 @@ export default function CollabEditor({
7375
const [value, setValue] = useState(questionSeed);
7476
const [socket, setSocket] = useState<WebSocket | null>(null);
7577
const [connected, setConnected] = useState(false);
78+
const [otherUserConnected, setOtherUserConnected] = useState<boolean>(false);
79+
const [lastPingReceived, setLastPingReceived] = useState<number | null>(null);
7680
const router = useRouter();
7781

7882
const generatePatch = (oldContent: string, newContent: string): string => {
@@ -168,6 +172,8 @@ export default function CollabEditor({
168172
}
169173
router.push("/questions");
170174
} else {
175+
// seem to be getting json error here. logs show messages of "ping" type with both user ids tho
176+
console.log(event.data);
171177
const message: Message = JSON.parse(event.data);
172178

173179
if (message.type === "content_change" && message.userId !== userId) {
@@ -183,6 +189,12 @@ export default function CollabEditor({
183189
return applyPatches(currentValue, message.data);
184190
});
185191
}
192+
193+
if (message.type === "ping" && message.userId !== userId) {
194+
console.log("other user connected!");
195+
setOtherUserConnected(true);
196+
setLastPingReceived(Date.now());
197+
}
186198
}
187199
};
188200

@@ -204,6 +216,42 @@ export default function CollabEditor({
204216
};
205217
}, []);
206218

219+
// ping ws
220+
const notifyRoomOfConnection = async () => {
221+
// send message over ws
222+
if (socket) {
223+
const msg: Message = {
224+
type: "ping",
225+
data: "pinging",
226+
userId: userId,
227+
};
228+
socket.send(JSON.stringify(msg));
229+
}
230+
};
231+
232+
useEffect(() => {
233+
if (!connected || !socket) return;
234+
235+
const interval = setInterval(
236+
notifyRoomOfConnection,
237+
PING_INTERVAL_MILLISECONDS,
238+
);
239+
240+
const disconnectCheckInterval = setInterval(() => {
241+
if (
242+
lastPingReceived &&
243+
Date.now() - lastPingReceived > 2 * PING_INTERVAL_MILLISECONDS
244+
) {
245+
setOtherUserConnected(false);
246+
clearInterval(disconnectCheckInterval);
247+
}
248+
}, PING_INTERVAL_MILLISECONDS);
249+
return () => {
250+
clearInterval(interval);
251+
clearInterval(disconnectCheckInterval);
252+
};
253+
}, [notifyRoomOfConnection, PING_INTERVAL_MILLISECONDS, connected, socket]);
254+
207255
const handleCloseConnection = () => {
208256
const confirmClose = confirm(
209257
"Are you sure you are finished? This will close the room for all users.",
@@ -224,7 +272,7 @@ export default function CollabEditor({
224272
{connected && (
225273
<CommsPanel className="flex flex-row justify-around" roomId={roomID} />
226274
)}
227-
<div className="m-4 flex items-center space-x-4 p-4">
275+
<div className="m-4 flex items-end space-x-4 p-4">
228276
<div className="flex flex-col">
229277
<label className="mb-1 font-semibold">Font Size</label>
230278
<input
@@ -261,13 +309,13 @@ export default function CollabEditor({
261309

262310
{roomID &&
263311
(connected ? (
264-
<div className="h-full align-middle">
312+
<div className="align-middle">
265313
<PeerprepButton onClick={handleCloseConnection}>
266314
Close Room
267315
</PeerprepButton>
268316
</div>
269317
) : (
270-
<div className="h-full align-middle">
318+
<div className="align-middle">
271319
<PeerprepButton
272320
onClick={handleCloseConnection}
273321
className="disabled"
@@ -277,6 +325,23 @@ export default function CollabEditor({
277325
</div>
278326
))}
279327
</div>
328+
{roomID &&
329+
(connected ? (
330+
<div className="flex items-center space-x-2 p-2">
331+
<span
332+
className={`h-4 w-4 rounded-full ${
333+
otherUserConnected ? "bg-difficulty-easy" : "bg-difficulty-hard"
334+
}`}
335+
></span>
336+
<span>
337+
{otherUserConnected
338+
? "Other user connected"
339+
: "Other user disconnected"}
340+
</span>
341+
</div>
342+
) : (
343+
<div className="py-2">Disconnected. Check logs.</div>
344+
))}
280345
<AceEditor
281346
mode={language}
282347
className={"editor"}

0 commit comments

Comments
 (0)