var socket; function load() { init_websocket(); document.querySelector('#player').addEventListener('ended', function() { if (document.querySelector('#shuffle').checked) { socket.send_event('random_track', {}); } }); } /* Websocket setup */ function init_websocket() { let _socket; _socket = new WebSocket('wss://' + window.location.hostname + ws_uri); _socket.send_event = send_event; _socket.onopen = onopen; _socket.onmessage = onmessage; _socket.onclose = onclose; _socket.onerror = onerror; _socket.events = {}; _socket.events['artist_albums'] = artist_albums_recv; _socket.events['album_tracks'] = album_tracks_recv; _socket.events['track'] = track_recv; window.socket = _socket; } function send_event(event_title, data) { data = JSON.stringify({'event': event_title, 'data': data}); if (this.readyState == 0) { console.log("Socket is still opening!"); return; } log_debug_message('debug', "Sending `" + event_title + "` event with following data: " + JSON.stringify(data)); this.send(data); } function onopen(event) { log_debug_message('debug', 'Websocket connected to server.'); } function onmessage(event) { let data; let event_title; try { data = JSON.parse(event.data); } catch(err) { // not JSON console.log(err); console.log(event); throw new Error("Error decoding JSON"); return; } if (!data.ok) { throw new Error("Socket error: event = " + event_title + ", error = " + data.error); } try { event_title = data.event; data = data.data; } catch(err) { // not proper event console.log(err); console.log(event); throw new Error("Event malformed"); return; } if (socket.events[event_title] === undefined) { console.log("Unknown socket event: " + event_title); return; } log_debug_message('debug', "Received `" + event_title + "` event with following data: " + JSON.stringify(data)); socket.events[event_title](data); } async function onclose(event) { log_debug_message('debug', 'Websocket lost connection to server.') if (event.wasClean) { return; } // no need to reconnect console.log(event); console.log('Websocket lost connection to server. Re-trying...'); await sleep(3000); init_websocket(); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function onerror(event) { log_debug_message('error', 'Websocket encountered an error.') console.log("Websocket error!") console.log(event); } /* Websocket receive */ function artist_albums_recv(data) { let albums_list = document.querySelector('#albumList'); while (albums_list.firstChild) { albums_list.removeChild(albums_list.lastChild); } for (let album of data) { let option = document.createElement('option'); option.value = album['album']; option.innerText = album['album']; albums_list.appendChild(option); } } function album_tracks_recv(data) { let track_list = document.querySelector('#trackList'); while (track_list.firstChild) { track_list.removeChild(track_list.lastChild); } for (let track of data) { let option = document.createElement('option'); option.value = track['title']; option.innerText = track['discnumber'] + '.' + track['tracknumber'] + ' - ' + track['title']; option.dataset['discnumber'] = track['discnumber'] option.dataset['tracknumber'] = track['tracknumber'] track_list.appendChild(option); } } function track_recv(data) { document.querySelector('#nowPlayingArtist').innerText = data['albumartist']; document.querySelector('#nowPlayingAlbum').innerText = data['album']; document.querySelector('#nowPlayingTitle').innerText = data['title']; document.title = 'Scorch | ' + data['artist'] + ' - ' + data['title']; let player = document.querySelector('#player'); player.firstElementChild.src = data['url']; player.load(); player.play(); document.querySelector('#albumCover').firstChild.src = data['coverart']; } /* Websocket send */ function select_artist(select) { let data = { 'artist': select.value, }; socket.send_event('select_artist', data); } function select_album(select) { let data = { 'artist': document.querySelector('#artistList').value, 'album': select.value, }; socket.send_event('select_album', data); } function select_track(select) { let data = { 'artist': document.querySelector('#artistList').value, 'album': document.querySelector('#albumList').value, 'discnumber': select.selectedOptions[0].dataset['discnumber'], 'tracknumber': select.selectedOptions[0].dataset['tracknumber'], }; socket.send_event('select_track', data); } /* DOM */ function show_debug(checkbox) { if (checkbox.checked) { document.querySelector('#debugLog').style.display = 'inherit'; } else { document.querySelector('#debugLog').style.display = 'none'; } } function log_debug_message(log_level, message) { let msg = new Date().toTimeString().replace(/ .*/, '') + ' ' + message; let li = document.createElement('li'); li.className = log_level; li.textContent = msg; document.querySelector('#debugLog').appendChild(li); }