import ReconnectingWebSocket from 'reconnecting-websocket'; import Sortable from 'sortablejs'; window.onload = function () { const ws = new ReconnectingWebSocket(((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.host + "/ws"); const items = document.querySelector("#items"); const amb = document.querySelector("#ambiance") const submit = document.querySelector("#addplaylist") const output = document.querySelector(".container2 p#output") const info = document.querySelector("#info") const link = document.querySelector("#link") const time = document.querySelector("#time") const waiting = document.querySelector("#waiting") document.querySelector("input#next").addEventListener("click", (e) => { ws.send(JSON.stringify({ "event": "next" })) }) document.querySelector("input#prev").addEventListener("click", (e) => { ws.send(JSON.stringify({ "event": "prev" })) }) Sortable.create(items, { delayOnTouchOnly: true, group: "dndmusicbot-playlists", filter: ".locked", onMove: (e) => { if (e.related) { return !e.related.classList.contains('locked'); } }, invertSwap: true, store: { get: function (sortable) { var order = localStorage.getItem(sortable.options.group.name); return order ? order.split('|') : []; }, set: function (sortable) { var order = sortable.toArray(); localStorage.setItem(sortable.options.group.name, order.join('|')); } } }) Sortable.create(amb, { delayOnTouchOnly: true, group: "dndmusicbot-ambiance", filter: ".locked", onMove: (e) => { if (e.related) { return !e.related.classList.contains('locked'); } }, invertSwap: true, store: { get: function (sortable) { var order = localStorage.getItem(sortable.options.group.name); return order ? order.split('|') : []; }, set: function (sortable) { var order = sortable.toArray(); localStorage.setItem(sortable.options.group.name, order.join('|')); } } }) ws.onopen = (e) => { waiting.classList.add("u-hidden") } ws.onclose = (e) => { waiting.classList.remove("u-hidden") } ws.onmessage = (e) => { data = JSON.parse(e.data) switch (data.event) { case "ambiance_play": document.querySelectorAll("#ambiance > div").forEach((e) => {e.style.removeProperty("background-color")}) document.querySelector(`#ambiance > div[data-id='${data.payload.type}']`).style.backgroundColor = "burlywood" ambiance.style.pointerEvents = 'auto' break case "ambiance_stop": document.querySelectorAll("#ambiance > div").forEach((el) => { el.style.removeProperty("background-color") }) break case "song_info": document.querySelectorAll("#items > div").forEach((el) => { el.style.removeProperty("background-color") }) if (data.payload.pause) { info.classList.add("u-hidden") } else { info.classList.remove("u-hidden") link.children.channel.innerText = data.payload.channel link.children.title.innerText = data.payload.current link.href = "https://youtu.be/" + data.payload.song link.target = "_blank" time.innerText = `${msToTime(data.payload.position)} / ${msToTime(data.payload.len)}` document.querySelector(`#items > div[data-id='${data.payload.playlist}']`).style.backgroundColor = "burlywood" } setTimeout(() => { items.style.pointerEvents = 'auto' }, 1000); break case "song_position": time.innerText = `${msToTime(data.payload.position)} / ${msToTime(data.payload.len)}` info.classList.remove("u-hidden") break case "stop": setTimeout(() => { items.style.pointerEvents = 'auto' }, 2000); info.classList.add("u-hidden") break case "new_playlist": addPlaylist(data.payload); break; default: } } document.querySelector("#addambiance").addEventListener("click", (e) => { e.preventDefault() output.innerText = "" var title = document.querySelector("#inputambiance > input[name='title']") var url = document.querySelector("#inputambiance > input[name='url']") if (title.value == "" || url.value == "") { output.innerText = "Title or Url is empty!" return } ws.send(JSON.stringify({ "event": "ambiance_add", "payload": { "title": title.value, "url": url.value } })) }) submit.addEventListener("click", (e) => { e.preventDefault() output.innerText = "" var title = document.querySelector("#inputplaylist > input[name='title']") var url = document.querySelector("#inputplaylist > input[name='url']") if (title.value == "" || url.value == "") { output.innerText = "Title or Url is empty!" return } ws.send(JSON.stringify({ "event": "add_playlist", "payload": { "title": title.value, "url": url.value } })) title.innerText = "" url.innerText = "" }) document.querySelectorAll("#items .item").forEach(item => item.addEventListener("click", (e) => { e.preventDefault() e.target.parentElement.style.pointerEvents = 'none' const disableui = setTimeout((t) => { t.style.pointerEvents = 'auto' }, 3000, e.target.parentElement); var id = e.target.dataset.id ws.send(JSON.stringify({ "event": ((id === "reset") ? "stop" : "load_playlist"), "payload": id })) })); document.querySelectorAll("#ambiance .item").forEach(item => item.addEventListener("click", (e) => { e.preventDefault() e.target.parentElement.style.pointerEvents = 'none' const disableui = setTimeout((t) => { t.style.pointerEvents = 'auto' }, 3000, e.target.parentElement); var id = e.target.dataset.id ws.send(JSON.stringify({ "event": ((id === "reset") ? "ambiance_stop" : "ambiance_play"), "payload": id })) })); }; function addPlaylist(payload) { const container = document.querySelector("body > div.container") var newdiv = document.createElement('div'); newdiv.className = "item" newdiv.dataset.id = payload.url newdiv.innerText = payload.title newdiv.addEventListener("click", (e) => { e.preventDefault() var id = e.target.dataset.id ws.send(JSON.stringify({ "event": ((id === "reset") ? "stop" : "load_playlist"), "payload": id })) }) container.insertBefore(newdiv, document.querySelector("body > div.container div:last-child")) output.innerText = "New playlist was added: " + payload.title } function msToTime(duration) { var milliseconds = parseInt((duration % 1000) / 100), seconds = Math.floor((duration / 1000) % 60), minutes = Math.floor((duration / (1000 * 60)) % 60), minutes = (minutes < 10) ? "0" + minutes : minutes; seconds = (seconds < 10) ? "0" + seconds : seconds; return minutes + ":" + seconds }