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

View file

@ -2,34 +2,6 @@
function imgFade(obj, time = 250) { function imgFade(obj, time = 250) {
$(obj).animate({ opacity: 1 }, time); $(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 // Lazy load images when they are in view
function loadOnView() { function loadOnView() {
let lazyLoad = document.querySelectorAll('#lazy-load'); let lazyLoad = document.querySelectorAll('#lazy-load');
@ -47,14 +19,6 @@ function loadOnView() {
window.onload = function () { window.onload = function () {
loadOnView(); 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'); let times = document.querySelectorAll('.time');
for (let i = 0; i < times.length; i++) { for (let i = 0; i < times.length; i++) {
// Remove milliseconds // Remove milliseconds
@ -97,9 +61,10 @@ window.onload = function () {
} }
infoButton.onclick = function () { infoButton.onclick = function () {
popUpShow('OnlyLegs on Flask', 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>' + '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) { function addNotification(notificationText, notificationLevel) {
let container = document.querySelector('.notifications'); 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 // Create notification element
let div = document.createElement('div'); let notification = document.createElement('div');
div.classList.add('sniffle__notification'); notification.classList.add('sniffle__notification');
div.onclick = function() { notification.onclick = function() {
if (div.parentNode) { if (notification) {
div.classList.add('hide'); notification.classList.add('hide');
setTimeout(function() { setTimeout(function() {
container.removeChild(div); notificationContainer.removeChild(notification);
}, 500); }, 500);
} }
}; };
// Create icon element and append to notification // Create icon element and append to notification
let icon = document.createElement('span'); let iconElement = document.createElement('span');
icon.classList.add('sniffle__notification-icon'); iconElement.classList.add('sniffle__notification-icon');
switch (type) { notification.appendChild(iconElement);
case 1: // Set the icon based on the notification level, not pretty but it works :3
div.classList.add('success'); if (notificationLevel == 1) {
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>'; notification.classList.add('success');
break; iconElement.innerHTML = successIcon;
case 2: } else if (notificationLevel == 2) {
div.classList.add('critical'); notification.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>'; iconElement.innerHTML = criticalIcon;
break; } else if (notificationLevel == 3) {
case 3: notification.classList.add('warning');
div.classList.add('warning'); iconElement.innerHTML = warningIcon;
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>'; } else {
break; notification.classList.add('info');
default: iconElement.innerHTML = infoIcon;
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;
} }
div.appendChild(icon);
// Create text element and append to notification // Create text element and append to notification
let description = document.createElement('span'); let description = document.createElement('span');
description.classList.add('sniffle__notification-text'); description.classList.add('sniffle__notification-text');
description.innerHTML = text; description.innerHTML = notificationText;
div.appendChild(description); notification.appendChild(description);
// Create span to show time remaining // Create span to show time remaining
let timer = document.createElement('span'); let timer = document.createElement('span');
timer.classList.add('sniffle__notification-time'); timer.classList.add('sniffle__notification-time');
div.appendChild(timer); notification.appendChild(timer);
// Append notification to container // Append notification to container
container.appendChild(div); notificationContainer.appendChild(notification);
setTimeout(function() { setTimeout(function() { notification.classList.add('show'); }, 5);
div.classList.add('show');
}, 100);
// Remove notification after 5 seconds // Remove notification after 5 seconds
setTimeout(function() { setTimeout(function() {
if (div.parentNode) { if (notification) {
div.classList.add('hide'); notification.classList.add('hide');
setTimeout(function() { setTimeout(function() {
container.removeChild(div); notificationContainer.removeChild(notification);
}, 500); }, 500);
} }
}, 5000); }, 5000);
} }
// uwu

View file

@ -1,42 +1,47 @@
function popUpShow(title, body, actions='<button class="btn-block" onclick="popupDissmiss()">Close</button>', content='') { function popUpShow(titleText, subtitleText, bodyContent=null, userActions=null) {
// Stop scrolling
document.querySelector("html").style.overflow = "hidden";
// Get popup elements // Get popup elements
let popup = document.querySelector('.pop-up'); let popupSelector = document.querySelector('.pop-up');
let popupContent = document.querySelector('.pop-up-content'); let headerSelector = document.querySelector('.pop-up-header');
let popupActions = document.querySelector('.pop-up-controlls'); let actionsSelector = document.querySelector('.pop-up-controlls');
// Set popup content // Clear popup elements
popupContent.innerHTML = `<h3>${title}</h3><p>${body}</p>${content}`; 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 // 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 // Stop scrolling and show popup
popup.style.display = 'block'; document.querySelector("html").style.overflow = "hidden";
setTimeout(function() { popupSelector.style.display = 'block';
popup.classList.add('active') setTimeout(function() { popupSelector.classList.add('active') }, 5); // 2ms delay to allow for css transition >:C
}, 10);
} }
function popupDissmiss() { function popupDissmiss() {
// un-Stop scrolling let popupSelector = document.querySelector('.pop-up');
document.querySelector("html").style.overflow = "auto"; document.querySelector("html").style.overflow = "auto";
popupSelector.classList.remove('active');
let popup = document.querySelector('.pop-up'); setTimeout(function() { popupSelector.style.display = 'none'; }, 200);
popup.classList.remove('active');
setTimeout(function() {
popup.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,3 +1,4 @@
// Remove default events on file drop, otherwise the browser will open the file
window.addEventListener("dragover", (event) => { window.addEventListener("dragover", (event) => {
event.preventDefault(); event.preventDefault();
}, false); }, false);
@ -5,48 +6,53 @@ window.addEventListener("drop",(event) => {
event.preventDefault(); event.preventDefault();
}, false); }, false);
function fileChanged(obj) {
document.querySelector('.fileDrop-block').classList.remove('error');
if ($(obj).val() === '') { // open upload tab
document.querySelector('.fileDrop-block').classList.remove('active'); function openUploadTab() {
document.querySelector('.fileDrop-block .status').innerHTML = 'Choose or Drop file'; let uploadTab = document.querySelector(".upload-panel");
// Stop scrolling and open upload tab
document.querySelector("html").style.overflow = "hidden";
uploadTab.style.display = "block";
setTimeout(function () { uploadTab.classList.add("open"); }, 5);
}
// close upload tab
function closeUploadTab() {
let uploadTab = document.querySelector(".upload-panel");
// un-Stop scrolling and close upload tab
document.querySelector("html").style.overflow = "auto";
uploadTab.classList.remove("open");
setTimeout(function () { uploadTab.style.display = "none"; }, 250);
}
// toggle upload tab
function toggleUploadTab() {
let uploadTab = document.querySelector(".upload-panel");
if (uploadTab.classList.contains("open")) {
closeUploadTab();
} else { } else {
document.querySelector('.fileDrop-block').classList.add('active'); openUploadTab();
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 // Edging the file plunge :3
function fileActivate(event) { function fileActivate(event) {
event.preventDefault()
let fileDrop = document.querySelector('.fileDrop-block');
let fileDropTitle = fileDrop.querySelector('.status');
fileDrop.classList.remove('error'); fileDrop.classList.remove('error');
fileDrop.classList.add('edging'); fileDrop.classList.add('edging');
fileDropTitle.innerHTML = 'Drop to upload!'; fileDropTitle.innerHTML = 'Drop to upload!';
} }
function fileDefault(event) { function fileDefault() {
let fileDrop = document.querySelector('.fileDrop-block');
let fileDropTitle = fileDrop.querySelector('.status');
fileDrop.classList.remove('error'); fileDrop.classList.remove('error');
fileDrop.classList.remove('edging'); fileDrop.classList.remove('edging');
fileDropTitle.innerHTML = 'Choose or Drop file'; fileDropTitle.innerHTML = 'Choose or Drop file';
@ -54,40 +60,44 @@ document.addEventListener('DOMContentLoaded', function() {
function fileDropHandle(event) { function fileDropHandle(event) {
event.preventDefault() event.preventDefault()
let fileDrop = document.querySelector('.fileDrop-block');
let fileUpload = fileDrop.querySelector('#file');
fileUpload.files = event.dataTransfer.files; fileUpload.files = event.dataTransfer.files;
fileDropTitle.innerHTML = fileUpload.files[0].name; fileChanged();
fileDrop.classList.add('active'); }
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 = "";
} }
uploadForm.addEventListener('submit', (event) => { function createJon(file) {
// 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 = document.createElement("div");
jobContainer.classList.add("job"); jobContainer.classList.add("job");
@ -99,7 +109,7 @@ document.addEventListener('DOMContentLoaded', function() {
jobProgress.classList.add("progress"); jobProgress.classList.add("progress");
jobImg = document.createElement("img"); jobImg = document.createElement("img");
jobImg.src = URL.createObjectURL($("#file").prop("files")[0]); jobImg.src = URL.createObjectURL(file);
jobImgFilter = document.createElement("span"); jobImgFilter = document.createElement("span");
jobImgFilter.classList.add("img-filter"); jobImgFilter.classList.add("img-filter");
@ -108,17 +118,82 @@ document.addEventListener('DOMContentLoaded', function() {
jobContainer.appendChild(jobProgress); jobContainer.appendChild(jobProgress);
jobContainer.appendChild(jobImg); jobContainer.appendChild(jobImg);
jobContainer.appendChild(jobImgFilter); jobContainer.appendChild(jobImgFilter);
jobList.appendChild(jobContainer);
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) { success: function (response) {
jobContainer.classList.add("success"); jobItem.classList.add("success");
jobStatus.innerHTML = "Uploaded!"; jobStatus.innerHTML = "Uploaded successfully";
if (!document.querySelector(".upload-panel").classList.contains("open")) { if (!document.querySelector(".upload-panel").classList.contains("open")) {
addNotification("Image uploaded successfully", 1); addNotification("Image uploaded successfully", 1);
} }
}, },
error: function (response) { error: function (response) {
jobContainer.classList.add("critical"); jobItem.classList.add("critical");
switch (response.status) { switch (response.status) {
case 500: case 500:
jobStatus.innerHTML = "Server exploded, F's in chat"; jobStatus.innerHTML = "Server exploded, F's in chat";
@ -143,54 +218,10 @@ document.addEventListener('DOMContentLoaded', function() {
}, },
}); });
// Empty values clearUpload();
$(fileUpload).val('');
$("#alt").val('');
$("#description").val('');
$("#tags").val('');
// Reset drop // Reset drop
fileDrop.classList.remove('active'); fileDrop.classList.remove('active');
fileDropTitle.innerHTML = 'Choose or Drop file'; fileDropTitle.innerHTML = 'Choose or Drop file';
}
}); });
}); });
// open upload tab
function openUploadTab() {
// Stop scrolling
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);
}
// close upload tab
function closeUploadTab() {
// un-Stop scrolling
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);
}
// toggle upload tab
function toggleUploadTab() {
if (document.querySelector(".upload-panel").classList.contains("open")) {
closeUploadTab();
} else {
openUploadTab();
}
}

View file

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

View file

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

View file

@ -41,20 +41,17 @@
<button class="top-of-page"> <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> <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>
{% if request.path == "/" %}
<button class="info-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> <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> </button>
{% endif %}
<div class="pop-up"> <div class="pop-up">
<span class="pop-up__click-off" onclick="popupDissmiss()"></span> <span class="pop-up__click-off" onclick="popupDissmiss()"></span>
<div class="pop-up-wrapper"> <div class="pop-up-wrapper">
<div class="pop-up-content"> <div class="pop-up-header"></div>
<h3>Title</h3> <div class="pop-up-controlls"></div>
<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> </div>
</div> </div>
@ -125,10 +122,10 @@
<h3>Upload stuffs</h3> <h3>Upload stuffs</h3>
<p>May the world see your stuff 👀</p> <p>May the world see your stuff 👀</p>
<form id="uploadForm"> <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> <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> <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> </button>
<input class="input-block" type="text" placeholder="alt" id="alt"/> <input class="input-block" type="text" placeholder="alt" id="alt"/>
@ -147,12 +144,13 @@
</div> </div>
</div> </div>
<script> <script type="text/javascript">
{% for message in get_flashed_messages() %}
// Show notifications on page load // Show notifications on page load
{% for message in get_flashed_messages() %}
addNotification('{{ message[0] }}', {{ message[1] }}); addNotification('{{ message[0] }}', {{ message[1] }});
{% endfor %} {% endfor %}
</script> </script>
{% block script %}{% endblock %} {% block script %}{% endblock %}
</body> </body>
</html> </html>

View file

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

View file

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

View file

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

28
poetry.lock generated
View file

@ -2,14 +2,14 @@
[[package]] [[package]]
name = "astroid" name = "astroid"
version = "2.15.0" version = "2.15.1"
description = "An abstract syntax tree for Python with inference support." description = "An abstract syntax tree for Python with inference support."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7.2" python-versions = ">=3.7.2"
files = [ files = [
{file = "astroid-2.15.0-py3-none-any.whl", hash = "sha256:e3e4d0ffc2d15d954065579689c36aac57a339a4679a679579af6401db4d3fdb"}, {file = "astroid-2.15.1-py3-none-any.whl", hash = "sha256:89860bda98fe2bbd1f5d262229be7629d778ce280de68d95d4a73d1f592ad268"},
{file = "astroid-2.15.0.tar.gz", hash = "sha256:525f126d5dc1b8b0b6ee398b33159105615d92dc4a17f2cd064125d57f6186fa"}, {file = "astroid-2.15.1.tar.gz", hash = "sha256:af4e0aff46e2868218502789898269ed95b663fba49e65d91c1e09c966266c34"},
] ]
[package.dependencies] [package.dependencies]
@ -641,19 +641,19 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa
[[package]] [[package]]
name = "platformdirs" name = "platformdirs"
version = "3.1.1" version = "3.2.0"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "platformdirs-3.1.1-py3-none-any.whl", hash = "sha256:e5986afb596e4bb5bde29a79ac9061aa955b94fca2399b7aaac4090860920dd8"}, {file = "platformdirs-3.2.0-py3-none-any.whl", hash = "sha256:ebe11c0d7a805086e99506aa331612429a72ca7cd52a1f0d277dc4adc20cb10e"},
{file = "platformdirs-3.1.1.tar.gz", hash = "sha256:024996549ee88ec1a9aa99ff7f8fc819bb59e2c3477b410d90a16d32d6e707aa"}, {file = "platformdirs-3.2.0.tar.gz", hash = "sha256:d5b638ca397f25f979350ff789db335903d7ea010ab28903f57b27e1b16c2b08"},
] ]
[package.extras] [package.extras]
docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
[[package]] [[package]]
name = "pylint" name = "pylint"
@ -752,14 +752,14 @@ files = [
[[package]] [[package]]
name = "setuptools" name = "setuptools"
version = "67.6.0" version = "67.6.1"
description = "Easily download, build, install, upgrade, and uninstall Python packages" description = "Easily download, build, install, upgrade, and uninstall Python packages"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "setuptools-67.6.0-py3-none-any.whl", hash = "sha256:b78aaa36f6b90a074c1fa651168723acbf45d14cb1196b6f02c0fd07f17623b2"}, {file = "setuptools-67.6.1-py3-none-any.whl", hash = "sha256:e728ca814a823bf7bf60162daf9db95b93d532948c4c0bea762ce62f60189078"},
{file = "setuptools-67.6.0.tar.gz", hash = "sha256:2ee892cd5f29f3373097f5a814697e397cf3ce313616df0af11231e2ad118077"}, {file = "setuptools-67.6.1.tar.gz", hash = "sha256:257de92a9d50a60b8e22abfcbb771571fde0dbf3ec234463212027a4eeecbe9a"},
] ]
[package.extras] [package.extras]
@ -859,14 +859,14 @@ files = [
[[package]] [[package]]
name = "tomlkit" name = "tomlkit"
version = "0.11.6" version = "0.11.7"
description = "Style preserving TOML library" description = "Style preserving TOML library"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.7"
files = [ files = [
{file = "tomlkit-0.11.6-py3-none-any.whl", hash = "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b"}, {file = "tomlkit-0.11.7-py3-none-any.whl", hash = "sha256:5325463a7da2ef0c6bbfefb62a3dc883aebe679984709aee32a317907d0a8d3c"},
{file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"}, {file = "tomlkit-0.11.7.tar.gz", hash = "sha256:f392ef70ad87a672f02519f99967d28a4d3047133e2d1df936511465fbb3791d"},
] ]
[[package]] [[package]]

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "onlylegs" name = "onlylegs"
version = "23.03.26" version = "23.03.30"
description = "Gallery built for fast and simple image management" description = "Gallery built for fast and simple image management"
authors = ["Fluffy-Bean <michal-gdula@protonmail.com>"] authors = ["Fluffy-Bean <michal-gdula@protonmail.com>"]
license = "MIT" license = "MIT"

2
run.py
View file

@ -14,7 +14,7 @@ print("""
#+# #+# #+# #+#+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+#+# #+# #+# #+# #+# #+# #+# #+# #+#
######## ### #### ########## ### ########## ######### ######### ######## ######## ### #### ########## ### ########## ######### ######### ########
Created by Fluffy Bean - Version 23.03.26 Created by Fluffy Bean - Version 23.03.30
""") """)