Add Mastodon toots to main page
This commit is contained in:
parent
a84195497e
commit
c7b9f9e67d
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -69,6 +69,7 @@ production stylesheet in assets/built/screen.css
|
|||||||
--container-width: 1320px;
|
--container-width: 1320px;
|
||||||
--container-gap: clamp(24px, 1.7032rem + 1.9355vw, 48px);
|
--container-gap: clamp(24px, 1.7032rem + 1.9355vw, 48px);
|
||||||
--grid-gap: 42px;
|
--grid-gap: 42px;
|
||||||
|
--card-border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root.light-theme {
|
:root.light-theme {
|
||||||
@ -1726,12 +1727,12 @@ Search LOGO Login Subscribe
|
|||||||
/* 11.1. With sidebar */
|
/* 11.1. With sidebar */
|
||||||
|
|
||||||
.gh-container.has-sidebar .gh-main {
|
.gh-container.has-sidebar .gh-main {
|
||||||
grid-column: 1 / span 12;
|
grid-column: 1 / span 11;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gh-container.has-sidebar .gh-sidebar {
|
.gh-container.has-sidebar .gh-sidebar {
|
||||||
grid-column: 13 / -1;
|
grid-column: 12 / -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gh-container.has-sidebar .gh-main::after {
|
.gh-container.has-sidebar .gh-main::after {
|
||||||
@ -1954,6 +1955,59 @@ Search LOGO Login Subscribe
|
|||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mastodon-comment {
|
||||||
|
background-color: var(--background-color);
|
||||||
|
border-radius: var(--card-border-radius);
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
display: flex;
|
||||||
|
border-top: 1px solid var(--background-secondary);
|
||||||
|
.mastodon-body {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.mastodon-avatar {
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
||||||
|
.mastodon-avatar img {
|
||||||
|
margin-right: 1rem;
|
||||||
|
min-width: 60px;
|
||||||
|
}
|
||||||
|
.mastodon-meta {
|
||||||
|
padding-top: 0;
|
||||||
|
display: flex;
|
||||||
|
.mastodon-author {
|
||||||
|
flex-grow: 1;
|
||||||
|
white-space: nowrap;
|
||||||
|
.mastodon-author-uid {
|
||||||
|
font-size: 80%;
|
||||||
|
color: var(--ghost-accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.toot-link {
|
||||||
|
flex-shrink: 1;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mastodon-comment-content {
|
||||||
|
padding-top: 10px;
|
||||||
|
.tootlink {
|
||||||
|
font-size: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.disabled {
|
||||||
|
color: var(--ghost-accent-color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mastodon-emoji {
|
||||||
|
display: inline-block;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
|
.mastodon-comment-content p:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 14. Post/page
|
/* 14. Post/page
|
||||||
/* ---------------------------------------------------------- */
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
3
assets/js/lib/purify.min.js
vendored
Normal file
3
assets/js/lib/purify.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
85
assets/js/mastodon.js
Normal file
85
assets/js/mastodon.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
const MASTODON_ACCOUNT_ID = '109285376472065471'
|
||||||
|
const MASTODON_HOST = 'social.sd.ai'
|
||||||
|
|
||||||
|
async function copyElementTextToClipboard(e)
|
||||||
|
{
|
||||||
|
const text = e.textContent
|
||||||
|
await navigator.clipboard.write(text)
|
||||||
|
|
||||||
|
e.classList.add('tootClick');
|
||||||
|
setTimeout(() => {
|
||||||
|
e.classList.remove('tootClick');
|
||||||
|
}, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeHtml(unsafe) {
|
||||||
|
return unsafe
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """)
|
||||||
|
.replace(/'/g, "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderMastodonContent(toots, parentElement) {
|
||||||
|
if (!Array.isArray(toots) || toots.length === 0) {
|
||||||
|
document.getElementById('mastodon-comments-list').innerHTML = "<div class='mastodon-comment'>No comments (yet)!</div>"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (const toot of toots) {
|
||||||
|
toot.account.display_name = escapeHtml(toot.account.display_name)
|
||||||
|
console.log(toot)
|
||||||
|
toot.account.emojis.forEach(emoji => {
|
||||||
|
toot.account.display_name = toot.account.display_name.replace(`:${emoji.shortcode}:`,
|
||||||
|
`<img src="${escapeHtml(emoji.static_url)}" alt="Emoji ${emoji.shortcode}" class="mastodon-emoji" />`);
|
||||||
|
})
|
||||||
|
toot.emojis.forEach(emoji => {
|
||||||
|
toot.content = toot.content.replace(`:${emoji.shortcode}:`,
|
||||||
|
`<img src="${escapeHtml(emoji.static_url)}" alt="Emoji ${emoji.shortcode}" class="mastodon-emoji" />`);
|
||||||
|
})
|
||||||
|
const comment =
|
||||||
|
`<div class="mastodon-comment">
|
||||||
|
<div class="mastodon-avatar">
|
||||||
|
<img src="${escapeHtml(toot.account.avatar_static)}" height=60 width=60 alt="${escapeHtml(toot.account.display_name)}'s avatar">
|
||||||
|
</div>
|
||||||
|
<div class="mastodon-body">
|
||||||
|
<div class="mastodon-meta">
|
||||||
|
<div class="mastodon-author">
|
||||||
|
<div class="mastodon-author-link">
|
||||||
|
<a href="${toot.account.url}" rel="nofollow">
|
||||||
|
<span>${toot.account.display_name}</span>
|
||||||
|
</a>
|
||||||
|
<br/>
|
||||||
|
<span class="mastodon-author-uid">(@${escapeHtml(toot.account.acct === 's' ? 's@sd.ai' : toot.account.acct)})</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="toot-link">
|
||||||
|
<a class="date" href="${toot.uri}" rel="nofollow">
|
||||||
|
${toot.created_at.substring(0, 10)}
|
||||||
|
</a>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mastodon-comment-content">
|
||||||
|
${toot.content}
|
||||||
|
<span class="tootlink">${toot.uri}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
const child = DOMPurify.sanitize(comment, {'RETURN_DOM_FRAGMENT': true});
|
||||||
|
const links = child.querySelectorAll('.tootlink');
|
||||||
|
for (const link of links) {
|
||||||
|
link.onclick = function() { return copyToClipboard(this); }
|
||||||
|
}
|
||||||
|
parentElement.appendChild(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", async (event) => {
|
||||||
|
if (document.getElementsByClassName('gh-sidebar').length > 0) {
|
||||||
|
const element = document.getElementById('mastodon-comments-list')
|
||||||
|
const response = await fetch(`https://${MASTODON_HOST}/api/v1/accounts/${MASTODON_ACCOUNT_ID}/statuses?exclude_replies=true&exclude_reblogs=true`)
|
||||||
|
const content = await response.json()
|
||||||
|
return renderMastodonContent(content, element)
|
||||||
|
}
|
||||||
|
})
|
@ -18,7 +18,6 @@ function changeFavicon() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function changeTheme(useLight) {
|
function changeTheme(useLight) {
|
||||||
console.log({ useLight })
|
|
||||||
document.documentElement.classList.remove('light-theme', 'dark-theme', 'has-light-text', 'has-dark-text')
|
document.documentElement.classList.remove('light-theme', 'dark-theme', 'has-light-text', 'has-dark-text')
|
||||||
if (useLight) {
|
if (useLight) {
|
||||||
document.documentElement.classList.add('light-theme', 'has-dark-text')
|
document.documentElement.classList.add('light-theme', 'has-dark-text')
|
||||||
@ -39,8 +38,6 @@ themeToggle.addEventListener("click", () => {
|
|||||||
changeTheme(document.documentElement.classList.contains('dark-theme'))
|
changeTheme(document.documentElement.classList.contains('dark-theme'))
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log({ localTheme, isOSLight })
|
|
||||||
|
|
||||||
if (localTheme === "light") {
|
if (localTheme === "light") {
|
||||||
changeTheme(true)
|
changeTheme(true)
|
||||||
} else {
|
} else {
|
||||||
|
@ -14,9 +14,11 @@
|
|||||||
</nav>
|
</nav>
|
||||||
<div class="gh-footer-copyright">
|
<div class="gh-footer-copyright">
|
||||||
Powered by <a href="https://ghost.org/" target="_blank" rel="noopener">Ghost</a>
|
Powered by <a href="https://ghost.org/" target="_blank" rel="noopener">Ghost</a>
|
||||||
|
:
|
||||||
|
<a href="https://git.sd.ai/simon/ghost-theme-sd.ai" target="_blank" rel="noopener">Theme</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if @site.members_enabled}}
|
{{#if @site.members_enabled}}
|
||||||
{{#unless @member}}
|
{{#unless @member}}
|
||||||
<section class="gh-footer-signup">
|
<section class="gh-footer-signup">
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<section class="gh-container is-{{#match postFeedStyle "List"}}list{{else}}grid{{/match}}{{#if showSidebar}} has-sidebar{{/if}}{{#unless @custom.show_images_in_feed}} no-image{{/unless}} gh-outer">
|
<section class="gh-container is-{{#match postFeedStyle "List"}}list{{else}}grid{{/match}}{{#if showSidebar}} has-sidebar{{/if}}{{#unless @custom.show_images_in_feed}} no-image{{/unless}} gh-outer">
|
||||||
<div class="gh-container-inner gh-inner">
|
<div class="gh-container-inner gh-inner">
|
||||||
|
|
||||||
{{#if showTitle}}
|
{{#if showTitle}}
|
||||||
<h2 class="gh-container-title">
|
<h2 class="gh-container-title">
|
||||||
{{#unless title}}Latest{{else}}{{title}}{{/unless}}
|
{{#unless title}}Latest{{else}}{{title}}{{/unless}}
|
||||||
@ -81,26 +81,8 @@
|
|||||||
|
|
||||||
{{#if showSidebar}}
|
{{#if showSidebar}}
|
||||||
<aside class="gh-sidebar">
|
<aside class="gh-sidebar">
|
||||||
<section class="gh-about">
|
<h3 class="gh-card-title is-title"><a href="https://social.sd.ai/@s" target="_blank" rel="noopener">Latest From Mastodon</a></h3>
|
||||||
{{#if @site.icon}}
|
<div id="mastodon-comments-list"></div>
|
||||||
<img class="gh-about-icon" src="{{@site.icon}}" alt="{{@site.title}}" loading="lazy">
|
|
||||||
{{/if}}
|
|
||||||
<h3 class="gh-about-title is-title">{{@site.title}}</h3>
|
|
||||||
{{#if @site.description}}
|
|
||||||
<p class="gh-about-description is-body">{{@site.description}}</p>
|
|
||||||
{{/if}}
|
|
||||||
{{#if @site.members_enabled}}
|
|
||||||
{{#unless @member}}
|
|
||||||
<button class="gh-button" data-portal="signup">Subscribe</button>
|
|
||||||
{{else}}
|
|
||||||
{{#if @site.paid_members_enabled}}
|
|
||||||
{{#unless @member.paid}}
|
|
||||||
<button class="gh-button" data-portal="upgrade">Upgrade</button>
|
|
||||||
{{/unless}}
|
|
||||||
{{/if}}
|
|
||||||
{{/unless}}
|
|
||||||
{{/if}}
|
|
||||||
</section>
|
|
||||||
</aside>
|
</aside>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user