learn-request-queue/public/main.js

394 lines
12 KiB
JavaScript

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 += `<option value=${i}>${i}</option>`;
}
document.getElementById("page").value = currentPage;
var requestsDivHTML = '<table><tr><th class="request-link">Song Title</th><th class="request-requester">Requester</th><th class="request-score">Score</th>';
requestsDivHTML += '<th class="request-state">State</td>';
if (window.loggedIn) requestsDivHTML += '<th class="request-vote">Vote</td>';
if (window.isStreamer) requestsDivHTML += '<th class="request-update">Update</th>'
requestsDivHTML += "</tr>";
for (request of requests.requests) {
requestsDivHTML += `<tr><td class="request-link"><a href="${request.url}" target="_blank">${request.title}</a></td>\
<td class="request-requester">${request.imageurl ? `<img src="${request.imageurl}" class="table-userpic"/>` : ''}${request.requester}</td>\
<td class="request-score">${request.score}</td>`;
requestsDivHTML += `<td class="request-state">${request.state}</td>`;
if (window.loggedIn) {
if (request.voted) {
requestsDivHTML += `<td class="request-vote"><button onclick="deleteVote('${request.url}')">Unvote</button></td>`;
} else {
requestsDivHTML += `<td class="request-vote"><button onclick="addVote('${request.url}')">Vote</button></td>`;
}
if (window.isStreamer) {
requestsDivHTML += '<td class="request-update"><button onclick="openUpdateRequestModal(this.parentElement.parentElement)">Update</button></td>'
}
}
requestsDivHTML += "</tr>";
}
requestsDivHTML += "</table>";
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();
}