add simple countdown timer

This commit is contained in:
Ross
2020-04-30 20:14:26 +01:00
parent 1230fddb2e
commit 38138600fc
4 changed files with 165 additions and 20 deletions
+30 -3
View File
@@ -550,7 +550,12 @@ img {
} }
.dialog-text { .dialog-text {
margin-bottom: 3.2rem; padding: .4rem 2.8rem;
/* margin-bottom: 3.2rem; */
}
#exam-time {
font-weight: bold;
} }
.dialog-cancel { .dialog-cancel {
@@ -570,6 +575,17 @@ img {
background-color: #b71c1c !important; background-color: #b71c1c !important;
} }
.dialog-review {
border-radius: 5px 5px 5px 5px !important;
border-width: 0px !important;
margin: 1.6rem 1.6rem 1.6rem 0.8rem !important;
width: 19.2rem !important;
padding: 0.8rem !important;
background-color: #4527A0 !important;
}
/* Options overlay */ /* Options overlay */
.fullscreen-overlay { .fullscreen-overlay {
@@ -769,8 +785,9 @@ select option:disabled {
.save-button { .save-button {
display:inline-block; display:inline-block;
padding-left: 10px; margin-left: 10px;
color:#FFFFFF; color:#FFFFFF;
border-bottom:2px solid transparent;
} }
.save-button a { .save-button a {
@@ -778,7 +795,8 @@ select option:disabled {
} }
.save-button:hover { .save-button:hover {
color: blue; color: #311B92;
border-bottom:2px solid #311B92;
} }
.packet-button:hover{ .packet-button:hover{
@@ -794,6 +812,15 @@ select option:disabled {
font-size: smaller; font-size: smaller;
} }
#timer {
position: relative;
top: 50%;
/* left: 50%; */
transform: translate(0, -20%);
/* color: #4527A0; */
opacity: 25%;
}
.sk-cube-grid { .sk-cube-grid {
width: 60px; width: 60px;
height: 60px; height: 60px;
+34 -15
View File
@@ -23,6 +23,7 @@
<button id="review-overlay-button" class="navigation nav-right">review</button> <button id="review-overlay-button" class="navigation nav-right">review</button>
<!--<button id="logout-button" class="navigation nav-right">logout</button>--> <!--<button id="logout-button" class="navigation nav-right">logout</button>-->
<div class="app-name nav-left">RTS</div> <div class="app-name nav-left">RTS</div>
<div id="timer"></div>
<div class="exam-name"></div> <div class="exam-name"></div>
<input type="button" class="navigation nav-left" value="previous" disabled="disabled"> <input type="button" class="navigation nav-left" value="previous" disabled="disabled">
<input type="button" class="navigation nav-left" value="next"> <input type="button" class="navigation nav-left" value="next">
@@ -92,29 +93,47 @@
</div> </div>
</div> </div>
<div id="start-dialog" class="dialog modal">
<h3 class="dialog-title">Start exam</h3>
<div class="dialog-text">
Click to start exam.
<p>You will have <span id='exam-time'></span> minutes.</p>
</div>
<button id="start-packet-button" class="navigation dialog-yes">Start</button>
</div>
<div id="time-up-dialog" class="dialog modal">
<h3 class="dialog-title">Time ended</h3>
<div class="dialog-text">
Allocated time has ended. You can review or continue.
</div>
<button id="time-up-review-button" class="navigation dialog-review">Review</button>
<button id="time-up-continue-button" class="navigation dialog-yes">Continue</button>
</div>
<div id="login-dialog" class="dialog modal"> <div id="login-dialog" class="dialog modal">
<h3 class="dialog-title">Select exam</h3> <h3 class="dialog-title">Select exam</h3>
Candidate number: <input type="text" id="candidate-number" name="candidate" required size="10">
<div class="dialog-text"> <div class="dialog-text">
<button id="start-exam-button" class="navigation dialog-yes">Start</button> Candidate number: <input type="text" id="candidate-number" name="candidate" required size="10">
</div> </div>
<button id="start-exam-button" class="navigation dialog-yes">Start</button>
</div> </div>
<div id="loading" class="fullscreen-overlay"> <div id="loading" class="fullscreen-overlay">
<div class="progress-block"> <div class="progress-block">
<div id="progress"> <div id="progress">
</div> </div>
<div class="sk-cube-grid full"> <div class="sk-cube-grid full">
<div class="sk-cube sk-cube1"></div> <div class="sk-cube sk-cube1"></div>
<div class="sk-cube sk-cube2"></div> <div class="sk-cube sk-cube2"></div>
<div class="sk-cube sk-cube3"></div> <div class="sk-cube sk-cube3"></div>
<div class="sk-cube sk-cube4"></div> <div class="sk-cube sk-cube4"></div>
<div class="sk-cube sk-cube5"></div> <div class="sk-cube sk-cube5"></div>
<div class="sk-cube sk-cube6"></div> <div class="sk-cube sk-cube6"></div>
<div class="sk-cube sk-cube7"></div> <div class="sk-cube sk-cube7"></div>
<div class="sk-cube sk-cube8"></div> <div class="sk-cube sk-cube8"></div>
<div class="sk-cube sk-cube9"></div> <div class="sk-cube sk-cube9"></div>
</div> </div>
</div> </div>
</div> </div>
+52
View File
@@ -40,3 +40,55 @@ export function formatBytes(bytes, decimals = 2) {
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
} }
export function CountDownTimer(duration, granularity) {
this.duration = duration;
this.granularity = granularity || 1000;
this.tickFtns = [];
this.running = false;
}
CountDownTimer.prototype.start = function () {
if (this.running) {
return;
}
this.running = true;
var start = Date.now(),
that = this,
diff,
obj;
(function timer() {
diff = that.duration - (((Date.now() - start) / 1000) | 0);
if (diff > 0) {
setTimeout(timer, that.granularity);
} else {
diff = 0;
that.running = false;
}
obj = CountDownTimer.parse(diff);
that.tickFtns.forEach(function (ftn) {
ftn.call(this, obj.minutes, obj.seconds);
}, that);
})();
};
CountDownTimer.prototype.onTick = function (ftn) {
if (typeof ftn === 'function') {
this.tickFtns.push(ftn);
}
return this;
};
CountDownTimer.prototype.expired = function () {
return !this.running;
};
CountDownTimer.parse = function (seconds) {
return {
'minutes': (seconds / 60) | 0,
seconds: seconds % 60 | 0,
};
};
+49 -2
View File
@@ -16,6 +16,7 @@ window.number_of_questions = null;
window.question_type = null; window.question_type = null;
window.loaded_question = null; window.loaded_question = null;
window.review = false; window.review = false;
window.exam_time = 60;
window.allow_self_marking = true; window.allow_self_marking = true;
@@ -83,13 +84,14 @@ function loadPacketFromAjax(path) {
// setUpPacket(data); // setUpPacket(data);
// $("#options-panel").hide(); // $("#options-panel").hide();
// }) // })
$("#progress").html(`Requesting packet: ${path}`);
$.ajax({ $.ajax({
dataType: "json", dataType: "json",
url: path, url: path,
progress: function (e) { progress: function (e) {
if (e.lengthComputable) { if (e.lengthComputable) {
var completedPercentage = Math.round((e.loaded * 100) / e.total); var completedPercentage = Math.round((e.loaded * 100) / e.total);
console.log(completedPercentage);
$("#progress").html( $("#progress").html(
`${completedPercentage}%<br/>${helper.formatBytes(e.total)}` `${completedPercentage}%<br/>${helper.formatBytes(e.total)}`
@@ -146,6 +148,19 @@ function setUpQuestions() {
loadQuestion(0, 1, true); loadQuestion(0, 1, true);
createQuestionListPanel(); createQuestionListPanel();
if (window.question_type == "rapid") {
window.exam_time = 35 * 60;
} else if (window.question_type == "anatomy"){
window.exam_time = 90 * 60;
} else if (window.question_type == "long"){
window.exam_time = 75 * 60;
}
$("#exam-time").text(window.exam_time / 60)
$("#start-dialog").modal();
} }
// Set up cornerstone (the dicom viewer) // Set up cornerstone (the dicom viewer)
@@ -1128,12 +1143,16 @@ $("#review-overlay-button").click(function (evt) {
} }
}); });
$("#finish-exam").click(function (evt) { $("#finish-exam, #time-up-review-button").click(function (evt) {
window.review = true; window.review = true;
reviewQuestions(); reviewQuestions();
$.modal.close(); $.modal.close();
}); });
$("#time-up-continue-button").click(function (evt) {
$.modal.close();
});
$("#finish-cancel").click(function (evt) { $("#finish-cancel").click(function (evt) {
$.modal.close(); $.modal.close();
}); });
@@ -1663,6 +1682,34 @@ $("#start-exam-button").click(function (evt) {
$.modal.close(); $.modal.close();
}); });
$("#start-packet-button").click(function (evt) {
//window.cid = parseInt($("#candidate-number").val());
// const t = 35 * 60;
//const t = 2;
let display = document.querySelector("#timer");
let timer = new helper.CountDownTimer(window.exam_time);
let timeObj = helper.CountDownTimer.parse(window.exam_time);
format(timeObj.minutes, timeObj.seconds);
timer.onTick(format);
timer.start();
function format(minutes, seconds) {
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = "Time left: " + minutes + ":" + seconds;
if (minutes == 0 && seconds == 0) {
$("#time-up-dialog").modal();
}
}
$.modal.close();
});
$("#btn-delete-databases").click(function (evt) { $("#btn-delete-databases").click(function (evt) {
var r = confirm("This will delete ALL saved answers!"); var r = confirm("This will delete ALL saved answers!");
if (r == true) { if (r == true) {