Implement addRequest in UI
- addRequest modal - Error box inside addRequest modal - Generic message modal - URL validation - same code as server - Update /api/addRequest to get requester from session - Fix return of requests.addRequest() for already requested - Make requests.addRequest() return 201 when createdmaster
parent
e54db3c4eb
commit
bf89c6956d
|
@ -34,18 +34,75 @@ function updateTable() {
|
||||||
getRequests(count,allRequests);
|
getRequests(count,allRequests);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 showMessage(msg) {
|
||||||
|
document.getElementById("messageModalText").innerText = msg;
|
||||||
|
document.getElementById("modalBackground").style.display = "flex";
|
||||||
|
document.getElementById("messageModal").style.display = "block";
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeMessageModal() {
|
||||||
|
document.getElementById("modalBackground").style.display = "none";
|
||||||
|
document.getElementById("messageModal").style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
function openAddRequestModal() {
|
function openAddRequestModal() {
|
||||||
document.getElementById("addRequestModalBackground").style.display = "flex";
|
document.getElementById("modalBackground").style.display = "flex";
|
||||||
|
document.getElementById("addRequestModal").style.display = "block";
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeAddRequestModal() {
|
function closeAddRequestModal() {
|
||||||
document.getElementById("addRequestModalBackground").style.display = "none";
|
document.getElementById("modalBackground").style.display = "none";
|
||||||
|
document.getElementById("addRequestModal").style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
const validUrlRegexes = [
|
||||||
|
/^https:\/\/www\.youtube\.com\/watch\?v=[a-zA-Z0-9_-]{11}$/
|
||||||
|
];
|
||||||
|
function validateAndSubmitRequest() {
|
||||||
|
addRequestErrReset();
|
||||||
|
var url = 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 => {
|
||||||
|
if (!response.ok) {
|
||||||
|
response.text().then(addRequestErr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
closeAddRequestModal();
|
||||||
|
updateTable();
|
||||||
|
document.getElementById("addRequestUrl").value = "";
|
||||||
|
response.text().then(showMessage);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTable();
|
updateTable();
|
||||||
|
|
||||||
document.addEventListener("keydown", function onEvent(event) {
|
document.addEventListener("keydown", function onEvent(event) {
|
||||||
if (event.key === "Escape") {
|
if (event.key === "Escape") {
|
||||||
|
closeMessageModal();
|
||||||
closeAddRequestModal();
|
closeAddRequestModal();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
document.getElementById("modalBackground").addEventListener("click", (e) => { if (e.target === e.currentTarget) closeAddRequestModal();});
|
||||||
|
|
|
@ -14,6 +14,13 @@ a:hover {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
|
margin: 1em;
|
||||||
|
display: none;
|
||||||
|
background-color: #f00c;
|
||||||
|
}
|
||||||
|
|
||||||
#topbar {
|
#topbar {
|
||||||
padding: 0.25em 0.5em;
|
padding: 0.25em 0.5em;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -84,9 +91,11 @@ div#nav-userpic {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
#addRequestModalBackground {
|
#modalBackground {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -94,11 +103,10 @@ div#nav-userpic {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
background-color: #444a;
|
background-color: #444a;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#addRequestModal {
|
.modal {
|
||||||
|
display: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
margin: 2em;
|
margin: 2em;
|
||||||
|
@ -108,11 +116,12 @@ div#nav-userpic {
|
||||||
box-shadow: 0px 5px 20px black;
|
box-shadow: 0px 5px 20px black;
|
||||||
}
|
}
|
||||||
|
|
||||||
#addRequestModal h1 {
|
.modal h1 {
|
||||||
margin-top: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#addRequestInputContainer {
|
#addRequestInputContainer {
|
||||||
|
margin-top: 1em;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
@ -123,13 +132,13 @@ div#nav-userpic {
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#addRequestModalClose {
|
.modalClose {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0.5em;
|
right: 0.5em;
|
||||||
font-size: 150%;
|
font-size: 150%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#addRequestModalClose a {
|
.modalClose a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
12
src/app.ts
12
src/app.ts
|
@ -38,18 +38,18 @@ app.get("/api/getAllRequests", async (request, response) => {
|
||||||
|
|
||||||
app.post("/api/addRequest", async (request, response) => {
|
app.post("/api/addRequest", async (request, response) => {
|
||||||
response.type('text/plain');
|
response.type('text/plain');
|
||||||
|
if (!request.session || !request.session.user) {
|
||||||
|
response.status(401);
|
||||||
|
response.send("Must be logged in");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!request.body.url) {
|
if (!request.body.url) {
|
||||||
response.status(400);
|
response.status(400);
|
||||||
response.send("Missing url");
|
response.send("Missing url");
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!request.body.requester) {
|
|
||||||
response.status(400);
|
|
||||||
response.send("Missing requester");
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var url = request.body.url as string;
|
var url = request.body.url as string;
|
||||||
var requester = request.body.requester as string;
|
var requester = request.session.user.display_name;
|
||||||
requests.addRequest(url,requester).then((val: [number,string]) => {
|
requests.addRequest(url,requester).then((val: [number,string]) => {
|
||||||
response.status(val[0]);
|
response.status(val[0]);
|
||||||
response.send(val[1]);
|
response.send(val[1]);
|
||||||
|
|
|
@ -52,11 +52,11 @@ export async function addRequest(url: string, requester: string) {
|
||||||
var query = Object.assign(checkRequestExistsQuery, { values: [url] });
|
var query = Object.assign(checkRequestExistsQuery, { values: [url] });
|
||||||
var result = await db.query(query);
|
var result = await db.query(query);
|
||||||
if (result.rowCount > 0) {
|
if (result.rowCount > 0) {
|
||||||
return `Song already requested by ${result.rows[0].requester}. State: ${result.rows[0].state}`
|
return [200,`Song already requested by ${result.rows[0].requester}. State: ${result.rows[0].state}`]
|
||||||
}
|
}
|
||||||
var query = Object.assign(addRequestQuery, { values: [url,requester] });
|
var query = Object.assign(addRequestQuery, { values: [url,requester] });
|
||||||
return db.query(query)
|
return db.query(query)
|
||||||
.then((result: pg.QueryResult) => [200,"Song request added."]);
|
.then((result: pg.QueryResult) => [201,"Song request added."]);
|
||||||
};
|
};
|
||||||
|
|
||||||
// updateRequestState
|
// updateRequestState
|
||||||
|
|
|
@ -30,10 +30,15 @@
|
||||||
</select>
|
</select>
|
||||||
<input type="checkbox" id="allRequests" onchange="updateTable()">View requests in any state</input>
|
<input type="checkbox" id="allRequests" onchange="updateTable()">View requests in any state</input>
|
||||||
</div>
|
</div>
|
||||||
<div id="addRequestModalBackground" onclick="closeAddRequestModal()">
|
<div id="modalBackground">
|
||||||
<div id="addRequestModal">
|
<div class="modal" id="messageModal">
|
||||||
<div id="addRequestModalClose"><a href="#" onclick="closeAddRequestModal()">×</a></div>
|
<div class="modalClose"><a href="#" onclick="closeMessageModal()">×</a></div>
|
||||||
|
<span id="messageModalText"></span>
|
||||||
|
</div>
|
||||||
|
<div class="modal" id="addRequestModal">
|
||||||
|
<div class="modalClose"><a href="#" onclick="closeAddRequestModal()">×</a></div>
|
||||||
<h1>Add Request</h1>
|
<h1>Add Request</h1>
|
||||||
|
<div class="error" id="addRequestError"></div>
|
||||||
<span id="addRequestInputContainer">
|
<span id="addRequestInputContainer">
|
||||||
URL: <input id="addRequestUrl" placeholder="https://www.youtube.com/watch?v=dQw4w9WgXcQ"></input>
|
URL: <input id="addRequestUrl" placeholder="https://www.youtube.com/watch?v=dQw4w9WgXcQ"></input>
|
||||||
<button onclick="validateAndSubmitRequest()">Request</button><br>
|
<button onclick="validateAndSubmitRequest()">Request</button><br>
|
||||||
|
@ -43,4 +48,3 @@
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue