Compare commits

..
10 Commits
Author SHA1 Message Date
simon c7b9f9e67d Add Mastodon toots to main page 2023-10-17 10:17:37 +01:00
simon a84195497e Fix error in theme switcher 2023-10-16 19:55:08 +01:00
simon ab61ad1a67 Fix colours 2023-10-16 19:05:59 +01:00
simon 9b04b09f33 Add logo 2023-10-16 18:53:40 +01:00
simon 328473e596 Add theme switcher 2023-10-16 17:04:36 +01:00
simon a9b861a6aa Update package.json 2023-10-16 15:06:45 +01:00
Sodbileg Gansukh 4b347f1b0d v1.0.1 2023-10-11 09:31:12 +08:00
Sodbileg Gansukh dedc9cbc3d Fixed pagination not working on tag templates
refs https://github.com/TryGhost/Source/issues/10
2023-10-11 09:30:48 +08:00
Daniel Lockyer e0483fd7f4 v1.0.0 2023-10-03 13:10:09 +02:00
Daniel Lockyer 98a35f9488 Updated built assets 2023-10-03 13:09:12 +02:00
18 changed files with 353 additions and 49 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Executable → Regular
+28 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+146 -4
View File
@@ -69,13 +69,35 @@ 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 {
/* light theme color */
--background-color: #fff;
--background-secondary: #eaeaea;
--header: #fafafa;
--color-primary-text: #222;
--color-secondary-text: #999;
--border-color: #dcdcdc;
--ghost-accent-color: #007700;
}
:root.dark-theme {
/* dark theme colors */
--background-color: #292a2d;
--background-secondary: #3b3d42;
--header: #252627;
--color-primary-text: #a9a9b3;
--color-secondary-text: #73747b;
--border-color: #4a4b50;
--ghost-accent-color: #77bb77;
} }
:root.has-light-text, :root.has-light-text,
:is(.gh-navigation, .gh-footer).has-accent-color { :is(.gh-navigation, .gh-footer).has-accent-color {
--color-lighter-gray: rgb(255 255 255 / 0.1); --color-lighter-gray: rgb(255 255 255 / 0.1);
--color-darker-gray: #fff; --color-darker-gray: var(--color-primary-text);
--color-secondary-text: rgb(255 255 255 / 0.64);
--color-border: rgb(255 255 255 / 0.15); --color-border: rgb(255 255 255 / 0.15);
--color-dark-border: rgb(255 255 255 / 0.5); --color-dark-border: rgb(255 255 255 / 0.5);
} }
@@ -1002,6 +1024,73 @@ Search LOGO Login Subscribe
/* 8. Header /* 8. Header
/* ---------------------------------------------------------- */ /* ---------------------------------------------------------- */
.gh-navigation-logo {
display: flex;
align-items: center;
flex: 0 0 auto;
text-decoration: none;
font-weight: bold;
color: var(--color-secondary-text)
}
.logo-mark {
display: inline-flex;
align-items: center;
margin-right: 5px;
height: 0.8em;
}
.logo-text {
font-size: 0.8em;
font-family: var(--font-mono);
}
.logo-cursor {
display: inline-block;
width: 0.4em;
height: 0.8em;
background: var(--color-secondary-text);
margin-left: 5px;
border-radius: 1px;
animation: cursor 1.5s infinite;
}
.greater-icon {
width: 0.6em;
height: 0.6em;
}
.greater-icon path {
stroke: currentColor;
stroke-width: .95rem;
}
@keyframes cursor {
0% { opacity: 0; }
50% { opacity: 1; }
100% { opacity: 0; }
}
#svglogo {
height: 2.5em;
width: 2.5em;
}
#svglogo use {
fill: var(--color-primary-text);
}
.theme-toggle {
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
cursor: pointer;
}
.theme-toggler {
fill: currentColor;
}
.gh-header { .gh-header {
position: relative; position: relative;
@@ -1638,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 {
@@ -1866,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
/* ---------------------------------------------------------- */ /* ---------------------------------------------------------- */
+1 -1
View File
@@ -40,7 +40,7 @@
/* Infinite scroll pagination */ /* Infinite scroll pagination */
(function () { (function () {
if (document.body.classList.contains('paged')) { if (!document.body.classList.contains('post-template')) {
pagination(); pagination();
} }
})(); })();
+3
View File
File diff suppressed because one or more lines are too long
+85
View 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, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
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)
}
})
+45
View File
@@ -0,0 +1,45 @@
// Toggle theme
const isOSLight = window.matchMedia("(prefers-color-scheme: light)").matches
const localTheme = window.localStorage && window.localStorage.getItem("lightTheme")
const themeToggle = document.querySelector(".theme-toggle")
function changeFavicon() {
const src = document.documentElement.classList.contains("dark-theme") ? "/img/favicon-dark.png" : "/img/favicon.png";
const link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = src;
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}
function changeTheme(useLight) {
document.documentElement.classList.remove('light-theme', 'dark-theme', 'has-light-text', 'has-dark-text')
if (useLight) {
document.documentElement.classList.add('light-theme', 'has-dark-text')
} else {
document.documentElement.classList.add('dark-theme', 'has-light-text')
}
if (window.localStorage) {
window.localStorage.setItem(
"lightTheme",
useLight ? "light" : "dark")
}
changeFavicon()
}
themeToggle.addEventListener("click", () => {
changeTheme(document.documentElement.classList.contains('dark-theme'))
});
if (localTheme === "light") {
changeTheme(true)
} else {
changeTheme(isOSLight)
}
+7 -16
View File
@@ -1,7 +1,7 @@
{ {
"name": "source", "name": "sd-ai",
"description": "A default theme for the Ghost publishing platform", "description": "Theme for sd.ai, forked from Source theme",
"demo": "https://source.ghost.io", "demo": "https://sd.ai/",
"version": "1.0.0", "version": "1.0.0",
"engines": { "engines": {
"ghost": ">=5.0.0" "ghost": ">=5.0.0"
@@ -18,16 +18,9 @@
"postship": "git fetch && gulp release" "postship": "git fetch && gulp release"
}, },
"author": { "author": {
"name": "Ghost Foundation", "name": "Simon Detheridge",
"email": "hello@ghost.org", "email": "s@sd.ai",
"url": "https://ghost.org/" "url": "https://sd.ai/"
},
"gpm": {
"type": "theme",
"categories": [
"Minimal",
"Magazine"
]
}, },
"keywords": [ "keywords": [
"ghost", "ghost",
@@ -36,10 +29,8 @@
], ],
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/TryGhost/Source.git" "url": "https://git.sd.ai/simon/ghost-theme-sd.ai"
}, },
"bugs": "https://github.com/TryGhost/Source/issues",
"contributors": "https://github.com/TryGhost/Source/graphs/contributors",
"devDependencies": { "devDependencies": {
"@tryghost/release-utils": "0.8.1", "@tryghost/release-utils": "0.8.1",
"autoprefixer": "10.4.7", "autoprefixer": "10.4.7",
+2
View File
@@ -14,6 +14,8 @@
</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>
+5
View File
@@ -0,0 +1,5 @@
{{> "icons/svglogo"}}
<span class="logo-mark">{{> "icons/greater-icon"}}</span>
<span class="logo-text">sd.ai</span>
<span class="logo-cursor"></span>
+2 -1
View File
@@ -6,7 +6,7 @@
{{#if @site.logo}} {{#if @site.logo}}
<img src="{{@site.logo}}" alt="{{@site.title}}"> <img src="{{@site.logo}}" alt="{{@site.title}}">
{{else}} {{else}}
{{@site.title}} {{> "components/logo"}}
{{/if}} {{/if}}
</a> </a>
{{> "search-toggle"}} {{> "search-toggle"}}
@@ -47,6 +47,7 @@
{{/unless}} {{/unless}}
</div> </div>
{{/unless}} {{/unless}}
{{> "theme-switcher"}}
</div> </div>
</div> </div>
+2 -20
View File
@@ -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}}
+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" class="greater-icon" viewBox="0 0 44 44">
<path fill="none" d="M15 8l14.729 14.382L15 35.367" />
</svg>

After

Width:  |  Height:  |  Size: 146 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 78 KiB

+14
View File
@@ -0,0 +1,14 @@
<svg
class="theme-toggler"
width="24"
height="24"
viewBox="0 0 48 48"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M22 41C32.4934 41 41 32.4934 41 22C41 11.5066 32.4934 3 22
3C11.5066 3 3 11.5066 3 22C3 32.4934 11.5066 41 22 41ZM7 22C7
13.7157 13.7157 7 22 7V37C13.7157 37 7 30.2843 7 22Z"
/>
</svg>

After

Width:  |  Height:  |  Size: 337 B

+3
View File
@@ -0,0 +1,3 @@
<button class="theme-toggle gh-icon-button" aria-label="Change theme">
{{> "icons/theme-icon"}}
</button>