summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPinapelz <yukais@pinapelz.com>2025-12-02 15:54:53 -0800
committerPinapelz <yukais@pinapelz.com>2025-12-02 15:54:53 -0800
commit081aa6bca4c079db2ac200acb331319e93c788a1 (patch)
tree87c3c45ddc3f346835d8129b47114fbb9ba4432e
parent32c01f72e70eaa003b4d84e89cce4e17652bb7e8 (diff)
make likes and repost more compact
-rw-r--r--indieweb-micro/themes/MinIndie/layouts/partials/webmentions.html261
-rw-r--r--micro.pinapelz.moe/posts/2025-12-01-hello-world/index.html259
-rw-r--r--micro.pinapelz.moe/posts/2025-12-02-china-town-fair/index.html259
3 files changed, 637 insertions, 142 deletions
diff --git a/indieweb-micro/themes/MinIndie/layouts/partials/webmentions.html b/indieweb-micro/themes/MinIndie/layouts/partials/webmentions.html
index ff572c7..86b2f51 100644
--- a/indieweb-micro/themes/MinIndie/layouts/partials/webmentions.html
+++ b/indieweb-micro/themes/MinIndie/layouts/partials/webmentions.html
@@ -15,27 +15,94 @@
margin-bottom: 1rem;
}
-/* Compact list */
.wm-list {
display: flex;
flex-direction: column;
+ gap: 1.5rem;
+}
+
+/* Compact reaction sections */
+.wm-reactions {
+ margin-bottom: 1.5rem;
+}
+
+.wm-reaction-group {
+ margin-bottom: 1rem;
+}
+
+.wm-reaction-title {
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: var(--titlecolor);
+ margin-bottom: 0.5rem;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.wm-avatar-grid {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 4px;
+ align-items: center;
+}
+
+.wm-avatar {
+ position: relative;
+ display: inline-block;
+}
+
+.wm-avatar img {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ border: 2px solid var(--hrcolor);
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.wm-avatar:hover img {
+ transform: scale(1.1);
+ box-shadow: 0 4px 12px rgba(255, 140, 200, 0.4);
+}
+
+.wm-avatar-tooltip {
+ position: absolute;
+ bottom: 120%;
+ left: 50%;
+ transform: translateX(-50%);
+ background: var(--blockquotecolor);
+ color: var(--titlecolor);
+ padding: 4px 8px;
+ border-radius: 4px;
+ font-size: 0.8rem;
+ white-space: nowrap;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.2s ease;
+ z-index: 10;
+ border: 1px solid var(--hrcolor);
+}
+
+.wm-avatar:hover .wm-avatar-tooltip {
+ opacity: 1;
+}
+
+/* Regular webmentions (replies, mentions) */
+.wm-regular {
+ display: flex;
+ flex-direction: column;
gap: 0.75rem;
}
-/* More compact card */
.wm {
display: flex;
gap: 0.6rem;
padding: 0.6rem 0.75rem;
border-radius: 10px;
-
background: var(--alertbgcolor);
border: 1px solid var(--hrcolor);
-
box-shadow: 0 0 6px rgba(255, 180, 220, 0.22);
}
-/* Smaller avatar */
.wm-author img {
width: 32px;
height: 32px;
@@ -43,13 +110,11 @@
box-shadow: 0 0 4px rgba(255, 140, 200, 0.35);
}
-/* Body stays compact */
.wm-body {
flex: 1;
font-size: 0.9rem;
}
-/* Name */
.wm-author-name a {
font-weight: 600;
color: var(--linkcolor);
@@ -61,38 +126,45 @@
color: var(--titlecolor);
}
-/* Tiny compact content bubble */
.wm-content {
margin-top: 4px;
padding: 6px 8px;
font-size: 0.9rem;
-
background: var(--blockquotecolor);
border-left: 3px solid var(--hrcolor);
border-radius: 6px;
}
-/* Meta line smaller */
.wm-meta {
margin-top: 3px;
font-size: 0.75rem;
opacity: 0.7;
}
-/* Mobile compact layout */
-@media (max-width: 800px) {
- .wm {
- flex-direction: column;
- text-align: left;
+.wm-meta a {
+ color: var(--linkcolor);
+}
+
+/* Mobile responsive */
+@media (max-width: 600px) {
+ .wm-avatar img {
+ width: 32px;
+ height: 32px;
}
- .wm-author img {
- margin-bottom: 4px;
+
+ .wm-avatar-grid {
+ gap: 3px;
+ }
+
+ .wm-reaction-title {
+ font-size: 1rem;
}
}
</style>
<script>
const PAGE_URL = "{{ .Permalink }}";
+
async function loadMentions() {
const url =
"https://webmention.io/api/mentions.jf2?domain=micro.pinapelz.moe&token=hdjQAqlZwgJmSuPSiU8h8w";
@@ -103,6 +175,7 @@ async function loadMentions() {
const container = document.getElementById("mentions");
container.innerHTML = "";
+ // Filter mentions for this specific page
const mentions = data.children.filter(m => {
const t = m["wm-target"];
const inReply = m["in-reply-to"];
@@ -124,46 +197,138 @@ async function loadMentions() {
return;
}
- mentions.forEach(m => {
- const div = document.createElement("div");
- div.className = "wm";
+ // Group mentions by type
+ const likes = mentions.filter(m => m["wm-property"] === "like-of");
+ const reposts = mentions.filter(m => m["wm-property"] === "repost-of");
+ const replies = mentions.filter(m => m["wm-property"] === "in-reply-to");
+ const regularMentions = mentions.filter(m =>
+ !["like-of", "repost-of", "in-reply-to"].includes(m["wm-property"])
+ );
+
+ // Create reactions section
+ const reactionsDiv = document.createElement("div");
+ reactionsDiv.className = "wm-reactions";
+
+ // Add reposts section
+ if (reposts.length > 0) {
+ const repostGroup = document.createElement("div");
+ repostGroup.className = "wm-reaction-group";
+
+ const repostTitle = document.createElement("div");
+ repostTitle.className = "wm-reaction-title";
+ repostTitle.textContent = `${reposts.length} Repost${reposts.length !== 1 ? 's' : ''}`;
+
+ const repostGrid = document.createElement("div");
+ repostGrid.className = "wm-avatar-grid";
+
+ reposts.forEach(mention => {
+ const author = mention.author || {};
+ const avatarDiv = document.createElement("div");
+ avatarDiv.className = "wm-avatar";
+
+ avatarDiv.innerHTML = `
+ <a href="${author.url || "#"}" target="_blank">
+ <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}" />
+ </a>
+ <div class="wm-avatar-tooltip">${author.name || 'Unknown'}</div>
+ `;
+
+ repostGrid.appendChild(avatarDiv);
+ });
+
+ repostGroup.appendChild(repostTitle);
+ repostGroup.appendChild(repostGrid);
+ reactionsDiv.appendChild(repostGroup);
+ }
+
+ // Add likes section
+ if (likes.length > 0) {
+ const likeGroup = document.createElement("div");
+ likeGroup.className = "wm-reaction-group";
- const author = m.author || {};
- const content = m.content || {};
- const type =
- m["wm-property"] === "like-of" ? "liked this ❤️" :
- m["wm-property"] === "repost-of" ? "reposted 🔁" :
- m["wm-property"] === "in-reply-to" ? "replied 💬" :
- "mentioned this";
+ const likeTitle = document.createElement("div");
+ likeTitle.className = "wm-reaction-title";
+ likeTitle.textContent = `${likes.length} Like${likes.length !== 1 ? 's' : ''}`;
- const isLikeOrRepost = m["wm-property"] === "like-of" || m["wm-property"] === "repost-of";
+ const likeGrid = document.createElement("div");
+ likeGrid.className = "wm-avatar-grid";
- div.innerHTML = `
- <div class="wm-author">
- <img src="${author.photo || ""}" alt="">
- </div>
+ likes.forEach(mention => {
+ const author = mention.author || {};
+ const avatarDiv = document.createElement("div");
+ avatarDiv.className = "wm-avatar";
- <div class="wm-body">
- <div class="wm-author-name">
- <a href="${author.url || "#"}" target="_blank">
- ${author.name || "Unknown"}
- </a>
+ avatarDiv.innerHTML = `
+ <a href="${author.url || "#"}" target="_blank">
+ <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}" />
+ </a>
+ <div class="wm-avatar-tooltip">${author.name || 'Unknown'}</div>
+ `;
+
+ likeGrid.appendChild(avatarDiv);
+ });
+
+ likeGroup.appendChild(likeTitle);
+ likeGroup.appendChild(likeGrid);
+ reactionsDiv.appendChild(likeGroup);
+ }
+
+ // Add reactions section to container if it has content
+ if (reactionsDiv.children.length > 0) {
+ container.appendChild(reactionsDiv);
+ }
+
+ // Add regular mentions (replies and other mentions)
+ const regularMentionsToShow = [...replies, ...regularMentions];
+
+ if (regularMentionsToShow.length > 0) {
+ const regularDiv = document.createElement("div");
+ regularDiv.className = "wm-regular";
+
+ regularMentionsToShow.forEach(m => {
+ const div = document.createElement("div");
+ div.className = "wm";
+
+ const author = m.author || {};
+ const content = m.content || {};
+ const type =
+ m["wm-property"] === "in-reply-to" ? "replied 💬" :
+ "mentioned this";
+
+ div.innerHTML = `
+ <div class="wm-author">
+ <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}">
</div>
- <div class="wm-type">${type}</div>
+ <div class="wm-body">
+ <div class="wm-author-name">
+ <a href="${author.url || "#"}" target="_blank">
+ ${author.name || "Unknown"}
+ </a>
+ </div>
+
+ <div class="wm-type">${type}</div>
- ${!isLikeOrRepost && content.text ? `<div class="wm-content">${content.text}</div>` : ""}
+ ${content.text ? `<div class="wm-content">${content.text}</div>` : ""}
- <div class="wm-meta">
- <a href="${m.url}" target="_blank">source</a> •
- ${m["wm-received"]
- ? new Date(m["wm-received"]).toLocaleString()
- : ""}
+ <div class="wm-meta">
+ <a href="${m.url}" target="_blank">source</a> •
+ ${m["wm-received"]
+ ? new Date(m["wm-received"]).toLocaleString()
+ : ""}
+ </div>
</div>
- </div>
- `;
- container.appendChild(div);
- });
+ `;
+ regularDiv.appendChild(div);
+ });
+
+ container.appendChild(regularDiv);
+ }
+
+ // If no mentions at all
+ if (container.children.length === 0) {
+ container.innerHTML = "<p>No webmentions yet.</p>";
+ }
}
loadMentions();
diff --git a/micro.pinapelz.moe/posts/2025-12-01-hello-world/index.html b/micro.pinapelz.moe/posts/2025-12-01-hello-world/index.html
index 2081599..4a957c0 100644
--- a/micro.pinapelz.moe/posts/2025-12-01-hello-world/index.html
+++ b/micro.pinapelz.moe/posts/2025-12-01-hello-world/index.html
@@ -140,27 +140,94 @@ AtProto allows you to host a <code>PDS (Personal Data Server)</code> which store
margin-bottom: 1rem;
}
-
.wm-list {
display: flex;
flex-direction: column;
- gap: 0.75rem;
+ gap: 1.5rem;
}
+.wm-reactions {
+ margin-bottom: 1.5rem;
+}
+
+.wm-reaction-group {
+ margin-bottom: 1rem;
+}
+
+.wm-reaction-title {
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: var(--titlecolor);
+ margin-bottom: 0.5rem;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.wm-avatar-grid {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 4px;
+ align-items: center;
+}
+
+.wm-avatar {
+ position: relative;
+ display: inline-block;
+}
+
+.wm-avatar img {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ border: 2px solid var(--hrcolor);
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.wm-avatar:hover img {
+ transform: scale(1.1);
+ box-shadow: 0 4px 12px rgba(255, 140, 200, 0.4);
+}
+
+.wm-avatar-tooltip {
+ position: absolute;
+ bottom: 120%;
+ left: 50%;
+ transform: translateX(-50%);
+ background: var(--blockquotecolor);
+ color: var(--titlecolor);
+ padding: 4px 8px;
+ border-radius: 4px;
+ font-size: 0.8rem;
+ white-space: nowrap;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.2s ease;
+ z-index: 10;
+ border: 1px solid var(--hrcolor);
+}
+
+.wm-avatar:hover .wm-avatar-tooltip {
+ opacity: 1;
+}
+
+
+.wm-regular {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
.wm {
display: flex;
gap: 0.6rem;
padding: 0.6rem 0.75rem;
border-radius: 10px;
-
background: var(--alertbgcolor);
border: 1px solid var(--hrcolor);
-
box-shadow: 0 0 6px rgba(255, 180, 220, 0.22);
}
-
.wm-author img {
width: 32px;
height: 32px;
@@ -168,13 +235,11 @@ AtProto allows you to host a <code>PDS (Personal Data Server)</code> which store
box-shadow: 0 0 4px rgba(255, 140, 200, 0.35);
}
-
.wm-body {
flex: 1;
font-size: 0.9rem;
}
-
.wm-author-name a {
font-weight: 600;
color: var(--linkcolor);
@@ -186,38 +251,45 @@ AtProto allows you to host a <code>PDS (Personal Data Server)</code> which store
color: var(--titlecolor);
}
-
.wm-content {
margin-top: 4px;
padding: 6px 8px;
font-size: 0.9rem;
-
background: var(--blockquotecolor);
border-left: 3px solid var(--hrcolor);
border-radius: 6px;
}
-
.wm-meta {
margin-top: 3px;
font-size: 0.75rem;
opacity: 0.7;
}
+.wm-meta a {
+ color: var(--linkcolor);
+}
+
-@media (max-width: 800px) {
- .wm {
- flex-direction: column;
- text-align: left;
+@media (max-width: 600px) {
+ .wm-avatar img {
+ width: 32px;
+ height: 32px;
}
- .wm-author img {
- margin-bottom: 4px;
+
+ .wm-avatar-grid {
+ gap: 3px;
+ }
+
+ .wm-reaction-title {
+ font-size: 1rem;
}
}
</style>
<script>
const PAGE_URL = "https:\/\/micro.pinapelz.moe\/posts\/2025-12-01-hello-world\/";
+
async function loadMentions() {
const url =
"https://webmention.io/api/mentions.jf2?domain=micro.pinapelz.moe&token=hdjQAqlZwgJmSuPSiU8h8w";
@@ -228,6 +300,7 @@ async function loadMentions() {
const container = document.getElementById("mentions");
container.innerHTML = "";
+
const mentions = data.children.filter(m => {
const t = m["wm-target"];
const inReply = m["in-reply-to"];
@@ -249,46 +322,138 @@ async function loadMentions() {
return;
}
- mentions.forEach(m => {
- const div = document.createElement("div");
- div.className = "wm";
+
+ const likes = mentions.filter(m => m["wm-property"] === "like-of");
+ const reposts = mentions.filter(m => m["wm-property"] === "repost-of");
+ const replies = mentions.filter(m => m["wm-property"] === "in-reply-to");
+ const regularMentions = mentions.filter(m =>
+ !["like-of", "repost-of", "in-reply-to"].includes(m["wm-property"])
+ );
+
+
+ const reactionsDiv = document.createElement("div");
+ reactionsDiv.className = "wm-reactions";
+
+
+ if (reposts.length > 0) {
+ const repostGroup = document.createElement("div");
+ repostGroup.className = "wm-reaction-group";
+
+ const repostTitle = document.createElement("div");
+ repostTitle.className = "wm-reaction-title";
+ repostTitle.textContent = `${reposts.length} Repost${reposts.length !== 1 ? 's' : ''}`;
+
+ const repostGrid = document.createElement("div");
+ repostGrid.className = "wm-avatar-grid";
+
+ reposts.forEach(mention => {
+ const author = mention.author || {};
+ const avatarDiv = document.createElement("div");
+ avatarDiv.className = "wm-avatar";
+
+ avatarDiv.innerHTML = `
+ <a href="${author.url || "#"}" target="_blank">
+ <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}" />
+ </a>
+ <div class="wm-avatar-tooltip">${author.name || 'Unknown'}</div>
+ `;
+
+ repostGrid.appendChild(avatarDiv);
+ });
+
+ repostGroup.appendChild(repostTitle);
+ repostGroup.appendChild(repostGrid);
+ reactionsDiv.appendChild(repostGroup);
+ }
+
+
+ if (likes.length > 0) {
+ const likeGroup = document.createElement("div");
+ likeGroup.className = "wm-reaction-group";
+
+ const likeTitle = document.createElement("div");
+ likeTitle.className = "wm-reaction-title";
+ likeTitle.textContent = `${likes.length} Like${likes.length !== 1 ? 's' : ''}`;
+
+ const likeGrid = document.createElement("div");
+ likeGrid.className = "wm-avatar-grid";
- const author = m.author || {};
- const content = m.content || {};
- const type =
- m["wm-property"] === "like-of" ? "liked this ❤️" :
- m["wm-property"] === "repost-of" ? "reposted 🔁" :
- m["wm-property"] === "in-reply-to" ? "replied 💬" :
- "mentioned this";
+ likes.forEach(mention => {
+ const author = mention.author || {};
+ const avatarDiv = document.createElement("div");
+ avatarDiv.className = "wm-avatar";
- const isLikeOrRepost = m["wm-property"] === "like-of" || m["wm-property"] === "repost-of";
+ avatarDiv.innerHTML = `
+ <a href="${author.url || "#"}" target="_blank">
+ <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}" />
+ </a>
+ <div class="wm-avatar-tooltip">${author.name || 'Unknown'}</div>
+ `;
+
+ likeGrid.appendChild(avatarDiv);
+ });
+
+ likeGroup.appendChild(likeTitle);
+ likeGroup.appendChild(likeGrid);
+ reactionsDiv.appendChild(likeGroup);
+ }
+
+
+ if (reactionsDiv.children.length > 0) {
+ container.appendChild(reactionsDiv);
+ }
+
+
+ const regularMentionsToShow = [...replies, ...regularMentions];
- div.innerHTML = `
- <div class="wm-author">
- <img src="${author.photo || ""}" alt="">
- </div>
+ if (regularMentionsToShow.length > 0) {
+ const regularDiv = document.createElement("div");
+ regularDiv.className = "wm-regular";
- <div class="wm-body">
- <div class="wm-author-name">
- <a href="${author.url || "#"}" target="_blank">
- ${author.name || "Unknown"}
- </a>
+ regularMentionsToShow.forEach(m => {
+ const div = document.createElement("div");
+ div.className = "wm";
+
+ const author = m.author || {};
+ const content = m.content || {};
+ const type =
+ m["wm-property"] === "in-reply-to" ? "replied 💬" :
+ "mentioned this";
+
+ div.innerHTML = `
+ <div class="wm-author">
+ <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}">
</div>
- <div class="wm-type">${type}</div>
+ <div class="wm-body">
+ <div class="wm-author-name">
+ <a href="${author.url || "#"}" target="_blank">
+ ${author.name || "Unknown"}
+ </a>
+ </div>
+
+ <div class="wm-type">${type}</div>
- ${!isLikeOrRepost && content.text ? `<div class="wm-content">${content.text}</div>` : ""}
+ ${content.text ? `<div class="wm-content">${content.text}</div>` : ""}
- <div class="wm-meta">
- <a href="${m.url}" target="_blank">source</a> •
- ${m["wm-received"]
- ? new Date(m["wm-received"]).toLocaleString()
- : ""}
+ <div class="wm-meta">
+ <a href="${m.url}" target="_blank">source</a> •
+ ${m["wm-received"]
+ ? new Date(m["wm-received"]).toLocaleString()
+ : ""}
+ </div>
</div>
- </div>
- `;
- container.appendChild(div);
- });
+ `;
+ regularDiv.appendChild(div);
+ });
+
+ container.appendChild(regularDiv);
+ }
+
+
+ if (container.children.length === 0) {
+ container.innerHTML = "<p>No webmentions yet.</p>";
+ }
}
loadMentions();
diff --git a/micro.pinapelz.moe/posts/2025-12-02-china-town-fair/index.html b/micro.pinapelz.moe/posts/2025-12-02-china-town-fair/index.html
index 3b955be..88ce868 100644
--- a/micro.pinapelz.moe/posts/2025-12-02-china-town-fair/index.html
+++ b/micro.pinapelz.moe/posts/2025-12-02-china-town-fair/index.html
@@ -145,27 +145,94 @@
margin-bottom: 1rem;
}
-
.wm-list {
display: flex;
flex-direction: column;
- gap: 0.75rem;
+ gap: 1.5rem;
}
+.wm-reactions {
+ margin-bottom: 1.5rem;
+}
+
+.wm-reaction-group {
+ margin-bottom: 1rem;
+}
+
+.wm-reaction-title {
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: var(--titlecolor);
+ margin-bottom: 0.5rem;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.wm-avatar-grid {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 4px;
+ align-items: center;
+}
+
+.wm-avatar {
+ position: relative;
+ display: inline-block;
+}
+
+.wm-avatar img {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ border: 2px solid var(--hrcolor);
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.wm-avatar:hover img {
+ transform: scale(1.1);
+ box-shadow: 0 4px 12px rgba(255, 140, 200, 0.4);
+}
+
+.wm-avatar-tooltip {
+ position: absolute;
+ bottom: 120%;
+ left: 50%;
+ transform: translateX(-50%);
+ background: var(--blockquotecolor);
+ color: var(--titlecolor);
+ padding: 4px 8px;
+ border-radius: 4px;
+ font-size: 0.8rem;
+ white-space: nowrap;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.2s ease;
+ z-index: 10;
+ border: 1px solid var(--hrcolor);
+}
+
+.wm-avatar:hover .wm-avatar-tooltip {
+ opacity: 1;
+}
+
+
+.wm-regular {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
.wm {
display: flex;
gap: 0.6rem;
padding: 0.6rem 0.75rem;
border-radius: 10px;
-
background: var(--alertbgcolor);
border: 1px solid var(--hrcolor);
-
box-shadow: 0 0 6px rgba(255, 180, 220, 0.22);
}
-
.wm-author img {
width: 32px;
height: 32px;
@@ -173,13 +240,11 @@
box-shadow: 0 0 4px rgba(255, 140, 200, 0.35);
}
-
.wm-body {
flex: 1;
font-size: 0.9rem;
}
-
.wm-author-name a {
font-weight: 600;
color: var(--linkcolor);
@@ -191,38 +256,45 @@
color: var(--titlecolor);
}
-
.wm-content {
margin-top: 4px;
padding: 6px 8px;
font-size: 0.9rem;
-
background: var(--blockquotecolor);
border-left: 3px solid var(--hrcolor);
border-radius: 6px;
}
-
.wm-meta {
margin-top: 3px;
font-size: 0.75rem;
opacity: 0.7;
}
+.wm-meta a {
+ color: var(--linkcolor);
+}
+
-@media (max-width: 800px) {
- .wm {
- flex-direction: column;
- text-align: left;
+@media (max-width: 600px) {
+ .wm-avatar img {
+ width: 32px;
+ height: 32px;
}
- .wm-author img {
- margin-bottom: 4px;
+
+ .wm-avatar-grid {
+ gap: 3px;
+ }
+
+ .wm-reaction-title {
+ font-size: 1rem;
}
}
</style>
<script>
const PAGE_URL = "https:\/\/micro.pinapelz.moe\/posts\/2025-12-02-china-town-fair\/";
+
async function loadMentions() {
const url =
"https://webmention.io/api/mentions.jf2?domain=micro.pinapelz.moe&token=hdjQAqlZwgJmSuPSiU8h8w";
@@ -233,6 +305,7 @@ async function loadMentions() {
const container = document.getElementById("mentions");
container.innerHTML = "";
+
const mentions = data.children.filter(m => {
const t = m["wm-target"];
const inReply = m["in-reply-to"];
@@ -254,46 +327,138 @@ async function loadMentions() {
return;
}
- mentions.forEach(m => {
- const div = document.createElement("div");
- div.className = "wm";
+
+ const likes = mentions.filter(m => m["wm-property"] === "like-of");
+ const reposts = mentions.filter(m => m["wm-property"] === "repost-of");
+ const replies = mentions.filter(m => m["wm-property"] === "in-reply-to");
+ const regularMentions = mentions.filter(m =>
+ !["like-of", "repost-of", "in-reply-to"].includes(m["wm-property"])
+ );
+
+
+ const reactionsDiv = document.createElement("div");
+ reactionsDiv.className = "wm-reactions";
+
+
+ if (reposts.length > 0) {
+ const repostGroup = document.createElement("div");
+ repostGroup.className = "wm-reaction-group";
+
+ const repostTitle = document.createElement("div");
+ repostTitle.className = "wm-reaction-title";
+ repostTitle.textContent = `${reposts.length} Repost${reposts.length !== 1 ? 's' : ''}`;
+
+ const repostGrid = document.createElement("div");
+ repostGrid.className = "wm-avatar-grid";
+
+ reposts.forEach(mention => {
+ const author = mention.author || {};
+ const avatarDiv = document.createElement("div");
+ avatarDiv.className = "wm-avatar";
+
+ avatarDiv.innerHTML = `
+ <a href="${author.url || "#"}" target="_blank">
+ <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}" />
+ </a>
+ <div class="wm-avatar-tooltip">${author.name || 'Unknown'}</div>
+ `;
+
+ repostGrid.appendChild(avatarDiv);
+ });
+
+ repostGroup.appendChild(repostTitle);
+ repostGroup.appendChild(repostGrid);
+ reactionsDiv.appendChild(repostGroup);
+ }
+
+
+ if (likes.length > 0) {
+ const likeGroup = document.createElement("div");
+ likeGroup.className = "wm-reaction-group";
+
+ const likeTitle = document.createElement("div");
+ likeTitle.className = "wm-reaction-title";
+ likeTitle.textContent = `${likes.length} Like${likes.length !== 1 ? 's' : ''}`;
+
+ const likeGrid = document.createElement("div");
+ likeGrid.className = "wm-avatar-grid";
- const author = m.author || {};
- const content = m.content || {};
- const type =
- m["wm-property"] === "like-of" ? "liked this ❤️" :
- m["wm-property"] === "repost-of" ? "reposted 🔁" :
- m["wm-property"] === "in-reply-to" ? "replied 💬" :
- "mentioned this";
+ likes.forEach(mention => {
+ const author = mention.author || {};
+ const avatarDiv = document.createElement("div");
+ avatarDiv.className = "wm-avatar";
- const isLikeOrRepost = m["wm-property"] === "like-of" || m["wm-property"] === "repost-of";
+ avatarDiv.innerHTML = `
+ <a href="${author.url || "#"}" target="_blank">
+ <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}" />
+ </a>
+ <div class="wm-avatar-tooltip">${author.name || 'Unknown'}</div>
+ `;
+
+ likeGrid.appendChild(avatarDiv);
+ });
+
+ likeGroup.appendChild(likeTitle);
+ likeGroup.appendChild(likeGrid);
+ reactionsDiv.appendChild(likeGroup);
+ }
+
+
+ if (reactionsDiv.children.length > 0) {
+ container.appendChild(reactionsDiv);
+ }
+
+
+ const regularMentionsToShow = [...replies, ...regularMentions];
- div.innerHTML = `
- <div class="wm-author">
- <img src="${author.photo || ""}" alt="">
- </div>
+ if (regularMentionsToShow.length > 0) {
+ const regularDiv = document.createElement("div");
+ regularDiv.className = "wm-regular";
- <div class="wm-body">
- <div class="wm-author-name">
- <a href="${author.url || "#"}" target="_blank">
- ${author.name || "Unknown"}
- </a>
+ regularMentionsToShow.forEach(m => {
+ const div = document.createElement("div");
+ div.className = "wm";
+
+ const author = m.author || {};
+ const content = m.content || {};
+ const type =
+ m["wm-property"] === "in-reply-to" ? "replied 💬" :
+ "mentioned this";
+
+ div.innerHTML = `
+ <div class="wm-author">
+ <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}">
</div>
- <div class="wm-type">${type}</div>
+ <div class="wm-body">
+ <div class="wm-author-name">
+ <a href="${author.url || "#"}" target="_blank">
+ ${author.name || "Unknown"}
+ </a>
+ </div>
+
+ <div class="wm-type">${type}</div>
- ${!isLikeOrRepost && content.text ? `<div class="wm-content">${content.text}</div>` : ""}
+ ${content.text ? `<div class="wm-content">${content.text}</div>` : ""}
- <div class="wm-meta">
- <a href="${m.url}" target="_blank">source</a> •
- ${m["wm-received"]
- ? new Date(m["wm-received"]).toLocaleString()
- : ""}
+ <div class="wm-meta">
+ <a href="${m.url}" target="_blank">source</a> •
+ ${m["wm-received"]
+ ? new Date(m["wm-received"]).toLocaleString()
+ : ""}
+ </div>
</div>
- </div>
- `;
- container.appendChild(div);
- });
+ `;
+ regularDiv.appendChild(div);
+ });
+
+ container.appendChild(regularDiv);
+ }
+
+
+ if (container.children.length === 0) {
+ container.innerHTML = "<p>No webmentions yet.</p>";
+ }
}
loadMentions();
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage