aboutsummaryrefslogblamecommitdiffstats
path: root/public/js/app.js
blob: e219af47c861f1a0a157db0365b1675c7f5dc713 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

















                                                                               







                                                  


                                           
                                                       




















                                                       




                                                                                  
                                            





















































































































                                                                                                      
                                







































                                                                                                    
      
 
          











                                                              
          

                           
/*
    Social program for Ramaskrik.
    Copyright (C) 2019  Harald Eilertsen <haraldei@anduin.net>

    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 <https://www.gnu.org/licenses/>.
*/

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 = '<h2>' + date_str + '</h2>'
                + '<canvas id="canvas-' + date_str + '" height="' + canvas_height + '" width="350">'
                + '</canvas>'
            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!")
})