Merge pull request #8 from Fluffy-Bean/unstable

Unstable
This commit is contained in:
Michał Gdula 2023-03-23 22:38:47 +00:00 committed by GitHub
commit 66689c586b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 458 additions and 299 deletions

View file

@ -16,7 +16,7 @@ from flask import Flask, render_template
# Configuration # Configuration
import platformdirs import platformdirs
from dotenv import load_dotenv from dotenv import load_dotenv
from yaml import FullLoader, safe_load from yaml import safe_load
# Utils # Utils
from gallery.utils import theme_manager from gallery.utils import theme_manager
@ -58,11 +58,6 @@ def create_app(test_config=None):
else: else:
app.config.from_mapping(test_config) app.config.from_mapping(test_config)
try:
os.makedirs(app.instance_path)
except OSError:
pass
# Load theme # Load theme
theme_manager.CompileTheme('default', app.root_path) theme_manager.CompileTheme('default', app.root_path)
@ -71,11 +66,7 @@ def create_app(test_config=None):
assets.register('js_all', js_scripts) assets.register('js_all', js_scripts)
# Error handlers # Error handlers
@app.errorhandler(403) @app.errorhandler(Exception)
@app.errorhandler(404)
@app.errorhandler(405)
@app.errorhandler(410)
@app.errorhandler(500)
def error_page(err): def error_page(err):
error = err.code error = err.code
msg = err.description msg = err.description

View file

@ -1,7 +1,7 @@
""" """
Onlylegs Gallery - Routing Onlylegs Gallery - Routing
""" """
from flask import Blueprint, render_template, url_for from flask import Blueprint, render_template, url_for, request
from werkzeug.exceptions import abort from werkzeug.exceptions import abort
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
@ -24,6 +24,9 @@ def index():
db.Posts.created_at, db.Posts.created_at,
db.Posts.id).order_by(db.Posts.id.desc()).all() db.Posts.id).order_by(db.Posts.id.desc()).all()
if request.args.get('coffee') == 'please':
abort(418)
return render_template('index.html', images=images) return render_template('index.html', images=images)

View file

@ -2,15 +2,15 @@
function showLogin() { function showLogin() {
popUpShow( popUpShow(
'Login!', 'Login!',
'Need an account? <span class="pop-up__link" onclick="showRegister()">Register!</span>', 'Need an account? <span class="link" onclick="showRegister()">Register!</span>',
'<button class="btn-block" onclick="popupDissmiss()">Cancelee</button>\ '<button class="btn-block" onclick="popupDissmiss()">Cancelee</button>' +
<button class="btn-block primary" form="loginForm" type="submit">Login</button>', '<button class="btn-block primary" form="loginForm" type="submit">Login</button>',
'<form id="loginForm" onsubmit="return login(event)">\ '<form id="loginForm" onsubmit="return login(event)">' +
<input class="input-block" type="text" placeholder="Namey" id="username"/>\ '<input class="input-block" type="text" placeholder="Namey" id="username"/>' +
<input class="input-block" type="password" placeholder="Passywassy" id="password"/>\ '<input class="input-block" type="password" placeholder="Passywassy" id="password"/>' +
</form>' '</form>'
); );
}; }
// Function to login // Function to login
function login(event) { function login(event) {
// AJAX takes control of subby form :3 // AJAX takes control of subby form :3
@ -57,7 +57,7 @@ function login(event) {
function showRegister() { function showRegister() {
popUpShow( popUpShow(
'Who are you?', 'Who are you?',
'Already have an account? <span class="pop-up__link" onclick="showLogin()">Login!</span>', 'Already have an account? <span class="link" onclick="showLogin()">Login!</span>',
'<button class="btn-block" onclick="popupDissmiss()">Canceleee</button>\ '<button class="btn-block" onclick="popupDissmiss()">Canceleee</button>\
<button class="btn-block primary" form="registerForm" type="submit">Register</button>', <button class="btn-block primary" form="registerForm" type="submit">Register</button>',
'<form id="registerForm" onsubmit="return register(event)">\ '<form id="registerForm" onsubmit="return register(event)">\
@ -67,7 +67,7 @@ function showRegister() {
<input class="input-block" type="password" placeholder="Passywassy again!" id="password-repeat"/>\ <input class="input-block" type="password" placeholder="Passywassy again!" id="password-repeat"/>\
</form>' </form>'
); );
}; }
// Function to register // Function to register
function register(obj) { function register(obj) {
// AJAX takes control of subby form // AJAX takes control of subby form
@ -101,7 +101,7 @@ function register(obj) {
addNotification('Registered successfully! Now please login to continue', 1); addNotification('Registered successfully! Now please login to continue', 1);
showLogin(); showLogin();
} else { } else {
for (var i = 0; i < response.length; i++) { for (let i = 0; i < response.length; i++) {
addNotification(response[i], 2); addNotification(response[i], 2);
} }
} }
@ -120,4 +120,4 @@ function register(obj) {
} }
} }
}); });
} }

View file

