Choose or drop image for upload

Fix up some JS
Update Icons
This commit is contained in:
Michał 2023-03-23 12:54:00 +00:00
parent 0e1514bf93
commit 69d264739b
13 changed files with 279 additions and 194 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
@ -23,6 +23,9 @@ def index():
db.Posts.image_colours, db.Posts.image_colours,
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

@ -3,14 +3,14 @@ function showLogin() {
popUpShow( popUpShow(
'Login!', 'Login!',
'Need an account? <span class="pop-up__link" onclick="showRegister()">Register!</span>', 'Need an account? <span class="pop-up__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
@ -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);
} }
@ -89,4 +91,4 @@ window.onscroll = function () {
}; };
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

@ -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

@ -42,11 +42,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

@ -119,8 +119,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,10 +1,10 @@
@mixin btn-block($color) @mixin btn-block($color)
background-color: transparent background-color: rgba($color, 0.1)
color: $color color: $color
&:hover &:hover
background-color: $color background-color: rgba($color, 0.3)
color: $black color: $color
&:focus-visible &:focus-visible
outline: 2px solid rgba($color, 0.5) outline: 2px solid rgba($color, 0.5)
@ -73,7 +73,7 @@
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
@ -96,7 +96,7 @@
&.file &.file
padding: 0 1rem 0 0 padding: 0 1rem 0 0
border: none border: none
background-color: $black2 background-color: rgba($white, 0.1)
&:focus-visible &:focus-visible
outline: 2px solid rgba($white, 0.5) outline: 2px solid rgba($white, 0.5)
@ -118,3 +118,51 @@
&:not([value=""]) &:not([value=""])
display: none display: none
.fileDrop-block
padding: 1rem 1.25rem
width: 100%
min-height: 2.5rem
display: flex
flex-direction: column
justify-content: center
align-items: center
gap: 0.5rem
position: relative
font-size: 1rem
font-weight: 600
text-align: center
background-color: rgba($white, 0.1)
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
&.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

@ -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
@ -59,7 +58,7 @@
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
@ -144,23 +143,9 @@
@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% - 1rem)
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 +153,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

@ -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