/* Social program for Ramaskrik. Copyright (C) 2019 Harald Eilertsen This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ function fetch_rooms(data_done) { let req = new XMLHttpRequest() req.addEventListener("load", data_done) req.open("GET", "http://localhost:8000/rooms") req.responseType = "json" req.send() } function load_screenings(data_done) { let req = new XMLHttpRequest() req.addEventListener("load", data_done) req.open("GET", "http://localhost:8000/screenings") req.responseType = "json" req.send() } function pluralize(num, word) { let result = num + " " + word if (num > 1) { result += "s" } return result } function log_film(film) { console.log(film["title"] + " (" + pluralize(film["screenings"].length, "screening") + ")") } function date_f(d) { let opts = { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' } return new Intl.DateTimeFormat('nb-NO', opts).format(d) } window.addEventListener("load", function() { let screenings_by_date = new Map() function _add(screening) { let d = Date.parse(screening.date) if (!screenings_by_date.has(d)) screenings_by_date.set(d, new Array()) let s = screenings_by_date.get(d) s.push(screening) }; function _end_time(screening) { if (screening.end_time < screening.start_time) { return screening.end_time .split(':') // Add 24 to the hour component of the time string .map( (v, i) => i == 0 ? (parseInt(v) + 24).toString() : v) .join(':') } else { return screening.end_time } } function _time_to_sec(t) { let expl = t.split(':').map( v => parseInt(v) ) return expl[0] * 3600 + expl[1] * 60 + expl[2] } function _sec_to_time(v) { let hour = Math.floor(v / 3600) v = v % 3600 let min = Math.floor(v / 60) let f = Intl.NumberFormat('nb-NO', { minimumIntegerDigits: 2 }) return [ f.format(hour), f.format(min) ].join(':') } function break_text(c, text, x, y, width) { let len = c.measureText(text).width if (len < width) { c.fillText(text, x, y) return } let expl = text.split(' ') let space = c.measureText(' ').width let llen = 0 let lpos = 0 for (let frag of expl) { flen = c.measureText(frag).width llen += flen if (llen > width) { llen = 0 lpos = 0 y += 15 } c.fillText(frag, x + lpos, y) lpos += flen + space } } function center_text(c, text, x, y, width) { let len = c.measureText(text).width let xpos = Math.ceil((width - len) / 2) c.fillText(text, x + xpos, y) } let margin = 30; let xmargin = 50; function draw_timescale(c, start, end) { let dur = Math.ceil((end - start) / 30) c.font = '10px Helvetica' c.lineWidth = 'thin' c.strokeStyle = '#ccc' for (let y = 0; y <= dur; y += 30) { let ypos = y + margin; c.beginPath() c.moveTo(35, ypos) c.lineTo(510, ypos) c.stroke() c.fillText(_sec_to_time(y * 30 + start + margin), 5, ypos + 3) } } function draw_room_headers(c, rooms) { let x = 0; c.font = '15px sans-serif' for (let r of [...rooms]) { center_text(c, r, 50 + x, 15, 100) x += 150 } } function draw_screenings(c, screenings, start_time, rooms) { let r = [...rooms] c.strokeStyle = '#000' for (let s of screenings) { let ystart = Math.ceil((_time_to_sec(s.start_time) - start_time) / 30) + margin; let height = Math.ceil((_time_to_sec(_end_time(s)) - start_time ) / 30) + margin - ystart; let ri = s.room.id - 1 let xstart = xmargin + ri * 150 c.fillStyle = '#ec9' c.fillRect(xstart, ystart, 100, height) c.strokeRect(xstart, ystart, 100, height) c.fillStyle = '#000' break_text(c, s.film.title, xstart + 5, ystart + 15, 90) } } load_screenings(function() { this.response.forEach(_add) console.log("Screenings in " + screenings_by_date.size + " days: ") for (let date of screenings_by_date.keys()) { let date_str = date_f(date) console.log(date_str) let s = screenings_by_date.get(date) let start_time = s .map( el => _time_to_sec(el.start_time) ) .reduce( (acc, cur) => cur < acc ? cur : acc, _time_to_sec('23:59:59') ) let end_time = s .map( el => _time_to_sec(_end_time(el))) .reduce( (acc, cur) => cur > acc ? cur : acc, 0 ) console.log(" Start time: " + _sec_to_time(start_time)) console.log(" End time : " + _sec_to_time(end_time)) let dur = end_time - start_time console.log(" Duration : " + _sec_to_time(dur)) // Each line in the canvas equals half a minute let canvas_height = Math.ceil(dur / 30) + 60 let p = document.querySelector('#program') let day = document.createElement('section') day.id = "program-" + date_str day.innerHTML = '

' + date_str + '

' + '' + '' p.appendChild(day) let canvas = document.getElementById('canvas-' + date_str) let c = canvas.getContext('2d'); let rooms = new Set(s.map( el => el.room.name )) draw_room_headers(c, rooms) draw_timescale(c, start_time, end_time) draw_screenings(c, s, start_time, rooms) } }) /* fetch_rooms(function() { let table = document.getElementById("screening-table") let row = document.createElement("tr") table.appendChild(row) this.response.forEach(function(room) { console.log(room["name"]) let item = document.createElement("th") item.innerHTML = room["name"] row.appendChild(item) }) }) */ console.log("Holahey!") })