Skip to content

Commit 81a9d8f

Browse files
committed
add timer before exam start
1 parent 61bd495 commit 81a9d8f

3 files changed

Lines changed: 37 additions & 19 deletions

File tree

client/uis/screen.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export interface UIExamModeElements {
2323
examStartText: HTMLSpanElement;
2424
examEndText: HTMLSpanElement;
2525
examStartButton: HTMLButtonElement;
26+
examStartTimer: HTMLParagraphElement;
2627
}
2728

2829
export abstract class UIScreen {

client/uis/screens/examscreen.ts

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export class ExamModeUI extends UIScreen {
1111
private _examMode: boolean = false;
1212
private _examIds: number[] = [];
1313
private _loginScreen: LoginScreenUI;
14-
private _examStartButtonTimeout: ReturnType<typeof setTimeout> | null = null;
14+
private _examStartButtonEnableInterval: ReturnType<typeof setInterval> | null = null;
1515
private _examStartTime = new Date("2099-01-01T00:00:00Z"); // Set to a future date so that the button is disabled by default
1616
protected _events: AuthenticatorEvents = {
1717
authenticationStart: () => {
@@ -45,6 +45,7 @@ export class ExamModeUI extends UIScreen {
4545
examStartText: document.getElementById('exam-mode-start') as HTMLSpanElement,
4646
examEndText: document.getElementById('exam-mode-end') as HTMLSpanElement,
4747
examStartButton: document.getElementById('exam-mode-start-button') as HTMLButtonElement,
48+
examStartTimer: document.getElementById('exam-mode-start-timer') as HTMLParagraphElement,
4849
} as UIExamModeElements;
4950

5051
this._initForm();
@@ -102,6 +103,17 @@ export class ExamModeUI extends UIScreen {
102103
});
103104
}
104105

106+
private _clearExamStartTimer(): void {
107+
const form = this._form as UIExamModeElements;
108+
if (this._examStartButtonEnableInterval) {
109+
clearTimeout(this._examStartButtonEnableInterval);
110+
this._examStartButtonEnableInterval = null;
111+
}
112+
this._examStartTime = new Date("2099-01-01T00:00:00Z");
113+
form.examStartTimer.innerText = "Click the arrow below to start your exam.";
114+
this._enableOrDisableSubmitButton();
115+
}
116+
105117
private _populateData(examsToPopulate: ExamForHost[]): void {
106118
const form = this._form as UIExamModeElements;
107119

@@ -111,12 +123,7 @@ export class ExamModeUI extends UIScreen {
111123
form.examStartText.innerText = 'unknown';
112124
form.examEndText.innerText = 'unknown';
113125
// Clear the timeout for the exam start button and disable it
114-
if (this._examStartButtonTimeout) {
115-
clearTimeout(this._examStartButtonTimeout);
116-
this._examStartButtonTimeout = null;
117-
}
118-
this._examStartTime = new Date("2099-01-01T00:00:00Z");
119-
this._enableOrDisableSubmitButton();
126+
this._clearExamStartTimer();
120127
}
121128
else {
122129
// Find all exams in the data.json file that match the ids in the exams variable
@@ -156,18 +163,21 @@ export class ExamModeUI extends UIScreen {
156163
form.examEndText.innerText = latestExam.toLocaleTimeString("en-NL", { hour: '2-digit', minute: '2-digit' });
157164

158165
// Enable or disable the exam start button based on the current time
159-
this._enableOrDisableSubmitButton();
160-
161-
// Enable the exam start button at the exam start time if it is in the future
162-
// Make sure to clear any existing timeout first
163-
if (this._examStartButtonTimeout) {
164-
clearTimeout(this._examStartButtonTimeout);
165-
this._examStartButtonTimeout = null;
166-
}
166+
this._clearExamStartTimer();
167167
if (this._examStartTime.getTime() > Date.now()) {
168-
this._examStartButtonTimeout = setTimeout(() => {
169-
this._enableOrDisableSubmitButton();
170-
}, this._examStartTime.getTime() - Date.now());
168+
this._examStartButtonEnableInterval = setInterval(() => {
169+
const timeLeft = Math.floor((this._examStartTime.getTime() - Date.now()) / 1000);
170+
const minutes = Math.floor(timeLeft / 60);
171+
const seconds = timeLeft % 60;
172+
const formattedTime = `${(minutes > 0 ? `${minutes} minutes and ` : '')} ${seconds} seconds`;
173+
form.examStartTimer.innerText = `The exam starts in ${formattedTime}.`;
174+
175+
if (this._examStartTime.getTime() <= Date.now()) {
176+
// Clear the timer and enable the button
177+
this._clearExamStartTimer();
178+
return;
179+
}
180+
}, 1000);
171181
}
172182
}
173183
}
@@ -177,6 +187,13 @@ export class ExamModeUI extends UIScreen {
177187
const form = this._form as UIExamModeElements;
178188
const buttonDisabled = this._examStartTime.getTime() > Date.now(); // Disable the button if the exam start time is in the future
179189
form.examStartButton.disabled = buttonDisabled;
190+
if (!buttonDisabled) {
191+
form.examStartTimer.innerText = "Click the arrow below to start your exam.";
192+
const focusInput = this._getInputToFocusOn();
193+
if (focusInput) {
194+
focusInput.focus();
195+
}
196+
}
180197
return buttonDisabled;
181198
}
182199

static/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ <h4 id="active-user-session-login-name">username</h4>
5353
<h3>This computer is reserved for an exam between <span id="exam-mode-start">...</span> and <span id="exam-mode-end">...</span>.</h3>
5454
<p><span id="exam-mode-projects"></span></p>
5555
<br>
56-
<p>Click the arrow below to start your exam.</p>
56+
<p id="exam-mode-start-timer">Click the arrow below to start your exam.</p>
5757
<button type="submit" id="exam-mode-start-button" title="Start your exam">&#10149;</button>
5858
</form>
5959

0 commit comments

Comments
 (0)