var requestsDiv = document.getElementById("requests"); var cronJobs = ['processBans']; var currentPage = 1; var totalPages = 1; var count = document.getElementById("count").value; var sortBy = document.getElementById("sortBy").value; var sortDir = "desc"; function getRequests(offset,allRequests) { if (allRequests) var reqUrl = "/api/getAllRequests"; else var reqUrl = "/api/getRequests"; reqUrl += `?count=${count}&offset=${offset}&sort=${sortBy}&sortDirection=${sortDir}`; fetch(reqUrl) .then(response => response.json()) .then(requests => { buildTable(requests); }); } function buildTable(requests) { totalPages = Math.ceil(requests.total/document.getElementById("count").value); document.getElementById("totalPages").innerText = totalPages; if (currentPage <= 1) { currentPage = 1; document.getElementById("pageBtnFirst").disabled = true; document.getElementById("pageBtnPrev").disabled = true; } else { document.getElementById("pageBtnFirst").disabled = false; document.getElementById("pageBtnPrev").disabled = false; } if (currentPage >= totalPages) { currentPage = totalPages; document.getElementById("pageBtnLast").disabled = true; document.getElementById("pageBtnNext").disabled = true; } else { document.getElementById("pageBtnLast").disabled = false; document.getElementById("pageBtnNext").disabled = false; } document.getElementById("page").innerHTML = ""; for (i = 1; i <= totalPages; i++) { document.getElementById("page").innerHTML += ``; } document.getElementById("page").value = currentPage; var requestsDivHTML = ''; requestsDivHTML += '' requestsDivHTML += ""; for (request of requests.requests) { requestsDivHTML += `\ \ `; requestsDivHTML += ``; if (window.loggedIn) { if (request.voted) { requestsDivHTML += ``; } else { requestsDivHTML += ``; } if (window.isStreamer) { requestsDivHTML += '' } } requestsDivHTML += ""; } requestsDivHTML += "
Song TitleRequesterScoreState'; if (window.loggedIn) requestsDivHTML += 'Vote'; if (window.isStreamer) requestsDivHTML += 'Update
${request.imageurl ? `` : ''}${request.requester}${request.score}${request.state}
"; requestsDiv.innerHTML = requestsDivHTML; } function updateTable() { var offset = (currentPage - 1) * count; var allRequests = document.getElementById("allRequests").checked; getRequests(offset,allRequests); } function applyUrlTransforms(url) { console.log("Begin applyUrlTransforms:" + url); url = url.trim(); if (url.match(/^https?:\/\/(www\.)?youtu(\.be|be\.com)\//)) { // Youtube console.log("Youtube"); var videoid = ""; // youtu.be share url - Do not anchor to $ due to parameters such as ?t= if (url.match(/^https?:\/\/youtu.be\/[A-Za-z0-9_-]{11}/)) { videoid = url.match(/(?<=^https:\/\/youtu.be\/)[A-Za-z0-9_-]{11}/)[0]; } else if (url.match(/^https?:\/\/(www\.)?youtube\.com\//)) { videoid = url.match(/(?<=^https?:\/\/(www\.)?youtube\.com\/watch.*[?&]v=)[A-Za-z0-9_-]{11}/)[0]; } var result = 'https://www.youtube.com/watch?v=' + videoid; console.log("Result: " + result); return result; } } function goToPage(page) { currentPage = parseInt(page,10); updateTable(); } function getColorObject() { return { bg: { primary: document.getElementById('color-bg-primary').value, table: document.getElementById('color-bg-table').value, navbar: document.getElementById('color-bg-navbar').value, error: document.getElementById('color-bg-error').value, }, fg: { primary: document.getElementById('color-fg-primary').value, ahover: document.getElementById('color-fg-ahover').value, title: document.getElementById('color-fg-title').value, } } } function addRequestErr(msg) { document.getElementById('addRequestError').style.display = "inline-block"; document.getElementById('addRequestError').innerText = msg; } function addRequestErrReset() { document.getElementById('addRequestError').style.display = "none"; document.getElementById('addRequestError').innerText = ""; } function updateRequestErr(msg) { document.getElementById('updateRequestError').style.display = "inline-block"; document.getElementById('updateRequestError').innerText = msg; } function updateRequestErrReset() { document.getElementById('updateRequestError').style.display = "none"; document.getElementById('updateRequestError').innerText = ""; } function streamerSettingsErr(msg) { document.getElementById('streamerSettingsError').style.display = "inline-block"; document.getElementById('streamerSettingsError').innerText = msg; } function streamerSettingsErrReset() { document.getElementById('streamerSettingsError').style.display = "none"; document.getElementById('streamerSettingsError').innerText = ""; } // Hides all modals in preparation to show a one or to close out of // all modals and return to the page. Does NOT hide modalBackground. function hideModals() { document.getElementById("messageModal").style.display = "none"; document.getElementById("addRequestModal").style.display = "none"; document.getElementById("updateRequestModal").style.display = "none"; document.getElementById("deleteRequestModal").style.display = "none"; document.getElementById("streamerSettingsModal").style.display = "none"; } function closeAllModals() { hideModals(); document.getElementById("modalBackground").style.display = "none"; } function showMessage(msg) { hideModals(); document.getElementById("messageModalText").innerText = msg; document.getElementById("modalBackground").style.display = "flex"; document.getElementById("messageModal").style.display = "block"; } function openAddRequestModal() { hideModals(); document.getElementById("modalBackground").style.display = "flex"; document.getElementById("addRequestModal").style.display = "block"; } function openUpdateRequestModal(tr) { hideModals(); var url = tr.getElementsByClassName('request-link')[0].firstChild.href; var score = tr.getElementsByClassName('request-score')[0].innerText; var state = tr.getElementsByClassName('request-state')[0].innerText; document.getElementById("updateRequestUrl").href = url; document.getElementById("updateRequestUrl").innerText = url; document.getElementById("updateRequestModalCurrentScore").innerText = score; document.querySelector(`#updateRequestStateSelect [value="${state}"]`).selected = true; document.getElementById("scoreModifierInput").value = 0; document.getElementById("modalBackground").style.display = "flex"; document.getElementById("updateRequestModal").style.display = "block"; } function openDeleteRequestModal(url) { hideModals(); document.getElementById("updateRequestUrl").href = url; document.getElementById("updateRequestUrl").innerText = url; document.getElementById("messageModal").style.display = "none"; document.getElementById("addRequestModal").style.display = "none"; document.getElementById("updateRequestModal").style.display = "none"; document.getElementById("modalBackground").style.display = "flex"; document.getElementById("deleteRequestModal").style.display = "block"; } // Returns to update request modal function closeDeleteRequestModal() { hideModals(); document.getElementById("deleteRequestModal").style.display = "none"; document.getElementById("updateRequestModal").style.display = "block"; } function openStreamerSettingsModal() { hideModals(); document.getElementById("modalBackground").style.display = "flex"; document.getElementById("streamerSettingsModal").style.display = "block"; } function cronRequest(job) { if (!cronJobs.includes(job)) throw new Error("Request for invalid job"); } const validUrlRegexes = [ /^https:\/\/www\.youtube\.com\/watch\?v=[a-zA-Z0-9_-]{11}$/ ]; function validateAndSubmitRequest() { addRequestErrReset(); var url = applyUrlTransforms(document.getElementById("addRequestUrl").value); var validUrl = false; for (var regex of validUrlRegexes) { if (regex.test(url)) { validUrl = true; break; } } if (!validUrl) { addRequestErr("Invalid URL"); return; } fetch("/api/addRequest", { method: 'POST', body: new URLSearchParams({ url: url })}) .then(response => { updateTable(); document.getElementById("addRequestUrl").value = ""; response.text().then((message) => { closeAllModals(); showMessage(message); }); }); } function addVote(url) { fetch("/api/addVote", { method: 'POST', body: new URLSearchParams({ url: url })}) .then(response => { if (!response.ok) { response.text().then(showMessage); return; } updateTable(); response.text().then(showMessage); }); } function deleteVote(url) { fetch("/api/deleteVote", { method: 'POST', body: new URLSearchParams({ url: url })}) .then(response => { if (!response.ok) { response.text().then(addRequestErr); return; } updateTable(); response.text().then(showMessage); }); } function updateRequestState(url,state) { updateRequestErrReset(); fetch("/api/updateRequestState", { method: 'POST', body: new URLSearchParams({ url: url, state: state })}) .then(response => { if (!response.ok) { response.text().then(updateRequestErr); return; } updateTable(); response.text().then(showMessage); }); } function updateRequestScoreModifier(url,scoreDiff) { updateRequestErrReset(); fetch("/api/updateRequestScoreModifier", { method: 'POST', body: new URLSearchParams({ url: url, scoreDiff: scoreDiff })}) .then(response => { if (!response.ok) { response.text().then(updateRequestErr); return; } updateTable(); response.text().then(showMessage); }); } function updateRequestMetadata(url) { fetch("/api/updateRequestMetadata?url=" + url) .then(response => { updateTable(); response.text().then(showMessage); }); } function deleteRequest(url) { fetch("/api/deleteRequest", { method: 'POST', body: new URLSearchParams({ url: url })}) .then(response => { updateTable(); response.text().then(showMessage); }); } function updatePageTitle(pageTitle) { streamerSettingsErrReset(); fetch("/api/updatePageTitle", { method: 'POST', body: new URLSearchParams({ pageTitle: pageTitle })}) .then(response => { if (response.ok) { location.reload(); } else { response.text().then(streamerSettingsErr); } }); } function updateColors(colors) { streamerSettingsErrReset(); fetch("/api/updateColors", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(colors)}) .then(response => { if (response.ok) { location.reload(); } else { response.text().then(streamerSettingsErr); } }); } function updateVotePoints(user,follower,subscriber) { streamerSettingsErrReset(); fetch("/api/updateVotePoints", { method: 'POST', body: new URLSearchParams({ user: user, follower: follower, subscriber: subscriber })}) .then(response => { if (response.ok) { location.reload(); } else { response.text().then(streamerSettingsErr); } }); } updateTable(); document.addEventListener("keydown", function onEvent(event) { if (event.key === "Escape") { closeAllModals(); } }); document.getElementById("modalBackground").addEventListener("click", (e) => { if (e.target === e.currentTarget) closeAllModals();}); var updateRequestStateSelect = document.getElementById("updateRequestStateSelect"); for(state of validStates) { var opt = document.createElement("option"); opt.text = state; opt.value = state; updateRequestStateSelect.add(opt); } function toggleSortDir() { if (window.sortDir == "desc") { document.getElementById("sortDir").innerText = "↑"; window.sortDir = "asc"; } else { document.getElementById("sortDir").innerText = "↓"; window.sortDir = "desc"; } updateTable(); }