From f1085ce37b3bf8b082a7481b613032cb6a017041 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 4 Nov 2019 12:45:00 +0100 Subject: [PATCH] init --- .gitignore | 3 ++ Makefile | 11 ++++++ app.css.sass | 68 ++++++++++++++++++++++++++++++++ app.js.coffee | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ index.html.haml | 32 +++++++++++++++ 5 files changed, 215 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 app.css.sass create mode 100644 app.js.coffee create mode 100644 index.html.haml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2132c7e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.css +*.html +*.js diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..52c0b73 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +all: index.html app.js app.css +.PHONY: all + +index.html: index.html.haml + haml $^ $@ + +app.js: app.js.coffee + coffee -cs >$@ <$^ + +app.css: app.css.sass + sassc $^ $@ diff --git a/app.css.sass b/app.css.sass new file mode 100644 index 0000000..05320d9 --- /dev/null +++ b/app.css.sass @@ -0,0 +1,68 @@ +#clock + .duration + font-size: 2em + text-align: center + + .controls + button, a + display: inline-block + border: none + background: #fff + color: #000 + box-shadow: inset 0 0 0.7ex white, 0 0 0.7ex white + margin: 1ex + &:not(:first-child) + margin-left: 2ex + padding: 1ex + font-size: 2em + border-radius: 1ex + outline: none + &:hover, &:active + box-shadow: inset 0 0 0.7ex white, 0 0 1ex white + background: #ddd + color: #000 + &:hover, &:active, &:focus, & + outline: none + > * + display: none + &[data-state=loaded] > .if_loaded, + &[data-state=started] > .if_started, + &[data-state=stopped] > .if_stopped + display: initial + +#timelist + tr > td:first-child + text-align: right + width: 3em + input + background: black + border: none + color: white + box-shadow: inset 0 0 1px white, 0 0 1px white + &:hover, &:focus, &:active + box-shadow: inset 0 0 0.7ex white, 0 0 1ex white + &:hover, &:focus, &:active, & + outline: none + +main + margin: 0 auto + width: 20em + text-align: center + table + text-align: initial + min-height: 20em + +.duration + font-family: monospace + +html, body + border: none + margin: 0 + padding: 0 + background-color: #111 + color: #fff + +footer + font-size: 0.5em + color: #444 + text-align: right diff --git a/app.js.coffee b/app.js.coffee new file mode 100644 index 0000000..d85e3bf --- /dev/null +++ b/app.js.coffee @@ -0,0 +1,101 @@ + +window.duration_to_string = (dur) -> + pad = (x) -> + x = Math.floor x + if 10 > x + "0#{x}" + else + x + pad3 = (x) -> + x = Math.floor x + if 10 > x + "00#{x}" + else if 100 > x + "0#{x}" + else + x + "#{pad dur/3600000}:#{pad (dur/60000) % 60}:#{pad dur / 1000 % 60}.#{pad3 dur % 1000}" + +class Clock + constructor: (el) -> + @element = el + @controls = el.querySelector ':scope .controls' + @startbtn = el.querySelector ':scope .start' + @splitbtn = el.querySelector ':scope .split' + @stopbtn = el.querySelector ':scope .stop' + @clock = el.querySelector ':scope .duration' + @starttime = null + @clock_interval = null + + new_event = (name, opts) -> + ev = new Event name + ev[k] = v for k, v of opts + ev + + activate: -> + @startbtn.addEventListener 'click', (e) => + e.preventDefault() + @starttime = new Date + clearInterval @clock_interval if @clock_interval + @clock_interval = setInterval( (=> @update_clock()), 47) + @controls.setAttribute 'data-state', 'started' + @element.dispatchEvent new_event( 'clock_started', clock: @, duration: 0, starttime: @starttime) + false + @stopbtn.addEventListener 'click', (e) => + e.preventDefault() + dur = @duration + @starttime = null + clearInterval @clock_interval if @clock_interval + @controls.setAttribute 'data-state', 'stopped' + @element.dispatchEvent new_event( 'clock_stopped', clock: @, duration: @duration, starttime: @starttime) + false + @splitbtn.addEventListener 'click', (e) => + e.preventDefault() + @element.dispatchEvent new_event( 'clock_splitted', clock: @, duration: @duration, starttime: @starttime) + false + + Object.defineProperty @::, 'duration', + enumerable: true + get: -> + if @starttime? + new Date - @starttime + else + null + + update_clock: -> + @clock.textContent = duration_to_string @duration + +window.addEventListener 'load', -> + window.clock = new Clock document.querySelector( '#clock') + clock.activate() + + window.timelist = document.querySelector( '#timelist') + window.list = [] + counter = 0 + clock.element.addEventListener 'clock_splitted', (e) -> + counter++ + dur = duration_to_string e.duration + tr = document.createElement 'tr' + td = document.createElement 'td' + td.textContent = "#{++counter}" + tr.appendChild td + td = document.createElement 'td' + td.textContent = dur + tr.appendChild td + td = document.createElement 'td' + iu = document.createElement('input') + iu.setAttribute 'type', 'text' + td.appendChild iu + tr.appendChild td + window.timelist.appendChild tr + window.list.push [counter, dur, iu] + true + + download = clock.element.querySelector ':scope .export' + exporthelper = clock.element.querySelector ':scope .exporthelper' + download.addEventListener 'click', (e) -> + t = '' + for en in window.list + t += "#{en[0]}\t#{en[1]}\t#{en[2].value}\n" + exporthelper.href = "data:text/csv;name=schplitted.csv,#{encodeURIComponent t}" + exporthelper.click() diff --git a/index.html.haml b/index.html.haml new file mode 100644 index 0000000..ede1803 --- /dev/null +++ b/index.html.haml @@ -0,0 +1,32 @@ +!!! % +%html + %head + %meta(charset="utf-8") + %meta(http-equiv="X-UA-Compatible" content="IE=edge") + %meta(name="viewport" content="width=device-width, initial-scale=1") + %title Zeitschplitter + %link(rel="stylesheet" href="app.css") + %script(type="text/javascript" src="app.js") + + %body + %header + %h1 Zeitschplitter + %main + #clock + .duration 00:00:00.0 + .controls(data-state="loaded") + .if_loaded + %button.start ▶ + .if_started + %button.stop ■ + %button.split ✁ + .if_stopped + %button.export ⤓ + .never + %a.exporthelper(download="schplitter.csv") + #TimeList + %table + %thead + %tbody#timelist + %footer + Denis Knauf - Zeitschplitter - Stoppuhr für n Teilnehmer