mirror of
https://github.com/svemagie/blog-eleventy-indiekit.git
synced 2026-04-02 08:44:56 +02:00
fix: use DOM-based dedup instead of timestamp for client-side webmentions
The previous approach filtered client-side webmentions by timestamp (only show items received after buildTime). This missed webmentions that existed in the API but weren't included in the build-time cache (e.g., Bluesky interactions via Bridgy that webmention.io stored but the Eleventy cache plugin didn't fetch). Now scans the DOM for actually-rendered items: author URLs in facepiles for likes/reposts/bookmarks, and wm-url on reply cards. Only appends webmentions not already visible, regardless of when they were received. Confab-Link: http://localhost:8080/sessions/184584f4-67e1-485a-aba8-02ac34a600fe
This commit is contained in:
@@ -57,12 +57,40 @@
|
||||
|
||||
let mentionsToShow;
|
||||
if (hasBuildTimeSection) {
|
||||
// Build-time section exists - only show NEW webmentions to avoid duplicates.
|
||||
// Both webmention.io and conversations items are included at build time,
|
||||
// so filter all by timestamp (only show items received after the build).
|
||||
mentionsToShow = allChildren.filter((wm) => {
|
||||
const wmTime = new Date(wm['wm-received']).getTime();
|
||||
return wmTime > buildTime;
|
||||
// Build-time section exists — deduplicate against what's actually rendered
|
||||
// in the DOM rather than using timestamps (which miss webmentions that the
|
||||
// build-time cache didn't include but that the API returns).
|
||||
|
||||
// Collect author URLs already shown in facepiles (likes, reposts, bookmarks)
|
||||
var renderedAvatars = new Set();
|
||||
document.querySelectorAll('.webmention-likes li[data-author-url], .webmention-reposts li[data-author-url], .webmention-bookmarks li[data-author-url]').forEach(function(li) {
|
||||
var authorUrl = li.dataset.authorUrl;
|
||||
// Determine the type from the parent section class
|
||||
var parent = li.closest('[class*="webmention-"]');
|
||||
var type = 'like-of';
|
||||
if (parent) {
|
||||
if (parent.classList.contains('webmention-reposts')) type = 'repost-of';
|
||||
if (parent.classList.contains('webmention-bookmarks')) type = 'bookmark-of';
|
||||
}
|
||||
if (authorUrl) renderedAvatars.add(authorUrl + '::' + type);
|
||||
});
|
||||
|
||||
// Collect reply URLs already shown in reply cards
|
||||
var renderedReplies = new Set();
|
||||
document.querySelectorAll('.webmention-replies li[data-wm-url]').forEach(function(li) {
|
||||
if (li.dataset.wmUrl) renderedReplies.add(li.dataset.wmUrl);
|
||||
});
|
||||
|
||||
mentionsToShow = allChildren.filter(function(wm) {
|
||||
var prop = wm['wm-property'] || 'mention-of';
|
||||
if (prop === 'in-reply-to') {
|
||||
// Skip replies whose source URL is already rendered
|
||||
return !renderedReplies.has(wm.url);
|
||||
}
|
||||
// Skip likes/reposts/bookmarks whose author is already in a facepile
|
||||
var authorUrl = (wm.author && wm.author.url) || '';
|
||||
if (authorUrl && renderedAvatars.has(authorUrl + '::' + prop)) return false;
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
// No build-time section - show ALL webmentions from API
|
||||
|
||||
Reference in New Issue
Block a user