Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions archetypes/default.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ share:
# ...
comment:
enable: true
# Set fediverse or mastodonTootId to a Mastodon toot ID to enable Fediverse comments for this post
# fediverse: ""
# ...
library:
css:
Expand Down
135 changes: 135 additions & 0 deletions assets/css/_partial/_single/_comment.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,139 @@
max-width: 1.5em;
max-height: 1.5em;
}

/* Mastodon / Fediverse comments (mastodon-comments web component) */
.mastodon-comments-powered {
margin-bottom: .5rem;
font-size: .9rem;
color: #5d686f;

i {
margin-right: .35rem;
}
}

.mastodon-comments-loading {
display: inline-flex;
align-items: center;
gap: .5rem;
margin: .5rem 0 1rem;
font-size: .9rem;
color: #5d686f;
}

.mastodon-comments-prompt {
margin-bottom: 1rem;
}

mastodon-comments {
--font-color: #5d686f;
--font-size: 1rem;
--block-border-width: 1px;
--block-border-radius: 3px;
--block-border-color: #ededf0;
--block-background-color: #f7f8f8;
--comment-indent: 40px;
}

.mastodon-comment {
background-color: var(--block-background-color, #f7f8f8);
border-radius: var(--block-border-radius, 3px);
border: 1px solid var(--block-border-color, #ededf0);
padding: 20px;
margin-bottom: 1.5rem;
display: flex;
flex-direction: column;
color: var(--font-color, #5d686f);
font-size: var(--font-size, 1rem);

p {
margin-bottom: 0;
}

.author {
padding-top: 0;
display: flex;

a {
text-decoration: none;
}

.avatar img {
margin-right: 1rem;
min-width: 60px;
border-radius: 5px;
}

.details {
display: flex;
flex-direction: column;
}

.details .name {
font-weight: bold;
}

.details .user {
color: #5d686f;
font-size: medium;
}

.date {
margin-left: auto;
font-size: small;
}
}

.content {
margin: 15px 20px;

p:first-child {
margin-top: 0;
margin-bottom: 0;
}
}

.attachments {
margin: 0 10px;

> * {
margin: 0 10px;
}
}

.status > div {
display: inline-block;
margin-right: 15px;
}

.status a {
color: #5d686f;
text-decoration: none;
}

.status .replies.active a {
color: #003eaa;
}

.status .reblogs.active a {
color: #8c8dff;
}

.status .favourites.active a {
color: #ca8f04;
}
}

@media only screen and (max-width: 1024px) {
mastodon-comments {
--comment-indent: 20px;
}
}

@media only screen and (max-width: 640px) {
mastodon-comments {
--comment-indent: 0;
}
}
}
6 changes: 6 additions & 0 deletions exampleSite/hugo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,12 @@ ignoreErrors = ["error-remote-getjson", "error-missing-instagram-accesstoken"]
lazyLoading = false
lightTheme = "light"
darkTheme = "dark"
# Mastodon / Fediverse comment config (https://github.com/dpecos/mastodon-comments)
# Mastodon / Fediverse 评论系统设置 (https://github.com/dpecos/mastodon-comments)
[params.page.comment.mastodon]
enable = false
host = ""
user = ""
# Waline comment config (https://waline.js.org/)
# Waline 评论系统设置 (https://waline.js.org/)
[params.page.comment.waline]
Expand Down
8 changes: 8 additions & 0 deletions hugo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,14 @@
lazyLoading = false
lightTheme = "light"
darkTheme = "dark"
# Mastodon / Fediverse comment config (https://github.com/dpecos/mastodon-comments)
# Mastodon / Fediverse 评论系统设置 (https://github.com/dpecos/mastodon-comments)
[params.page.comment.mastodon]
enable = false
# Your Mastodon instance host (e.g. mastodon.social, fosstodon.org)
host = ""
# Your Mastodon username (without @). Per-post: set 'fediverse' or 'mastodonTootId' in front matter to the toot ID.
user = ""
# Third-party library config
# 第三方库配置
[params.page.library]
Expand Down
6 changes: 6 additions & 0 deletions i18n/en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ other = "en"

[walineLang]
other = "en"
[mastodonCommentsNoscript]
other = "Please enable JavaScript to view the comments powered by the Fediverse."
[mastodonCommentsPrompt]
other = "You can use your Fediverse (e.g. Mastodon) account to reply to this"
[mastodonCommentsPost]
other = "post"
# === partials/comment.html ===

# === partials/assets.html ===
Expand Down
6 changes: 6 additions & 0 deletions i18n/zh-CN.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ other = "zh-CN"

[walineLang]
other = "zh-CN"
[mastodonCommentsNoscript]
other = "请启用 JavaScript 以查看由 Fediverse 提供的评论。"
[mastodonCommentsPrompt]
other = "您可以使用 Fediverse(如 Mastodon)账号回复本"
[mastodonCommentsPost]
other = "帖子"
# === partials/comment.html ===

# === partials/assets.html ===
Expand Down
104 changes: 104 additions & 0 deletions layouts/_partials/comment.html
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,110 @@
</noscript>
{{- end -}}

{{- /* Mastodon / Fediverse Comment System */ -}}
{{- $mastodon := $comment.mastodon | default dict -}}
{{- $fediverseTootId := .Params.fediverse | default .Params.mastodonTootId -}}
{{- if and $mastodon.enable $mastodon.host $mastodon.user $fediverseTootId -}}
<div id="mastodon-comments" class="comment">
<p class="mastodon-comments-powered">
<i class="fas fa-comments" aria-hidden="true"></i>
Comments are powered by the Fediverse (Mastodon).
</p>
<noscript>
<div id="mastodon-comments-noscript">
{{ T "mastodonCommentsNoscript" | default "Please enable JavaScript to view the comments powered by the Fediverse." }}
</div>
</noscript>
<p class="mastodon-comments-prompt">
{{ T "mastodonCommentsPrompt" | default "You can use your Fediverse (e.g. Mastodon) account to reply to this" }}
<a href="https://{{ $mastodon.host }}/@{{ $mastodon.user }}/{{ $fediverseTootId }}" rel="noopener noreferrer" target="_blank">{{ T "mastodonCommentsPost" | default "post" }}</a>.
</p>
<div class="mastodon-comments-loading">
<i class="fas fa-spinner fa-spin" aria-hidden="true"></i>
<span>Loading comments…</span>
</div>
<mastodon-comments host="{{ $mastodon.host }}" user="{{ $mastodon.user }}" toot-id="{{ $fediverseTootId }}"></mastodon-comments>
</div>
<script>
(function () {
var mastodonScriptsLoaded = false;

function enhanceMastodonComments() {
var root = document.getElementById('mastodon-comments');
if (!root) return;
var loading = root.querySelector('.mastodon-comments-loading');
var list = root.querySelector('mastodon-comments #mastodon-comments-list');
if (!list) return;

var observer = new MutationObserver(function () {
// Hide loading spinner once component starts rendering something
if (loading && list.innerHTML.trim() !== '') {
loading.style.display = 'none';
}
// Friendlier empty state
if (list.textContent && list.textContent.trim() === 'No comments found') {
list.textContent = 'No comments yet \u2013 be the first to reply on Mastodon.';
}
});
observer.observe(list, { childList: true, characterData: true, subtree: true });
}

function loadMastodonScripts() {
if (mastodonScriptsLoaded) return;
mastodonScriptsLoaded = true;

var head = document.head || document.getElementsByTagName('head')[0];

// Load DOMPurify first
var purifyScript = document.createElement('script');
purifyScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.4.1/purify.min.js';
purifyScript.integrity = 'sha512-uHOKtSfJWScGmyyFr2O2+efpDx2nhwHU2v7MVeptzZoiC7bdF6Ny/CmZhN2AwIK1oCFiVQQ5DA/L9FSzyPNu6Q==';
purifyScript.crossOrigin = 'anonymous';
purifyScript.referrerPolicy = 'no-referrer';
purifyScript.onload = function () {
var mcScript = document.createElement('script');
mcScript.src = 'https://cdn.jsdelivr.net/gh/dpecos/mastodon-comments@master/mastodon-comments.js';
mcScript.crossOrigin = 'anonymous';
mcScript.defer = true;
mcScript.onload = function () {
enhanceMastodonComments();
};
head.appendChild(mcScript);
};
head.appendChild(purifyScript);
}

function initIntersectionObserver() {
var root = document.getElementById('mastodon-comments');
if (!root || !('IntersectionObserver' in window)) {
// Fallback: load immediately
loadMastodonScripts();
return;
}

var observer = new IntersectionObserver(function (entries, obs) {
entries.forEach(function (entry) {
if (entry.isIntersecting || entry.intersectionRatio > 0) {
loadMastodonScripts();
obs.disconnect();
}
});
});
observer.observe(root);
}

if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initIntersectionObserver);
} else {
initIntersectionObserver();
}
})();
</script>
<noscript>
Please enable JavaScript to view the comments powered by <a href="https://github.com/dpecos/mastodon-comments">Mastodon Comments</a>.
</noscript>
{{- end -}}

{{- /* Waline Comment System */ -}}
{{- $waline := $comment.waline | default dict -}}
{{- if $waline.enable -}}
Expand Down