Add ownership checks to groups

Fix contrast checking
Add coloured highlights to images
Update top-of-page button icon
This commit is contained in:
Michał Gdula 2023-03-10 17:38:24 +00:00
parent feadaba8a1
commit e192554a0b
8 changed files with 81 additions and 38 deletions

View file

@ -225,17 +225,22 @@ def modify_group():
""" """
Changes the images in a group Changes the images in a group
""" """
group_id = request.form['group_id'] group_id = request.form['group']
image_id = request.form['images'] image_id = request.form['image']
action = request.form['action']
if action == 'add': group = db_session.query(db.Groups).filter_by(id=group_id).first()
# Check if image is already in group
if group is None:
abort(404)
elif group.author_id != g.user.id:
abort(403)
if request.form['action'] == 'add':
if db_session.query(db.GroupJunction).filter_by(group_id=group_id, post_id=image_id).first() is None: if db_session.query(db.GroupJunction).filter_by(group_id=group_id, post_id=image_id).first() is None:
db_session.add(db.GroupJunction(group_id=group_id, post_id=image_id, date_added=dt.utcnow())) db_session.add(db.GroupJunction(group_id=group_id, post_id=image_id, date_added=dt.utcnow()))
db_session.commit() elif request.form['action'] == 'remove':
elif action == 'remove':
db_session.query(db.GroupJunction).filter_by(group_id=group_id, post_id=image_id).delete() db_session.query(db.GroupJunction).filter_by(group_id=group_id, post_id=image_id).delete()
db_session.commit() db_session.commit()
return ':3' return ':3'

View file

