mirror of
https://github.com/Derpy-Leggies/OnlyLegs.git
synced 2025-06-29 11:36:16 +00:00
Fix errors in metadata parsing
Remove useless extra checks in metadata parser Add Flask-Caching, need to test how helpfull this is
This commit is contained in:
parent
91278e2d11
commit
99c1d81869
27 changed files with 504 additions and 125 deletions
|
@ -15,6 +15,7 @@ import logging
|
|||
|
||||
# Flask
|
||||
from flask_compress import Compress
|
||||
from flask_caching import Cache
|
||||
from flask import Flask, render_template
|
||||
|
||||
# Configuration
|
||||
|
@ -73,6 +74,7 @@ def create_app(test_config=None):
|
|||
"""
|
||||
app = Flask(__name__,instance_path=INSTANCE_PATH)
|
||||
compress = Compress()
|
||||
cache = Cache(config={'CACHE_TYPE': 'SimpleCache', 'CACHE_DEFAULT_TIMEOUT': 69})
|
||||
|
||||
# App configuration
|
||||
app.config.from_mapping(
|
||||
|
@ -146,4 +148,5 @@ def create_app(test_config=None):
|
|||
app.register_blueprint(api.blueprint)
|
||||
|
||||
compress.init_app(app)
|
||||
cache.init_app(app)
|
||||
return app
|
||||
|
|
|
@ -13,7 +13,7 @@ from flask import (
|
|||
from werkzeug.utils import secure_filename
|
||||
|
||||
from colorthief import ColorThief
|
||||
from PIL import Image, ImageOps # ImageFilter
|
||||
from PIL import Image, ImageOps, ImageFilter
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from gallery.auth import login_required
|
||||
|
@ -33,11 +33,13 @@ def uploads(file):
|
|||
Returns a file from the uploads folder
|
||||
w and h are the width and height of the image for resizing
|
||||
f is whether to apply filters to the image, such as blurring NSFW images
|
||||
b is whether to force blur the image, even if it's not NSFW
|
||||
"""
|
||||
# Get args
|
||||
width = request.args.get('w', default=0, type=int) # Width of image
|
||||
height = request.args.get('h', default=0, type=int) # Height of image
|
||||
filtered = request.args.get('f', default=False, type=bool) # Whether to apply filters
|
||||
filtered = request.args.get('f', default=False, type=bool) # Whether to apply filters
|
||||
blur = request.args.get('b', default=False, type=bool) # Whether to force blur
|
||||
|
||||
# if no args are passed, return the raw file
|
||||
if width == 0 and height == 0 and not filtered:
|
||||
|
@ -78,6 +80,10 @@ def uploads(file):
|
|||
if filtered:
|
||||
#img = img.filter(ImageFilter.GaussianBlur(20))
|
||||
pass
|
||||
|
||||
# If forced to blur, blur image
|
||||
if blur:
|
||||
img = img.filter(ImageFilter.GaussianBlur(20))
|
||||
|
||||
try:
|
||||
img.save(buff, img_ext, icc_profile=img_icc)
|
||||
|
|
|
@ -69,6 +69,7 @@ class Metadata:
|
|||
exif['Photographer'][PHOTOGRAHER_MAPPING[data][0]] = {
|
||||
'raw': encoded_exif[data],
|
||||
}
|
||||
continue
|
||||
elif data in CAMERA_MAPPING:
|
||||
if len(CAMERA_MAPPING[data]) == 2:
|
||||
# Camera - Exif Tag name
|
||||
|
@ -81,6 +82,7 @@ class Metadata:
|
|||
exif['Camera'][CAMERA_MAPPING[data][0]] = {
|
||||
'raw': encoded_exif[data],
|
||||
}
|
||||
continue
|
||||
elif data in SOFTWARE_MAPPING:
|
||||
if len(SOFTWARE_MAPPING[data]) == 2:
|
||||
exif['Software'][SOFTWARE_MAPPING[data][0]] = {
|
||||
|
@ -92,6 +94,7 @@ class Metadata:
|
|||
exif['Software'][SOFTWARE_MAPPING[data][0]] = {
|
||||
'raw': encoded_exif[data],
|
||||
}
|
||||
continue
|
||||
elif data in FILE_MAPPING:
|
||||
if len(FILE_MAPPING[data]) == 2:
|
||||
exif['File'][FILE_MAPPING[data][0]] = {
|
||||
|
|
|
@ -352,6 +352,7 @@ def orientation(value):
|
|||
Maps the value of the orientation to a human readable format
|
||||
"""
|
||||
value_map = {
|
||||
0: 'Undefined',
|
||||
1: 'Horizontal (normal)',
|
||||
2: 'Mirror horizontal',
|
||||
3: 'Rotate 180',
|
||||
|
|
|
@ -31,7 +31,7 @@ CAMERA_MAPPING = {
|
|||
'ISOSpeedRatings': ['ISO Speed Ratings', 'iso'],
|
||||
'ISOSpeed': ['ISO Speed', 'iso'],
|
||||
'SensitivityType': ['Sensitivity Type', 'sensitivity_type'],
|
||||
'ExposureBiasValue': ['Exposure Bias', 'ev'],
|
||||
'ExposureBiasValue': ['Exposure Bias', 'exposure'],
|
||||
'ExposureTime': ['Exposure Time', 'shutter'],
|
||||
'ExposureMode': ['Exposure Mode', 'exposure_mode'],
|
||||
'ExposureProgram': ['Exposure Program', 'exposure_program'],
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
Onlylegs Gallery - Routing
|
||||
"""
|
||||
import os
|
||||
from datetime import datetime as dt
|
||||
|
||||
from flask import Blueprint, render_template, current_app
|
||||
from flask import Blueprint, render_template, current_app, request, g
|
||||
from werkzeug.exceptions import abort
|
||||
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
@ -23,9 +24,10 @@ def index():
|
|||
Home page of the website, shows the feed of latest images
|
||||
"""
|
||||
images = db_session.query(db.Posts.file_name,
|
||||
db.Posts.id,
|
||||
db.Posts.created_at
|
||||
).order_by(db.Posts.id.desc()).all()
|
||||
db.Posts.image_colours,
|
||||
db.Posts.author_id,
|
||||
db.Posts.created_at,
|
||||
db.Posts.id).order_by(db.Posts.id.desc()).all()
|
||||
|
||||
return render_template('index.html',
|
||||
images=images,
|
||||
|
@ -47,12 +49,25 @@ def image(image_id):
|
|||
|
||||
return render_template('image.html', image=img, exif=img.image_exif)
|
||||
|
||||
@blueprint.route('/group')
|
||||
@blueprint.route('/group', methods=['GET', 'POST'])
|
||||
def groups():
|
||||
"""
|
||||
Group overview, shows all image groups
|
||||
"""
|
||||
return render_template('group.html', group_id='gwa gwa')
|
||||
if request.method == 'GET':
|
||||
groups = db_session.query(db.Groups.name, db.Groups.author_id).all()
|
||||
|
||||
return render_template('group.html', groups=groups)
|
||||
elif request.method == 'POST':
|
||||
group_name = request.form['name']
|
||||
group_description = request.form['description']
|
||||
group_author = g.user.id
|
||||
|
||||
new_group = db.Groups(name=group_name, description=group_description, author_id=group_author, created_at=dt.now())
|
||||
|
||||
db_session.add(new_group)
|
||||
|
||||
return ':3'
|
||||
|
||||
@blueprint.route('/group/<int:group_id>')
|
||||
def group(group_id):
|
||||
|
@ -73,4 +88,4 @@ def profile_id(user_id):
|
|||
"""
|
||||
Shows user ofa given id, displays their uploads and other info
|
||||
"""
|
||||
return render_template('profile.html', user_id=user_id)
|
||||
return render_template('profile.html', user_id=user_id)
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 19 KiB |
1
gallery/static/images/bg.svg
Normal file
1
gallery/static/images/bg.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 225 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB |
|
@ -1,20 +1,9 @@
|
|||
function showUpload() {
|
||||
popUpShow(
|
||||
'Upload funny stuff',
|
||||
'May the world see your stuff 👀',
|
||||
'<button class="pop-up__btn pop-up__btn-primary-fill" form="uploadForm" type"submit">Upload</button>',
|
||||
'<form id="uploadForm" onsubmit="return uploadFile(event)">\
|
||||
<input class="pop-up__input" type="file" id="file"/>\
|
||||
<input class="pop-up__input" type="text" placeholder="alt" id="alt"/>\
|
||||
<input class="pop-up__input" type="text" placeholder="description" id="description"/>\
|
||||
<input class="pop-up__input" type="text" placeholder="tags" id="tags"/>\
|
||||
</form>'
|
||||
);
|
||||
};
|
||||
function uploadFile(){
|
||||
// AJAX takes control of subby form
|
||||
event.preventDefault();
|
||||
|
||||
const jobList = document.querySelector(".upload-jobs");
|
||||
|
||||
// Check for empty upload
|
||||
if ($("#file").val() === "") {
|
||||
addNotification("Please select a file to upload", 2);
|
||||
|
@ -35,32 +24,58 @@ function uploadFile(){
|
|||
contentType: false,
|
||||
processData: false,
|
||||
beforeSend: function() {
|
||||
console.log("Uploading...");
|
||||
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) {
|
||||
addNotification("File uploaded successfully!", 1);
|
||||
console.log('File processed successfully');
|
||||
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:
|
||||
addNotification('Server exploded, F\'s in chat', 2);
|
||||
jobStatus.innerHTML = "Server exploded, F's in chat";
|
||||
break;
|
||||
case 400:
|
||||
case 404:
|
||||
addNotification('Error uploading. Blame yourself', 2);
|
||||
jobStatus.innerHTML = "Error uploading. Blame yourself";
|
||||
break;
|
||||
case 403:
|
||||
addNotification('None but devils play past here...', 2);
|
||||
jobStatus.innerHTML = "None but devils play past here...";
|
||||
break;
|
||||
case 413:
|
||||
addNotification('File too large!!!!!!', 3);
|
||||
jobStatus.innerHTML = "File too large!!!!!!";
|
||||
break;
|
||||
default:
|
||||
addNotification('Error uploading file, blame someone', 2);
|
||||
jobStatus.innerHTML = "Error uploading file, blame someone";
|
||||
break;
|
||||
}
|
||||
console.log('Error uploading file');
|
||||
if (!document.querySelector(".upload-panel").classList.contains("open")) {
|
||||
addNotification("Error uploading file", 2);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -70,4 +85,23 @@ function uploadFile(){
|
|||
$("#description").val("");
|
||||
$("#tags").val("");
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function openUploadTab() {
|
||||
// Open upload tab
|
||||
const uploadTab = document.querySelector(".upload-panel");
|
||||
uploadTab.style.display = "block";
|
||||
|
||||
setTimeout( function() {
|
||||
uploadTab.classList.add("open");
|
||||
}, 10);
|
||||
}
|
||||
|
||||
function closeUploadTab() {
|
||||
// Close upload tab
|
||||
const uploadTab = document.querySelector(".upload-panel");
|
||||
uploadTab.classList.remove("open");
|
||||
setTimeout( function() {
|
||||
uploadTab.style.display = "none";
|
||||
}, 250);
|
||||
}
|
|
@ -1,15 +1,45 @@
|
|||
{% extends 'layout.html' %}
|
||||
|
||||
{% block header %}
|
||||
<div class="background-decoration">
|
||||
<img src="{{ url_for('static', filename='images/background.svg') }}" onload="imgFade(this)" style="opacity:0;"/>
|
||||
<div class="banner">
|
||||
<img src="{{ url_for('static', filename='images/bg.svg') }}" onload="imgFade(this)" style="opacity:0;"/>
|
||||
<span></span>
|
||||
|
||||
<div class="banner__content">
|
||||
{% block banner_subtitle%}{% endblock %}
|
||||
<h1>Groups</h1>
|
||||
<p>gwa gwa</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block nav_groups %}navigation-item__selected{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Image Group</h1>
|
||||
<p>{{group_id}}</p>
|
||||
<div class="gallery">
|
||||
{% for group in groups %}
|
||||
<a id="group-{{ group['id'] }}" class="gallery__item" href="/group/{{ group['id'] }}">
|
||||
<span class="gallery__item-info">
|
||||
<p>{{ group['id'] }}</p>
|
||||
<h2><span class="time">{{ group['created_at'] }}</span></h2>
|
||||
</span>
|
||||
<img
|
||||
class="gallery__item-group"
|
||||
data-src="{{ group['file_name'] }}"
|
||||
onload="imgFade(this)"
|
||||
style="opacity:0;"
|
||||
/>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<form action="/group" method="post" enctype="multipart/form-data">
|
||||
<input type="text" name="name" placeholder="name">
|
||||
<input type="text" name="description" placeholder="description">
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block script %}
|
||||
<script>
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -3,7 +3,7 @@
|
|||
{% block header %}
|
||||
<div class="background-decoration">
|
||||
<img src="/api/uploads/{{ image['file_name'] }}?w=1000&h=1000" onload="imgFade(this)" style="opacity:0;"/>
|
||||
<span></span>
|
||||
<span style="background-image: linear-gradient(to top, rgba({{ image['image_colours'][0][0] }}, {{ image['image_colours'][0][1] }}, {{ image['image_colours'][0][2] }}, 1), transparent);"></span>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block wrapper_class %}image-wrapper{% endblock %}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{% block header %}
|
||||
<div class="banner">
|
||||
<img src="{{ url_for('static', filename='images/leaves.jpg') }}" onload="imgFade(this)" style="opacity:0;"/>
|
||||
<img src="{{ url_for('static', filename='images/bg.svg') }}" onload="imgFade(this)" style="opacity:0;"/>
|
||||
<span></span>
|
||||
|
||||
<div class="banner__content">
|
||||
|
@ -19,9 +19,9 @@
|
|||
{% block content %}
|
||||
<div class="gallery">
|
||||
{% for image in images %}
|
||||
<a id="image-{{ image['id'] }}" class="gallery__item" href="/image/{{ image['id'] }}">
|
||||
<a id="image-{{ image['id'] }}" class="gallery__item" href="/image/{{ image['id'] }}" style="background-color: rgb({{ image['image_colours'][0][0] }}, {{ image['image_colours'][0][1] }}, {{ image['image_colours'][0][2] }})">
|
||||
<span class="gallery__item-info">
|
||||
<p>{{ image['id'] }}</p>
|
||||
<p></p>
|
||||
<h2><span class="time">{{ image['created_at'] }}</span></h2>
|
||||
</span>
|
||||
<img
|
||||
|
@ -59,15 +59,19 @@
|
|||
};
|
||||
|
||||
if (document.referrer.includes('image')) {
|
||||
var referrerId = document.referrer.split('/').pop();
|
||||
|
||||
var imgOffset = document.getElementById('image-' + referrerId).offsetTop;
|
||||
var imgHeight = document.getElementById('image-' + referrerId).offsetHeight;
|
||||
var windowHeight = window.innerHeight;
|
||||
|
||||
document.querySelector('html').style.scrollBehavior = 'auto';
|
||||
window.scrollTo(0, imgOffset + (imgHeight / 2) - (windowHeight / 2));
|
||||
document.querySelector('html').style.scrollBehavior = 'smooth';
|
||||
try {
|
||||
var referrerId = document.referrer.split('/').pop();
|
||||
|
||||
var imgOffset = document.getElementById('image-' + referrerId).offsetTop;
|
||||
var imgHeight = document.getElementById('image-' + referrerId).offsetHeight;
|
||||
var windowHeight = window.innerHeight;
|
||||
|
||||
document.querySelector('html').style.scrollBehavior = 'auto';
|
||||
window.scrollTo(0, imgOffset + (imgHeight / 2) - (windowHeight / 2));
|
||||
document.querySelector('html').style.scrollBehavior = 'smooth';
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -18,8 +18,8 @@
|
|||
<script src="{{ url_for('static', filename='js/login.js') }}" defer></script>
|
||||
|
||||
<!-- UI -->
|
||||
<script src="{{ url_for('static', filename='js/ui/popup.js') }}" defer></script>
|
||||
<script src="{{ url_for('static', filename='js/ui/notifications.js') }}" defer></script>
|
||||
<script src="{{ url_for('static', filename='js/ui/popup.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/ui/notifications.js') }}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
|
@ -29,9 +29,9 @@
|
|||
<path d="M11 8.414V14a1 1 0 0 1-2 0V8.414L6.464 10.95A1 1 0 1 1 5.05 9.536l4.243-4.243a.997.997 0 0 1 1.414 0l4.243 4.243a1 1 0 1 1-1.414 1.414L11 8.414zM10 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 16z"></path>
|
||||
</svg>
|
||||
|
||||
{% block header %}{% endblock %}
|
||||
|
||||
<div class="navigation">
|
||||
<img src="{{url_for('static', filename='images/icon.png')}}" alt="Logo" class="logo" onload="imgFade(this)" style="opacity:0;">
|
||||
|
||||
<a href="{{url_for('gallery.index')}}" class="navigation-item {% block nav_home %}{% endblock %}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 24 24" width="24" fill="currentColor">
|
||||
<path d="M2 8v10h12V8H2zm2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-2v4a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2zm2 0h8a2 2 0 0 1 2 2v4h2V2H6v4zm0 9a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"></path><path d="M7 6a3 3 0 1 1 6 0h-2a1 1 0 0 0-2 0H7zm1.864 13.518l2.725-4.672a1 1 0 0 1 1.6-.174l1.087 1.184 1.473-1.354-1.088-1.183a3 3 0 0 0-4.8.52L7.136 18.51l1.728 1.007zm6.512-12.969a2.994 2.994 0 0 1 3.285.77l1.088 1.183-1.473 1.354-1.087-1.184A1 1 0 0 0 16 8.457V8c0-.571-.24-1.087-.624-1.451z"></path>
|
||||
|
@ -47,7 +47,7 @@
|
|||
</a>
|
||||
|
||||
{% if g.user %}
|
||||
<button class="navigation-item {% block nav_upload %}{% endblock %}" onclick="showUpload()">
|
||||
<button class="navigation-item {% block nav_upload %}{% endblock %}" onclick="openUploadTab()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-5 -5 24 24" width="24" fill="currentColor">
|
||||
<path d="M8 3.414v5.642a1 1 0 1 1-2 0V3.414L4.879 4.536A1 1 0 0 1 3.464 3.12L6.293.293a1 1 0 0 1 1.414 0l2.829 2.828A1 1 0 1 1 9.12 4.536L8 3.414zM1 12h12a1 1 0 0 1 0 2H1a1 1 0 0 1 0-2z"></path>
|
||||
</svg>
|
||||
|
@ -81,6 +81,8 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% block header %}{% endblock %}
|
||||
|
||||
<div class="content {% block wrapper_class %}{% endblock %}">
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
@ -98,6 +100,22 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="upload-panel">
|
||||
<span class="click-off" onclick="closeUploadTab()"></span>
|
||||
<div class="container">
|
||||
<h3>Upload stuffs</h3>
|
||||
<p>May the world see your stuff 👀</p>
|
||||
<form id="uploadForm" onsubmit="return uploadFile(event)">
|
||||
<input type="file" id="file"/>
|
||||
<input type="text" placeholder="alt" id="alt"/>
|
||||
<input type="text" placeholder="description" id="description"/>
|
||||
<input type="text" placeholder="tags" id="tags"/>
|
||||
<button type="submit">Upload</button>
|
||||
</form>
|
||||
<div class="upload-jobs"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -17,3 +17,9 @@
|
|||
100%
|
||||
left: 0%
|
||||
height: 0
|
||||
|
||||
@keyframes uploadingLoop
|
||||
0%
|
||||
left: -100%
|
||||
100%
|
||||
left: 100%
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
@import "ui/notification"
|
||||
@import "ui/pop-up"
|
||||
@import "ui/upload-panel"
|
||||
|
||||
@import "ui/navigation"
|
||||
@import "ui/content"
|
||||
@import "ui/background"
|
||||
|
|
|
@ -42,6 +42,4 @@
|
|||
width: 100%
|
||||
height: 100%
|
||||
|
||||
background-image: linear-gradient(to bottom, rgba($white, 0), rgba($white, 1))
|
||||
|
||||
z-index: +1
|
||||
|
|
|
@ -9,13 +9,9 @@
|
|||
top: 0
|
||||
left: 3.5rem
|
||||
|
||||
background-color: $white
|
||||
background-color: $black
|
||||
color: $black
|
||||
|
||||
background-image: linear-gradient(to right, darken($white, 1%) 15%, darken($white, 10%) 35%, darken($white, 1%) 50%)
|
||||
background-size: 1000px 640px
|
||||
animation: imgLoading 1.8s linear infinite forwards
|
||||
|
||||
overflow: hidden
|
||||
transition: opacity 0.3s ease-in-out
|
||||
|
||||
|
@ -27,7 +23,7 @@
|
|||
width: 100%
|
||||
height: 100%
|
||||
|
||||
background-color: $white
|
||||
background-color: $black
|
||||
|
||||
object-fit: cover
|
||||
object-position: center center
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
position: relative
|
||||
|
||||
background: linear-gradient(to right, darken($white, 1%) 15%, darken($white, 10%) 35%, darken($white, 1%) 50%)
|
||||
background-size: 1000px 640px
|
||||
animation: imgLoading 1.8s linear infinite forwards
|
||||
// background: linear-gradient(to right, darken($white, 1%) 15%, darken($white, 10%) 35%, darken($white, 1%) 50%)
|
||||
// background-size: 1000px 640px
|
||||
// animation: imgLoading 1.8s linear infinite forwards
|
||||
border-radius: $rad
|
||||
|
||||
box-sizing: border-box
|
||||
|
|
|
@ -22,6 +22,18 @@
|
|||
> span
|
||||
height: 100%
|
||||
|
||||
.logo
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 3.5rem
|
||||
height: 3.5rem
|
||||
min-height: 3.5rem
|
||||
|
||||
display: flex
|
||||
flex-direction: row
|
||||
align-items: center
|
||||
|
||||
.navigation-item
|
||||
margin: 0
|
||||
padding: 1rem
|
||||
|
@ -108,6 +120,9 @@
|
|||
> span
|
||||
display: none
|
||||
|
||||
.logo
|
||||
display: none
|
||||
|
||||
.navigation-item
|
||||
margin: 0.25rem
|
||||
padding: 0
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
|
||||
animation: notificationTimeout 5.1s linear
|
||||
|
||||
@each $name, $colour in (success: $succes, error: $critical, warning: $warning, info: $info)
|
||||
@each $name, $colour in (success: $success, error: $critical, warning: $warning, info: $info)
|
||||
.sniffle__notification--#{$name}
|
||||
@include notification($colour)
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
left: 3.5rem
|
||||
|
||||
background-color: rgba($black, 0.8)
|
||||
backdrop-filter: blur(1rem)
|
||||
|
||||
opacity: 0
|
||||
z-index: 101
|
||||
|
|
219
gallery/themes/default/ui/upload-panel.sass
Normal file
219
gallery/themes/default/ui/upload-panel.sass
Normal file
|
@ -0,0 +1,219 @@
|
|||
.upload-panel
|
||||
position: fixed
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
display: none
|
||||
|
||||
width: 100%
|
||||
height: 100vh
|
||||
|
||||
background-color: rgba($black, 0)
|
||||
|
||||
overflow: hidden
|
||||
z-index: 68
|
||||
transition: background-color 0.25s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
|
||||
h3
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
font-size: 1.5rem
|
||||
font-weight: 600
|
||||
|
||||
color: $white
|
||||
|
||||
p
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 500
|
||||
|
||||
color: $white
|
||||
|
||||
form
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 100%
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
input
|
||||
margin: 0
|
||||
padding: 0.5rem 1rem
|
||||
|
||||
width: 100%
|
||||
height: 2.5rem
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 600
|
||||
|
||||
color: $white
|
||||
background-color: $black2
|
||||
|
||||
border: none
|
||||
border-radius: $rad-inner
|
||||
|
||||
&::placeholder
|
||||
color: $white
|
||||
|
||||
button
|
||||
margin: 0
|
||||
padding: 0.5rem 1rem
|
||||
|
||||
width: 100%
|
||||
height: 2.5rem
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 600
|
||||
|
||||
color: $white
|
||||
background-color: $primary
|
||||
|
||||
border: none
|
||||
border-radius: $rad-inner
|
||||
cursor: pointer
|
||||
|
||||
&:hover
|
||||
background-color: $black2
|
||||
color: $primary
|
||||
|
||||
.click-off
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
z-index: +1
|
||||
|
||||
|
||||
.container
|
||||
padding: 0.5rem
|
||||
|
||||
position: absolute
|
||||
top: 0
|
||||
left: calc(-400px + 3.5rem)
|
||||
|
||||
width: 400px
|
||||
height: 100%
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 1rem
|
||||
|
||||
background-color: $black
|
||||
opacity: 0
|
||||
|
||||
z-index: +2
|
||||
|
||||
transition: left 0.25s cubic-bezier(0.76, 0, 0.17, 1), opacity 0.25s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
|
||||
.upload-jobs
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 0.5rem
|
||||
|
||||
border-radius: $rad
|
||||
|
||||
overflow-y: auto
|
||||
|
||||
.job
|
||||
width: 100%
|
||||
height: 5rem
|
||||
min-height: 5rem
|
||||
|
||||
position: relative
|
||||
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
background-color: $black2
|
||||
border-radius: $rad
|
||||
|
||||
overflow: hidden
|
||||
|
||||
img
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
width: 100%
|
||||
height: 5rem
|
||||
|
||||
object-fit: cover
|
||||
|
||||
.img-filter
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
background-image: linear-gradient(to right, rgba($black, 0.8), rgba($black, 0))
|
||||
|
||||
.job__status
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
position: absolute
|
||||
top: 0.5rem
|
||||
left: 0.5rem
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 600
|
||||
|
||||
color: $white
|
||||
|
||||
z-index: +3
|
||||
|
||||
transition: color 0.25s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
|
||||
.progress
|
||||
width: 100%
|
||||
height: $rad-inner
|
||||
|
||||
position: absolute
|
||||
bottom: 0
|
||||
left: -100%
|
||||
|
||||
background-color: $primary
|
||||
|
||||
animation: uploadingLoop 1s cubic-bezier(0.76, 0, 0.17, 1) infinite
|
||||
|
||||
z-index: +5
|
||||
transition: left 1s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
|
||||
&.critical
|
||||
.job__status, .progress
|
||||
color: $critical
|
||||
&.success
|
||||
.job__status
|
||||
color: $success
|
||||
.progress
|
||||
height: 0
|
||||
animation: none
|
||||
&.warning
|
||||
.job__status, .progress
|
||||
color: $warning
|
||||
|
||||
&.critical, &.success, &.warning
|
||||
.progress
|
||||
height: 0
|
||||
|
||||
&.open
|
||||
background-color: rgba($black, 0.5)
|
||||
|
||||
.container
|
||||
left: 3.5rem
|
||||
opacity: 1
|
||||
|
||||
|
|
@ -24,7 +24,6 @@
|
|||
opacity: 0 // hide
|
||||
|
||||
background-color: rgba($black, 0.8)
|
||||
backdrop-filter: blur(1rem)
|
||||
z-index: 21
|
||||
|
||||
box-sizing: border-box
|
||||
|
@ -86,6 +85,8 @@
|
|||
object-fit: contain
|
||||
object-position: center
|
||||
|
||||
// box-shadow: 0 0 0.5rem rgba($black, 0.5)
|
||||
|
||||
.image-info__container
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
|
|
@ -12,7 +12,7 @@ $purple: #A988B0
|
|||
$primary: $green
|
||||
$warning: $orange
|
||||
$critical: $red
|
||||
$succes: $green
|
||||
$success: $green
|
||||
$info: $blue
|
||||
|
||||
$rad: 6px
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue