python-gallery/onlylegs/templates/image.html

250 lines
17 KiB
HTML

{% extends 'layout.html' %}
{% block page_index %}
{% if return_page %}?page={{ return_page }}{% endif %}{% endblock %}
{% block head %}
<meta property="og:image" content="{{ url_for('api.file', file_name=image.filename) }}"/>
<meta name="theme-color" content="rgb({{ image.colours.0.0 }}{{ image.colours.0.1 }}{{ image.colours.0.2 }})"/>
<script type="text/javascript">
function imageShare() {
try {
navigator.clipboard.writeText(window.location.href)
addNotification("Copied link!", 4);
} catch (err) {
addNotification("Failed to copy link! Are you on HTTP?", 2);
}
}
function fullscreen() {
let info = document.querySelector('.info-container');
let wrapper = document.querySelector('.image-grid');
if (info.classList.contains('collapsed')) {
info.classList.remove('collapsed');
wrapper.classList.remove('collapsed');
} else {
info.classList.add('collapsed');
wrapper.classList.add('collapsed');
}
}
{% if current_user.id == image.author.id %}
function imageDelete() {
cancelBtn = document.createElement('button');
cancelBtn.classList.add('btn-block');
cancelBtn.classList.add('transparent');
cancelBtn.innerHTML = 'nuuuuuuuu';
cancelBtn.onclick = popupDissmiss;
deleteBtn = document.createElement('button');
deleteBtn.classList.add('btn-block');
deleteBtn.classList.add('critical');
deleteBtn.innerHTML = 'Dewww eeeet!';
deleteBtn.onclick = deleteConfirm;
popUpShow('DESTRUCTION!!!!!!',
'Do you want to delete this image along with all of its data??? ' +
'This action is irreversible!',
null,
[cancelBtn, deleteBtn]);
}
function deleteConfirm() {
popupDissmiss();
fetch('{{ url_for('api.delete_image', image_id=image['id']) }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: 'delete'
})
}).then(function(response) {
if (response.ok) {
window.location.href = '/';
} else {
addNotification(`Image *clings*`, 2);
}
});
}
function imageEdit() {
addNotification("Not an option, oops!", 3);
}
{% endif %}
</script>
<style>
.background span {
background-image: linear-gradient(to top, rgba({{ image.colours.0.0 }}, {{ image.colours.0.1 }}, {{ image.colours.0.2 }}, 0.8),
rgba({{ image.colours.1.0 }}, {{ image.colours.1.1 }}, {{ image.colours.1.2 }}, 0.2));
}
</style>
{% endblock %}
{% block content %}
<div class="background">
<img src="{{ url_for('api.file', file_name=image.filename) }}?r=prev" alt="{{ image.alt }}" onload="imgFade(this)" style="opacity:0;"/>
<span></span>
</div>
<div class="image-grid">
<div class="image-block">
<div class="image-container">
<img
src="{{ url_for('api.file', file_name=image.filename) }}?r=prev"
alt="{{ image.alt }}"
onload="imgFade(this)"
style="opacity: 0;"
onerror="this.src='{{ url_for('static', filename='error.png')}}'"
{% if "File" in image.exif %}
width="{{ image.exif.File.Width.raw }}"
height="{{ image.exif.File.Height.raw }}"
{% endif %}
/>
</div>
<div class="pill-row">
{% if next_url %}
<div>
<a class="pill-item" href="{{ next_url }}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M224,128a8,8,0,0,1-8,8H59.31l58.35,58.34a8,8,0,0,1-11.32,11.32l-72-72a8,8,0,0,1,0-11.32l72-72a8,8,0,0,1,11.32,11.32L59.31,120H216A8,8,0,0,1,224,128Z"></path></svg>
</a>
</div>
{% endif %}
<div>
<button class="pill-item" onclick="fullscreen()" id="fullscreenImage">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,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,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path></svg>
</button>
<button class="pill-item" onclick="imageShare()">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><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>
</button>
<a class="pill-item" href="/api/file/{{ image.filename }}" download onclick="addNotification('Download started!', 4)">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,82.34l-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40V216a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM160,51.31,188.69,80H160ZM200,216H56V40h88V88a8,8,0,0,0,8,8h48V216Zm-42.34-61.66a8,8,0,0,1,0,11.32l-24,24a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L120,164.69V120a8,8,0,0,1,16,0v44.69l10.34-10.35A8,8,0,0,1,157.66,154.34Z"></path></svg>
</a>
</div>
{% if current_user.id == image.author.id %}
<div>
<button class="pill-item pill__critical" onclick="imageDelete()">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM96,40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8v8H96Zm96,168H64V64H192ZM112,104v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Z"></path></svg>
</button>
<button class="pill-item pill__critical" onclick="imageEdit()">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M227.31,73.37,182.63,28.68a16,16,0,0,0-22.63,0L36.69,152A15.86,15.86,0,0,0,32,163.31V208a16,16,0,0,0,16,16H92.69A15.86,15.86,0,0,0,104,219.31L227.31,96a16,16,0,0,0,0-22.63ZM92.69,208H48V163.31l88-88L180.69,120ZM192,108.68,147.31,64l24-24L216,84.68Z"></path></svg>
</button>
</div>
{% endif %}
{% if prev_url %}
<div>
<a class="pill-item" href="{{ prev_url }}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M221.66,133.66l-72,72a8,8,0,0,1-11.32-11.32L196.69,136H40a8,8,0,0,1,0-16H196.69L138.34,61.66a8,8,0,0,1,11.32-11.32l72,72A8,8,0,0,1,221.66,133.66Z"></path></svg>
</a>
</div>
{% endif %}
</div>
</div>
<div class="info-container">
<div class="info-tab">
<div class="info-header">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,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,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path></svg>
<h2>Info</h2>
<button class="collapse-indicator">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-5 -8 24 24" fill="currentColor">
<path d="M7.071 5.314l4.95-4.95a1 1 0 1 1 1.414 1.414L7.778 7.435a1 1 0 0 1-1.414 0L.707 1.778A1 1 0 1 1 2.121.364l4.95 4.95z"></path>
</svg>
</button>
</div>
<div class="info-table">
<table>
<tr>
<td>Author</td>
<td><a href="{{ url_for('profile.profile', id=image.author.id) }}" class="link">{{ image.author.username }}</a></td>
</tr>
<tr>
<td>Upload date</td>
<td><span class="time">{{ image.created_at }}</span></td>
</tr>
{% if image.description %}
<tr>
<td>Description</td>
<td>{{ image.description }}</td>
</tr>
{% endif %}
</table>
<div class="img-colours">
{% for col in image.colours %}
<span style="background-color: rgb({{col.0}}, {{col.1}}, {{col.2}})"></span>
{% endfor %}
</div>
{% if image.groups %}
<div class="img-groups">
{% for group in image.groups %}
<a href="{{ url_for('group.group', group_id=group.id) }}" class="tag-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M216,72H131.31L104,44.69A15.86,15.86,0,0,0,92.69,40H40A16,16,0,0,0,24,56V200.62A15.4,15.4,0,0,0,39.38,216H216.89A15.13,15.13,0,0,0,232,200.89V88A16,16,0,0,0,216,72ZM40,56H92.69l16,16H40ZM216,200H40V88H216Z"></path></svg>
{{ group['name'] }}
</a>
{% endfor %}
</div>
{% endif %}
</div>
</div>
{% for tag in image.exif %}
<div class="info-tab">
<div class="info-header">
{% if tag == 'Photographer' %}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M160,40a32,32,0,1,0-32,32A32,32,0,0,0,160,40ZM128,56a16,16,0,1,1,16-16A16,16,0,0,1,128,56Zm90.34,78.05L173.17,82.83a32,32,0,0,0-24-10.83H106.83a32,32,0,0,0-24,10.83L37.66,134.05a20,20,0,0,0,28.13,28.43l16.3-13.08L65.55,212.28A20,20,0,0,0,102,228.8l26-44.87,26,44.87a20,20,0,0,0,36.41-16.52L173.91,149.4l16.3,13.08a20,20,0,0,0,28.13-28.43Zm-11.51,16.77a4,4,0,0,1-5.66,0c-.21-.2-.42-.4-.65-.58L165,121.76A8,8,0,0,0,152.26,130L175.14,217a7.72,7.72,0,0,0,.48,1.35,4,4,0,1,1-7.25,3.38,6.25,6.25,0,0,0-.33-.63L134.92,164a8,8,0,0,0-13.84,0L88,221.05a6.25,6.25,0,0,0-.33.63,4,4,0,0,1-2.26,2.07,4,4,0,0,1-5-5.45,7.72,7.72,0,0,0,.48-1.35L103.74,130A8,8,0,0,0,91,121.76L55.48,150.24c-.23.18-.44.38-.65.58a4,4,0,1,1-5.66-5.65c.12-.12.23-.24.34-.37L94.83,93.41a16,16,0,0,1,12-5.41h42.34a16,16,0,0,1,12,5.41l45.32,51.39c.11.13.22.25.34.37A4,4,0,0,1,206.83,150.82Z"></path></svg>
<h2>Photographer</h2>
{% elif tag == 'Camera' %}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M208,56H180.28L166.65,35.56A8,8,0,0,0,160,32H96a8,8,0,0,0-6.65,3.56L75.71,56H48A24,24,0,0,0,24,80V192a24,24,0,0,0,24,24H208a24,24,0,0,0,24-24V80A24,24,0,0,0,208,56Zm8,136a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V80a8,8,0,0,1,8-8H80a8,8,0,0,0,6.66-3.56L100.28,48h55.43l13.63,20.44A8,8,0,0,0,176,72h32a8,8,0,0,1,8,8ZM128,88a44,44,0,1,0,44,44A44.05,44.05,0,0,0,128,88Zm0,72a28,28,0,1,1,28-28A28,28,0,0,1,128,160Z"></path></svg>
<h2>Camera</h2>
{% elif tag == 'Software' %}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M24,96v72a8,8,0,0,0,8,8h80a8,8,0,0,1,0,16H96v16h16a8,8,0,0,1,0,16H64a8,8,0,0,1,0-16H80V192H32A24,24,0,0,1,8,168V96A24,24,0,0,1,32,72h80a8,8,0,0,1,0,16H32A8,8,0,0,0,24,96ZM208,64H176a8,8,0,0,0,0,16h32a8,8,0,0,0,0-16Zm0,32H176a8,8,0,0,0,0,16h32a8,8,0,0,0,0-16Zm40-48V208a16,16,0,0,1-16,16H152a16,16,0,0,1-16-16V48a16,16,0,0,1,16-16h80A16,16,0,0,1,248,48ZM232,208V48H152V208h80Zm-40-40a12,12,0,1,0,12,12A12,12,0,0,0,192,168Z"></path></svg>
<h2>Software</h2>
{% elif tag == 'File' %}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M110.66,147.56a8,8,0,0,0-13.32,0L76.49,178.85l-9.76-15.18a8,8,0,0,0-13.46,0l-36,56A8,8,0,0,0,24,232H152a8,8,0,0,0,6.66-12.44ZM38.65,216,60,182.79l9.63,15a8,8,0,0,0,13.39.11l21-31.47L137.05,216Zm175-133.66-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40v96a8,8,0,0,0,16,0V40h88V88a8,8,0,0,0,8,8h48V216h-8a8,8,0,0,0,0,16h8a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM160,51.31,188.69,80H160Z"></path></svg>
<h2>File</h2>
{% else %}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M110.66,147.56a8,8,0,0,0-13.32,0L76.49,178.85l-9.76-15.18a8,8,0,0,0-13.46,0l-36,56A8,8,0,0,0,24,232H152a8,8,0,0,0,6.66-12.44ZM38.65,216,60,182.79l9.63,15a8,8,0,0,0,13.39.11l21-31.47L137.05,216Zm175-133.66-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40v96a8,8,0,0,0,16,0V40h88V88a8,8,0,0,0,8,8h48V216h-8a8,8,0,0,0,0,16h8a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM160,51.31,188.69,80H160Z"></path></svg>
<h2>{{ tag }}</h2>
{% endif %}
<button class="collapse-indicator">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-5 -8 24 24" fill="currentColor">
<path d="M7.071 5.314l4.95-4.95a1 1 0 1 1 1.414 1.414L7.778 7.435a1 1 0 0 1-1.414 0L.707 1.778A1 1 0 1 1 2.121.364l4.95 4.95z"></path>
</svg>
</button>
</div>
<div class="info-table">
<table>
{% for subtag in image.exif[tag] %}
<tr>
<td>{{ subtag }}</td>
{% if image.exif[tag][subtag]['formatted'] %}
{% if image.exif[tag][subtag]['type'] == 'date' %}
<td><span class="time">{{ image.exif[tag][subtag]['formatted'] }}</span></td>
{% else %}
<td>{{ image.exif[tag][subtag]['formatted'] }}</td>
{% endif %}
{% elif image.exif[tag][subtag]['raw'] %}
<td>{{ image.exif[tag][subtag]['raw'] }}</td>
{% else %}
<td class="empty-table">Oops, an error</td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
{% block script %}
<script type="text/javascript">
let infoTab = document.querySelectorAll('.info-tab');
for (let i = 0; i < infoTab.length; i++) {
infoTab[i].querySelector('.collapse-indicator').addEventListener('click', function() {
infoTab[i].classList.toggle('collapsed');
});
}
</script>
{% endblock %}