Clean up JavaScript code and make it more reliable

Update version
This commit is contained in:
Michał Gdula 2023-03-30 15:51:06 +00:00
parent 95a116ef50
commit c2e42e7179
14 changed files with 446 additions and 365 deletions

View file

@ -1,14 +1,43 @@
// Function to show login
function showLogin() {
// Create elements
cancelBtn = document.createElement('button');
cancelBtn.classList.add('btn-block');
cancelBtn.innerHTML = 'nuuuuuuuu';
cancelBtn.onclick = popupDissmiss;
loginBtn = document.createElement('button');
loginBtn.classList.add('btn-block');
loginBtn.classList.add('primary');
loginBtn.innerHTML = 'Login';
loginBtn.type = 'submit';
loginBtn.setAttribute('form', 'loginForm');
// Create form
loginForm = document.createElement('form');
loginForm.id = 'loginForm';
loginForm.setAttribute('onsubmit', 'return login(event);');
usernameInput = document.createElement('input');
usernameInput.classList.add('input-block');
usernameInput.type = 'text';
usernameInput.placeholder = 'Namey';
usernameInput.id = 'username';
passwordInput = document.createElement('input');
passwordInput.classList.add('input-block');
passwordInput.type = 'password';
passwordInput.placeholder = 'Passywassy';
passwordInput.id = 'password';
loginForm.appendChild(usernameInput);
loginForm.appendChild(passwordInput);
popUpShow(
'Login!',
'Need an account? <span class="link" onclick="showRegister()">Register!</span>',
'<button class="btn-block" onclick="popupDissmiss()">Cancelee</button>' +
'<button class="btn-block primary" form="loginForm" type="submit">Login</button>',
'<form id="loginForm" onsubmit="return login(event)">' +
'<input class="input-block" type="text" placeholder="Namey" id="username"/>' +
'<input class="input-block" type="password" placeholder="Passywassy" id="password"/>' +
'</form>'
loginForm,
[cancelBtn, loginBtn]
);
}
// Function to login
@ -29,16 +58,13 @@ function login(event) {
formData.append("username", formUsername);
formData.append("password", formPassword);
$.ajax({
url: '/auth/login',
type: 'post',
data: formData,
contentType: false,
processData: false,
success: function (response) {
fetch('/auth/login', {
method: 'POST',
body: formData
}).then(response => {
if (response.status === 200) {
location.reload();
},
error: function (response) {
} else {
switch (response.status) {
case 500:
addNotification('Server exploded, F\'s in chat', 2);
@ -51,25 +77,68 @@ function login(event) {
break;
}
}
}).catch(error => {
addNotification('Error logging in, blame someone', 2);
});
}
// Function to show register
function showRegister() {
// Create buttons
cancelBtn = document.createElement('button');
cancelBtn.classList.add('btn-block');
cancelBtn.innerHTML = 'nuuuuuuuu';
cancelBtn.onclick = popupDissmiss;
registerBtn = document.createElement('button');
registerBtn.classList.add('btn-block');
registerBtn.classList.add('primary');
registerBtn.innerHTML = 'Register';
registerBtn.type = 'submit';
registerBtn.setAttribute('form', 'registerForm');
// Create form
registerForm = document.createElement('form');
registerForm.id = 'registerForm';
registerForm.setAttribute('onsubmit', 'return register(event);');
usernameInput = document.createElement('input');
usernameInput.classList.add('input-block');
usernameInput.type = 'text';
usernameInput.placeholder = 'Namey';
usernameInput.id = 'username';
emailInput = document.createElement('input');
emailInput.classList.add('input-block');
emailInput.type = 'text';
emailInput.placeholder = 'E mail!';
emailInput.id = 'email';
passwordInput = document.createElement('input');
passwordInput.classList.add('input-block');
passwordInput.type = 'password';
passwordInput.placeholder = 'Passywassy';
passwordInput.id = 'password';
passwordInputRepeat = document.createElement('input');
passwordInputRepeat.classList.add('input-block');
passwordInputRepeat.type = 'password';
passwordInputRepeat.placeholder = 'Passywassy again!';
passwordInputRepeat.id = 'password-repeat';
registerForm.appendChild(usernameInput);
registerForm.appendChild(emailInput);
registerForm.appendChild(passwordInput);
registerForm.appendChild(passwordInputRepeat);
popUpShow(
'Who are you?',
'Already have an account? <span class="link" onclick="showLogin()">Login!</span>',
'<button class="btn-block" onclick="popupDissmiss()">Canceleee</button>\
<button class="btn-block primary" form="registerForm" type="submit">Register</button>',
'<form id="registerForm" onsubmit="return register(event)">\
<input class="input-block" type="text" placeholder="Namey" id="username"/>\
<input class="input-block" type="text" placeholder="E mail!" id="email"/>\
<input class="input-block" type="password" placeholder="Passywassy" id="password"/>\
<input class="input-block" type="password" placeholder="Passywassy again!" id="password-repeat"/>\
</form>'
registerForm,
[cancelBtn, registerBtn]
);
}
// Function to register
function register(obj) {
function register(event) {
// AJAX takes control of subby form
event.preventDefault();
@ -90,13 +159,12 @@ function register(obj) {
formData.append("password", formPassword);
formData.append("password-repeat", formPasswordRepeat);
$.ajax({
url: '/auth/register',
type: 'post',
data: formData,
contentType: false,
processData: false,
success: function (response) {
// Send form to server
fetch('/auth/login', {
method: 'POST',
body: formData
}).then(response => {
if (response.status === 200) {
if (response === "gwa gwa") {
addNotification('Registered successfully! Now please login to continue', 1);
showLogin();
@ -105,19 +173,20 @@ function register(obj) {
addNotification(response[i], 2);
}
}
},
error: function (response) {
} else {
switch (response.status) {
case 500:
addNotification('Server exploded, F\'s in chat', 2);
break;
case 403:
addNotification('None but devils play past here...', 2);
addNotification('None but devils play past here... Wrong information', 2);
break;
default:
addNotification('Error logging in, blame someone', 2);
break;
}
}
}).catch(error => {
addNotification('Error logging in, blame someone', 2);
});
}

View file

@ -2,34 +2,6 @@
function imgFade(obj, time = 250) {
$(obj).animate({ opacity: 1 }, time);
}
// https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
function colourContrast(bgColor, lightColor, darkColor, threshold = 0.179) {
// if color is in hex format then convert to rgb else parese rgb
let r = 0
let g = 0
let b = 0
if (bgColor.charAt(0) === '#') {
const color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor;
r = parseInt(color.substring(0, 2), 16); // hexToR
g = parseInt(color.substring(2, 4), 16); // hexToG
b = parseInt(color.substring(4, 6), 16); // hexToB
} else {
const color = bgColor.replace('rgb(', '').replace(')', '').split(',');
r = color[0];
g = color[1];
b = color[2];
}
const uicolors = [r / 255, g / 255, b / 255];
const c = uicolors.map((col) => {
if (col <= 0.03928) {
return col / 12.92;
}
return Math.pow((col + 0.055) / 1.055, 2.4);
});
const L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]);
return (L > threshold) ? darkColor : lightColor;
}
// Lazy load images when they are in view
function loadOnView() {
let lazyLoad = document.querySelectorAll('#lazy-load');
@ -47,14 +19,6 @@ function loadOnView() {
window.onload = function () {
loadOnView();
const darkColor = 'rgb(var(--black))';
const lightColor = 'rgb(var(--white))';
let contrastCheck = document.querySelectorAll('#contrast-check');
for (let i = 0; i < contrastCheck.length; i++) {
let bgColor = contrastCheck[i].getAttribute('data-color');
contrastCheck[i].style.color = colourContrast(bgColor, lightColor, darkColor);
}
let times = document.querySelectorAll('.time');
for (let i = 0; i < times.length; i++) {
// Remove milliseconds
@ -97,9 +61,10 @@ window.onload = function () {
}
infoButton.onclick = function () {
popUpShow('OnlyLegs on Flask',
'Using <a href="https://phosphoricons.com/">Phosphoricons</a> and <a href="https://www.gent.media/manrope">Manrope</a> <br>' +
'Using <a href="https://phosphoricons.com/">Phosphoricons</a> and ' +
'<a href="https://www.gent.media/manrope">Manrope</a> <br>' +
'Made by Fluffy and others with ❤️ <br>' +
'<a href="https://github.com/Fluffy-Bean/onlylegs">V23.03.26</a>');
'<a href="https://github.com/Fluffy-Bean/onlylegs">V23.03.30</a>');
}
}
};

View file

@ -1,67 +1,69 @@
function addNotification(text='Sample notification', type=4) {
let container = document.querySelector('.notifications');
function addNotification(notificationText, notificationLevel) {
let notificationContainer = document.querySelector('.notifications');
// Set the different icons for the different notification levels
let successIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z"></path></svg>';
let criticalIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM222.93,203.8a8.5,8.5,0,0,1-7.48,4.2H40.55a8.5,8.5,0,0,1-7.48-4.2,7.59,7.59,0,0,1,0-7.72L120.52,44.21a8.75,8.75,0,0,1,15,0l87.45,151.87A7.59,7.59,0,0,1,222.93,203.8ZM120,144V104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,180Z"></path></svg>';
let warningIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path></svg>';
let infoIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path></svg>';
// Create notification element
let div = document.createElement('div');
div.classList.add('sniffle__notification');
div.onclick = function() {
if (div.parentNode) {
div.classList.add('hide');
let notification = document.createElement('div');
notification.classList.add('sniffle__notification');
notification.onclick = function() {
if (notification) {
notification.classList.add('hide');
setTimeout(function() {
container.removeChild(div);
notificationContainer.removeChild(notification);
}, 500);
}
};
// Create icon element and append to notification
let icon = document.createElement('span');
icon.classList.add('sniffle__notification-icon');
switch (type) {
case 1:
div.classList.add('success');
icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z"></path></svg>';
break;
case 2:
div.classList.add('critical');
icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM222.93,203.8a8.5,8.5,0,0,1-7.48,4.2H40.55a8.5,8.5,0,0,1-7.48-4.2,7.59,7.59,0,0,1,0-7.72L120.52,44.21a8.75,8.75,0,0,1,15,0l87.45,151.87A7.59,7.59,0,0,1,222.93,203.8ZM120,144V104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,180Z"></path></svg>';
break;
case 3:
div.classList.add('warning');
icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM222.93,203.8a8.5,8.5,0,0,1-7.48,4.2H40.55a8.5,8.5,0,0,1-7.48-4.2,7.59,7.59,0,0,1,0-7.72L120.52,44.21a8.75,8.75,0,0,1,15,0l87.45,151.87A7.59,7.59,0,0,1,222.93,203.8ZM120,144V104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,180Z"></path></svg>';
break;
default:
div.classList.add('info');
icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path></svg>';
break;
let iconElement = document.createElement('span');
iconElement.classList.add('sniffle__notification-icon');
notification.appendChild(iconElement);
// Set the icon based on the notification level, not pretty but it works :3
if (notificationLevel == 1) {
notification.classList.add('success');
iconElement.innerHTML = successIcon;
} else if (notificationLevel == 2) {
notification.classList.add('critical');
iconElement.innerHTML = criticalIcon;
} else if (notificationLevel == 3) {
notification.classList.add('warning');
iconElement.innerHTML = warningIcon;
} else {
notification.classList.add('info');
iconElement.innerHTML = infoIcon;
}
div.appendChild(icon);
// Create text element and append to notification
let description = document.createElement('span');
description.classList.add('sniffle__notification-text');
description.innerHTML = text;
div.appendChild(description);
description.innerHTML = notificationText;
notification.appendChild(description);
// Create span to show time remaining
let timer = document.createElement('span');
timer.classList.add('sniffle__notification-time');
div.appendChild(timer);
notification.appendChild(timer);
// Append notification to container
container.appendChild(div);
setTimeout(function() {
div.classList.add('show');
}, 100);
notificationContainer.appendChild(notification);
setTimeout(function() { notification.classList.add('show'); }, 5);
// Remove notification after 5 seconds
setTimeout(function() {
if (div.parentNode) {
div.classList.add('hide');
if (notification) {
notification.classList.add('hide');
setTimeout(function() {
container.removeChild(div);
notificationContainer.removeChild(notification);
}, 500);
}
}, 5000);
}
}
// uwu

View file

@ -1,42 +1,47 @@
function popUpShow(title, body, actions='<button class="btn-block" onclick="popupDissmiss()">Close</button>', content='') {
// Stop scrolling
document.querySelector("html").style.overflow = "hidden";
function popUpShow(titleText, subtitleText, bodyContent=null, userActions=null) {
// Get popup elements
let popup = document.querySelector('.pop-up');
let popupContent = document.querySelector('.pop-up-content');
let popupActions = document.querySelector('.pop-up-controlls');
// Set popup content
popupContent.innerHTML = `<h3>${title}</h3><p>${body}</p>${content}`;
let popupSelector = document.querySelector('.pop-up');
let headerSelector = document.querySelector('.pop-up-header');
let actionsSelector = document.querySelector('.pop-up-controlls');
// Clear popup elements
headerSelector.innerHTML = '';
actionsSelector.innerHTML = '';
// Set popup header and subtitle
let titleElement = document.createElement('h2');
titleElement.innerHTML = titleText;
headerSelector.appendChild(titleElement);
let subtitleElement = document.createElement('p');
subtitleElement.innerHTML = subtitleText;
headerSelector.appendChild(subtitleElement);
if (bodyContent) {
headerSelector.appendChild(bodyContent);
}
// Set buttons that will be displayed
popupActions.innerHTML = actions;
if (userActions) {
// for each user action, add the element
for (let i = 0; i < userActions.length; i++) {
let action = userActions[i];
actionsSelector.appendChild(action);
}
} else {
actionsSelector.innerHTML = '<button class="btn-block" onclick="popupDissmiss()">Close</button>';
}
// Show popup
popup.style.display = 'block';
setTimeout(function() {
popup.classList.add('active')
}, 10);
// Stop scrolling and show popup
document.querySelector("html").style.overflow = "hidden";
popupSelector.style.display = 'block';
setTimeout(function() { popupSelector.classList.add('active') }, 5); // 2ms delay to allow for css transition >:C
}
function popupDissmiss() {
// un-Stop scrolling
let popupSelector = document.querySelector('.pop-up');
document.querySelector("html").style.overflow = "auto";
let popup = document.querySelector('.pop-up');
popup.classList.remove('active');
setTimeout(function() {
popup.style.display = 'none';
}, 200);
popupSelector.classList.remove('active');
setTimeout(function() { popupSelector.style.display = 'none'; }, 200);
}
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
if (document.querySelector('.pop-up').classList.contains('active')) {
popupDissmiss();
}
}
});

View file

@ -1,196 +1,227 @@
window.addEventListener("dragover",(event) => {
event.preventDefault();
},false);
window.addEventListener("drop",(event) => {
event.preventDefault();
},false);
// Remove default events on file drop, otherwise the browser will open the file
window.addEventListener("dragover", (event) => {
event.preventDefault();
}, false);
window.addEventListener("drop", (event) => {
event.preventDefault();
}, false);
function fileChanged(obj) {
document.querySelector('.fileDrop-block').classList.remove('error');
if ($(obj).val() === '') {
document.querySelector('.fileDrop-block').classList.remove('active');
document.querySelector('.fileDrop-block .status').innerHTML = 'Choose or Drop file';
} else {
document.querySelector('.fileDrop-block').classList.add('active');
document.querySelector('.fileDrop-block .status').innerHTML = obj.files[0].name;
}
}
document.addEventListener('DOMContentLoaded', function() {
// Function to upload images
const uploadForm = document.querySelector('#uploadForm');
const fileDrop = document.querySelector('.fileDrop-block');
const fileDropTitle = fileDrop.querySelector('.status');
const fileUpload = uploadForm.querySelector('#file');
$(fileUpload).val('');
// Choose or drop file button
['dragover', 'dragenter'].forEach(eventName => {
fileDrop.addEventListener(eventName, fileActivate, false);
});
['dragleave', 'drop'].forEach(eventName => {
fileDrop.addEventListener(eventName, fileDefault, false);
})
// Drop file into box
fileDrop.addEventListener('drop', fileDropHandle, false);
// Edging the file plunge :3
function fileActivate(event) {
fileDrop.classList.remove('error');
fileDrop.classList.add('edging');
fileDropTitle.innerHTML = 'Drop to upload!';
}
function fileDefault(event) {
fileDrop.classList.remove('error');
fileDrop.classList.remove('edging');
fileDropTitle.innerHTML = 'Choose or Drop file';
}
function fileDropHandle(event) {
event.preventDefault()
fileUpload.files = event.dataTransfer.files;
fileDropTitle.innerHTML = fileUpload.files[0].name;
fileDrop.classList.add('active');
}
uploadForm.addEventListener('submit', (event) => {
// AJAX takes control of subby form
event.preventDefault()
const jobList = document.querySelector(".upload-jobs");
// Check for empty upload
if ($(fileUpload).val() === '') {
fileDrop.classList.add('error');
fileDropTitle.innerHTML = 'No file selected!';
} else {
// Make form
let formData = new FormData();
formData.append("file", $("#file").prop("files")[0]);
formData.append("alt", $("#alt").val());
formData.append("description", $("#description").val());
formData.append("tags", $("#tags").val());
formData.append("submit", $("#submit").val());
// Upload the information
$.ajax({
url: '/api/upload',
type: 'post',
data: formData,
contentType: false,
processData: false,
beforeSend: function () {
jobContainer = document.createElement("div");
jobContainer.classList.add("job");
jobStatus = document.createElement("span");
jobStatus.classList.add("job__status");
jobStatus.innerHTML = "Uploading...";
jobProgress = document.createElement("span");
jobProgress.classList.add("progress");
jobImg = document.createElement("img");
jobImg.src = URL.createObjectURL($("#file").prop("files")[0]);
jobImgFilter = document.createElement("span");
jobImgFilter.classList.add("img-filter");
jobContainer.appendChild(jobStatus);
jobContainer.appendChild(jobProgress);
jobContainer.appendChild(jobImg);
jobContainer.appendChild(jobImgFilter);
jobList.appendChild(jobContainer);
},
success: function (response) {
jobContainer.classList.add("success");
jobStatus.innerHTML = "Uploaded!";
if (!document.querySelector(".upload-panel").classList.contains("open")) {
addNotification("Image uploaded successfully", 1);
}
},
error: function (response) {
jobContainer.classList.add("critical");
switch (response.status) {
case 500:
jobStatus.innerHTML = "Server exploded, F's in chat";
break;
case 400:
case 404:
jobStatus.innerHTML = "Error uploading. Blame yourself";
break;
case 403:
jobStatus.innerHTML = "None but devils play past here...";
break;
case 413:
jobStatus.innerHTML = "File too large!!!!!!";
break;
default:
jobStatus.innerHTML = "Error uploading file, blame someone";
break;
}
if (!document.querySelector(".upload-panel").classList.contains("open")) {
addNotification("Error uploading file", 2);
}
},
});
// Empty values
$(fileUpload).val('');
$("#alt").val('');
$("#description").val('');
$("#tags").val('');
// Reset drop
fileDrop.classList.remove('active');
fileDropTitle.innerHTML = 'Choose or Drop file';
}
});
});
// open upload tab
function openUploadTab() {
// Stop scrolling
let uploadTab = document.querySelector(".upload-panel");
// Stop scrolling and open upload tab
document.querySelector("html").style.overflow = "hidden";
document.querySelector(".content").tabIndex = "-1";
// Open upload tab
const uploadTab = document.querySelector(".upload-panel");
uploadTab.style.display = "block";
setTimeout(function () {
uploadTab.classList.add("open");
}, 10);
setTimeout(function () { uploadTab.classList.add("open"); }, 5);
}
// close upload tab
function closeUploadTab() {
// un-Stop scrolling
let uploadTab = document.querySelector(".upload-panel");
// un-Stop scrolling and close upload tab
document.querySelector("html").style.overflow = "auto";
document.querySelector(".content").tabIndex = "";
// Close upload tab
const uploadTab = document.querySelector(".upload-panel");
uploadTab.classList.remove("open");
setTimeout(function () {
uploadTab.style.display = "none";
}, 250);
setTimeout(function () { uploadTab.style.display = "none"; }, 250);
}
// toggle upload tab
function toggleUploadTab() {
if (document.querySelector(".upload-panel").classList.contains("open")) {
let uploadTab = document.querySelector(".upload-panel");
if (uploadTab.classList.contains("open")) {
closeUploadTab();
} else {
openUploadTab();
}
}
// Edging the file plunge :3
function fileActivate(event) {
event.preventDefault()
let fileDrop = document.querySelector('.fileDrop-block');
let fileDropTitle = fileDrop.querySelector('.status');
fileDrop.classList.remove('error');
fileDrop.classList.add('edging');
fileDropTitle.innerHTML = 'Drop to upload!';
}
function fileDefault() {
let fileDrop = document.querySelector('.fileDrop-block');
let fileDropTitle = fileDrop.querySelector('.status');
fileDrop.classList.remove('error');
fileDrop.classList.remove('edging');
fileDropTitle.innerHTML = 'Choose or Drop file';
}
function fileDropHandle(event) {
event.preventDefault()
let fileDrop = document.querySelector('.fileDrop-block');
let fileUpload = fileDrop.querySelector('#file');
fileUpload.files = event.dataTransfer.files;
fileChanged();
}
function fileChanged() {
let dropBlock = document.querySelector('.fileDrop-block');
let dropBlockStatus = dropBlock.querySelector('.status');
let dropBlockInput = dropBlock.querySelector('#file');
if (dropBlockInput.value !== "") {
dropBlock.classList.add('active');
dropBlockStatus.innerHTML = dropBlockInput.files[0].name;
} else {
fileDefault();
}
}
function clearUpload() {
let fileDrop = document.querySelector('#uploadForm');
let fileUpload = fileDrop.querySelector('#file');
let fileAlt = fileDrop.querySelector('#alt');
let fileDescription = fileDrop.querySelector('#description');
let fileTags = fileDrop.querySelector('#tags');
fileUpload.value = "";
fileAlt.value = "";
fileDescription.value = "";
fileTags.value = "";
}
function createJon(file) {
jobContainer = document.createElement("div");
jobContainer.classList.add("job");
jobStatus = document.createElement("span");
jobStatus.classList.add("job__status");
jobStatus.innerHTML = "Uploading...";
jobProgress = document.createElement("span");
jobProgress.classList.add("progress");
jobImg = document.createElement("img");
jobImg.src = URL.createObjectURL(file);
jobImgFilter = document.createElement("span");
jobImgFilter.classList.add("img-filter");
jobContainer.appendChild(jobStatus);
jobContainer.appendChild(jobProgress);
jobContainer.appendChild(jobImg);
jobContainer.appendChild(jobImgFilter);
return jobContainer;
}
document.addEventListener('DOMContentLoaded', function() {
// Function to upload images
let uploadForm = document.querySelector('#uploadForm');
let fileDrop = document.querySelector('.fileDrop-block');
let fileDropTitle = fileDrop.querySelector('.status');
let jobList = document.querySelector(".upload-jobs");
let fileUpload = uploadForm.querySelector('#file');
let fileAlt = uploadForm.querySelector('#alt');
let fileDescription = uploadForm.querySelector('#description');
let fileTags = uploadForm.querySelector('#tags');
clearUpload();
fileDefault();
// Drag over/enter event
fileDrop.addEventListener('dragover', fileActivate, false);
fileDrop.addEventListener('dragenter', fileActivate, false);
// Drag out
fileDrop.addEventListener('dragleave', fileDefault, false);
// Drop file into box
fileDrop.addEventListener('drop', fileDropHandle, false);
// File upload change
fileUpload.addEventListener('change', fileChanged, false);
// Submit form
uploadForm.addEventListener('submit', (event) => {
// AJAX takes control of subby form
event.preventDefault()
if (fileUpload.value === "") {
fileDrop.classList.add('error');
fileDropTitle.innerHTML = 'No file selected!';
// Stop the function
return;
}
// Make form
let formData = new FormData();
formData.append("file", fileUpload.files[0]);
formData.append("alt", fileAlt.value);
formData.append("description", fileDescription.value);
formData.append("tags", fileTags.value);
jobItem = createJon(fileUpload.files[0]);
jobStatus = jobItem.querySelector(".job__status");
// Upload the information
$.ajax({
url: '/api/upload',
type: 'post',
data: formData,
contentType: false,
processData: false,
beforeSend: function () {
// Add job to list
jobList.appendChild(jobItem);
},
success: function (response) {
jobItem.classList.add("success");
jobStatus.innerHTML = "Uploaded successfully";
if (!document.querySelector(".upload-panel").classList.contains("open")) {
addNotification("Image uploaded successfully", 1);
}
},
error: function (response) {
jobItem.classList.add("critical");
switch (response.status) {
case 500:
jobStatus.innerHTML = "Server exploded, F's in chat";
break;
case 400:
case 404:
jobStatus.innerHTML = "Error uploading. Blame yourself";
break;
case 403:
jobStatus.innerHTML = "None but devils play past here...";
break;
case 413:
jobStatus.innerHTML = "File too large!!!!!!";
break;
default:
jobStatus.innerHTML = "Error uploading file, blame someone";
break;
}
if (!document.querySelector(".upload-panel").classList.contains("open")) {
addNotification("Error uploading file", 2);
}
},
});
clearUpload();
// Reset drop
fileDrop.classList.remove('active');
fileDropTitle.innerHTML = 'Choose or Drop file';
});
});

View file

@ -16,15 +16,13 @@
}, 200);
}
function imageFullscreenOn() {
document.querySelector("html").style.overflow = "hidden";
let fullscreen = document.querySelector('.image-fullscreen')
fullscreen.querySelector('img').src = '{{ url_for('api.file', file_name=image.file_name) }}';
fullscreen.style.display = 'flex';
setTimeout(function() {
fullscreen.classList.add('active');
}, 10);
document.querySelector("html").style.overflow = "hidden";
fullscreen.style.display = 'flex';
setTimeout(function() { fullscreen.classList.add('active'); }, 5);
}
function imageShare() {
try {
@ -36,12 +34,23 @@
}
{% if g.user['id'] == image['author_id'] %}
cancelBtn = document.createElement('button');
cancelBtn.classList.add('btn-block');
cancelBtn.innerHTML = 'nuuuuuuuu';
cancelBtn.onclick = popupDissmiss;
deleteBtn = document.createElement('button');
deleteBtn.classList.add('btn-block');
deleteBtn.classList.add('critical');
deleteBtn.innerHTML = 'Dewww eeeet!';
deleteBtn.onclick = deleteConfirm;
function imageDelete() {
popUpShow(
'DESTRUCTION!!!!!!',
'Do you want to delete this image along with all of its data??? This action is irreversible!',
'<button class="btn-block" onclick="popupDissmiss()">Nuuu</button>' +
'<button class="btn-block critical" onclick="deleteConfirm()">Dewww eeeet!</button>'
null,
[cancelBtn, deleteBtn]
);
}
function deleteConfirm() {

View file

@ -34,7 +34,7 @@
{% endif %}
{% endblock %}
{% block script %}
<script>
<script type="text/javascript">
if (document.referrer.includes('image')) {
try {
let referrerId = document.referrer.split('/').pop();

View file

@ -41,20 +41,17 @@
<button class="top-of-page">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M184,216a8,8,0,0,1-8,8H80a8,8,0,0,1,0-16h96A8,8,0,0,1,184,216Zm45.66-101.66-96-96a8,8,0,0,0-11.32,0l-96,96A8,8,0,0,0,32,128H72v24a8,8,0,0,0,8,8h96a8,8,0,0,0,8-8V128h40a8,8,0,0,0,5.66-13.66ZM176,176H80a8,8,0,0,0,0,16h96a8,8,0,0,0,0-16Z"></path></svg>
</button>
<button class="info-button">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm-4,48a12,12,0,1,1-12,12A12,12,0,0,1,124,72Zm12,112a16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40a8,8,0,0,1,0,16Z"></path></svg>
</button>
{% if request.path == "/" %}
<button class="info-button">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm-4,48a12,12,0,1,1-12,12A12,12,0,0,1,124,72Zm12,112a16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40a8,8,0,0,1,0,16Z"></path></svg>
</button>
{% endif %}
<div class="pop-up">
<span class="pop-up__click-off" onclick="popupDissmiss()"></span>
<div class="pop-up-wrapper">
<div class="pop-up-content">
<h3>Title</h3>
<p>Very very very drawn out example description</p>
</div>
<div class="pop-up-controlls">
<button class="pop-up__btn" onclick="popupDissmiss()">Cancel</button>
</div>
<div class="pop-up-header"></div>
<div class="pop-up-controlls"></div>
</div>
</div>
@ -125,10 +122,10 @@
<h3>Upload stuffs</h3>
<p>May the world see your stuff 👀</p>
<form id="uploadForm">
<button class="fileDrop-block">
<button class="fileDrop-block" type="button">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M240,136v64a16,16,0,0,1-16,16H32a16,16,0,0,1-16-16V136a16,16,0,0,1,16-16H80a8,8,0,0,1,0,16H32v64H224V136H176a8,8,0,0,1,0-16h48A16,16,0,0,1,240,136ZM85.66,77.66,120,43.31V128a8,8,0,0,0,16,0V43.31l34.34,34.35a8,8,0,0,0,11.32-11.32l-48-48a8,8,0,0,0-11.32,0l-48,48A8,8,0,0,0,85.66,77.66ZM200,168a12,12,0,1,0-12,12A12,12,0,0,0,200,168Z"></path></svg>
<span class="status">Choose or Drop file</span>
<input type="file" id="file" onchange="fileChanged(this)" onclick="this.value=null; fileChanged(this)" tab-index="-1"/>
<input type="file" id="file" tab-index="-1"/>
</button>
<input class="input-block" type="text" placeholder="alt" id="alt"/>
@ -147,12 +144,13 @@
</div>
</div>
<script>
<script type="text/javascript">
// Show notifications on page load
{% for message in get_flashed_messages() %}
// Show notifications on page load
addNotification('{{ message[0] }}', {{ message[1] }});
{% endfor %}
</script>
{% block script %}{% endblock %}
</body>
</html>

View file

@ -120,12 +120,12 @@
width: calc(100vw - 0.6rem)
height: auto
.sniffle__notification
width: 100%
&.hide
opacity: 0
transform: translateY(-5rem)
.sniffle__notification
width: 100%
.sniffle__notification-time
width: 100%

View file

@ -38,14 +38,14 @@
display: flex
flex-direction: column
background-color: RGB($bg-100)
background-color: RGB($bg-200)
border-radius: $rad
overflow: hidden
z-index: +2
transition: transform 0.2s $animation-smooth
.pop-up-content
.pop-up-header
margin: 0
padding: 1rem
@ -61,7 +61,7 @@
text-size-adjust: auto
text-overflow: ellipsis
h3
h2, h3
margin: 0
width: 100%
@ -143,7 +143,7 @@
justify-content: flex-end
gap: 0.25rem
background-color: RGB($bg-200)
background-color: RGB($bg-100)
&.active
opacity: 1

View file

@ -125,7 +125,7 @@
height: calc(100% - 6px)
background-color: RGB($primary)
border-radius: $rad-inner
border-radius: 0 $rad-inner $rad-inner 0
@media (max-width: $breakpoint)
.navigation
@ -164,3 +164,5 @@
width: 100%
height: 3px
border-radius: $rad-inner