@ -5,26 +5,29 @@ function imgFade(obj, time = 250) {
// https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color // 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) { function colourContrast(bgColor, lightColor, darkColor, threshold = 0.179) {
// if color is in hex format then convert to rgb else parese rgb // 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) === '#') { if (bgColor.charAt(0) === '#') {
var color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor; const color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor;
var r = parseInt(color.substring(0, 2), 16); // hexToR r = parseInt(color.substring(0, 2), 16); // hexToR
var g = parseInt(color.substring(2, 4), 16); // hexToG g = parseInt(color.substring(2, 4), 16); // hexToG
var b = parseInt(color.substring(4, 6), 16); // hexToB b = parseInt(color.substring(4, 6), 16); // hexToB
} else { } else {
var color = bgColor.replace('rgb(', '').replace(')', '').split(','); const color = bgColor.replace('rgb(', '').replace(')', '').split(',');
var r = color[0]; r = color[0];
var g = color[1]; g = color[1];
var b = color[2]; b = color[2];
} }
var uicolors = [r / 255, g / 255, b / 255]; const uicolors = [r / 255, g / 255, b / 255];
var c = uicolors.map((col) => { const c = uicolors.map((col) => {
if (col <= 0.03928) { if (col <= 0.03928) {
return col / 12.92; return col / 12.92;
} }
return Math.pow((col + 0.055) / 1.055, 2.4); return Math.pow((col + 0.055) / 1.055, 2.4);
}); });
var L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]); const L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]);
return (L > threshold) ? darkColor : lightColor; return (L > threshold) ? darkColor : lightColor;
} }
// Lazy load images when they are in view // Lazy load images when they are in view
@ -48,8 +51,7 @@ window.onload = function () {
const lightColor = '#E8E3E3'; const lightColor = '#E8E3E3';
let contrastCheck = document.querySelectorAll('#contrast-check'); let contrastCheck = document.querySelectorAll('#contrast-check');
for (let i = 0; i < contrastCheck.length; i++) { for (let i = 0; i < contrastCheck.length; i++) {
console.log(contrastCheck[i].getAttribute('data-color')); let bgColor = contrastCheck[i].getAttribute('data-color');
bgColor = contrastCheck[i].getAttribute('data-color');
contrastCheck[i].style.color = colourContrast(bgColor, lightColor, darkColor); contrastCheck[i].style.color = colourContrast(bgColor, lightColor, darkColor);
} }
@ -71,11 +73,8 @@ window.onload = function () {
// Convert to local time // Convert to local time
times[i].innerHTML = dateTime.toLocaleDateString() + ' ' + dateTime.toLocaleTimeString(); times[i].innerHTML = dateTime.toLocaleDateString() + ' ' + dateTime.toLocaleTimeString();
} }
};
window.onscroll = function () {
loadOnView();
// Jump to top button // Top Of Page button
let topOfPage = document.querySelector('.top-of-page'); let topOfPage = document.querySelector('.top-of-page');
if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 20) { if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 20) {
topOfPage.classList.add('show'); topOfPage.classList.add('show');
@ -86,7 +85,40 @@ window.onscroll = function () {
document.body.scrollTop = 0; document.body.scrollTop = 0;
document.documentElement.scrollTop = 0; document.documentElement.scrollTop = 0;
} }
// Info button
let infoButton = document.querySelector('.info-button');
if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 20) {
infoButton.classList.remove('show');
} else {
infoButton.classList.add('show');
}
infoButton.onclick = function () {
popUpShow('OnlyLegs Gallery',
'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.23</a>');
}
};
window.onscroll = function () {
loadOnView();
// Top Of Page button
let topOfPage = document.querySelector('.top-of-page');
if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 20) {
topOfPage.classList.add('show');
} else {
topOfPage.classList.remove('show');
}
// Info button
let infoButton = document.querySelector('.info-button');
if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 20) {
infoButton.classList.remove('show');
} else {
infoButton.classList.add('show');
}
}; };
window.onresize = function () { window.onresize = function () {
loadOnView(); loadOnView();
}; };

View file

