Skip to content

Commit 68023da

Browse files
committed
Implement session timer using localstorage
1 parent bb2b215 commit 68023da

File tree

2 files changed

+84
-15
lines changed

2 files changed

+84
-15
lines changed

apps/frontend/src/app/collaboration/[id]/page.tsx

Lines changed: 78 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
import { Content } from "antd/es/layout/layout";
1616
import "./styles.scss";
1717
import { useRouter, useSearchParams } from "next/navigation";
18-
import { useEffect, useState } from "react";
18+
import { useEffect, useRef, useState } from "react";
1919
import { GetSingleQuestion, Question } from "@/app/services/question";
2020
import {
2121
ClockCircleOutlined,
@@ -50,6 +50,11 @@ export default function CollaborationPage(props: CollaborationProps) {
5050
);
5151
const [currentUser, setCurrentUser] = useState<string | undefined>(undefined);
5252
const [matchedUser, setMatchedUser] = useState<string | undefined>(undefined);
53+
const [sessionDuration, setSessionDuration] = useState<number>(() => {
54+
const storedTime = localStorage.getItem("session-duration");
55+
return storedTime ? parseInt(storedTime) : 0;
56+
}); // State for count-up timer (TODO: currently using localstorage to store time, change to db stored time in the future)
57+
const stopwatchRef = useRef<NodeJS.Timeout | null>(null);
5358

5459
// Chat states
5560
const [messageToSend, setMessageToSend] = useState<string | undefined>(
@@ -61,8 +66,42 @@ export default function CollaborationPage(props: CollaborationProps) {
6166
undefined
6267
);
6368

64-
// Retrieve the docRefId from query params during page navigation
65-
// const searchParams = useSearchParams();
69+
// Stops the session duration stopwatch
70+
const stopStopwatch = () => {
71+
if (stopwatchRef.current) {
72+
clearInterval(stopwatchRef.current);
73+
}
74+
};
75+
76+
// Starts the session duration stopwatch
77+
const startStopwatch = () => {
78+
if (stopwatchRef.current) {
79+
clearInterval(stopwatchRef.current);
80+
}
81+
82+
stopwatchRef.current = setInterval(() => {
83+
setSessionDuration((prevTime) => {
84+
const newTime = prevTime + 1;
85+
localStorage.setItem("session-duration", newTime.toString());
86+
return newTime;
87+
});
88+
}, 1000);
89+
};
90+
91+
// Convert seconds into time of format "hh:mm:ss"
92+
const formatTime = (seconds: number) => {
93+
const hours = Math.floor(seconds / 3600);
94+
const minutes = Math.floor((seconds % 3600) / 60);
95+
const secs = seconds % 60;
96+
97+
return (
98+
(hours > 9 ? hours : "0" + hours) +
99+
":" +
100+
(minutes > 9 ? minutes : "0" + minutes) +
101+
":" +
102+
(secs > 9 ? secs : "0" + secs)
103+
);
104+
};
66105

67106
// Fetch the question on initialisation
68107
useEffect(() => {
@@ -81,14 +120,19 @@ export default function CollaborationPage(props: CollaborationProps) {
81120
setMatchedUser(matchedUser);
82121
setCurrentUser(currentUser);
83122

123+
// Fetch question and set question states
84124
GetSingleQuestion(docRefId).then((data: Question) => {
85125
setQuestionTitle(`${data.id}. ${data.title}`);
86126
setComplexity(data.complexity);
87127
setCategories(data.categories);
88128
setDescription(data.description);
89129
});
130+
131+
// Start stopwatch
132+
startStopwatch();
90133
}, []);
91134

135+
// Tabs component items for testcases
92136
const items: TabsProps["items"] = [
93137
{
94138
key: "1",
@@ -117,15 +161,21 @@ export default function CollaborationPage(props: CollaborationProps) {
117161
},
118162
];
119163

164+
// Handles the cleaning of localstorage variables, stopping the timer & signalling collab user on webrtc
120165
const handleCloseCollaboration = () => {
121-
// Remove localstorage variables for collaboration
122-
localStorage.removeItem("user");
123-
localStorage.removeItem("matchedUser");
124-
localStorage.removeItem("collaId");
125-
localStorage.removeItem("docRefId");
166+
// Stop stopwatch
167+
stopStopwatch();
168+
// Remove localstorage variable for stored session duration
169+
localStorage.removeItem("session-duration"); // TODO: Remove this after collaboration backend data stored
126170

127-
// Redirect back to matching page
128-
router.push("/matching");
171+
// // Remove localstorage variables for collaboration
172+
// localStorage.removeItem("user");
173+
// localStorage.removeItem("matchedUser");
174+
// localStorage.removeItem("collaId");
175+
// localStorage.removeItem("docRefId");
176+
177+
// // Redirect back to matching page
178+
// router.push("/matching");
129179
};
130180

131181
return (
@@ -170,7 +220,11 @@ export default function CollaborationPage(props: CollaborationProps) {
170220
Test Cases
171221
</div>
172222
{/* TODO: Link to execution service for running code against test-cases */}
173-
<Button icon={<PlayCircleOutlined />} iconPosition="end">
223+
<Button
224+
icon={<PlayCircleOutlined />}
225+
iconPosition="end"
226+
className="test-case-button"
227+
>
174228
Run Test Cases
175229
</Button>
176230
</div>
@@ -189,7 +243,11 @@ export default function CollaborationPage(props: CollaborationProps) {
189243
Code
190244
</div>
191245
{/* TODO: Link to execution service for code submission */}
192-
<Button icon={<SendOutlined />} iconPosition="end">
246+
<Button
247+
icon={<SendOutlined />}
248+
iconPosition="end"
249+
className="code-submit-button"
250+
>
193251
Submit
194252
</Button>
195253
</div>
@@ -221,15 +279,20 @@ export default function CollaborationPage(props: CollaborationProps) {
221279
Session Details
222280
</div>
223281
{/* TODO: End the collaboration session, cleanup the localstorage variables */}
224-
<Button danger onClick={handleCloseCollaboration}>
282+
<Button
283+
danger
284+
onClick={handleCloseCollaboration}
285+
className="session-end-button"
286+
>
225287
End
226288
</Button>
227289
</div>
228290

229291
<div className="session-duration">
230292
Duration:
231-
{/* TODO: Implement a count-up timer for session duration */}
232-
<text className="session-duration-timer">00:00:00</text>
293+
<text className="session-duration-timer">
294+
{formatTime(sessionDuration)}
295+
</text>
233296
</div>
234297
<div className="session-matched-user-label">
235298
Matched User:

apps/frontend/src/app/collaboration/[id]/styles.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,9 @@
168168
.title-icons {
169169
margin-right: 4px;
170170
}
171+
172+
.code-submit-button,
173+
.session-end-button,
174+
.test-case-button {
175+
width: fit-content;
176+
}

0 commit comments

Comments
 (0)