aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2015-03-17 12:56:14 +0000
committerSean Whitton <spwhitton@spwhitton.name>2015-03-17 12:56:14 +0000
commit9e18ea7128a4a5160d7f6ed1a1f609b763e455f6 (patch)
treef314fe77b56fe13d6c084a3dc7d5888a49657808
parent94df9312f3461c4a6b53227bb1bab12965be3bd9 (diff)
downloadsariulclocks-9e18ea7128a4a5160d7f6ed1a1f609b763e455f6.tar.gz
the clocks have returned
-rw-r--r--assets/js/main.js267
-rw-r--r--src/sariulclocks.hs23
2 files changed, 284 insertions, 6 deletions
diff --git a/assets/js/main.js b/assets/js/main.js
index c090ec3..02b8ae0 100644
--- a/assets/js/main.js
+++ b/assets/js/main.js
@@ -1,3 +1,42 @@
+// sound setup
+
+$.ionSound({
+ sounds: [
+ {
+ name: "klaxon"
+ },
+ {
+ name: "button_tiny",
+ },
+ {
+ name: "cheonjae",
+ },
+ {
+ name: "onetwothree",
+ },
+ {
+ name: "too_noisy",
+ },
+ {
+ name: "sit_down_quickly",
+ },
+ {
+ name: "school_bell",
+ }
+ ],
+ // volume: 0.5,
+ path: "sounds/",
+ preload: true
+});
+
+// random integers
+
+// courtesy of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
+
+function getRandomInt(min, max) {
+ return Math.floor(Math.random() * (max - min)) + min;
+}
+
// famous functions from <http://www.quirksmode.org/js/cookies.html>
function createCookie(name,value,days) {
@@ -53,6 +92,42 @@ function startLesson()
location.reload(true);
}
+// end a class
+
+function endLesson()
+{
+ var oldCookie = readCookie("class_cookie");
+ // bail out if we've already started a class (the cookie will
+ // always be set cos our CGI monad always sets it)
+ if (oldCookie == "Nothing")
+ return false;
+
+ // get input
+ var points = prompt("How many points did they earn?", "0");
+
+ // validate
+ var valRegExp = new RegExp("^[0-9]*$");
+ if (valRegExp.test(points) == false)
+ {
+ alert ("invalid points!");
+ return false;
+ }
+
+ // TODO: submit time wasted and points (probs. via a form in a hidden div)
+
+ // set the cookie and reload to start the session
+ timeWastingClock.reset();
+ createCookie("class_cookie", "Nothing", 1);
+ location.reload(true);
+}
+
+// choose a student
+
+function luckyNumber()
+{
+ alert("not yet");
+}
+
// toggle the count-down and count-up clocks
function leftClockToggle()
@@ -65,12 +140,204 @@ function leftClockToggle()
location.reload(true);
}
+// function to make a FlipClock with a few additional features. Not
+// as neat a constructor as I would like because I don't fully
+// understand how jQuery works
+function MyFlipClock (jq, obj)
+{
+ var thisClock = new FlipClock(jq, obj);
+
+ thisClock.go = $.proxy(function (seconds) {
+ this.setTime(seconds);
+ this.start();
+ }, thisClock);
+ thisClock.reset = $.proxy(function () {
+ thisClock.stop();
+ thisClock.setTime(0);
+ }, thisClock);
+ thisClock.custom = $.proxy(function () {
+ var minutes = parseInt(prompt('Number of minutes', '0'));
+ var seconds = parseInt(prompt('Number of seconds', '0'));
+ thisClock.go(minutes * 60 + seconds);
+ }, thisClock);
+
+ return thisClock;
+}
+
+var timeWastingClock = MyFlipClock($('#time-wasting-clock'), {
+ autoStart:false,
+ callbacks:{
+ interval:function () {
+ $.ionSound.play("button_tiny");
+ var time = timeWastingClock.getTime().time;
+ $.jStorage.set("time_wasted", time);
+ }
+ }
+});
+timeWastingClock.setTime($.jStorage.get("time_wasted", 0));
+
+timeWastingClock.running = false;
+timeWastingClock.reset = $.proxy(function () {
+ if (this.getTime() != 1)
+ {
+ if (confirm('Are you sure?'))
+ {
+ if (this.running)
+ {
+ $('#timeWastingClockGo').html('Start <u>t</u>imer');
+ this.stop();
+ this.running = false;
+ }
+ $.jStorage.set('time_wasted', 0);
+ this.setTime(0);
+ }
+ }
+}, timeWastingClock);
+timeWastingClock.toggle = $.proxy(function () {
+ if (this.running)
+ {
+ $('#timeWastingClockGo').html('Start <u>t</u>imer');
+ this.stop();
+ this.running = false;
+ }
+ else
+ {
+ $('#timeWastingClockGo').html('Stop <u>t</u>imer');
+ this.start();
+ this.running = true;
+ }
+}, timeWastingClock);
+
+var activityClock = MyFlipClock($('#activity-countdown'), {
+ autoStart:false,
+ countdown:true,
+ callbacks:{
+ stop:function () {
+ $.ionSound.play("cheonjae");
+ }
+ }
+});
+
+var activityClockUp = MyFlipClock($('#activity-countup'), {
+ autoStart:false,
+ countdown:false
+});
+activityClockUp.toggle = $.proxy(function () {
+ if (this.running)
+ {
+ $('#activityClockUpGo').html('Start stopwatch (<u>a</u>)');
+ this.stop();
+ this.running = false;
+ }
+ else
+ {
+ $('#activityClockUpGo').html('Stop stopwatch (<u>a</u>)');
+ this.start();
+ this.running = true;
+ }
+}, activityClockUp);
+// activityClockUp.reset = $.proxy(function () {
+// if (this.getTime() != 1)
+// {
+// if (confirm('Are you sure?'))
+// {
+// if (this.running)
+// {
+// $('#activityClockUpGo').html('Start <u>t</u>imer');
+// this.stop();
+// this.running = false;
+// }
+// this.setTime(0);
+// }
+// }
+// }, activityClockUp);
+
+// bind to keys
+
+// only bind if the div exists (that is, a class is in session)
+if ($("#time-wasting-clock").length)
+{
+ $(document).bind('keydown', 't', timeWastingClock.toggle);
+ $(document).bind('keydown', 'j', timeWastingClock.toggle);
+ // $(document).bind('keydown', 'space', timeWastingClock.toggle);
+ $(document).bind('keydown', 'l', luckyNumber);
+}
+
+$(document).bind('keydown', 's', timeWastingClock.reset);
+$(document).bind('keydown', 'r', activityClock.reset);
+$(document).bind('keydown', 'c', activityClock.custom);
+
+$(document).bind('keydown', 'z', activityClockUp.reset);
+$(document).bind('keydown', 'a', activityClockUp.toggle);
+
+$(document).bind('keydown', '0', function (){activityClock.go(30);});
+$(document).bind('keydown', '1', function (){activityClock.go(60);});
+$(document).bind('keydown', '9', function (){activityClock.go(90);});
+$(document).bind('keydown', '2', function (){activityClock.go(120);});
+$(document).bind('keydown', '3', function (){activityClock.go(180);});
+$(document).bind('keydown', '4', function (){activityClock.go(240);});
+$(document).bind('keydown', '5', function (){activityClock.go(300);});
+$(document).bind('keydown', '6', function (){activityClock.go(360);});
+$(document).bind('keydown', '7', function (){activityClock.go(420);});
+$(document).bind('keydown', '8', function (){activityClock.go(480);});
+
+$(document).bind('keydown', 'k', function (){$.ionSound.play("klaxon");});
+$(document).bind('keydown', 'o', function (){$.ionSound.play("onetwothree");});
+$(document).bind('keydown', 'b', function (){$.ionSound.play("school_bell");});
+
// bind to buttons
$(document).ready(function(){
+
$('#start-lesson').button();
$('#start-lesson').click(function (){ startLesson(); });
+ $('#end-lesson').button();
+ $('#end-lesson').click(function (){ endLesson(); });
+
+ $('#lucky-number').button();
+ $('#lucky-number').click(function (){ luckyNumber(); });
+
$('#leftClockToggle').button();
$('#leftClockToggle').click(function (){ leftClockToggle(); });
+
+ $('#activityClockUpGo').button();
+ $('#activityClockUpGo').click(activityClockUp.toggle);
+
+ $('#activityClockUpReset').button();
+ $('#activityClockUpReset').click(activityClockUp.reset);
+
+ $('#timeWastingClockGo').button();
+ $('#timeWastingClockGo').click(timeWastingClock.toggle);
+
+ $('#timeWastingClockReset').button();
+ $('#timeWastingClockReset').click(timeWastingClock.reset);
+
+ $('#activityClockReset').button();
+ $('#activityClockReset').click(activityClock.reset);
+
+ $('#activityClockCustom').button();
+ $('#activityClockCustom').click(activityClock.custom);
+
+ $('#activityClock30s').button();
+ $('#activityClock30s').click(function (){activityClock.go(30);})
+
+ $('#activityClock60s').button();
+ $('#activityClock60s').click(function (){activityClock.go(60);})
+
+ $('#activityClock90s').button();
+ $('#activityClock90s').click(function (){activityClock.go(90);})
+
+ $('#activityClock120s').button();
+ $('#activityClock120s').click(function (){activityClock.go(120);})
+
+ $('#activityClock180s').button();
+ $('#activityClock180s').click(function (){activityClock.go(180);})
+
+ $('#activityClock240s').button();
+ $('#activityClock240s').click(function (){activityClock.go(240);})
+
+ $('#activityClock300s').button();
+ $('#activityClock300s').click(function (){activityClock.go(300);})
+
});
diff --git a/src/sariulclocks.hs b/src/sariulclocks.hs
index 8bdb4b4..78d2a8c 100644
--- a/src/sariulclocks.hs
+++ b/src/sariulclocks.hs
@@ -17,12 +17,14 @@ import Utils.Classes
import Text.XHtml.Bootstrap
navBar :: Page Html
-navBar = return $
+navBar = do
+ currentClass <- liftM (currentClass) getSession
+ return $
thediv # "navbar navbar-inverse navbar-fixed-top" ! [strAttr "role" "navigation"]
<< thediv # "container"
<< (primHtml "<div class=\"navbar-header\"> <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\"> <span class=\"sr-only\">Toggle navigation</span> <span class=\"icon-bar\"></span> <span class=\"icon-bar\"></span> <span class=\"icon-bar\"></span> </button> <a class=\"navbar-brand\" href=\"#\">Mr Whitton's timers</a> </div>"
+++ (thediv # "navbar-collapse collapse" << form # "navbar-form navbar-right" ! [strAttr "role" "form"]
- << ( bsButton "start-lesson" "btn btn-info" "Start lesson"
+ << ( lessonButtons currentClass
+++ bsButton "date-toggle" "btn btn-default" ("Toggle " +++ (underline << "d") +++ "ate style")
+++ soundsButton)))
where
@@ -37,12 +39,21 @@ navBar = return $
<< ((li << anchor ! [strAttr "href" "#"] << "Klaxon")
+++ (li << anchor ! [strAttr "href" "#"] << "Too noisy")))
+lessonButtons :: Maybe Class -> Html
+lessonButtons Nothing = bsButton "start-lesson" "btn btn-info" "Start lesson"
+lessonButtons (Just _) = bsButton "end-lesson" "btn btn-info" "End lesson"
+ +++ bsButton "lucky-number" "btn btn-danger" "Lucky number"
+
makeClockToggle :: Clock -> Html
makeClockToggle _ = bsButton "leftClockToggle" "btn btn-info" "Count up/down toggle"
makeLeftClockButtons :: Clock -> Html
-makeLeftClockButtons CountUpClock = stringToHtml "start, stop, reset?"
-makeLeftClockButtons CountDownClock = (paragraph # "text-center" << timeButtons)
+makeLeftClockButtons CountUpClock = paragraph # "text-center" << controlButtons
+ where
+ controlButtons = (+++) br $ foldr (+++) noHtml $
+ [ bsButton "activityClockUpGo" "btn btn-primary btn-lg btn-block" ("Start stopwatch (" +++ (underline << "a") +++ ")")
+ , bsButton "activityClockUpReset" "btn btn-default btn-lg btn-block" ("Reset stopwatch (" +++ (underline << "z") +++ ")")]
+makeLeftClockButtons CountDownClock = br +++ (paragraph # "text-center" << timeButtons)
+++ (paragraph # "text-center" << controlButtons)
+++ (paragraph # "text-center"
<< "Hotkeys: press the number key for the number of minutes you want to countdown.")
@@ -60,7 +71,7 @@ makeLeftClockButtons CountDownClock = (paragraph # "text-center" << timeButtons)
, bsButton "activityClockReset" "btn btn-default btn-lg" ((underline << "R") +++ "eset")]
makeRightClockButtons :: Html
-makeRightClockButtons = primHtml $ "<a id=\"timeWastingClockGo\" class=\"btn btn-primary btn-lg btn-block\">Start <u>t</u>imer</a> <a id=\"timeWastingClockReset\" class=\"btn btn-default btn-lg btn-block\">Re<u>s</u>et timer (end of class)</a>"
+makeRightClockButtons = primHtml $ "<a id=\"timeWastingClockGo\" class=\"btn btn-primary btn-lg btn-block\">Start <u>t</u>imer</a> <a id=\"timeWastingClockReset\" class=\"btn btn-default btn-lg btn-block\">Re<u>s</u>et timer </a>"
clocks :: Page Html
clocks = do
@@ -81,7 +92,7 @@ clocks = do
let rightClock = (<<) clockColumn $
case currentClass of
Just _ -> (h1 << "Time wasting clock") +++ br
- +++ (thediv ! [strAttr "class" "time-wasting-clock"] << noHtml) +++ br
+ +++ (thediv ! [strAttr "id" "time-wasting-clock"] << noHtml) +++ br
+++ makeRightClockButtons
Nothing -> noHtml
return $ thediv # "container"