feat: merge Mastodon/AP thread replies into webmention Replies section
Build & Deploy / build-and-deploy (push) Has been cancelled

This commit is contained in:
svemagie
2026-04-20 17:47:28 +02:00
parent 17ab259cd8
commit 67585971c3
+55 -8
View File
@@ -110,28 +110,45 @@
</div> </div>
{% endif %} {% endif %}
{# Replies — webmention replies merged with Bluesky thread (deduplicated) #} {# Replies — webmention replies merged with Bluesky + Mastodon/AP threads (deduplicated) #}
{% set wm_replies = mentions | webmentionsByType('replies') %} {% set wm_replies = mentions | webmentionsByType('replies') %}
{# Detect Bluesky syndication URL #}
{% set bskySyndUrl = "" %} {% set bskySyndUrl = "" %}
{% if syndication %} {% if syndication %}
{% for url in syndication %} {% for url in syndication %}
{% if "bsky.app" in url %}{% set bskySyndUrl = url %}{% endif %} {% if "bsky.app" in url %}{% set bskySyndUrl = url %}{% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{# Filter out Bluesky-sourced webmention replies when a direct thread is available #}
{# Detect Mastodon/AP activity: check if any webmention reply came via fed.brid.gy #}
{% set mastodonInstance = site.feeds.mastodon.instance %}
{% set apIdentity = site.fediverseCreator %}
{% set hasApReplies = false %}
{% for reply in wm_replies %}
{% if 'fed.brid.gy' in reply['wm-source'] | default('') %}{% set hasApReplies = true %}{% endif %}
{% endfor %}
{% set mastodonActive = mastodonInstance and hasApReplies %}
{% set replyComponentActive = bskySyndUrl or mastodonActive %}
{# Filter: remove Bluesky-sourced webmentions if bskySyndUrl; remove fed.brid.gy webmentions if mastodonActive #}
{% set filtered_replies = [] %} {% set filtered_replies = [] %}
{% for reply in wm_replies %} {% for reply in wm_replies %}
{% set src = reply['wm-source'] | default('') %} {% set src = reply['wm-source'] | default('') %}
{% if not bskySyndUrl or ('bsky.app' not in src and 'brid.gy' not in src and 'bridgy' not in src) %} {% set includeReply = true %}
{% if bskySyndUrl and ('bsky.app' in src or 'brid.gy' in src or 'bridgy' in src) %}{% set includeReply = false %}{% endif %}
{% if mastodonActive and 'fed.brid.gy' in src %}{% set includeReply = false %}{% endif %}
{% if includeReply %}
{% set filtered_replies = (filtered_replies.push(reply), filtered_replies) %} {% set filtered_replies = (filtered_replies.push(reply), filtered_replies) %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% if filtered_replies.length or bskySyndUrl %}
<div class="webmention-replies"{% if bskySyndUrl %} x-data="bskyThread('{{ bskySyndUrl }}')"{% endif %}> {% if filtered_replies.length or replyComponentActive %}
{% set wmRepliesCount = filtered_replies.length %} {% set wmRepliesCount = filtered_replies.length %}
<div class="webmention-replies"{% if replyComponentActive %} x-data="socialReplies('{{ bskySyndUrl }}', '{{ absoluteUrl }}', '{{ mastodonInstance if mastodonActive else "" }}', '{{ apIdentity if mastodonActive else "" }}')"{% endif %}>
<h3 class="text-sm font-semibold text-surface-600 dark:text-surface-400 uppercase tracking-wide mb-4" <h3 class="text-sm font-semibold text-surface-600 dark:text-surface-400 uppercase tracking-wide mb-4"
{% if bskySyndUrl %}x-text="({{ wmRepliesCount }} + replies.length) + ' Repl' + (({{ wmRepliesCount }} + replies.length !== 1) ? 'ies' : 'y')"{% endif %}> {% if replyComponentActive %}x-text="({{ wmRepliesCount }} + bskyReplies.length + mastodonReplies.length) + ' Repl' + (({{ wmRepliesCount }} + bskyReplies.length + mastodonReplies.length !== 1) ? 'ies' : 'y')"{% endif %}>
{% if not bskySyndUrl %}{{ wmRepliesCount }} Repl{% if wmRepliesCount != 1 %}ies{% else %}y{% endif %}{% endif %} {% if not replyComponentActive %}{{ wmRepliesCount }} Repl{% if wmRepliesCount != 1 %}ies{% else %}y{% endif %}{% endif %}
</h3> </h3>
<ul class="space-y-4"> <ul class="space-y-4">
{% for reply in filtered_replies %} {% for reply in filtered_replies %}
@@ -190,7 +207,7 @@
</li> </li>
{% endfor %} {% endfor %}
{% if bskySyndUrl %} {% if bskySyndUrl %}
<template x-for="reply in replies" :key="reply.uri"> <template x-for="reply in bskyReplies" :key="reply.uri">
<li class="p-4 bg-surface-50 dark:bg-surface-800 rounded-lg border border-surface-200 dark:border-surface-700 shadow-sm" <li class="p-4 bg-surface-50 dark:bg-surface-800 rounded-lg border border-surface-200 dark:border-surface-700 shadow-sm"
:class="reply.depth > 0 ? 'ml-4 sm:ml-8' : ''"> :class="reply.depth > 0 ? 'ml-4 sm:ml-8' : ''">
<div class="flex gap-3"> <div class="flex gap-3">
@@ -220,6 +237,36 @@
</li> </li>
</template> </template>
{% endif %} {% endif %}
{% if mastodonActive %}
<template x-for="reply in mastodonReplies" :key="reply.id">
<li class="p-4 bg-surface-50 dark:bg-surface-800 rounded-lg border border-surface-200 dark:border-surface-700 shadow-sm">
<div class="flex gap-3">
<a :href="reply.author.url" target="_blank" rel="noopener" class="flex-shrink-0">
<img :src="reply.author.avatar || '/images/default-avatar.svg'"
:alt="reply.author.name"
class="w-10 h-10 rounded-full"
loading="lazy">
</a>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1 flex-wrap">
<a :href="reply.author.url"
class="font-semibold text-surface-900 dark:text-surface-100 hover:underline"
target="_blank" rel="noopener"
x-text="reply.author.name"></a>
<span class="wm-provenance-badge" data-source="mastodon"></span>
<a :href="reply.url"
class="text-xs text-surface-600 dark:text-surface-400 hover:underline"
target="_blank" rel="noopener">
<time :datetime="reply.published" x-text="formatDate(reply.published)"></time>
</a>
</div>
<div class="text-surface-700 dark:text-surface-300 prose dark:prose-invert prose-sm max-w-none"
x-html="reply.content"></div>
</div>
</div>
</li>
</template>
{% endif %}
</ul> </ul>
</div> </div>
{% endif %} {% endif %}