diff --git a/assets/articles.js b/assets/articles.js index eab4902..8c00e92 100644 --- a/assets/articles.js +++ b/assets/articles.js @@ -1,80 +1,7 @@ if (localStorage.getItem("auth") == null) { localStorage.setItem("auth", "true"); } -var articleList = []; -var groups = [{ - 'name': 'Group 1', - 'id': 'group-1', - 'password': 'test1', - 'articles': [{ - 'title': 'Cold Nose Article', - 'filename': 'cold_nose_article' - }, - { - 'title': 'Exoplanet Article', - 'filename': 'exoplanet_article' - }, - { - 'title': 'Osmosis Article', - 'filename': 'osmosis_article' - } - ] - }, - { - 'name': 'Group 2', - 'id': 'group-2', - 'password': 'test2', - 'articles': [{ - 'title': 'Frogs Evaluation Article', - 'filename': 'frogs_evolution_article' - }, - { - 'title': 'Soils & Nutrient Cycle', - 'filename': 'table_readings_1' - }, - { - 'title': 'Earthworms Article', - 'filename': 'table_readings_2' - } - ] - }, { - 'name': 'Group 3', - 'id': 'group-3', - 'password': 'test3', - 'articles': [{ - 'title': 'Consume vs Consumed', - 'filename': 'table_readings_3' - }, - { - 'title': 'An Alive Bug?', - 'filename': 'table_readings_4' - }, - { - 'title': 'Nitrogen Cycle', - 'filename': 'table_readings_5' - } - ] - }, { - 'name': 'Group 4', - 'id': 'group-4', - 'password': 'test4', - 'articles': [{ - 'title': 'Carbon Cycle', - 'filename': 'table_readings_6' - }, - { - 'title': 'Recycling the Dead', - 'filename': 'table_readings_7' - }, - { - 'title': 'Gut Bacteria', - 'filename': 'table_readings_8' - } - ] - } -]; - -var articles = [{ +var articleLibrary = [{ 'title': 'Doctor with an eye for eyes', 'filename': 'doctor-with-an-eye-for-eyes' }, @@ -113,59 +40,112 @@ var articles = [{ { 'title': 'The Camping Trip', 'filename': 'the-camping-trip' + }, + { + 'title': 'Cold Nose Article', + 'filename': 'cold_nose_article', + 'from': new Date('2024-12-20T10:00:00'), + 'to': new Date('2024-12-20T16:30:00') + }, + { + 'title': 'Exoplanet Article', + 'filename': 'exoplanet_article', + 'from': new Date('2024-12-20T16:31:00'), + 'to': new Date('2024-12-21T16:30:00') + }, + { + 'title': 'Osmosis Article', + 'filename': 'osmosis_article', + 'from': new Date('2024-12-22T16:31:00'), + 'to': new Date('2024-12-23T16:30:00') + }, + { + 'title': 'Frogs Evaluation Article', + 'filename': 'frogs_evolution_article' + }, + { + 'title': 'Soils & Nutrient Cycle', + 'filename': 'table_readings_1' + }, + { + 'title': 'Earthworms Article', + 'filename': 'table_readings_2' + }, + { + 'title': 'Consume vs Consumed', + 'filename': 'table_readings_3' + }, + { + 'title': 'An Alive Bug?', + 'filename': 'table_readings_4' + }, + { + 'title': 'Nitrogen Cycle', + 'filename': 'table_readings_5' + }, + { + 'title': 'Carbon Cycle', + 'filename': 'table_readings_6' + }, + { + 'title': 'Recycling the Dead', + 'filename': 'table_readings_7' + }, + { + 'title': 'Gut Bacteria', + 'filename': 'table_readings_8' } ]; - -// var articles = [{ -// 'title': 'Cold Nose Article', -// 'filename': 'cold_nose_article' -// }, -// { -// 'title': 'Exoplanet Article', -// 'filename': 'exoplanet_article' -// }, -// { -// 'title': 'Osmosis Article', -// 'filename': 'osmosis_article' -// }, -// { -// 'title': 'Frogs Evaluation Article', -// 'filename': 'frogs_evolution_article' -// }, -// { -// 'title': 'Soils & Nutrient Cycle', -// 'filename': 'table_readings_1' -// }, -// { -// 'title': 'Earthworms Article', -// 'filename': 'table_readings_2' -// }, -// { -// 'title': 'Consume vs Consumed', -// 'filename': 'table_readings_3' -// }, -// { -// 'title': 'An Alive Bug?', -// 'filename': 'table_readings_4' -// }, -// { -// 'title': 'Nitrogen Cycle', -// 'filename': 'table_readings_5' -// }, -// { -// 'title': 'Carbon Cycle', -// 'filename': 'table_readings_6' -// }, -// { -// 'title': 'Recycling the Dead', -// 'filename': 'table_readings_7' -// }, -// { -// 'title': 'Gut Bacteria', -// 'filename': 'table_readings_8' -// } -// ]; - +var articleList = []; +var groups = [{ + 'name': 'Group 1', + 'id': 'group-1', + 'password': 'test1', + 'articles': [articleLibrary[10], articleLibrary[11], articleLibrary[12]] + }, + { + 'name': 'Group 2', + 'id': 'group-2', + 'password': 'test2', + 'articles': [articleLibrary[13], articleLibrary[14], articleLibrary[15]] + }, { + 'name': 'Group 3', + 'id': 'group-3', + 'password': 'test3', + 'articles': [articleLibrary[16], articleLibrary[17], articleLibrary[18]] + }, { + 'name': 'Group 4', + 'id': 'group-4', + 'password': 'test4', + 'articles': [articleLibrary[19], articleLibrary[20], articleLibrary[21]] + } +]; +var articles = [ + articleLibrary[0], + articleLibrary[1], + articleLibrary[2], + articleLibrary[3], + articleLibrary[4], + articleLibrary[5], + articleLibrary[6], + articleLibrary[7], + articleLibrary[8], + articleLibrary[9] +]; +var articlesPrev = [ + articleLibrary[10], + articleLibrary[11], + articleLibrary[12], + articleLibrary[13], + articleLibrary[14], + articleLibrary[15], + articleLibrary[16], + articleLibrary[17], + articleLibrary[18], + articleLibrary[19], + articleLibrary[20], + articleLibrary[21] +]; if (localStorage.getItem("auth") == "guest") { articleList = articles; } else { @@ -175,7 +155,6 @@ if (localStorage.getItem("auth") == "guest") { } }); } - if (localStorage.getItem("currentArticle") === null) { localStorage.setItem("currentArticle", articleList[0].filename); localStorage.setItem("currentArticleTitle", articleList[0].title); diff --git a/assets/main-working.js b/assets/main-working.js index 4dbad3e..e286e0d 100644 --- a/assets/main-working.js +++ b/assets/main-working.js @@ -1231,6 +1231,7 @@ ); }); $(".teacher-facing #article-menu p span").text(localStorage.getItem("currentArticleTitle")); + $(".student-robot-facing #article-menu p span").text(localStorage.getItem("currentArticleTitle")); $("#assignment-title").text(localStorage.getItem("currentArticleTitle")); window.pathArticleTitle = localStorage.getItem("currentArticleTitle"); $.each(emotionsList, function(i, v) { diff --git a/assets/session-recording.js b/assets/session-recording.js new file mode 100644 index 0000000..d1e5b99 --- /dev/null +++ b/assets/session-recording.js @@ -0,0 +1,123 @@ +var audioRecorders = new Map(); // Map to store recorder objects with IDs +var audioChunks = new Map(); // Map to store chunks for each ID +const today = new Date(); +var sessionRecordingData = { + 'title': formatAudioFileName(localStorage.getItem("currentArticleTitle")) + // will add the student usernames, password, related articles and deadlines here + // for now reusing the teacher side login info for the demo purposes +}; +sessionInit(); +$(document).on("click", "#start-assignment", function() { + startRecording(sessionRecordingData.title); +}); + +function sessionInit() { + $.each(articleList, function(i, v) { + $("#assignment-list").append( + "= v.from && today <= v.to) ? + ' class="active"' : + "") + + ' data-article="' + + v.filename + + '">' + + v.title + '. Due: ' + formatDate(v.to) + '' + + "" + ); + }); +} + +function formatDate(date) { + return date.toLocaleString('en-US', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: true, // 12-hour clock + }); +} + +function formatAudioFileName(articleTitle) { + // Convert the string to lowercase and replace spaces or word breaks with dashes + // This is for audio file naming convention + const formatted = articleTitle + .toLowerCase() // Convert to lowercase + .replace(/\s+/g, '-') // Replace spaces or word breaks with dashes + .replace(/[^\w\-]/g, ''); // Optionally remove any non-alphanumeric characters (except dashes) + + return formatted; +} + +function startRecording(id) { + if (!id) { + console.error("Error: Please provide a unique ID to start the recording."); + return; + } + + // Check if a recording with the same ID already exists + if (audioRecorders.has(id)) { + console.warn(`Warning: Recording with ID ${id} already exists. Stopping and saving it before starting a new one.`); + stopRecording(id); // Stop and save the existing recording + } + + navigator.mediaDevices.getUserMedia({ audio: true }) + .then(stream => { + const mediaRecorder = new MediaRecorder(stream); + const chunks = []; + + mediaRecorder.ondataavailable = (e) => { + chunks.push(e.data); + }; + + mediaRecorder.onstop = () => { + const blob = new Blob(chunks, { type: 'audio/webm' }); + audioChunks.set(id, blob); // Save blob to map for later use + saveRecording(blob, id); // Save the recording as a file + audioRecorders.delete(id); // Clean up map entry + audioChunks.delete(id); + console.log(`Recording ${id} saved and removed from active recorders`); + }; + + mediaRecorder.start(); + audioRecorders.set(id, mediaRecorder); // Add to map + console.log(`Recording ${id} started`); + }) + .catch(err => console.error('Error accessing microphone:', err)); +} + +function stopRecording(id) { + if (audioRecorders.has(id)) { + const recorder = audioRecorders.get(id); + recorder.stop(); + console.log(`Recording ${id} stopped`); + } else { + console.error(`No active recording found with ID ${id}`); + } +} + +function saveRecording(blob, id) { + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.style.display = 'none'; + a.href = url; + a.download = `${id}.webm`; // Filename includes recording ID + document.body.appendChild(a); + a.click(); + URL.revokeObjectURL(url); +} + +window.addEventListener('beforeunload', (event) => { + audioRecorders.forEach((recorder, id) => { + if (recorder.state === 'recording') { + recorder.stop(); + console.log(`Recording ${id} stopped on unload`); + } + }); + + // Prevent the immediate closing of the tab + event.preventDefault(); + event.returnValue = ''; +}); \ No newline at end of file diff --git a/assets/styles-working.css b/assets/styles-working.css index 744dadf..fc64d43 100644 --- a/assets/styles-working.css +++ b/assets/styles-working.css @@ -77,7 +77,8 @@ li { clear: both; } -#splash { +#splash, +#student-splash { font-size: 20px; line-height: 40px; width: 100vw; @@ -86,23 +87,46 @@ li { position: fixed; top: 0; left: 0; - z-index: 9; padding-top: 100px; text-align: center; } -#splash .brand { - font-size: 60px; +#splash { + z-index: 99; +} + +#student-splash { + z-index: 98; +} + +#splash .brand, +#student-splash .brand { line-height: 72px; margin-bottom: 50px; } -#splash>div { - width: 300px; +#splash .brand { + font-size: 60px; +} + +#student-splash .brand { + font-size: 50px; +} + +#splash>div, +#student-splash>div { margin: 0 auto; position: relative; } +#splash>div { + width: 300px; +} + +#student-splash>div { + width: 700px; +} + #splash>div p { background-color: white; } @@ -117,19 +141,67 @@ li { text-align: center; } +#student-splash ul { + text-align: left; + margin-bottom: 50px; + color: rgba(255, 255, 255, 0.5); +} + +#student-splash ul li { + padding-left: 25px; +} + +#student-splash ul li.active { + font-weight: bold; + color: white; +} + +#student-splash ul li:not(last-child) { + margin-bottom: 30px; + position: relative; +} + +#student-splash ul li::before { + content: "o"; + font-weight: bold; + position: absolute; + left: 0; + top: -1px; +} + +#student-splash ul li::after { + content: ""; + position: absolute; + left: 5px; + top: 30px; + width: 4px; + height: 50px; + border-left: dotted rgba(255, 255, 255, 0.5) 4px; +} + +#student-splash ul li.active::after { + border-color: white !important; +} + +#student-splash ul li:last-child::after { + display: none !important; +} + #splash input, -#splash button { +#splash button, +#student-splash button { display: block; - width: 100%; + width: 300px; height: 40px; - margin-top: 15px; + margin: 15px auto 0; text-align: center; font-size: 20px; line-height: 40px; color: #457ab1; } -#splash button { +#splash button, +#student-splash button { text-transform: uppercase; cursor: pointer; } diff --git a/student-robot.htm b/student-robot.htm index 058ece2..01a940f 100644 --- a/student-robot.htm +++ b/student-robot.htm @@ -48,6 +48,13 @@ +
+
Assignments
+
+
    + +
    +