Skip to content

Initial photoswipe widget support #309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/files/templates/includes/file_pswp_caption.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
<div class="pswp-caption-content" data-bma-file-uuid="{{ file.uuid }}">
<p class="d-inline-block"><i class="{{ file.filetype_icon }}"></i> <a href="{{ file.get_absolute_url }}"><b>{{ file.title }}</b></a></p>
<p class="d-inline-block me-3"><i class="{{ file.filetype_icon }}"></i> <a href="{{ file.get_absolute_url }}"><b>{{ file.title }}</b></a></p>

<span class="d-inline-block me-3"><i class="fas fa-user fa-fw"></i> {{ file.attribution }}</span>

{% if file.description %}
<span class="d-inline-block me-3"><i class="fas fa-newspaper fa-fw"></i> {{ file.description }}</span>
{% endif %}

<span class="d-inline-block me-3">
{% if file.license == "CC_ZERO_1_0" %}<i class="fa-brands fa-creative-commons-zero"></i>{% endif %}
{% if file.license == "CC_BY_4_0" %}<i class="fa-brands fa-creative-commons-by"></i>{% endif %}
{% if file.license == "CC_BY_SA_4_0" %}<i class="fa-brands fa-creative-commons-sa"></i>{% endif %}
{{ file.license_name }}
</span>

{% if file.filetype == "image" %}

{% if file.get_exif_camera %}
Expand Down
2 changes: 1 addition & 1 deletion src/files/templates/includes/file_thumbnail_pswp.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<span class="d-inline-block mb-1">
<span class="d-inline-block m-1">
{% if record.filetype == "image" %}
<a class="gallerya text-decoration-none" href="{{ record.fullsize_url }}"
data-bma-file-uuid="{{ record.uuid }}"
Expand Down
9 changes: 9 additions & 0 deletions src/static_src/css/bma.css
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ div.image-hover i {
position: absolute;
transform: translate(-50%, -50%);
}
div.image-hover div {
display: none;
bottom: 5px;
right: 10px;
position: absolute;
}
div.image-hover:hover div {
display: inline-block;
}
div.image-hover img:hover {
opacity: 0.2;
background-color: black;
Expand Down
3 changes: 3 additions & 0 deletions src/static_src/css/photoswipe-widget.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.photoswipe-attribution-size {
max-width: 130px;
}
12 changes: 11 additions & 1 deletion src/static_src/js/photoswipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const captionPlugin = new PhotoSwipeDynamicCaption(lightbox, {
// Plugins options
type: 'auto',
captionContent: (slide) => {
return slide.data.element.parentElement.querySelector("div.pswp-caption-content").innerHTML
return document.querySelector(`.pswp-caption-content[data-bma-file-uuid="${slide.data.element.dataset.bmaFileUuid}"]`).innerHTML
},
});

Expand Down Expand Up @@ -180,3 +180,13 @@ if (location.hash && location.hash.substring(0, 10) == "#lightbox=") {
let slide = document.querySelector("a.gallerya[data-bma-file-uuid='" + uuid + "']");
slide.click();
}

//Disable license link click propagation
$(".license-link").bind("click", function(e) {
e.stopPropagation();
});

//Disable license link click propagation
$(".attribution-link").bind("click", function(e) {
e.stopPropagation();
});
8 changes: 8 additions & 0 deletions src/utils/templates/thumbnail.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
<div class="image-hover {{ hoverclass }}">
<i class="fas fa-2x"></i>
<img srcset="{{ url }}{{ url2x }}" src="{{ url }}" height="{{ t.height }}" width="{{ width }}" title="{{ title }}" alt="{{ alt }}" class="img-fluid img-thumbnail">
<div>
<object><a class="attribution-link" href="{{ file.get_absolute_url }}"><span title="{{ file.title }} ({{ file.attribution }})" class="fa-regular fa-arrow-up-right-from-square"></span></a></object>
<object><a class="text-decoration-none license-link" href="{{ file.license_url }}">
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{% if file.license == "CC_ZERO_1_0" %}<span title="{{ file.license_name}}" class="fa-brands fa-creative-commons-zero"></span>{% endif %}
{% if file.license == "CC_BY_4_0" %}<span title="{{ file.license_name}}" class="fa-brands fa-creative-commons-by"></span>{% endif %}
{% if file.license == "CC_BY_SA_4_0" %}<span title="{{ file.license_name}}" class="fa-brands fa-creative-commons-sa"></span>{% endif %}
</a></object>
</div>
</div>
1 change: 1 addition & 0 deletions src/utils/templatetags/bma_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ def thumbnail(basefile: "BaseFile", width: int, ratio: str, mimetype: str = "ima
"width": width,
"height": t.height,
"title": title,
"file": basefile,
"alt": alt,
}
)
Expand Down
17 changes: 17 additions & 0 deletions src/widgets/templates/gallery.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{% extends "includes/iframe.html" %}
{% load humanize static %}
{% block extra_head %}
<link rel="stylesheet" href="{% static 'css/vendor/photoswipe-v5.4.4.css' %}">
<link rel="stylesheet" href="{% static 'css/vendor/photoswipe-dynamic-caption-plugin-v1.2.7.css' %}">
{% endblock extra_head %}

