diff --git a/www/worker_specs/dateformat.js b/www/worker_specs/dateformat.js new file mode 100644 index 0000000..466f649 --- /dev/null +++ b/www/worker_specs/dateformat.js @@ -0,0 +1,125 @@ +/* + * Date Format 1.2.3 + * (c) 2007-2009 Steven Levithan + * MIT license + * + * Includes enhancements by Scott Trenda + * and Kris Kowal + * + * Accepts a date, a mask, or a date and a mask. + * Returns a formatted version of the given date. + * The date defaults to the current date/time. + * The mask defaults to dateFormat.masks.default. + */ + +var dateFormat = function () { + var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g, + timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, + timezoneClip = /[^-+\dA-Z]/g, + pad = function (val, len) { + val = String(val); + len = len || 2; + while (val.length < len) val = "0" + val; + return val; + }; + + // Regexes and supporting functions are cached through closure + return function (date, mask, utc) { + var dF = dateFormat; + + // You can't provide utc if you skip other args (use the "UTC:" mask prefix) + if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) { + mask = date; + date = undefined; + } + + // Passing date through Date applies Date.parse, if necessary + date = date ? new Date(date) : new Date; + if (isNaN(date)) throw SyntaxError("invalid date"); + + mask = String(dF.masks[mask] || mask || dF.masks["default"]); + + // Allow setting the utc argument via the mask + if (mask.slice(0, 4) == "UTC:") { + mask = mask.slice(4); + utc = true; + } + + var _ = utc ? "getUTC" : "get", + d = date[_ + "Date"](), + D = date[_ + "Day"](), + m = date[_ + "Month"](), + y = date[_ + "FullYear"](), + H = date[_ + "Hours"](), + M = date[_ + "Minutes"](), + s = date[_ + "Seconds"](), + L = date[_ + "Milliseconds"](), + o = utc ? 0 : date.getTimezoneOffset(), + flags = { + d: d, + dd: pad(d), + ddd: dF.i18n.dayNames[D], + dddd: dF.i18n.dayNames[D + 7], + m: m + 1, + mm: pad(m + 1), + mmm: dF.i18n.monthNames[m], + mmmm: dF.i18n.monthNames[m + 12], + yy: String(y).slice(2), + yyyy: y, + h: H % 12 || 12, + hh: pad(H % 12 || 12), + H: H, + HH: pad(H), + M: M, + MM: pad(M), + s: s, + ss: pad(s), + l: pad(L, 3), + L: pad(L > 99 ? Math.round(L / 10) : L), + t: H < 12 ? "a" : "p", + tt: H < 12 ? "am" : "pm", + T: H < 12 ? "A" : "P", + TT: H < 12 ? "AM" : "PM", + Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""), + o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4), + S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10] + }; + + return mask.replace(token, function ($0) { + return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1); + }); + }; +}(); + +// Some common format strings +dateFormat.masks = { + "default": "ddd mmm dd yyyy HH:MM:ss", + shortDate: "m/d/yy", + mediumDate: "mmm d, yyyy", + longDate: "mmmm d, yyyy", + fullDate: "dddd, mmmm d, yyyy", + shortTime: "h:MM TT", + mediumTime: "h:MM:ss TT", + longTime: "h:MM:ss TT Z", + isoDate: "yyyy-mm-dd", + isoTime: "HH:MM:ss", + isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", + isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" +}; + +// Internationalization strings +dateFormat.i18n = { + dayNames: [ + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" + ], + monthNames: [ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" + ] +}; + +// For convenience... +Date.prototype.format = function (mask, utc) { + return dateFormat(this, mask, utc); +}; diff --git a/www/worker_specs/font/BebasNeue-Regular.eot b/www/worker_specs/font/BebasNeue-Regular.eot new file mode 100644 index 0000000..63df3a7 Binary files /dev/null and b/www/worker_specs/font/BebasNeue-Regular.eot differ diff --git a/www/worker_specs/font/BebasNeue-Regular.otf b/www/worker_specs/font/BebasNeue-Regular.otf new file mode 100644 index 0000000..4f5676c Binary files /dev/null and b/www/worker_specs/font/BebasNeue-Regular.otf differ diff --git a/www/worker_specs/font/BebasNeue-Regular.ttf b/www/worker_specs/font/BebasNeue-Regular.ttf new file mode 100644 index 0000000..76e22b8 Binary files /dev/null and b/www/worker_specs/font/BebasNeue-Regular.ttf differ diff --git a/www/worker_specs/font/BebasNeue-Regular.woff b/www/worker_specs/font/BebasNeue-Regular.woff new file mode 100644 index 0000000..457f916 Binary files /dev/null and b/www/worker_specs/font/BebasNeue-Regular.woff differ diff --git a/www/worker_specs/font/BebasNeue-Regular.woff2 b/www/worker_specs/font/BebasNeue-Regular.woff2 new file mode 100644 index 0000000..b4099a9 Binary files /dev/null and b/www/worker_specs/font/BebasNeue-Regular.woff2 differ diff --git a/www/worker_specs/font/DroidSansFallbackFull.ttf b/www/worker_specs/font/DroidSansFallbackFull.ttf new file mode 100644 index 0000000..89959f5 Binary files /dev/null and b/www/worker_specs/font/DroidSansFallbackFull.ttf differ diff --git a/www/worker_specs/font/FreeSans.ttf b/www/worker_specs/font/FreeSans.ttf new file mode 100644 index 0000000..7d1be71 Binary files /dev/null and b/www/worker_specs/font/FreeSans.ttf differ diff --git a/www/worker_specs/index.html b/www/worker_specs/index.html new file mode 100644 index 0000000..12b53ea --- /dev/null +++ b/www/worker_specs/index.html @@ -0,0 +1,55 @@ + + + + + + + + + + +
+ + + +
+ human worker id +   + ip address +   + location +   + browser +   + os +   + + task started at +   + task status +   + task fee +   + + + time elapsed +   +
+ + + + + + + +
+ + + + diff --git a/www/worker_specs/reconnecting-websocket.min.js b/www/worker_specs/reconnecting-websocket.min.js new file mode 100644 index 0000000..3015099 --- /dev/null +++ b/www/worker_specs/reconnecting-websocket.min.js @@ -0,0 +1 @@ +!function(a,b){"function"==typeof define&&define.amd?define([],b):"undefined"!=typeof module&&module.exports?module.exports=b():a.ReconnectingWebSocket=b()}(this,function(){function a(b,c,d){function l(a,b){var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,!1,!1,b),c}var e={debug:!1,automaticOpen:!0,reconnectInterval:1e3,maxReconnectInterval:3e4,reconnectDecay:1.5,timeoutInterval:2e3};d||(d={});for(var f in e)this[f]="undefined"!=typeof d[f]?d[f]:e[f];this.url=b,this.reconnectAttempts=0,this.readyState=WebSocket.CONNECTING,this.protocol=null;var h,g=this,i=!1,j=!1,k=document.createElement("div");k.addEventListener("open",function(a){g.onopen(a)}),k.addEventListener("close",function(a){g.onclose(a)}),k.addEventListener("connecting",function(a){g.onconnecting(a)}),k.addEventListener("message",function(a){g.onmessage(a)}),k.addEventListener("error",function(a){g.onerror(a)}),this.addEventListener=k.addEventListener.bind(k),this.removeEventListener=k.removeEventListener.bind(k),this.dispatchEvent=k.dispatchEvent.bind(k),this.open=function(b){h=new WebSocket(g.url,c||[]),b||k.dispatchEvent(l("connecting")),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","attempt-connect",g.url);var d=h,e=setTimeout(function(){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","connection-timeout",g.url),j=!0,d.close(),j=!1},g.timeoutInterval);h.onopen=function(){clearTimeout(e),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onopen",g.url),g.protocol=h.protocol,g.readyState=WebSocket.OPEN,g.reconnectAttempts=0;var d=l("open");d.isReconnect=b,b=!1,k.dispatchEvent(d)},h.onclose=function(c){if(clearTimeout(e),h=null,i)g.readyState=WebSocket.CLOSED,k.dispatchEvent(l("close"));else{g.readyState=WebSocket.CONNECTING;var d=l("connecting");d.code=c.code,d.reason=c.reason,d.wasClean=c.wasClean,k.dispatchEvent(d),b||j||((g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onclose",g.url),k.dispatchEvent(l("close")));var e=g.reconnectInterval*Math.pow(g.reconnectDecay,g.reconnectAttempts);setTimeout(function(){g.reconnectAttempts++,g.open(!0)},e>g.maxReconnectInterval?g.maxReconnectInterval:e)}},h.onmessage=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onmessage",g.url,b.data);var c=l("message");c.data=b.data,k.dispatchEvent(c)},h.onerror=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onerror",g.url,b),k.dispatchEvent(l("error"))}},1==this.automaticOpen&&this.open(!1),this.send=function(b){if(h)return(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","send",g.url,b),h.send(b);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(a,b){"undefined"==typeof a&&(a=1e3),i=!0,h&&h.close(a,b)},this.refresh=function(){h&&h.close()}}return a.prototype.onopen=function(){},a.prototype.onclose=function(){},a.prototype.onconnecting=function(){},a.prototype.onmessage=function(){},a.prototype.onerror=function(){},a.debugAll=!1,a.CONNECTING=WebSocket.CONNECTING,a.OPEN=WebSocket.OPEN,a.CLOSING=WebSocket.CLOSING,a.CLOSED=WebSocket.CLOSED,a}); diff --git a/www/worker_specs/script.js b/www/worker_specs/script.js new file mode 100644 index 0000000..4cd6701 --- /dev/null +++ b/www/worker_specs/script.js @@ -0,0 +1,114 @@ + +// DOM STUFF /////////////////////////////////////////////////////////////////// + +let divs = {}, + spec_names = [ + 'worker_id', + 'ip', + 'location', + 'browser', + 'os', + 'state', + 'fee', + 'hit_created', + 'hit_opened', + 'hit_submitted', + 'elapsed_time' + ] + +divs.linkDOM = function(name){ + divs[name] = document.getElementById(`${name}`) +} + +spec_names.forEach(function(name){ + divs.linkDOM(name) +}) + + + +let request_time = timeStamp(), + elapsed_time, + hit_finished = false + + +// SOCKET STUFF //////////////////////////////////////////////////////////////// + + +let ws = new ReconnectingWebSocket('ws://localhost:8888/status/ws') + +let test = `{"property": "os", "value": "213.127.20.197"}` + +// fakeWs(test) +// +// function fakeWs(json){ +// +// +// } + + +ws.addEventListener('open', () => { + // ws.send('hi server') +}) + + +ws.addEventListener('message', (event) => { + console.log('message: ' + event.data) + + let data = JSON.parse(event.data) + if(data.property === 'hit_opened') { + hit_finished = false + request_time = timeStamp() + divs[data.property].innerHTML = `${request_time.format('dd mmm HH:MM:ss')}` + } + else if(data.property === 'hit_submitted'){ + hit_finished = true; + } + else if(divs[data.property]) divs[data.property].innerHTML = `${data.value}` +}) + + + + + + + + + +// ANIMATION STUFF ///////////////////////////////////////////////////////////// + +let frames, +frames_per_sec = 10, +current_frame = 0 + + + +function makeAnimation(){ + let now, + delta = 0, + last = timeStamp(), + step = 1/frames_per_sec + function frame() { + now = timeStamp() + delta += Math.min(1, (now - last) / 1000) + while(delta > step){ + delta -= step + update(step) + } + last = now + requestAnimationFrame(frame) + } + requestAnimationFrame(frame) +} + +function update(step){ + + if(!hit_finished) elapsed_time = `${new Date((Date.now() - request_time)).format('MM"m "ss"s"')}` + + divs['elapsed_time'].innerHTML = elapsed_time +} + + +makeAnimation() + + +function timeStamp(){return window.performance && window.performance.now ? window.performance.now() : new Date().getTime()} diff --git a/www/worker_specs/script.js.old b/www/worker_specs/script.js.old new file mode 100644 index 0000000..752d828 --- /dev/null +++ b/www/worker_specs/script.js.old @@ -0,0 +1,114 @@ + +let spec = { + worker_id: '-', + ip_address: '-', + country: '-', + start_time: '-', + time: '-', + assign_status: '-', + approval_status: '-' +} + +let worker_specs = Object.create(spec), + prev_specs = Object.create(spec) + +let divs = { + worker_id: document.getElementById('worker_id'), + ip_address: document.getElementById('ip_address'), + country: document.getElementById('country'), + time: document.getElementById('time'), + assign_status: document.getElementById('assign_status'), + approval_status: document.getElementById('approval_status') +} + +let socket = io.connect('/') + +socket.on('connection', function(){ + console.log('connected to node server') +}) + +let opacity = 0.1 + +socket.on('workerSpecs', function(data){ + Object.assign(prev_specs, worker_specs) + worker_specs = data + opacity = 0 +}) + + + +let display_specs = function(){ + Object.keys(worker_specs).forEach(function(key){ + if(divs[key]){ + divs[key].innerText = worker_specs[key] + divs[key].style = `opacity: ${opacity}` + } + }) + opacity == 1 ? opacity = 0 : opacity += 0.1 +} + + + + + +// ANIMATION /////////////////////////////////////////////////////////////////// + + let frames, + frames_per_sec = 10, + current_frame = 0 + + function makeAnimation(){ + let now, + delta = 0, + last = timeStamp(), + step = 1/frames_per_sec + function frame() { + now = timeStamp() + delta += Math.min(1, (now - last) / 1000) + while(delta > step){ + delta -= step + update(step) + } + // render(delta) + last = now + requestAnimationFrame(frame) + } + requestAnimationFrame(frame) + } + + //// update state according to framerate + function update(step){ + +display_specs() + + + } + + //// render as fast as possible + // function render(delta){ + // } + + + + + // + // let time = (new Date().getTime() - worker_specs.start_time) / 1000 + // worker_specs.time = time.toString() + // Object.keys(worker_specs).forEach( function(key){ + // if(divs[key]) while(divs[key].firstChild){divs[key].removeChild(divs[key].firstChild)} + // for(let i = 0; i < worker_specs[key].length; i++){ + // let span = document.createElement('span') + // worker_specs[key][i] == prev_specs[key][i] ? span.className = 'char_normal' : span.className = 'char_big' + // span.innerText = worker_specs[key][i] + // if(divs[key]) divs[key].append(span) + // } + // }) + // Object.assign(prev_specs, worker_specs) + + + + + makeAnimation() + + + function timeStamp(){return window.performance && window.performance.now ? window.performance.now() : new Date().getTime()} diff --git a/www/worker_specs/style.css b/www/worker_specs/style.css new file mode 100644 index 0000000..1f398bd --- /dev/null +++ b/www/worker_specs/style.css @@ -0,0 +1,93 @@ +@font-face { + font-family: 'bebas'; + src: url('font/BebasNeue-Regular.ttf'); +} + +@font-face { + font-family: 'freesans'; + src: url('font/FreeSans.ttf') +} + + +:root{ + + --base-font-size: 25px; + --spec_name-font-size: 120%; + --spec_value-font-size: 250%; + + --base-color: #271601; /* tekst */ + --alt-color: #FFF5DF; /* achtergrond */ + + /* /////// GAT VOORKANT PLEK & POSITIE //////// */ + /* */ /* */ + /* */ --pos-x: calc(50% - (var(--width)/2)); /* */ + /* */ --pos-y: 200px; /* */ + /* */ --width: 560px; /* 115mm */ + /* */ --height: 1250px; /* 260mm */ + /* */ /* */ + /* //////////////////////////////////////////// */ + +} + + +html, body{ + margin: 0; + padding: 0; + border: 0; + text-decoration: none; + font-family: 'bebas'; + font-size: var(--base-font-size); + line-height: 1.1; + background: #000; + overflow: hidden; +} + + +#wrapper{ + + position: absolute; + left: var(--pos-x); + top: var(--pos-y); + width: var(--width); + height: var(--height); + + background: var(--alt-color); + box-sizing: border-box; + padding: 2%; +} + + +#worker_specs{ + display:grid; + grid-template-columns: 1fr ; + grid-template-rows: repeat(50, 1fr 2fr); +} + +.grid-item{ + color: var(--base-color); +} + +.spec_name{ + font-size: var(--spec_name-font-size); + font-family: 'freesans'; +} + +.spec_value{ + font-size: var(--spec_value-font-size); + padding-bottom: 2%; +} + + +.phase{ + display:none; +} + + +.phase:not(#worker_specs){ + padding-top: 100%; + text-align: center; +} + +.narrative_phase_text{ + font-size: var(--spec_value-font-size); +} diff --git a/www/worker_specs/style.css.old b/www/worker_specs/style.css.old new file mode 100644 index 0000000..3ef3465 --- /dev/null +++ b/www/worker_specs/style.css.old @@ -0,0 +1,142 @@ +@font-face { + font-family: 'bebas'; + src: url('font/BebasNeue-Regular.ttf'); + +} + + +:root{ + + --base-font-size: 20px; + --desc-font-size: 24px; + --val-font-size: 48px; + +} + +html, body{ + margin: 0; + padding: 0; + border: 0; + text-decoration: none; + font-family: bebas; + font-size: var(--base-font-size); + background: #000; + text-align: center; +} + + + + + +.grid-item{ + vertical-align: middle; +} + + + +.char_normal{ + height: inherit; display: inherit; text-align: inherit; vertical-align: inherit; + /* font-size: 40px; */ + /* color: #222; */ +} + + +.char_big{ + height: inherit; display: inherit; text-align: inherit; vertical-align: inherit; + /* font-size: 48px; */ + color:#000; +} + + + + + +/* GRID //////////////////////////////////////////////////////////////////////*/ + + +.grid-wrap{ + display:grid; + grid-template-columns: 1fr 2fr 1fr 1fr 2fr 1fr 1fr 2fr; + grid-template-rows: repeat(14, 20px); + /* line-height: 0.7; */ + + position: absolute; + width: 1610px; + height: 200px; + top: 200px; + left: 10px; + background: #fff; + padding: 40px 20px 0px 20px; + justify-items: end; + align-items: end; +} + +.grid-item *{ + display: inline; + height: 60px; + + +} + +.desc{ + justify-self: start; + font-size: var(--desc-font-size); +} + +.val{ + font-size: var(--val-font-size); +} + + + + + +/* row start / col start / row end / col end */ + +#worker_id_desc{ + grid-area: 1 / 1 / span 1 / span 1; +} + +#worker_id{ + grid-area: 1 / 2 / span 2 / span 1; +} + +#ip_address_desc{ + grid-area: 4 / 1 / span 1 / span 1; +} + +#ip_address{ + grid-area: 4 / 2 / span 2 / span 1; +} + +#country_desc{ + grid-area: 7 / 1 / span 1 / span 1; +} + +#country{ + grid-area: 7 / 2 / span 2 / span 1; +} + +#time_desc{ + grid-area: 1 / 4 / span 1 /span 1; +} + +#time{ + grid-area: 1 / 5 / span 2 / span 1; +} + +#assign_status_desc{ + grid-area: 4 / 4 / span 1 / span 1; +} + +#assign_status{ + grid-area: 4 / 5 / span 2 / span 1; +} + +#approval_status_desc{ + grid-area: 7 / 4 / span 1 / span 1; +} + +#approval_status{ + grid-area: 7 / 5 / span 2 / span 1; +}