@ -1,8 +1,8 @@
function addNotification(text='Sample notification', type=4) { function addNotification(text='Sample notification', type=4) {
var container = document.querySelector('.notifications'); let container = document.querySelector('.notifications');
// Create notification element // Create notification element
var div = document.createElement('div'); let div = document.createElement('div');
div.classList.add('sniffle__notification'); div.classList.add('sniffle__notification');
div.onclick = function() { div.onclick = function() {
if (div.parentNode) { if (div.parentNode) {
@ -15,44 +15,36 @@ function addNotification(text='Sample notification', type=4) {
}; };
// Create icon element and append to notification // Create icon element and append to notification
var icon = document.createElement('span'); let icon = document.createElement('span');
icon.classList.add('sniffle__notification-icon'); icon.classList.add('sniffle__notification-icon');
switch (type) { switch (type) {
case 1: case 1:
div.classList.add('sniffle__notification--success'); div.classList.add('sniffle__notification--success');
icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="-5 -7 24 24" fill="currentColor">\ icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M237.66,85.26l-128.4,128.4a8,8,0,0,1-11.32,0l-71.6-72a8,8,0,0,1,0-11.31l24-24a8,8,0,0,1,11.32,0l36.68,35.32a8,8,0,0,0,11.32,0l92.68-91.32a8,8,0,0,1,11.32,0l24,23.6A8,8,0,0,1,237.66,85.26Z" opacity="0.2"></path><path d="M243.28,68.24l-24-23.56a16,16,0,0,0-22.58,0L104,136h0l-.11-.11L67.25,100.62a16,16,0,0,0-22.57.06l-24,24a16,16,0,0,0,0,22.61l71.62,72a16,16,0,0,0,22.63,0L243.33,90.91A16,16,0,0,0,243.28,68.24ZM103.62,208,32,136l24-24,.11.11,36.64,35.27a16,16,0,0,0,22.52,0L208.06,56,232,79.6Z"></path></svg>';
<path d="M5.486 9.73a.997.997 0 0 1-.707-.292L.537 5.195A1 1 0 1 1 1.95 3.78l3.535 3.535L11.85.952a1 1 0 0 1 1.415 1.414L6.193 9.438a.997.997 0 0 1-.707.292z"></path>\
</svg>';
break; break;
case 2: case 2:
div.classList.add('sniffle__notification--error'); div.classList.add('sniffle__notification--error');
icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="-6 -6 24 24" fill="currentColor">\ icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M215.46,216H40.54C27.92,216,20,202.79,26.13,192.09L113.59,40.22c6.3-11,22.52-11,28.82,0l87.46,151.87C236,202.79,228.08,216,215.46,216Z" opacity="0.2"></path><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>';
<path d="M7.314 5.9l3.535-3.536A1 1 0 1 0 9.435.95L5.899 4.485 2.364.95A1 1 0 1 0 .95 2.364l3.535 3.535L.95 9.435a1 1 0 1 0 1.414 1.414l3.535-3.535 3.536 3.535a1 1 0 1 0 1.414-1.414L7.314 5.899z"></path>\
</svg>';
break; break;
case 3: case 3:
div.classList.add('sniffle__notification--warning'); div.classList.add('sniffle__notification--warning');
icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2 -3 24 24" fill="currentColor">\ icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M215.46,216H40.54C27.92,216,20,202.79,26.13,192.09L113.59,40.22c6.3-11,22.52-11,28.82,0l87.46,151.87C236,202.79,228.08,216,215.46,216Z" opacity="0.2"></path><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>';
<path d="M12.8 1.613l6.701 11.161c.963 1.603.49 3.712-1.057 4.71a3.213 3.213 0 0 1-1.743.516H3.298C1.477 18 0 16.47 0 14.581c0-.639.173-1.264.498-1.807L7.2 1.613C8.162.01 10.196-.481 11.743.517c.428.276.79.651 1.057 1.096zm-2.22.839a1.077 1.077 0 0 0-1.514.365L2.365 13.98a1.17 1.17 0 0 0-.166.602c0 .63.492 1.14 1.1 1.14H16.7c.206 0 .407-.06.581-.172a1.164 1.164 0 0 0 .353-1.57L10.933 2.817a1.12 1.12 0 0 0-.352-.365zM10 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm0-9a1 1 0 0 1 1 1v4a1 1 0 0 1-2 0V6a1 1 0 0 1 1-1z"></path>\
</svg>';
break; break;
default: default:
div.classList.add('sniffle__notification--info'); div.classList.add('sniffle__notification--info');
icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 24 24" fill="currentColor">\ icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z" opacity="0.2"></path><path d="M144,176a8,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,176Zm88-48A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128ZM124,96a12,12,0,1,0-12-12A12,12,0,0,0,124,96Z"></path></svg>';
<path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm0-10a1 1 0 0 1 1 1v5a1 1 0 0 1-2 0V9a1 1 0 0 1 1-1zm0-1a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"></path>\
</svg>';
break; break;
} }
div.appendChild(icon); div.appendChild(icon);
// Create text element and append to notification // Create text element and append to notification
var 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 = text;
div.appendChild(description); div.appendChild(description);
// Create span to show time remaining // Create span to show time remaining
var timer = document.createElement('span'); let timer = document.createElement('span');
timer.classList.add('sniffle__notification-time'); timer.classList.add('sniffle__notification-time');
div.appendChild(timer); div.appendChild(timer);

View file

@ -1,11 +1,11 @@
function popUpShow(title, body, actions, content) { function popUpShow(title, body, actions='<button class="btn-block" onclick="popupDissmiss()">Close</button>', content='') {
// Stop scrolling // Stop scrolling
document.querySelector("html").style.overflow = "hidden"; document.querySelector("html").style.overflow = "hidden";
// Get popup elements // Get popup elements
var popup = document.querySelector('.pop-up'); let popup = document.querySelector('.pop-up');
var popupContent = document.querySelector('.pop-up-content'); let popupContent = document.querySelector('.pop-up-content');
var popupActions = document.querySelector('.pop-up-controlls'); let popupActions = document.querySelector('.pop-up-controlls');
// Set popup content // Set popup content
popupContent.innerHTML = `<h3>${title}</h3><p>${body}</p>${content}`; popupContent.innerHTML = `<h3>${title}</h3><p>${body}</p>${content}`;
@ -24,7 +24,7 @@ function popupDissmiss() {
// un-Stop scrolling // un-Stop scrolling
document.querySelector("html").style.overflow = "auto"; document.querySelector("html").style.overflow = "auto";
var popup = document.querySelector('.pop-up'); let popup = document.querySelector('.pop-up');
popup.classList.remove('active'); popup.classList.remove('active');

View file

@ -1,92 +1,160 @@
// Function to upload images window.addEventListener("dragover",(event) => {
function uploadFile() { event.preventDefault();
// AJAX takes control of subby form },false);
event.preventDefault(); window.addEventListener("drop",(event) => {
event.preventDefault();
},false);
const jobList = document.querySelector(".upload-jobs"); function fileChanged(obj) {
document.querySelector('.fileDrop-block').classList.remove('error');
// Check for empty upload if ($(obj).val() === '') {
if ($("#file").val() === "") { document.querySelector('.fileDrop-block').classList.remove('active');
addNotification("Please select a file to upload", 2); document.querySelector('.fileDrop-block .status').innerHTML = 'Choose or Drop file';
} else { } else {
// Make form document.querySelector('.fileDrop-block').classList.add('active');
let formData = new FormData(); document.querySelector('.fileDrop-block .status').innerHTML = obj.files[0].name;
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
$("#file").val("");
$("#alt").val("");
$("#description").val("");
$("#tags").val("");
} }
}; }
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 // open upload tab
function openUploadTab() { function openUploadTab() {

View file

@ -1,7 +1,5 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block nav_groups %}navigation-item__selected{% endblock %} {% block nav_groups %}navigation-item__selected{% endblock %}
{% block content %} {% block content %}
<div class="banner"> <div class="banner">
{% if images %} {% if images %}

View file

@ -1,23 +1,24 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block nav_groups %}navigation-item__selected{% endblock %} {% block nav_groups %}navigation-item__selected{% endblock %}
{% block content %} {% block content %}
<div class="banner"> <div class="banner">
<img src="{{ url_for('static', filename='images/bg.svg') }}" onload="imgFade(this)" style="opacity:0;"/>
<span class="banner-filter"></span>
<div class="banner-content"> <div class="banner-content">
<p>{{ config.WEBSITE.motto }}</p> <p>{{ config.WEBSITE.motto }}</p>
<h1>Groups</h1> <h1>Groups</h1>
<p>{{ groups|length }} Groups</p> {% if groups|length == 0 %}
<p>0 photo groups :<</p>
{% elif groups|length == 69 %}
<p>{{ groups|length }} photo groups, uwu</p>
{% else %}
<p>{{ groups|length }} photo groups</p>
{% endif %}
</div> </div>
</div> </div>
<form action="/api/group/create" method="post" enctype="multipart/form-data"> <form action="/api/group/create" method="post" enctype="multipart/form-data">
<input type="text" name="name" placeholder="name"> <input class="input-block black" type="text" name="name" placeholder="name">
<input type="text" name="description" placeholder="description"> <input class="input-block black" type="text" name="description" placeholder="description">
<button type="submit">Submit</button> <button class="btn-block black" type="submit">Submit</button>
</form> </form>
{% if groups %} {% if groups %}

View file

@ -35,9 +35,7 @@
{% if next_url %} {% if next_url %}
<div> <div>
<a class="pill-item" href="{{ next_url }}"> <a class="pill-item" href="{{ next_url }}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-5 -5 24 24" width="24" fill="currentColor"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M112,56V200L40,128Z" opacity="0.2"></path><path d="M216,120H120V56a8,8,0,0,0-13.66-5.66l-72,72a8,8,0,0,0,0,11.32l72,72A8,8,0,0,0,120,200V136h96a8,8,0,0,0,0-16ZM104,180.69,51.31,128,104,75.31Z"></path></svg>
<path d="M3.414 7.657l3.95 3.95A1 1 0 0 1 5.95 13.02L.293 7.364a.997.997 0 0 1 0-1.414L5.95.293a1 1 0 1 1 1.414 1.414l-3.95 3.95H13a1 1 0 0 1 0 2H3.414z"></path>
</svg>
<span class="tool-tip"> <span class="tool-tip">
Previous Previous
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z"></path></svg>
@ -47,14 +45,14 @@
{% endif %} {% endif %}
<div> <div>
<button class="pill-item" id="img-fullscreen"> <button class="pill-item" id="img-fullscreen">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M208,48V96L160,48ZM48,208H96L48,160Zm160,0V160l-48,48ZM48,96,96,48H48Z" opacity="0.2"></path><path d="M98.34,146.34,72,172.69,53.66,154.34A8,8,0,0,0,40,160v48a8,8,0,0,0,8,8H96a8,8,0,0,0,5.66-13.66L83.31,184l26.35-26.34a8,8,0,0,0-11.32-11.32ZM56,200V179.31L76.69,200ZM83.31,72l18.35-18.34A8,8,0,0,0,96,40H48a8,8,0,0,0-8,8V96a8,8,0,0,0,13.66,5.66L72,83.31l26.34,26.35a8,8,0,0,0,11.32-11.32ZM56,76.69V56H76.69ZM208,40H160a8,8,0,0,0-5.66,13.66L172.69,72,146.34,98.34a8,8,0,0,0,11.32,11.32L184,83.31l18.34,18.35A8,8,0,0,0,216,96V48A8,8,0,0,0,208,40Zm-8,36.69L179.31,56H200Zm11.06,75.92a8,8,0,0,0-8.72,1.73L184,172.69l-26.34-26.35a8,8,0,0,0-11.32,11.32L172.69,184l-18.35,18.34A8,8,0,0,0,160,216h48a8,8,0,0,0,8-8V160A8,8,0,0,0,211.06,152.61ZM200,200H179.31L200,179.31Z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M224,56V200a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V56a8,8,0,0,1,8-8H216A8,8,0,0,1,224,56Z" opacity="0.2"></path><path d="M200,80v32a8,8,0,0,1-16,0V88H160a8,8,0,0,1,0-16h32A8,8,0,0,1,200,80ZM96,168H72V144a8,8,0,0,0-16,0v32a8,8,0,0,0,8,8H96a8,8,0,0,0,0-16ZM232,56V200a16,16,0,0,1-16,16H40a16,16,0,0,1-16-16V56A16,16,0,0,1,40,40H216A16,16,0,0,1,232,56ZM216,200V56H40V200H216Z"></path></svg>
<span class="tool-tip"> <span class="tool-tip">
Fullscreen Fullscreen
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z"></path></svg>
</span> </span>
</button> </button>
<button class="pill-item" id="img-share"> <button class="pill-item" id="img-share">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M209.94,113.94l-28,28a47.76,47.76,0,0,1-26.52,13.48,47.76,47.76,0,0,1-13.48,26.52l-28,28a48,48,0,0,1-67.88-67.88l28-28a47.76,47.76,0,0,1,26.52-13.48,47.76,47.76,0,0,1,13.48-26.52l28-28a48,48,0,0,1,67.88,67.88Z" opacity="0.2"></path><path d="M137.54,186.36a8,8,0,0,1,0,11.31l-17.94,18A56,56,0,0,1,40.38,136.4L68.5,108.29A56,56,0,0,1,145.31,106a8,8,0,1,1-10.64,12,40,40,0,0,0-54.85,1.63L51.7,147.72a40,40,0,1,0,56.58,56.58l17.94-17.94A8,8,0,0,1,137.54,186.36Zm78.08-146a56.08,56.08,0,0,0-79.22,0L118.46,58.33a8,8,0,0,0,11.32,11.31L147.72,51.7a40,40,0,0,1,56.58,56.58L176.18,136.4A40,40,0,0,1,121.33,138,8,8,0,1,0,110.69,150a56,56,0,0,0,76.81-2.27l28.12-28.11A56.08,56.08,0,0,0,215.62,40.38Z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M208,104V216H48V104Z" opacity="0.2"></path><path d="M216,112v96a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V112A16,16,0,0,1,56,96H80a8,8,0,0,1,0,16H56v96H200V112H176a8,8,0,0,1,0-16h24A16,16,0,0,1,216,112ZM93.66,69.66,120,43.31V136a8,8,0,0,0,16,0V43.31l26.34,26.35a8,8,0,0,0,11.32-11.32l-40-40a8,8,0,0,0-11.32,0l-40,40A8,8,0,0,0,93.66,69.66Z"></path></svg>
<span class="tool-tip"> <span class="tool-tip">
Share Share
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z"></path></svg>
@ -89,9 +87,7 @@
{% if prev_url %} {% if prev_url %}
<div> <div>
<a class="pill-item" href="{{ prev_url }}"> <a class="pill-item" href="{{ prev_url }}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-5 -5 24 24" width="24" fill="currentColor"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M216,128l-72,72V56Z" opacity="0.2"></path><path d="M221.66,122.34l-72-72A8,8,0,0,0,136,56v64H40a8,8,0,0,0,0,16h96v64a8,8,0,0,0,13.66,5.66l72-72A8,8,0,0,0,221.66,122.34ZM152,180.69V75.31L204.69,128Z"></path></svg>
<path d="M10.586 5.657l-3.95-3.95A1 1 0 0 1 8.05.293l5.657 5.657a.997.997 0 0 1 0 1.414L8.05 13.021a1 1 0 1 1-1.414-1.414l3.95-3.95H1a1 1 0 1 1 0-2h9.586z"></path>
</svg>
<span class="tool-tip"> <span class="tool-tip">
Next Next
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z"></path></svg>
@ -263,10 +259,9 @@
$('#img-delete').click(function() { $('#img-delete').click(function() {
popUpShow( popUpShow(
'DESTRUCTION!!!!!!', 'DESTRUCTION!!!!!!',
'This will delete the image and all of its data!!! This action is irreversible!!!!! Are you sure you want to do this?????', 'Do you want to delete this image along with all of its data??? This action is irreversible!',
'<button class="btn-block" onclick="popupDissmiss()">Nooooooo</button>\ '<button class="btn-block" onclick="popupDissmiss()">Nuuu</button>' +
<button class="btn-block critical" onclick="deleteImage()">Dewww eeeet!</button>', '<button class="btn-block critical" onclick="deleteImage()">Dewww eeeet!</button>'
'<img src="/api/file/{{ image.file_name }}?w=1920&h=1080"/>'
); );
}); });
function deleteImage() { function deleteImage() {

View file

@ -4,13 +4,16 @@
{% block content %} {% block content %}
<div class="banner"> <div class="banner">
<img src="{{ url_for('static', filename='images/bg.svg') }}" onload="imgFade(this)" style="opacity:0;"/>
<span class="banner-filter"></span>
<div class="banner-content"> <div class="banner-content">
<p>{{ config.WEBSITE.motto }}</p> <p>{{ config.WEBSITE.motto }}</p>
<h1>{{ config.WEBSITE.name }}</h1> <h1>{{ config.WEBSITE.name }}</h1>
<p>Serving {{ images|length }} images</p> {% if images|length == 0 %}
<p>Serving 0 images :<</p>
{% elif images|length == 69 %}
<p>Serving {{ images|length }} images, nice</p>
{% else %}
<p>Serving {{ images|length }} images</p>
{% endif %}
</div> </div>
</div> </div>
@ -28,12 +31,7 @@
</div> </div>
{% else %} {% else %}
<div class="big-text"> <div class="big-text">
<h1>No images</h1> <h1>*crickets chirping*</h1>
{% if g.user %}
<p>You can get started by uploading an image!</p>
{% else %}
<p>Login to start uploading images!</p>
{% endif %}
</div> </div>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
@ -42,11 +40,11 @@
<script> <script>
if (document.referrer.includes('image')) { if (document.referrer.includes('image')) {
try { try {
var referrerId = document.referrer.split('/').pop(); let referrerId = document.referrer.split('/').pop();
var imgOffset = document.getElementById('image-' + referrerId).offsetTop; let imgOffset = document.getElementById('image-' + referrerId).offsetTop;
var imgHeight = document.getElementById('image-' + referrerId).offsetHeight; let imgHeight = document.getElementById('image-' + referrerId).offsetHeight;
var windowHeight = window.innerHeight; let windowHeight = window.innerHeight;
document.querySelector('html').style.scrollBehavior = 'auto'; document.querySelector('html').style.scrollBehavior = 'auto';
window.scrollTo(0, imgOffset + (imgHeight / 2) - (windowHeight / 2)); window.scrollTo(0, imgOffset + (imgHeight / 2) - (windowHeight / 2));

View file

@ -38,7 +38,12 @@
<body> <body>
<div class="notifications"></div> <div class="notifications"></div>
<svg class="top-of-page" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M224,120H176v88a8,8,0,0,1-8,8H88a8,8,0,0,1-8-8V120H32l96-96Z" opacity="0.2"></path><path d="M229.66,114.34l-96-96a8,8,0,0,0-11.32,0l-96,96A8,8,0,0,0,32,128H72v80a16,16,0,0,0,16,16h80a16,16,0,0,0,16-16V128h40a8,8,0,0,0,5.66-13.66ZM176,112a8,8,0,0,0-8,8v88H88V120a8,8,0,0,0-8-8H51.31L128,35.31,204.69,112Z"></path></svg> <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="M200,144H56l72-72Z" opacity="0.2"></path><path d="M133.66,66.34a8,8,0,0,0-11.32,0l-72,72A8,8,0,0,0,56,152h64v72a8,8,0,0,0,16,0V152h64a8,8,0,0,0,5.66-13.66ZM75.31,136,128,83.31,180.69,136ZM224,40a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,40Z"></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="M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z" opacity="0.2"></path><path d="M144,176a8,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,176Zm88-48A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128ZM124,96a12,12,0,1,0-12-12A12,12,0,0,0,124,96Z"></path></svg>
</button>
<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>
@ -119,8 +124,13 @@
<div class="container"> <div class="container">
<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" onsubmit="return uploadFile(event)"> <form id="uploadForm">
<input class="input-block file" type="file" id="file"/> <div class="fileDrop-block">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M232,136v64a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V136a8,8,0,0,1,8-8H224A8,8,0,0,1,232,136Z" opacity="0.2"></path><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)"/>
</div>
<input class="input-block" type="text" placeholder="alt" id="alt"/> <input class="input-block" type="text" placeholder="alt" id="alt"/>
<input class="input-block" type="text" placeholder="description" id="description"/> <input class="input-block" type="text" placeholder="description" id="description"/>
<input class="input-block" type="text" placeholder="tags" id="tags"/> <input class="input-block" type="text" placeholder="tags" id="tags"/>

View file

@ -1,11 +1,11 @@
.banner .banner
width: 100% width: 100%
height: 40vh height: 50vh
position: relative position: relative
background-color: $black background-color: $black
color: $black color: $white
overflow: hidden overflow: hidden
transition: opacity 0.3s ease-in-out transition: opacity 0.3s ease-in-out
@ -18,7 +18,7 @@
width: 100% width: 100%
height: 100% height: 100%
background-color: $black background-color: $black2
object-fit: cover object-fit: cover
object-position: center center object-position: center center
@ -46,7 +46,6 @@
display: flex display: flex
flex-direction: column flex-direction: column
justify-content: flex-end justify-content: flex-end
gap: 0.5rem
z-index: +2 z-index: +2
@ -55,22 +54,19 @@
padding: 0 padding: 0
font-size: 6.9rem font-size: 6.9rem
font-weight: 700 font-weight: 800
line-height: 1
text-align: left text-align: left
color: $black color: $primary
p p
margin: 0 margin: 0
padding: 0 padding: 0
font-size: 1rem font-size: 1rem
font-weight: 600 font-weight: 500
line-height: 1 line-height: 1
text-align: left text-align: left
color: $black
@media (max-width: $breakpoint) @media (max-width: $breakpoint)
.banner .banner

View file

@ -1,10 +1,10 @@
@mixin btn-block($color) @mixin btn-block($color)
background-color: transparent background-color: rgba($color, 0)
color: $color color: $color
&:hover &:hover
background-color: $color background-color: rgba($color, 0.2)
color: $black color: $color
&:focus-visible &:focus-visible
outline: 2px solid rgba($color, 0.5) outline: 2px solid rgba($color, 0.5)
@ -26,7 +26,7 @@
font-weight: 600 font-weight: 600
text-align: center text-align: center
background-color: transparent background-color: rgba($white, 0)
color: $white color: $white
border: none border: none
border-radius: $rad-inner border-radius: $rad-inner
@ -36,10 +36,10 @@
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out
&:hover &:hover
background-color: $black background-color: rgba($white, 0.2)
&:focus-visible &:focus-visible
outline: 2px solid rgba($black, 0.5) outline: 2px solid rgba($white, 0.5)
&.primary &.primary
@include btn-block($primary) @include btn-block($primary)
@ -56,6 +56,9 @@
&.info &.info
@include btn-block($info) @include btn-block($info)
&.black
@include btn-block($black)
.input-block .input-block
padding: 0.5rem 1rem padding: 0.5rem 1rem
@ -73,48 +76,77 @@
font-weight: 600 font-weight: 600
text-align: left text-align: left
background-color: transparent background-color: rgba($white, 0.1)
color: $white color: $white
border: none border: none
border-bottom: 3px solid $gray border-bottom: 3px solid rgba($white, 0.1)
border-radius: $rad-inner border-radius: $rad-inner
cursor: pointer cursor: pointer
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out
&:not(:focus):not([value=""]):not(:placeholder-shown) &:not(:focus):not([value=""]):not(:placeholder-shown)
border-color: $white border-color: rgba($white, 0.3)
&:hover &:hover
border-color: $white border-color: rgba($white, 0.3)
&:focus &:focus
border-color: $primary border-color: $primary
outline: none outline: none
&.file &.black
padding: 0 1rem 0 0 @include btn-block($black)
border: none
background-color: $black2
&:focus-visible .fileDrop-block
outline: 2px solid rgba($white, 0.5) padding: 1rem 1.25rem
&::file-selector-button width: 100%
margin-right: 1rem min-height: 2.5rem
padding: 0.5rem 1rem
width: auto display: flex
height: 100% flex-direction: column
justify-content: center
align-items: center
gap: 0.5rem
font-size: 1rem position: relative
text-decoration: none
background-color: $white font-size: 1rem
color: $black font-weight: 600
border: none text-align: center
border-radius: $rad-inner
&:not([value=""]) background-color: rgba($white, 0.1)
display: none color: $white
border: none
border-radius: $rad-inner
cursor: pointer
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out
input
position: absolute
inset: 0
opacity: 0
cursor: pointer
&:hover
background-color: rgba($white, 0.2)
color: $white
&.active
background-color: rgba($primary, 0.2)
color: $primary
&.edging
background-color: rgba($white, 0.2)
color: $white
input
display: none // So it doesnt get in the way of the drop as that breaks things
&.error
background-color: rgba($critical, 0.2)
color: $critical

View file

@ -0,0 +1,41 @@
.info-button
margin: 0
padding: 0
width: auto
height: auto
position: fixed
bottom: 0.75rem
right: -3rem
display: flex
justify-content: center
align-items: center
background-color: $black2
color: $white
border-radius: $rad
border: none
opacity: 0
z-index: 20
cursor: pointer
transition: all 0.2s cubic-bezier(.86, 0, .07, 1)
&:hover
color: $info
svg
margin: 0.5rem
width: 1.25rem
height: 1.25rem
&.show
right: 0.75rem
opacity: 1
@media (max-width: $breakpoint)
.info-button
bottom: 4.25rem

View file

@ -1,33 +1,37 @@
.top-of-page .top-of-page
margin: 0 margin: 0
padding: 0.55rem padding: 0
width: 2.5rem width: auto
height: 2.5rem height: auto
position: fixed position: fixed
bottom: 0.75rem bottom: 0.75rem
right: -3rem right: -3rem
display: flex // hidden display: flex
justify-content: center justify-content: center
align-items: center align-items: center
border-radius: 50% background-color: $black2
background-color: $black
color: $white color: $white
opacity: 0 // hidden border-radius: $rad
border: none
z-index: 2 opacity: 0
z-index: 20
cursor: pointer cursor: pointer
transition: all 0.2s cubic-bezier(.86, 0, .07, 1) transition: all 0.2s cubic-bezier(.86, 0, .07, 1)
&:hover &:hover
background-color: $black
color: $primary color: $primary
svg
margin: 0.5rem
width: 1.25rem
height: 1.25rem
&.show &.show
right: 0.75rem right: 0.75rem
opacity: 1 opacity: 1

View file

@ -1,10 +1,9 @@
.pop-up .pop-up
width: calc(100% - 3.5rem) width: 100%
height: 100vh height: 100vh
position: fixed position: fixed
top: 0 inset: 0
left: 3.5rem
display: none display: none
@ -55,11 +54,11 @@
display: flex display: flex
flex-direction: column flex-direction: column
gap: 1rem gap: 0.5rem
overflow-y: auto overflow-y: auto
overflow-x: hidden overflow-x: hidden
text-size-adjust: auto; text-size-adjust: auto
text-overflow: ellipsis text-overflow: ellipsis
h3 h3
@ -70,13 +69,11 @@
position: sticky position: sticky
top: 0 top: 0
font-size: 2.25rem font-size: 1.5rem
font-weight: 600 font-weight: 800
text-align: center text-align: center
line-height: 1
color: $white color: $white
background-color: $black
p p
margin: 0 margin: 0
@ -86,10 +83,30 @@
font-size: 1rem font-size: 1rem
font-weight: 500 font-weight: 500
text-align: center text-align: center
line-height: 1
color: $white color: $white
svg
width: 1rem
height: 1rem
display: inline-block
vertical-align: middle
a, .link
font-size: 1rem
font-weight: 500
text-align: center
line-height: 1
color: $primary
cursor: pointer
text-decoration: none
&:hover
text-decoration: underline
img img
margin: auto margin: auto
padding: 0 padding: 0
@ -134,33 +151,11 @@
.pop-up-wrapper .pop-up-wrapper
transform: translate(-50%, 50%) scale(1) transform: translate(-50%, 50%) scale(1)
.pop-up__link
color: $primary
text-decoration: none
&:hover
text-decoration: underline
cursor: pointer
@media (max-width: $breakpoint) @media (max-width: $breakpoint)
.pop-up .pop-up
width: 100%
height: 100vh
height: 100dvh
position: fixed
left: 0
bottom: 0
.pop-up-wrapper .pop-up-wrapper
width: calc(100vw - 1rem) width: calc(100% - 0.75rem)
max-height: 99vh max-height: 95vh
left: 0.5rem
bottom: 0.5rem
border-radius: $rad
transform: translateY(5rem)
.pop-up-content .pop-up-content
max-height: 100% max-height: 100%
@ -168,12 +163,8 @@
img img
max-height: 50vh max-height: 50vh
.pop-up-controlls .pop-up-controlls button
flex-direction: column width: 100%
justify-content: center
&.active &.active
opacity: 1 opacity: 1
.pop-up-wrapper
transform: translateY(0)

View file

@ -18,10 +18,10 @@
margin: 0 margin: 0
padding: 0 padding: 0
font-size: 1.5rem font-size: 1.75rem
font-weight: 600 font-weight: 700
color: $white color: $primary
p p
margin: 0 margin: 0

Binary file not shown.

Binary file not shown.

View file

@ -14,6 +14,7 @@
@import "components/gallery" @import "components/gallery"
@import "components/buttons/top-of-page" @import "components/buttons/top-of-page"
@import "components/buttons/info-button"
@import "components/buttons/pill" @import "components/buttons/pill"
@import "components/buttons/block" @import "components/buttons/block"

View file

@ -4,7 +4,7 @@ $gray: #666
$white: #E8E3E3 $white: #E8E3E3
$red: #B66467 $red: #B66467
$orange: #D8A657 $orange: #D98C5F
$yellow: #D9BC8C $yellow: #D9BC8C
$green: #8C977D $green: #8C977D
$blue: #8DA3B9 $blue: #8DA3B9
@ -22,7 +22,7 @@ $rad-inner: 3px
$animation-smooth: cubic-bezier(0.76, 0, 0.17, 1) $animation-smooth: cubic-bezier(0.76, 0, 0.17, 1)
$animation-bounce: cubic-bezier(.68,-0.55,.27,1.55) $animation-bounce: cubic-bezier(.68,-0.55,.27,1.55)
$font: "Work Sans", sans-serif $font: "Manrope", sans-serif
$breakpoint: 800px $breakpoint: 800px
@font-face @font-face
@ -38,4 +38,10 @@ $breakpoint: 800px
@font-face @font-face
font-family: 'Work Sans' font-family: 'Work Sans'
src: url('fonts/worksans-black.woff2') src: url('fonts/worksans-black.woff2')
font-weight: 900 font-weight: 900
@font-face
font-family: 'Manrope'
src: url('fonts/Manrope[wght].woff2') format('woff2')
font-style: normal;
font-display: swap;

6
poetry.lock generated
View file

@ -657,14 +657,14 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytes
[[package]] [[package]]
name = "pylint" name = "pylint"
version = "2.17.0" version = "2.17.1"
description = "python code static checker" description = "python code static checker"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7.2" python-versions = ">=3.7.2"
files = [ files = [
{file = "pylint-2.17.0-py3-none-any.whl", hash = "sha256:e097d8325f8c88e14ad12844e3fe2d963d3de871ea9a8f8ad25ab1c109889ddc"}, {file = "pylint-2.17.1-py3-none-any.whl", hash = "sha256:8660a54e3f696243d644fca98f79013a959c03f979992c1ab59c24d3f4ec2700"},
{file = "pylint-2.17.0.tar.gz", hash = "sha256:1460829b6397cb5eb0cdb0b4fc4b556348e515cdca32115f74a1eb7c20b896b4"}, {file = "pylint-2.17.1.tar.gz", hash = "sha256:d4d009b0116e16845533bc2163493d6681846ac725eab8ca8014afb520178ddd"},
] ]
[package.dependencies] [package.dependencies]

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "onlylegs" name = "onlylegs"
version = "23.03.20" version = "23.03.23"
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"
@ -28,6 +28,5 @@ build-backend = "poetry.core.masonry.api"
[tool.pylint.messages_control] [tool.pylint.messages_control]
# C0415: Flask uses it to register blueprints # C0415: Flask uses it to register blueprints
# W1401: Anomalous backslash in string used in __init__
# W0718: Exception are logged so we don't need to raise them # W0718: Exception are logged so we don't need to raise them
disable = "C0415, W1401, W0718" disable = "C0415, W0718"

13
run.py
View file

@ -7,16 +7,17 @@ from setup.configuration import Configuration
print(""" print("""
___ _ _ ___ _ _
/ _ \ _ __ | |_ _| | ___ __ _ ___ / _ \\ _ __ | |_ _| | ___ __ _ ___
| | | | '_ \| | | | | | / _ \/ _` / __| | | | | '_ \\| | | | | | / _ \\/ _` / __|
| |_| | | | | | |_| | |__| __/ (_| \__ \ | |_| | | | | | |_| | |__| __/ (_| \\__ \\
\___/|_| |_|_|\__, |_____\___|\__, |___/ \\___/|_| |_|_|\\__, |_____\\___|\\__, |___/
|___/ |___/ |___/ |___/
Created by Fluffy Bean - Version 23.03.20 Created by Fluffy Bean - Version 23.03.23
""") """)
Configuration() # Run pre-checks # Run pre-startup checks and load configuration
Configuration()
if DEBUG: if DEBUG: