You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
6.8 KiB
162 lines
6.8 KiB
{% extends 'layout.html.twig' %} |
|
|
|
{% block body %} |
|
|
|
{% if author.image is defined %} |
|
<img src="{{ author.image }}" class="avatar" alt="{{ author.name }}" onerror="this.style.display = 'none'" /> |
|
{% endif %} |
|
|
|
<h1><twig:Atoms:NameOrNpub :author="author" :npub="npub"></twig:Atoms:NameOrNpub></h1> |
|
{% if author.nip05 is defined %} |
|
{% if author.nip05 is iterable %} |
|
{% for nip05Value in author.nip05 %} |
|
<twig:Atoms:Nip05Badge |
|
nip05="{{ nip05Value }}" |
|
:npub="npub" |
|
/> |
|
{% endfor %} |
|
{% else %} |
|
<twig:Atoms:Nip05Badge |
|
nip05="{{ author.nip05 }}" |
|
:npub="npub" |
|
/> |
|
{% endif %} |
|
{% endif %} |
|
<div class="mt-2"> |
|
{% if author.about is defined %} |
|
{{ author.about|markdown_to_html|mentionify|linkify }} |
|
{% endif %} |
|
</div> |
|
|
|
<div class="profile-tabs"> |
|
<a href="{{ path('author-profile', {'npub': npub}) }}" class="tab-link">Articles</a> |
|
<a href="{{ path('author-media', {'npub': npub}) }}" class="tab-link active">Media</a> |
|
{% if is_granted('ROLE_ADMIN') %} |
|
<a href="{{ path('author-about', {'npub': npub}) }}" class="tab-link">About</a> |
|
{% endif %} </div> |
|
|
|
<div class="w-container"> |
|
{% if pictureEvents|length > 0 %} |
|
<div class="masonry-grid"> |
|
{% for event in pictureEvents %} |
|
<div class="masonry-item"> |
|
{# Extract title #} |
|
{% set title = null %} |
|
{% for tag in event.tags %} |
|
{% if tag[0] == 'title' %} |
|
{% set title = tag[1] %} |
|
{% endif %} |
|
{% endfor %} |
|
|
|
{# Extract first image from imeta tags #} |
|
{% set firstImageUrl = null %} |
|
{% set firstVideoUrl = null %} |
|
{% set imageAlt = null %} |
|
{% set isVideo = false %} |
|
{% for tag in event.tags %} |
|
{% if tag[0] == 'imeta' %} |
|
{% set videoUrl = null %} |
|
{% set imageUrl = null %} |
|
{% for i in 1..(tag|length - 1) %} |
|
{% set param = tag[i] %} |
|
{% if param starts with 'url ' %} |
|
{% set potentialUrl = param[4:] %} |
|
{# Check if it's a video URL #} |
|
{% if potentialUrl matches '/\\.(mp4|webm|ogg|mov)$/i' or potentialUrl matches '/video/i' %} |
|
{% set videoUrl = potentialUrl %} |
|
{% set isVideo = true %} |
|
{% else %} |
|
{% set imageUrl = potentialUrl %} |
|
{% endif %} |
|
{% elseif param starts with 'image ' %} |
|
{# Preview image for video #} |
|
{% set imageUrl = param[6:] %} |
|
{% elseif param starts with 'alt ' %} |
|
{% set imageAlt = param[4:] %} |
|
{% endif %} |
|
{% endfor %} |
|
{# Set the first video and image found #} |
|
{% if videoUrl and firstVideoUrl is null %} |
|
{% set firstVideoUrl = videoUrl %} |
|
{% endif %} |
|
{% if imageUrl and firstImageUrl is null %} |
|
{% set firstImageUrl = imageUrl %} |
|
{% endif %} |
|
{% endif %} |
|
{% endfor %} |
|
|
|
{# Generate nevent for linking #} |
|
{% set eventId = event.id %} |
|
{% set noteId = event.noteId %} |
|
|
|
<a href="/e/{{ noteId }}" class="masonry-link"> |
|
{% if firstImageUrl %} |
|
<div class="masonry-image-container"> |
|
<img src="{{ firstImageUrl }}" |
|
alt="{{ imageAlt|default(title|default(isVideo ? 'Video' : 'Picture')) }}" |
|
class="masonry-image" |
|
loading="lazy" /> |
|
{% if isVideo %} |
|
<div class="video-overlay"> |
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="white" opacity="0.9"> |
|
<path d="M8 5v14l11-7z"/> |
|
</svg> |
|
</div> |
|
{% endif %} |
|
</div> |
|
{% endif %} |
|
|
|
{% if title %} |
|
<div class="masonry-caption"> |
|
<h3>{{ title }}</h3> |
|
</div> |
|
{% endif %} |
|
|
|
{% if event.content %} |
|
<div class="masonry-description mt-1"> |
|
{{ event.content|length > 100 ? event.content[:100] ~ '...' : event.content }} |
|
</div> |
|
{% endif %} |
|
|
|
<div class="masonry-meta"> |
|
<span class="event-date">{{ event.created_at|date('M j, Y') }}</span> |
|
</div> |
|
</a> |
|
</div> |
|
{% endfor %} |
|
</div> |
|
{% else %} |
|
<div class="no-media"> |
|
<p>No media found for this author.</p> |
|
</div> |
|
{% endif %} |
|
</div> |
|
{% endblock %} |
|
|
|
{% block stylesheets %} |
|
{{ parent() }} |
|
<style> |
|
.masonry-image-container { |
|
position: relative; |
|
} |
|
|
|
.video-overlay { |
|
position: absolute; |
|
top: 50%; |
|
left: 50%; |
|
transform: translate(-50%, -50%); |
|
pointer-events: none; |
|
background: rgba(0, 0, 0, 0.5); |
|
border-radius: 50%; |
|
width: 64px; |
|
height: 64px; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
} |
|
|
|
.video-overlay svg { |
|
margin-left: 4px; |
|
} |
|
</style> |
|
{% endblock %}
|
|
|