Sith/sas/templates/sas/album.jinja

231 lines
6.7 KiB
Django/Jinja

{% extends "core/base.jinja" %}
{% from 'core/macros.jinja' import paginate_alpine %}
{%- block additional_css -%}
<link rel="stylesheet" href="{{ static('sas/css/album.scss') }}">
{%- endblock -%}
{%- block additional_js -%}
<script src="{{ static('webpack/sas/album-index.js') }}" defer></script>
{%- endblock -%}
{% block title %}
{% trans %}SAS{% endtrans %}
{% endblock %}
{% from "sas/macros.jinja" import display_album, print_path %}
{% block content %}
<code>
<a href="{{ url('sas:main') }}">SAS</a> / {{ print_path(album.parent) }} {{ album.get_display_name() }}
</code>
{% set is_sas_admin = user.can_edit(album) %}
{% set start = timezone.now() %}
{% if is_sas_admin %}
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="album-navbar">
<h3>{{ album.get_display_name() }}</h3>
<div class="toolbar">
<a href="{{ url('sas:album_edit', album_id=album.id) }}">{% trans %}Edit{% endtrans %}</a>
<input name="delete" type="submit" value="{% trans %}Delete{% endtrans %}">
<input name="cut" type="submit" value="{% trans %}Cut{% endtrans %}">
<input {% if not clipboard %}disabled{% endif %} name="paste" type="submit" value="{% trans %}Paste{% endtrans %}">
</div>
</div>
{% if clipboard %}
<div class="clipboard">
{% trans %}Clipboard: {% endtrans %}
<ul>
{% for f in clipboard %}
<li>{{ f.get_full_path() }}</li>
{% endfor %}
</ul>
<input name="clear" type="submit" value="{% trans %}Clear clipboard{% endtrans %}">
</div>
{% endif %}
{% endif %}
{% if children_albums|length > 0 %}
<h4>{% trans %}Albums{% endtrans %}</h4>
<div class="albums">
{% for a in children_albums %}
{{ display_album(a, is_sas_admin) }}
{% endfor %}
</div>
<br>
{% endif %}
<div x-data="pictures">
<h4>{% trans %}Pictures{% endtrans %}</h4>
<div class="photos" :aria-busy="loading">
<template x-for="picture in pictures.results">
<a :href="`/sas/picture/${picture.id}`">
<div
class="photo"
:class="{not_moderated: !picture.is_moderated}"
:style="`background-image: url(${picture.thumb_url})`"
>
<template x-if="!picture.is_moderated">
<div class="overlay">&nbsp;</div>
<div class="text">{% trans %}To be moderated{% endtrans %}</div>
</template>
<template x-if="picture.is_moderated">
<div class="text">&nbsp;</div>
</template>
</div>
{% if is_sas_admin %}
<input type="checkbox" name="file_list" :value="picture.id">
{% endif %}
</a>
</template>
</div>
{{ paginate_alpine("page", "nbPages()") }}
</div>
{% if is_sas_admin %}
</form>
<form class="add-files" id="upload_form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="inputs">
{{ form.as_p() }}
<input type="submit" value="{% trans %}Upload{% endtrans %}" />
</div>
</form>
{% endif %}
<hr>
<p style="font-size: small; color: #444;">{% trans %}Template generation time: {% endtrans %}
{{ timezone.now() - start }}
</p>
{% endblock %}
{% block script %}
{{ super() }}
<script>
window.addEventListener("DOMContentLoaded", () => {
loadAlbum({
albumId: {{ album.id }},
maxPageSize: {{ settings.SITH_SAS_IMAGES_PER_PAGE }},
});
});
// Todo: migrate to alpine.js if we have some time
$("form#upload_form").submit(function (event) {
let formData = new FormData($(this)[0]);
if(!formData.get('album_name') && !formData.get('images').name)
return false;
if(!formData.get('images').name) {
return true;
}
event.preventDefault();
let errorList;
if((errorList = this.querySelector('#upload_form ul.errorlist.nonfield')) === null) {
errorList = document.createElement('ul');
errorList.classList.add('errorlist', 'nonfield');
this.insertBefore(errorList, this.firstElementChild);
}
while(errorList.childElementCount > 0)
errorList.removeChild(errorList.firstElementChild);
let progress;
if((progress = this.querySelector('progress')) === null) {
progress = document.createElement('progress');
progress.value = 0;
let p = document.createElement('p');
p.appendChild(progress);
this.insertBefore(p, this.lastElementChild);
}
let dataHolder;
if(formData.get('album_name')) {
dataHolder = new FormData();
dataHolder.set('csrfmiddlewaretoken', '{{ csrf_token }}');
dataHolder.set('album_name', formData.get('album_name'));
$.ajax({
method: 'POST',
url: "{{ url('sas:album_upload', album_id=object.id) }}",
data: dataHolder,
processData: false,
contentType: false,
success: onSuccess
});
}
let images = formData.getAll('images');
let imagesCount = images.length;
let completeCount = 0;
let poolSize = 1;
let imagePool = [];
while(images.length > 0 && imagePool.length < poolSize) {
let image = images.shift();
imagePool.push(image);
sendImage(image);
}
function sendImage(image) {
dataHolder = new FormData();
dataHolder.set('csrfmiddlewaretoken', '{{ csrf_token }}');
dataHolder.set('images', image);
$.ajax({
method: 'POST',
url: "{{ url('sas:album_upload', album_id=object.id) }}",
data: dataHolder,
processData: false,
contentType: false,
})
.fail(onSuccess.bind(undefined, image))
.done(onSuccess.bind(undefined, image))
.always(next.bind(undefined, image));
}
function next(image, _, __) {
let index = imagePool.indexOf(image);
let nextImage = images.shift();
if(index !== -1)
imagePool.splice(index, 1);
if(nextImage) {
imagePool.push(nextImage);
sendImage(nextImage);
}
}
function onSuccess(image, data, _, __) {
let errors = [];
if ($(data.responseText).find('.errorlist.nonfield')[0])
errors = Array.from($(data.responseText).find('.errorlist.nonfield')[0].children);
while(errors.length > 0)
errorList.appendChild(errors.shift());
progress.value = ++completeCount / imagesCount;
if(progress.value === 1 && errorList.children.length === 0)
document.location.reload()
}
});
</script>
{% endblock %}