ppt_control / static / ppt-control.json commit add config file comments, minor JS refactoring (ae22cb8)
   1const DEFAULT_TITLE = "ppt-control";
   2const LABEL_STOPPED = "Slideshow stopped";
   3const LABEL_RUNNING = "Slideshow running";
   4const LABEL_DISCONNECTED = "Disconnected";
   5const LABEL_FINAL_PREFIX = "Final slide ‐ ";
   6const LABEL_END_PREFIX = "End of slideshow ‐ ";
   7var preloaded = false;
   8var preload = [];
   9
  10var presentation = document.querySelector('#presentation'),
  11    startBtn = document.querySelector('.start'),
  12    stopBtn = document.querySelector('.stop'),
  13    prev = document.querySelector('#prev'),
  14    next = document.querySelector('#next'),
  15    first = document.querySelector('#first'),
  16    last = document.querySelector('#last'),
  17    black = document.querySelector('#black'),
  18    white = document.querySelector('#white'),
  19    slide_label = document.querySelector('#slide_label'),
  20    current = document.querySelector('#current'),
  21    total = document.querySelector('#total'),
  22    status_text = document.querySelector('.status_text'),
  23    presentation_text = document.querySelector('.presentation_text'),
  24    current_img = document.querySelector('#current_img'),
  25    next_img = document.querySelector('#next_img'),
  26    current_div = document.querySelector('#current_div'),
  27    next_div = document.querySelector('#next_div'),
  28    controls_container = document.querySelector('#controls_container'),
  29    controls_container_inner = document.querySelector('#controls_container_inner'),
  30    show_current = document.querySelector('#show_current'),
  31    show_next = document.querySelector('#show_next'),
  32    shortcuts = document.querySelector('#shortcuts');
  33
  34var presentationData = {};
  35var presentationOptions = {};
  36
  37
  38function getPresentationName() {
  39    if (presentation.selectedOptions.length > 0) {
  40        return presentation.selectedOptions[0].innerText;
  41    } else {
  42        return "";
  43    }
  44}
  45
  46
  47function startWebsocket() {
  48    console.log("Attempting to connect")
  49    ws = new WebSocket("ws://" + window.location.host + ":5678/");
  50    ws.onmessage = receive_message;
  51    ws.onclose = function(){
  52        ws = null;
  53        setTimeout(function(){websocket = startWebsocket()}, 1000);
  54    }
  55    if (ws.readyState !== WebSocket.OPEN) {
  56      disconnect()
  57    }
  58    return ws;
  59}
  60
  61var websocket = startWebsocket();
  62
  63prev.onclick = function (event) {
  64    if (getPresentationName()) {
  65        websocket.send(JSON.stringify({presentation: getPresentationName(), action: 'prev'}));
  66    }
  67}
  68
  69next.onclick = function (event) {
  70    if (getPresentationName()) {
  71        websocket.send(JSON.stringify({presentation: getPresentationName(), action: 'next'}));
  72    }
  73}
  74
  75first.onclick = function (event) {
  76    if (getPresentationName()) {
  77        websocket.send(JSON.stringify({presentation: getPresentationName(), action: 'first'}));
  78    }
  79}
  80
  81last.onclick = function (event) {
  82    if (getPresentationName()) {
  83        websocket.send(JSON.stringify({presentation: getPresentationName(), action: 'last'}));
  84    }
  85}
  86
  87black.onclick = function (event) {
  88    if (getPresentationName()) {
  89        websocket.send(JSON.stringify({presentation: getPresentationName(), action: 'black'}));
  90    }
  91}
  92
  93white.onclick = function (event) {
  94    if (getPresentationName()) {
  95        websocket.send(JSON.stringify({presentation: getPresentationName(), action: 'white'}));
  96    }
  97}
  98
  99current.onblur = function (event) {
 100    if (getPresentationName()) {
 101        websocket.send(JSON.stringify({presentation: getPresentationName(), action: 'goto', value: current.value}));
 102    }
 103}
 104
 105startBtn.onclick = function (event) {
 106    if (getPresentationName()) {
 107        websocket.send(JSON.stringify({presentation: getPresentationName(), action: 'start'}));
 108    }
 109}
 110
 111stopBtn.onclick = function (event) {
 112    if (getPresentationName()) {
 113        websocket.send(JSON.stringify({presentation: getPresentationName(), action: 'stop'}));
 114    }
 115}
 116
 117current.addEventListener('keyup',function(e){
 118    if (e.which == 13) this.blur();
 119});
 120
 121
 122presentation.addEventListener('change',function(event){
 123    refreshInterface();
 124});
 125
 126current_img.onclick = function (event) {
 127        next.click()
 128}
 129
 130next_img.onclick = function (event) {
 131        next.click()
 132}
 133
 134window.addEventListener('resize', function(event) {set_control_width()}, true);
 135
 136
 137function sync_current() {
 138    if (show_current.checked) {
 139        current_div.style.display = "block";
 140        slide_label.style.display = "none";
 141        next_div.style.width = "25%";
 142    } else {
 143        current_div.style.display = "none";
 144        slide_label.style.display = "inline";
 145        next_div.style.width = "calc(100% - 20px)";
 146    }
 147    set_control_width();
 148    saveSettings();
 149}
 150show_current.onclick = sync_current;
 151
 152function sync_next() {
 153    if (show_next.checked) {
 154        next_div.style.display = "block";
 155        current_div.style.width = "70%";
 156    } else {
 157        next_div.style.display = "none";
 158        current_div.style.width = "calc(100% - 20px)";
 159    }
 160    set_control_width();
 161    saveSettings();
 162}
 163show_next.onclick = sync_next;
 164
 165function sync_shortcuts() {
 166  saveSettings();
 167}
 168shortcuts.onclick = sync_shortcuts;
 169
 170function set_control_width() {
 171        var width = window.innerWidth
 172        || document.documentElement.clientWidth
 173        || document.body.clientWidth;
 174    if (show_current.checked && show_next.checked && width > 800) {
 175        controls_container_inner.style.width = "70%"
 176    } else {
 177        controls_container_inner.style.width = "100%"
 178    }
 179}
 180
 181
 182document.addEventListener('keydown', function (e) {
 183        if (shortcuts.checked) {
 184                switch (e.key) {
 185                        case "Left":
 186                        case "ArrowLeft":
 187                        case "Up":
 188                        case "ArrowUp":
 189                        case "k":
 190                        case "K":
 191                                prev.click();
 192                                break;
 193                        case " ":
 194                        case "Spacebar":
 195                        case "Enter":
 196                        case "Right":
 197                        case "ArrowRight":
 198                        case "Down":
 199                        case "ArrowDown":
 200                        case "j":
 201                        case "J":
 202                                next.click();
 203                                break;
 204                        case "b":
 205                        case "B":
 206                                black.click();
 207                break;
 208                        case "w":
 209                        case "W":
 210                                white.click();
 211                        default:
 212                                return
 213                }
 214        }
 215});
 216
 217function refreshInterface() {
 218    var d = new Date;
 219    if (Object.keys(presentationData).length > 0) {
 220        currentPresentationData = presentationData[getPresentationName()];
 221        presentation_text.style.display = "block";
 222        status_text.innerHTML = LABEL_RUNNING;
 223        startBtn.style.display = "none";
 224        stopBtn.style.display = "block";
 225        if (show_current.checked) {
 226            switch (currentPresentationData.visible) {
 227                case 3:
 228                    current_img.src = "/black.jpg";
 229                    break;
 230                case 4:
 231                    current_img.src = "/white.jpg";
 232                    break;
 233                default:
 234                    current_img.src = "/cache/" + currentPresentationData.name + "/" + currentPresentationData.slide_current + ".jpg?t=" + d.getTime();
 235                    break;
 236            }
 237        }
 238        if (currentPresentationData.slide_current == currentPresentationData.slide_total) {
 239            status_text.innerHTML = LABEL_FINAL_PREFIX + LABEL_RUNNING;
 240        }
 241        if (currentPresentationData.slide_current == currentPresentationData.slide_total + 1) { 
 242            status_text.innerHTML = LABEL_END_PREFIX + LABEL_RUNNING;
 243            next_img.src = "/black.jpg";
 244        } else {
 245            next_img.src = "/cache/" + currentPresentationData.name + "/" + (currentPresentationData.slide_current + 1) + ".jpg?t=" + d.getTime();
 246        }
 247        if (currentPresentationData.slide_current == 0) {
 248            current_img.src = "/black.jpg";
 249            next_img.src = "/black.jpg";
 250            status_text.innerHTML = LABEL_STOPPED;
 251            startBtn.style.display = "block";
 252            stopBtn.style.display = "none";
 253        }
 254
 255        if (document.activeElement != current) {
 256            current.value = currentPresentationData.slide_current;
 257        }
 258        total.textContent = currentPresentationData.slide_total;
 259        document.title = currentPresentationData.name;
 260    } else {
 261        disconnect()
 262    }
 263}
 264
 265function disconnect() {
 266    console.log("Disconnecting")
 267    document.title = DEFAULT_TITLE;
 268    current_img.src = "/black.jpg";
 269    next_img.src = "/black.jpg";
 270    status_text.innerHTML = LABEL_DISCONNECTED;
 271    total.textContent = "?";
 272    current.value = "";
 273    presentation_text.style.display = "none";
 274    startBtn.style.display = "none";
 275    stopBtn.style.display = "none";
 276}
 277
 278function receive_message(event) {
 279    data = JSON.parse(event.data);
 280    if (Object.keys(presentationData).includes(data.name)) {
 281        // Existing presentation
 282        presentationData[data.name] = {"name": data.name, "pres_open": data.pres_open, "slideshow": data.slideshow, "visible": data.visible, "slide_current": data.slide_current, "slide_total": data.slide_total, "option": presentationData[data.name].option};
 283    } else {
 284        console.log("Adding new presentation " + data.name);
 285        var dropdownOption = document.createElement("option");
 286        dropdownOption.textContent = data.name;
 287        dropdownOption.value = data.name;
 288        presentationData[data.name] = {"name": data.name, "pres_open": data.pres_open, "slideshow": data.slideshow, "visible": data.visible, "slide_current": data.slide_current, "slide_total": data.slide_total, "option": dropdownOption};
 289        presentation.appendChild(dropdownOption);
 290    }
 291    if (! presentationData[data.name].pres_open) {
 292        presentation.removeChild(presentationData[data.name].option);
 293        delete presentationData[data.name]
 294        disconnect()
 295        
 296        //console.log("Deleting presentation data from list");
 297        //delete presentationData[data.name];
 298        //presentationOptions[data.name].remove()
 299    }
 300    refreshInterface()
 301        
 302        if (preloaded == false && ! isNaN(total.textContent)) {
 303                image = document.getElementById("preload_img");
 304                for (let i=1; i<=Number(total.textContent); i++) {
 305                        image.src = "/cache/" + getPresentationName() + "/" + i + ".jpg";
 306                        preload.push(image);
 307                }
 308                preloaded = true;
 309        }
 310
 311};