{% block main_content %}
<div class="row">
{% csrf_token %}
<div class="pswp-gallery" id="gallery">
{% for file in files %}
{% include "includes/file_thumbnail_pswp.html" with record=file width=150 ratio="1/1" %}
{% endfor %}
</div>
</div>
{% endblock main_content %}
79 changes: 79 additions & 0 deletions src/widgets/templates/includes/base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// config (rendered serverside)
const uuid = "{{ uuid }}";
const host = "{{ host }}";
const count = "{{ count }}";

const templateFiles = "{{ files|escapejs }}";

// custom error class
class BmaNotFoundError extends Error {
constructor(message) {
super(message);
this.name = "BmaNotFoundError";
}
}
class BmaApiError extends Error {
constructor(message) {
super(message);
this.name = "BmaApiError";
}
}
class BmaPermissionError extends Error {
constructor(message) {
super(message);
this.name = "BmaPermissionError";
}
}

const main_loader = document.createElement('div');
main_loader.id = "photoswipe-" + count + "-loader"
main_loader.innerHTML = `<div class="spinner-grow" role="status"></div><span class="h3">Loading Gallery....</span>`;
// A reference to the currently running script
const bma_script = document.scripts[document.scripts.length - 1];
bma_script.parentElement.insertBefore(main_loader, bma_script);


async function getFileMetadata(file_uuid) {
const response = fetch("//" + host + "/api/v1/json/files/" + file_uuid + "/", {mode: 'cors'})
.then((x) => {
if (!x.ok) {
// handle non-2xx x code
if (x.status === 404) {
throw new BmaNotFoundError("File UUID " + file_uuid + " not found!");
} else if (x.status === 403) {
throw new BmaPermissionError("No permission for file UUID " + file_uuid + "!");
} else {
throw new BmaApiError("BMA API returned unexpected x code " + x.status);
}
}
return x.json()
})
.then((x) => ({[file_uuid]: x['bma_response']}))
.catch((response) => {
console.log(response);
});
return response
}

async function getAlbumMetadata(album_uuid) {
const response = fetch("//" + host + "/api/v1/json/albums/" + album_uuid + "/", {mode: 'cors'})
.then((response) => {
if (!response.ok) {
// handle non-2xx response code
if (response.status === 404) {
throw new BmaNotFoundError("Album UUID " + album_uuid + " not found!");
} else if (response.status === 403) {
throw new BmaPermissionError("No permission for album UUID " + album_uuid + "!");
} else {
throw new BmaApiError("BMA API returned unexpected response code " + response.status);
}
}
return response.json();
})
.then((data) => data["bma_response"])
.catch((response) => {
console.log(response);
});
return response;
}

52 changes: 52 additions & 0 deletions src/widgets/templates/includes/iframe.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{% load static %}
{% load django_bootstrap5 %}
{% load django_htmx %}
{% load bma_utils %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}Untitled page{% endblock %} - BornHack Media Archive</title>

<!-- Bootstrap CSS -->
{% bootstrap_css %}

<!-- FontAwesome CSS -->
<link href="{% static 'fontawesomefree/css/fontawesome.css' %}" rel="stylesheet" type="text/css">
<link href="{% static 'fontawesomefree/css/brands.css' %}" rel="stylesheet" type="text/css">
<link href="{% static 'fontawesomefree/css/solid.css' %}" rel="stylesheet" type="text/css">

<!-- Custom stylesheets -->
<link href="{% static "css/bma.css" %}" rel="stylesheet">

<!-- jQuery -->
<script src="{% static "js/vendor/jquery-3.6.0.min.js" %}"></script>

<!-- bootstrap JS -->
{% bootstrap_javascript %}

<!-- Custom javascript -->
<script src="{% static "js/bma.js" %}" defer></script>

<!-- BMA version -->
{{ bma_version|json_script:"bma-version" }}

{% block extra_head %}{% endblock %}
</head>

<body class="d-flex flex-column min-vh-100 bma-no-js {% block body-extra-classes %}{% endblock %}">
{% block body %}
<main class="flex-shrink-0">
<div class="container-fluid">
{% bootstrap_messages %}
<!-- Begin page content -->
{% block main_content %}
<p class="lead">This is the default content of the block 'body' in the iframe.html template of the BMA widget. Please replace in templates inheriting from iframe.html</p>
{% endblock main_content %}
</div>
</main>
{% endblock body %}
</body>
</html>

Loading
Loading