diff --git a/resources/public/index.html b/resources/public/index.html
index a4cafe9..446375c 100644
--- a/resources/public/index.html
+++ b/resources/public/index.html
@@ -16,6 +16,7 @@ src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"
Muharni table
Long forms
diff --git a/resources/public/scripts/muharni.js b/resources/public/scripts/muharni.js
index d83502e..be6c5b4 100644
--- a/resources/public/scripts/muharni.js
+++ b/resources/public/scripts/muharni.js
@@ -16,13 +16,57 @@
*/
const studentSounds = Array(80).fill(0).map(x => Array(13).fill(null));
+/**
+ * Creates a progressbar. Adapted from
+ * https://stackoverflow.com/questions/31109581/javascript-timer-progress-bar
+ *
+ * @param id the id of the div we want to transform in a progressbar
+ * @param duration the duration of the timer example: '10s'
+ * @param callback, optional function which is called when the progressbar reaches 0.
+ */
+function createProgressbar(id, duration) {
+ // We select the div that we want to turn into a progressbar
+ try {
+ const progressbar = document.getElementById(id);
+ progressbar.className = 'progressbar';
+
+ // We create the div that changes width to show progress
+ let progressbarinner = progressbar.querySelector('.inner');
+
+ if (progressbarinner == null) {
+ progressbarinner = document.createElement('div');
+ progressbarinner.className = 'inner';
+
+ // Now we set the animation parameters
+ progressbarinner.style.animationDuration = duration;
+
+ // Append the progressbar to the main progressbardiv
+ progressbar.appendChild(progressbarinner);
+ }
+ progressbarinner.addEventListener('animationend', () => {
+ while (progressbar.hasChildNodes()) {
+ progressbar.removeChild(progressbar.lastChild);
+ }
+ });
+
+ // When everything is set up we start the animation
+ progressbarinner.style.animationPlayState = 'running';
+ } catch (e) {
+ console.warn("Failed to create progress bar because " +
+ e.message +
+ ". This does not, cosmically speaking, matter.");
+ }
+}
+
function recordStudentSound(r, c) {
console.info("Entered recordStudentSound for row " + r + ", column " + c);
if (Number.isInteger(r) && Number.isInteger(c)) {
- $('#record-student').css('color', 'green');
+ $('#record-stop').css('color', 'green');
try {
+ createProgressbar('progress', '5s');
+
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
const mediaRecorder = new MediaRecorder(stream);
@@ -42,18 +86,19 @@ function recordStudentSound(r, c) {
if (audioChunks.length > 0) {
studentSounds[r][c] = new Blob(audioChunks);
-
+
$('#play-student').prop('disabled', false);
+ $('#play-student').css('color', 'black');
$("#play-student").on("click", function (e) {
console.log("Playing student sound for row " + r + ", column " + c);
new Audio(URL.createObjectURL(studentSounds[r][c])).play();
- });
+ });
console.log("Successfully recorded student sound for row " + r + ", column " + c);
} else {
console.warn("Failed to record student sound for row " + r + ", column " + c);
window.alert("No sound detected. Check your microphone?");
}
- $('#record-student').css('color', 'red');
+ $('#record-stop').css('color', 'red');
};
setTimeout(() => {
@@ -115,7 +160,9 @@ $(document).ready(function () {
});
$("#play-student").off("click");
+ $('#play-student').css('color', 'gray');
if (studentAudio != null) {
+ $('#play-student').css('color', 'black');
$("#play-student").on("click", function (e) {
console.log("Playing student sound for row " + row + ", column " + col);
new Audio(URL.createObjectURL(studentAudio)).play();
diff --git a/resources/public/style.css b/resources/public/style.css
index 33c7a14..2d83e6a 100644
--- a/resources/public/style.css
+++ b/resources/public/style.css
@@ -29,11 +29,49 @@ th {
font-size: 3em;
}
+.progressbar {
+ width: 80%;
+ margin: 25px auto;
+ border: solid 1px #000;
+}
+
+.progressbar .inner {
+ height: 15px;
+ animation: progressbar-countdown;
+ /* Placeholder, this will be updated using javascript */
+ animation-duration: 40s;
+ /* We stop in the end */
+ animation-iteration-count: 1;
+ /* Stay on pause when the animation is finished finished */
+ animation-fill-mode: forwards;
+ /* We start paused, we start the animation using javascript */
+ animation-play-state: paused;
+ /* We want a linear animation, ease-out is standard */
+ animation-timing-function: linear;
+}
+
+@keyframes progressbar-countdown {
+ 0% {
+ width: 100%;
+ background: #0F0;
+ }
+
+ 100% {
+ width: 0%;
+ background: #F00;
+ }
+}
+
#bug {
width: 1em;
height: 1em;
}
+#closebox {
+ color: red;
+ float: right;
+}
+
#footer {
margin-top: 2em;
border-top: thin solid gray;
@@ -51,4 +89,8 @@ th {
display: none;
background-color: whitesmoke;
z-index: 10;
-}
\ No newline at end of file
+}
+
+#record-stop {
+ color: red;
+}
diff --git a/src/muharni/construct.clj b/src/muharni/construct.clj
index 59b7784..2b4f533 100644
--- a/src/muharni/construct.clj
+++ b/src/muharni/construct.clj
@@ -4,7 +4,7 @@
(:require [hiccup.core :refer [html]]
[clojure.java.io :refer [input-stream]]
[clojure.string :as s])
- (:import [java.io StringWriter PrintWriter]
+ (:import [java.io StringWriter]
[java.util Properties]
[org.w3c.tidy Tidy]))
@@ -192,16 +192,20 @@
[:body {:id "body"}
[:div {:id "popup"
:style "display: none; border: thin solid gray; width: 10%"}
+ [:div {:id "closebox"
+ :onclick "$('#popup').hide();"} "✖"]
[:p {:id "character" :style "text-align: center; margin: 0; font-size: 4em;"} "?"]
[:table {:id "controls" :summary "Controls for audio playback and recording"}
[:tr
[:th "Tutor"]
- [:td [:button {:id "play-tutor"}
+ [:td [:span {:id "play-tutor"}
"►"]]]
[:tr
[:th "You"]
- [:td [:button {:id "play-student"} "►"]]
- [:td [:button {:id "record-stop"} "⏺"]]]]]
+ [:td [:span {:id "play-student"} "►"]]
+ [:td [:span {:id "record-stop"} "⏺"]]]
+ [:tr
+ [:td {:colspan 3 :id "progress"}]]]]
[:h1 (str title)]
[:button {:onclick "var l = document.getElementById('long');
var s = document.getElementById('short');
@@ -211,7 +215,8 @@
} else {
l.style.display = 'none';
s.style.display = 'block';
- }"} "Toggle short/long"]
+ }
+ $('#popup').hide();"} "Toggle short/long"]
[:div {:id "long"
:style "display: block;"}
[:h2 "Long forms"]