diff --git a/css/main.css b/css/main.css index bb64b41..051cd02 100644 --- a/css/main.css +++ b/css/main.css @@ -1012,4 +1012,38 @@ display: block .packet-list-title { text-transform: capitalize; font-weight: bolder; +} + + +.lds-ripple { + display: inline-block; + position: relative; + width: 80px; + height: 80px; +} +.lds-ripple div { + position: absolute; + border: 4px solid #4527A0; + opacity: 1; + border-radius: 50%; + animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite; +} +.lds-ripple div:nth-child(2) { + animation-delay: -0.5s; +} +@keyframes lds-ripple { + 0% { + top: 36px; + left: 36px; + width: 0; + height: 0; + opacity: 1; + } + 100% { + top: 0px; + left: 0px; + width: 72px; + height: 72px; + opacity: 0; + } } \ No newline at end of file diff --git a/index.html b/index.html index db20556..cdfb0e7 100644 --- a/index.html +++ b/index.html @@ -163,6 +163,11 @@ +
diff --git a/js/interact.js b/js/interact.js index 0f6fb86..ae74430 100644 --- a/js/interact.js +++ b/js/interact.js @@ -128,6 +128,7 @@ export function getQuestion(url, question_number, question_total) { ); } }, + error: (jqXHR, textStatus, errorThrown) => { console.log("error downlading", jqXHR, textStatus, errorThrown) }, //success: function (data) { // strReturn = data; //}, diff --git a/js/main.js b/js/main.js index 1af5c6c..dcb80ad 100644 --- a/js/main.js +++ b/js/main.js @@ -23,7 +23,8 @@ window.packet_list = []; window.exams = []; window.packet_name = null; -window.questions = null; +//window.questions = null; +let questions = null; window.question_order = []; window.questions_correct = {}; window.number_of_questions = null; @@ -36,7 +37,7 @@ window.score = 0; window.allow_self_marking = true; -window.timer = null; +let timer = null; //window.dfile = null; @@ -54,7 +55,7 @@ retrievePacketList(); function retrievePacketList() { let url = "packets/"; - console.log(window.config.exam_query_url); + //console.log(window.config.exam_query_url); if (window.config.exam_query_url != undefined) { url = window.config.exam_query_url; @@ -81,9 +82,9 @@ function retrievePacketList() { loadPacketList(data); } }).fail(function (jqXHR, textStatus, errorThrown) { - console.log(jqXHR); - console.log(textStatus); - console.log(errorThrown); + //console.log(jqXHR); + //console.log(textStatus); + //console.log(errorThrown); console.log("No packet list available"); showLoginDialog(); }); @@ -98,7 +99,7 @@ function retrievePacketList() { * @param {JSON} data - json containing available exams */ async function loadExamList(data) { - let sessions = await window.db.session.toArray().catch(function (error) { + let sessions = await db.session.toArray().catch(function (error) { console.log("Error loading session", error); $("#database-error").text( "Error loading the database, schema has probably changed and needs updating. You will probably need to delete the local database." @@ -179,7 +180,7 @@ async function loadExamList(data) { * @param {JSON} data - json containing available packets */ async function loadPacketList(data) { - let sessions = await window.db.session.toArray().catch(function (error) { + let sessions = await db.session.toArray().catch(function (error) { console.log("Error loading session", error); $("#database-error").text( "Error loading the database, schema has probably changed and needs updating. You will probably need to delete the local database." @@ -244,7 +245,7 @@ async function loadPacketList(data) { $( `` ).click(function (evt) { - console.log("packets/" + packet); + //console.log("packets/" + packet); evt.stopPropagation(); }) ) @@ -258,7 +259,7 @@ async function loadPacketList(data) { * @param {string} path - relative path to the packet json file */ function loadPacketFromAjax(path) { - console.log("loading packet from " + path); + //console.log("loading packet from " + path); $("#progress").html(`Requesting packet: ${path}`); $.ajax({ @@ -278,13 +279,13 @@ function loadPacketFromAjax(path) { .done(function (data) { //setUpPacket(data, path.split("/").pop()); if (data.hasOwnProperty("cached") && data["cached"]) { - console.log("loading cached packet"); + //console.log("loading cached packet"); } setUpPacket(data, path); $("#options-panel").hide(); }) .fail(function () { - console.log("Unable to load packet at: " + path); + //console.log("Unable to load packet at: " + path); }); } @@ -292,19 +293,31 @@ function loadPacketFromAjax(path) { * Build the currently loaded quiz */ function setUpQuestions(load_previous) { - if (window.questions == undefined) { + if (questions == undefined) { return; } + + Object.keys(questions).forEach(function (e) { + // Store question data into dexie + let d = { + eid: window.exam_details.eid, + qid: e, + data: questions[e], + }; + + question_db.question_data.put(d); + }); + // Set an order for the questions if (!load_previous) { if (window.question_order.length < 1) { window.question_order = []; - Object.keys(window.questions).forEach(function (e) { + Object.keys(questions).forEach(function (e) { window.question_order.push(e); // Make sure answers are arrays - if (!Array.isArray(window.questions[e]["answers"])) { - window.questions[e]["answers"] = [window.questions[e]["answers"]]; + if (!Array.isArray(questions[e]["answers"])) { + questions[e]["answers"] = [questions[e]["answers"]]; } }); } @@ -317,13 +330,13 @@ function setUpQuestions(load_previous) { window.question_order = helper.shuffleArray(window.question_order); } } - window.number_of_questions = Object.keys(window.questions).length; + window.number_of_questions = Object.keys(questions).length; window.review = false; // Horrible way to get type of questions // We assume they are all of the same type.... window.question_type = - window.questions[Object.keys(window.questions)[0]].type; + questions[Object.keys(questions)[0]].type; if (window.exam_details.exam_mode) { $("#options-button, #review-overlay-button").hide(); @@ -331,10 +344,10 @@ function setUpQuestions(load_previous) { $("#submit-button").hide(); } - loadQuestion(0, 1, true); - createQuestionListPanel(); + questions = null; - console.log(window.question_type); + + //console.log(window.question_type); // exam_time can be defined in packets if (!load_previous && window.exam_time == null) { @@ -374,8 +387,13 @@ function setUpQuestions(load_previous) { } else { $("#start-dialog").modal(); } + + loadQuestion(0, 1, true); + createQuestionListPanel(); } +cornerstone.imageCache.setMaximumSizeBytes(5128800); + // Set up cornerstone (the dicom viewer) cornerstoneBase64ImageLoader.external.cornerstone = cornerstone; cornerstoneWebImageLoader.external.cornerstone = cornerstone; @@ -388,8 +406,6 @@ cornerstoneWebImageLoader.external.cornerstone = cornerstone; cornerstoneWADOImageLoader.external.cornerstone = cornerstone; -cornerstone.imageCache.setMaximumSizeBytes(22428800); - // cornerstoneWADOImageLoader.configure({ // beforeSend: function(xhr) { // // Add custom headers here (e.g. auth tokens) @@ -409,7 +425,12 @@ db.version(1).stores({ "[packet+aid], packet, aid, status, date, score, max_score, exam_time, time_left, question_order, questions_answered, total_questions", }); -window.db = db; +const question_db = new Dexie("question_database"); +question_db.version(1).stores({ + question_data: "[eid+qid], eid, data", +}); + +//db = db; /** * Parse the packet and extract metadata (if it exists) @@ -438,9 +459,9 @@ function setUpPacket(data, path) { } if (data.hasOwnProperty("questions")) { - window.questions = data.questions; + questions = data.questions; } else { - window.questions = data; + questions = data; } if (data.hasOwnProperty("exam_order")) { @@ -465,13 +486,13 @@ function setUpPacket(data, path) { const question_url = `${path}/${n}`; question_number++; - console.log("Creating ", question_url, question_number, question_total); + //console.log("Creating ", question_url, question_number, question_total); //$("#progress").html(`Downloading [${question_number}/${question_total}]`); let question_json = {}; question_json = await interact .getQuestion(question_url, question_number, question_total) .fail((jqXHR, textStatus, errorThrown) => { - console.log(jqXHR, textStatus, errorThrown); + //console.log(jqXHR, textStatus, errorThrown); console.log("error loading question"); data["questions"][n] = {}; }); @@ -500,9 +521,9 @@ function setUpPacket(data, path) { } function loadSession() { - console.log("load session"); + //console.log("load session"); // Either continue session or create a new one - window.db.session + db.session // .where("status") // .equals("active") .where("[packet+aid]") @@ -512,7 +533,7 @@ function loadSession() { ) .toArray() .then((sessions) => { - console.log("sessions", sessions); + //console.log("sessions", sessions); // let active_sessions = []; @@ -533,7 +554,7 @@ function loadSession() { if (window.exam_details.exam_mode) { text = "Session will be continued"; } - console.log(sessions.date); + //console.log(sessions.date); for (let i = 0; i < sessions.length; i++) { let d = new Date(sessions[i].date); @@ -588,7 +609,7 @@ function loadSession() { // If cancel is pressed or input is blank window.exam_details.aid = uuidv4(); window.date_started = Date.now(); - console.log("new date", window.date_started); + //console.log("new date", window.date_started); } } @@ -602,18 +623,27 @@ function loadSession() { * @param {number} section - Question section to focus * @param {boolean} force_reload - Force question to be reloaded if already loaded */ -function loadQuestion(n, section = 1, force_reload = false) { +async function loadQuestion(n, section = 1, force_reload = false) { + + $("#question-loading").show(); const aid = window.exam_details.aid; const cid = window.exam_details.cid; const eid = window.exam_details.eid; + // Make sure we have an integer n = parseInt(n); - console.log("loading question (n)", n); + //console.log("loading question (n)", n); const qid = window.question_order[n]; - console.log("qid", qid); - const current_question = window.questions[qid]; + + let q = {qid: qid.toString(), eid: eid}; + + let return_data = await question_db.question_data.get(q); + const question_data = return_data.data; + return_data = null; + + //const current_question = window.questions[qid]; if (n == window.loaded_question && force_reload == false) { // Question already loaded @@ -648,32 +678,33 @@ function loadQuestion(n, section = 1, force_reload = false) { const display_n = n + 1; - if (current_question.title) { + if (question_data.title) { $(".question .title").get(0).innerHTML = '' + display_n + " " + - current_question.title; + question_data.title; } else { $(".question .title").get(0).innerHTML = '' + display_n + ""; } // Close any open figures - let el = document.getElementById("dicom-image"); - if (el != undefined) { - cornerstone.disable(el); - $(".canvas-panel").remove(); - } + //let el = document.getElementById("dicom-image"); + //if (el != undefined) { + // cornerstone.disable(el); + //} // disable any further enabled elements let enabled_elements = cornerstone.getEnabledElements(); for (var i = enabled_elements.length - 1; i >= 0; i--) { - console.log("disable, ", enabled_elements[i]); + //console.log("disable, ", enabled_elements[i]); cornerstone.disable(enabled_elements[i].element); } + $(".canvas-panel").remove(); cornerstone.imageCache.purgeCache(); + cornerstoneWADOImageLoader.default.wadouri.dataSetCacheManager.purge(); // Remove feedback images $(".feedback-image").remove(); @@ -681,86 +712,94 @@ function loadQuestion(n, section = 1, force_reload = false) { // Set up thumbnails const thumbnails = $(".thumbs"); // Why are we checking this? - if (thumbnails) { - thumbnails.empty(); + thumbnails.empty(); - // TODO: figure captions (need to extend base json) + // TODO: figure captions (need to extend base json) + function createThumbnail(image, id, caption, thumbnails) { + //console.log("create thumb", image); + // For thumbnails we only want a single image - current_question.images.forEach(function createThumbnail(image, id) { - //console.log("create thumb", image); - // For thumbnails we only want a single image - if (Array.isArray(image)) { - image = image[0]; // Do we want the middle image? - } + thumbnails.append( + `' +
@@ -793,7 +832,7 @@ function loadQuestion(n, section = 1, force_reload = false) {
ans: evt.target.value,
};
- window.db.answers.put(answer);
+ db.answers.put(answer);
saveSession();
updateQuestionListPanel(answer);
});
@@ -802,7 +841,7 @@ function loadQuestion(n, section = 1, force_reload = false) {
$(".long-answer").change(function (evt) {
// ignore blank text and delete any stored value
if (evt.target.value.length < 1) {
- window.db.answers.delete([aid, cid, eid, qid, "2"]);
+ db.answers.delete([aid, cid, eid, qid, "2"]);
$(
"#question-list-item-" + window.question_order.indexOf(qid) + "-2"
).removeClass("question-saved-localdb");
@@ -818,7 +857,7 @@ function loadQuestion(n, section = 1, force_reload = false) {
ans: evt.target.value,
};
// db.answers.put({aid: [cid, eid, qidn], ans: evt.target.value});
- window.db.answers.put(answer);
+ db.answers.put(answer);
$(
"#question-list-item-" + window.question_order.indexOf(qid) + "-2"
@@ -831,7 +870,7 @@ function loadQuestion(n, section = 1, force_reload = false) {
// We chain our db requests as we can only check answers once
// they have been loaded (should probably use then or after)
- window.db.answers
+ db.answers
.get({ aid: aid, cid: cid, eid: eid, qid: qid, qidn: "1" })
.then(function (answer) {
if (answer != undefined) {
@@ -851,14 +890,13 @@ function loadQuestion(n, section = 1, force_reload = false) {
console.log("error-", error);
})
.then(
- window.db.answers
+ db.answers
.get({ aid: aid, cid: cid, eid: eid, qid: qid, qidn: "2" })
.then(function (answer) {
if (answer != undefined) {
- console.log(answer);
$(".long-answer").text(answer.ans);
}
- markAnswer(qid, current_question);
+ markAnswer(qid, question_data);
})
.catch(function (error) {
console.log("error-", error);
@@ -876,7 +914,7 @@ function loadQuestion(n, section = 1, force_reload = false) {
' ' +
display_n +
'.1' +
- current_question.question +
+ question_data.question +
'