@ -4,10 +4,19 @@ 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 (bgColor.charAt(0) === '#') {
var color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor; var color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor;
var r = parseInt(color.substring(0, 2), 16); // hexToR var r = parseInt(color.substring(0, 2), 16); // hexToR
var g = parseInt(color.substring(2, 4), 16); // hexToG var g = parseInt(color.substring(2, 4), 16); // hexToG
var b = parseInt(color.substring(4, 6), 16); // hexToB var b = parseInt(color.substring(4, 6), 16); // hexToB
} else {
var color = bgColor.replace('rgb(', '').replace(')', '').split(',');
var r = color[0];
var g = color[1];
var b = color[2];
}
var uicolors = [r / 255, g / 255, b / 255]; var uicolors = [r / 255, g / 255, b / 255];
var c = uicolors.map((col) => { var c = uicolors.map((col) => {
if (col <= 0.03928) { if (col <= 0.03928) {
@ -285,8 +294,9 @@ 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'));
bgColor = contrastCheck[i].getAttribute('data-color'); bgColor = contrastCheck[i].getAttribute('data-color');
contrastCheck[i].style.color = colourContrast(bgColor, lightColor, darkColor, 0.9); contrastCheck[i].style.color = colourContrast(bgColor, lightColor, darkColor);
} }
let times = document.querySelectorAll('.time'); let times = document.querySelectorAll('.time');

View file

@ -14,20 +14,25 @@
class="banner-filter" class="banner-filter"
style="background: linear-gradient(to right, rgb({{ images.0.image_colours.0.0 }}, {{ images.0.image_colours.0.1 }}, {{ images.0.image_colours.0.2 }}), transparent)" style="background: linear-gradient(to right, rgb({{ images.0.image_colours.0.0 }}, {{ images.0.image_colours.0.1 }}, {{ images.0.image_colours.0.2 }}), transparent)"
></span> ></span>
<div class="banner-content">
<p><span id="contrast-check" data-color="rgb({{ images.0.image_colours.0.0 }}, {{ images.0.image_colours.0.1 }}, {{ images.0.image_colours.0.2 }})">{{ group.description }}</span></p>
<h1><span id="contrast-check" data-color="rgb({{ images.0.image_colours.0.0 }}, {{ images.0.image_colours.0.1 }}, {{ images.0.image_colours.0.2 }})">{{ group.name }}</span></h1>
<p><span id="contrast-check" data-color="rgb({{ images.0.image_colours.0.0 }}, {{ images.0.image_colours.0.1 }}, {{ images.0.image_colours.0.2 }})">{{ images|length }} Images</span></p>
</div>
{% else %} {% else %}
<img src="{{ url_for('static', filename='images/bg.svg') }}" onload="imgFade(this)" style="opacity:0;"/> <img src="{{ url_for('static', filename='images/bg.svg') }}" onload="imgFade(this)" style="opacity:0;"/>
<span></span> <span></span>
{% endif %}
<div class="banner-content"> <div class="banner-content">
<p>{{ group.description }}</p> <p>{{ group.description }}</p>
<h1>{{ group.name }}</h1> <h1>{{ group.name }}</h1>
<p>{{ images|length }} Images</p> <p>{{ images|length }} Images</p>
</div> </div>
{% endif %}
</div> </div>
<form action="/api/group/modify" method="post" enctype="multipart/form-data"> <form id="modifyGroup">
<input type="text" name="group_id" placeholder="group id" value="{{ group.id }}"> <input type="text" name="group" placeholder="group id" value="{{ group.id }}">
<input type="text" name="images" placeholder="image id"> <input type="text" name="image" placeholder="image id">
<input type="text" name="action" placeholder="add/remove" value="add"> <input type="text" name="action" placeholder="add/remove" value="add">
<button type="submit">Submit</button> <button type="submit">Submit</button>
</form> </form>
@ -36,9 +41,9 @@
<div class="gallery-grid"> <div class="gallery-grid">
{% for image in images %} {% for image in images %}
<a id="image-{{ image.id }}" class="gallery-item" href="{{ url_for('group.group_post', group_id=group.id, image_id=image.id) }}" style="background-color: rgb({{ image.image_colours.0.0 }}, {{ image.image_colours.0.1 }}, {{ image.image_colours.0.2 }})"> <a id="image-{{ image.id }}" class="gallery-item" href="{{ url_for('group.group_post', group_id=group.id, image_id=image.id) }}" style="background-color: rgb({{ image.image_colours.0.0 }}, {{ image.image_colours.0.1 }}, {{ image.image_colours.0.2 }})">
<span> <span class="image-filter" style="background: linear-gradient(to top, rgb({{ image.image_colours.0.0 }}, {{ image.image_colours.0.1 }}, {{ image.image_colours.0.2 }}), transparent)">
<p></p> <p></p>
<h2><span class="time">{{ image.created_at }}</span></h2> <h2><span id="contrast-check" data-color="rgb({{ image.image_colours.0.0 }}, {{ image.image_colours.0.1 }}, {{ image.image_colours.0.2 }})"><span class="time">{{ image.created_at }}</span></span></h2>
</span> </span>
<img data-src="{{ image.file_name }}" onload="imgFade(this)" style="opacity:0;" id="lazy-load"/> <img data-src="{{ image.file_name }}" onload="imgFade(this)" style="opacity:0;" id="lazy-load"/>
</a> </a>
@ -57,5 +62,30 @@
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script></script> <script>
// /api/group/modify
modForm = document.querySelector('#modifyGroup');
modForm.addEventListener('submit', function (event) {
event.preventDefault();
const formData = new FormData();
formData.append('group', modForm.group.value);
formData.append('image', modForm.image.value);
formData.append('action', modForm.action.value);
$.ajax({
url: '/api/group/modify',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function (data) {
addNotification('Image added to group', 1);
}
})
})
</script>
{% endblock %} {% endblock %}

View file

@ -24,7 +24,8 @@
<div class="gallery-grid"> <div class="gallery-grid">
{% for group in groups %} {% for group in groups %}
<a id="group-{{ group.id }}" class="gallery-item" href="{{ url_for('group.group', group_id=group.id) }}"> <a id="group-{{ group.id }}" class="gallery-item" href="{{ url_for('group.group', group_id=group.id) }}">
<span> <span class="image-filter">
<p></p>
<h2>{{ group.name }}</h2> <h2>{{ group.name }}</h2>
</span> </span>
{% if group.thumbnail %} {% if group.thumbnail %}

View file

@ -18,9 +18,9 @@
<div class="gallery-grid"> <div class="gallery-grid">
{% for image in images %} {% for image in images %}
<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 }})"> <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> <span class="image-filter" style="background: linear-gradient(to top, rgb({{ image.image_colours.0.0 }}, {{ image.image_colours.0.1 }}, {{ image.image_colours.0.2 }}), transparent)">
<p></p> <p></p>
<h2><span class="time">{{ image.created_at }}</span></h2> <h2><span id="contrast-check" data-color="rgb({{ image.image_colours.0.0 }}, {{ image.image_colours.0.1 }}, {{ image.image_colours.0.2 }})"><span class="time">{{ image.created_at }}</span></span></h2>
</span> </span>
<img data-src="{{ image.file_name }}" onload="imgFade(this)" style="opacity:0;" id="lazy-load"/> <img data-src="{{ image.file_name }}" onload="imgFade(this)" style="opacity:0;" id="lazy-load"/>
</a> </a>

View file

@ -14,9 +14,7 @@
<body> <body>
<div class="notifications"></div> <div class="notifications"></div>
<svg class="jumpUp" xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 24 24" fill="currentColor"> <svg class="jumpUp" 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>
<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>
<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>

View file

@ -1,6 +1,6 @@
.jumpUp .jumpUp
margin: 0 margin: 0
padding: 0.5rem padding: 0.55rem
width: 2.5rem width: 2.5rem
height: 2.5rem height: 2.5rem

View file

@ -21,7 +21,7 @@
box-sizing: border-box box-sizing: border-box
overflow: hidden overflow: hidden
span .image-filter
margin: 0 margin: 0
padding: 0.5rem padding: 0.5rem
@ -30,7 +30,7 @@
position: absolute position: absolute
left: 0 left: 0
bottom: 0 bottom: -1rem
display: flex display: flex
flex-direction: column flex-direction: column
@ -79,15 +79,13 @@
height: 100% height: 100%
position: absolute position: absolute
top: 0 inset: 0
left: 0
right: 0
bottom: 0
object-fit: cover object-fit: cover
object-position: center object-position: center
background-color: $white background-color: $white
transform: scale(1.05)
transition: all 0.3s cubic-bezier(.79, .14, .15, .86) transition: all 0.3s cubic-bezier(.79, .14, .15, .86)
@ -98,6 +96,7 @@
&:hover &:hover
span span
bottom: 0
opacity: 1 opacity: 1
transform: scale(1) transform: scale(1)
@ -105,7 +104,7 @@
opacity: 1 opacity: 1
img img
transform: scale(1.05) transform: scale(1)
@media (max-width: 800px) @media (max-width: 800px)
.gallery-grid .gallery-grid