Implement mastodon comments

This commit is contained in:
2024-02-04 19:36:44 -06:00
parent aa60dc5e32
commit 69d7cd1da6
20 changed files with 354 additions and 22 deletions

View File

@ -1,4 +1,4 @@
main > p:not(.nodropcap):first-of-type:first-letter {
main > article > p:not(.nodropcap):first-of-type:first-letter {
float: left;
font-size: 4rem;
padding: .5rem .5rem .5rem .5rem;

View File

@ -24,7 +24,7 @@
--icon-filter: none;
/* Corners */
--corner-radius: .3rem;
--border-radius: .3rem;
/* Space & Size */
--syntax-tab-size: 2;
@ -32,6 +32,7 @@
--single-gap: 1rem;
--double-gap: 2rem;
--triple-gap: 3rem;
--quad-gap: 4rem;
/* Transitions */
--transition-normal: all .3s;
@ -49,11 +50,28 @@
--weight-heavy: 500;
--weight-normal: 300;
/* Links */
--link-decoration-thickness: .1rem;
/* Borders */
--border-nav: 1px solid var(--text-color);
--border-nav-currentpage: 20px solid var(--contrast-color);
--border-nav-hover: 20px solid var(--text-color);
--border-thin: 1px solid var(--color-gray-20);
/* Shadow */
--box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
/* Components */
--wc-card-background-color: var(--card-color);
--wc-card-border-radius: var(--border-radius);
--wc-card-box-shadow: var(--box-shadow);
--wc-link-color: var(--text-color);
--wc-link-decoration-color: var(--contrast-color);
--wc-link-decoration-thickness: var(--link-decoration-thickness);
--wc-comment-text-margin: auto auto auto 4rem;
--wc-profile-pic-size: 3rem;
--wc-profile-pic-border-radius: 10rem;
}
@media (prefers-color-scheme: dark) {
@ -64,7 +82,7 @@
--contrast-color: #04c49e;
/* --text-color is assigned to --color-gray-_ above */
--text-color-link: var(--contrast-color);
--text-color-link: var(--text-color);
--background-color: #15202b;
--logo-filter: none;
@ -96,6 +114,7 @@ body {
background-color: var(--background-color);
color: var(--text-color);
font-family: var(--font-family);
font-size: 13px;
font-variant-Ligatures: normal;
font-weight: var(--weight-normal);
margin: 0 auto;
@ -109,7 +128,7 @@ body {
}
a {
text-decoration-color: var(--contrast-color);
text-decoration-thickness: .1rem;
text-decoration-thickness: var(--link-decoration-thickness);
transition: var(--transition-normal);
}
/* https://www.a11yproject.com/posts/how-to-hide-content/ */
@ -123,8 +142,18 @@ a {
width: 1px;
}
footer {
margin-top: var(--triple-gap);
padding: var(--single-gap);
border-top: var(--border-thin);
}
footer .copyright-notice {
padding-right: var(--single-gap);
}
footer .webring {
display: inline-block;
padding-right: var(--single-gap);
}
footer p {
font-size: var(--font-s);
}
h1, h2, h3 {
color: var(--text-color);
@ -140,7 +169,7 @@ h1 {
h2 {
font-size: var(--font-xl);
font-weight: var(--weight-extraheavy);
margin-top: var(--double-gap);
margin: var(--quad-gap) auto 0 auto;
}
h3 {
font-size: var(--font-l);
@ -167,7 +196,7 @@ p, li {
}
figure {
margin: 0;
padding: var(--single-gap) 0 var(--single-gap) 0;
padding: var(--single-gap) 0 0 0;
width: 100%;
}
figure > a > img {
@ -182,6 +211,17 @@ figcaption {
.page-block {
margin-bottom: var(--triple-gap);
}
.big-link {
width: 100%;
padding: var(--half-gap);
border: var(--border-nav);
border-radius: var(--border-radius);
margin: var(--single-gap) auto var(--single-gap) auto;
transition: var(--transition-normal);
}
.big-link:hover {
border-color: var(--contrast-color);
}
a[href]:not(.icon-button) {
color: var(--text-color-link);
}
@ -194,9 +234,8 @@ a[href]:active:not(.icon-button) {
}
.links-nextprev {
list-style: none;
border-top: var(--border-thin);
padding: var(--triple-gap) 0 var(--single-gap) 0;
margin-top: var(--triple-gap);
padding: 0 0 var(--single-gap) 0;
margin-top: var(--single-gap);
}
table {
@ -207,6 +246,27 @@ table th {
padding-right: 1em;
}
/* Comments */
.comment-ingress {
margin-bottom: var(--double-gap);
}
#comment-section h2 {
margin: var(--quad-gap) auto 0 auto;
}
wc-comment::part(author-link) {
font-size: var(--font-n);
font-weight: var(--weight-extraheavy);
text-decoration: none;
}
wc-comment::part(main) {
margin-bottom: var(--double-gap);
}
wc-comment::part(publish-date) {
font-weight: var(--weight-heavy);
font-size: var(--font-s);
margin-top: -.25rem;
}
/* Code Fences */
pre,
code {
@ -233,7 +293,6 @@ code {
/* Header */
header {
align-items: end;
border-bottom: var(--border-thin);
display: flex;
flex-wrap: wrap;
gap: 1em .5em;
@ -331,17 +390,17 @@ nav ul {
.postlist-item {
align-items: flex-start;
background-color: var(--card-color);
border-radius: var(--corner-radius);
border-radius: var(--border-radius);
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
margin-bottom: 1em;
margin-bottom: var(--double-gap);
padding: var(--single-gap) 1.1rem var(--single-gap) 1.1rem;
width: 100%;
}
.post-image-container {
border-radius: var(--corner-radius);
border-radius: var(--border-radius);
margin-right: var(--single-gap);
max-height: 15rem;
overflow: hidden;
@ -421,9 +480,14 @@ a.post-tag:hover {
align-self: center;
}
/* Article / Post */
.post h2 {
font-size: var(--font-l);
}
/* Post Metadata */
.post-metadata {
margin-bottom: var(--triple-gap);
margin-bottom: var(--double-gap);
margin-top: var(--single-gap);
padding: 0 0 0 .4rem;
}
@ -481,7 +545,7 @@ h2 + .header-anchor {
margin-bottom: var(--single-gap);
}
h3, .post-copy a h3 {
font-size: 1rem;
font-size: 1.25rem;
}
/* Header */
@ -494,6 +558,11 @@ h2 + .header-anchor {
margin-top: var(--single-gap);
}
/* Footer */
footer .webring {
display: block;
}
/* Nav */
.nav {
flex-flow: row wrap;

4
public/js/main.js Normal file
View File

@ -0,0 +1,4 @@
import './webComponents/card.js';
import './webComponents/profilePic.js';
import './webComponents/speechBubble.js';
import './webComponents/comment.js';

View File

@ -0,0 +1,33 @@
const template = document.createElement('template');
template.innerHTML = `
<style>
#card {
align-items: flex-start;
background-color: var(--wc-card-background-color);
border-radius: var(--wc-card-border-radius);
box-shadow: var(--wc-card-box-shadow);
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
margin-bottom: 1em;
padding: var(--single-gap) 1.1rem var(--single-gap) 1.1rem;
width: 100%;
}
</style>
<div id="card" part="main">
<slot></slot>
</div>
`
class card extends HTMLElement {
constructor() {
super();
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
this._shadowRoot.appendChild(template.content.cloneNode(true));
}
}
window.customElements.define('wc-card', card);

View File

@ -0,0 +1,76 @@
const template = document.createElement('template');
template.innerHTML = `
<style>
a {
color: var(--wc-link-color);
text-decoration-color: var(--wc-link-decoration-color);
text-decoration-thickness: var(--wc-link-decoration-thickness);
}
#comment {
margin: var(--wc-comment-text-margin);
}
#comment p {
margin: 0 auto 0 auto;
}
#meta {
display: flex;
flex-flow: row nowrap;
}
#meta-text {
display: flex;
flex-flow: column nowrap;
width: 100%;
}
#meta-text p {
margin: 0 1rem 0 1rem;
}
</style>
<article id="commentContainer" class="blog-comment" part="main">
<div id="meta" part="meta">
<div>
<wc-profile-pic url="" />
</div>
<div id="meta-text" part="meta-text">
<p id="author" part="author">
<a id="author-link" part="author-link"></a><span> says:</span>
</p>
<p id="publish-date" part="publish-date"></p>
</div>
</div>
<div id="comment" part="content">
</div>
</article>
`
class comment extends HTMLElement {
constructor() {
super();
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
this._shadowRoot.appendChild(template.content.cloneNode(true));
this.$comment = this._shadowRoot.querySelector('#commentContainer');
}
static get observedAttributes() {
return ['author_name', 'author_url', 'avatar_url', 'comment_content', 'publish_date'];
}
attributeChangedCallback(name, oldVal, newVal) {
if (oldVal != newVal) {
this[name] = newVal;
this.render();
}
}
render() {
this.$comment.querySelector('#author-link').innerHTML = this.author_name;
this.$comment.querySelector('#author-link').href = this.author_url;
this.$comment.querySelector('wc-profile-pic').setAttribute('url', this.avatar_url)
this.$comment.querySelector('#comment').innerHTML = this.comment_content;
this.$comment.querySelector('#publish-date').innerHTML = this.publish_date;
}
}
window.customElements.define('wc-comment', comment);

View File

@ -0,0 +1,40 @@
const template = document.createElement('template');
template.innerHTML = `
<style>
#profilePic {
border-radius: var(--wc-profile-pic-border-radius);
width: var(--wc-profile-pic-size);
height: var(--wc-profile-pic-size);
}
</style>
<img src="" id="profilePic"/>
`
class profilePic extends HTMLElement {
constructor() {
super();
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
this._shadowRoot.appendChild(template.content.cloneNode(true));
this.$profilePic = this._shadowRoot.querySelector('#profilePic');
}
static get observedAttributes() {
return ['url'];
}
attributeChangedCallback(name, oldVal, newVal) {
if (oldVal != newVal) {
this[name] = newVal;
this.render();
}
}
render() {
this.url ? this.$profilePic.src = this.url : null;
}
}
window.customElements.define('wc-profile-pic', profilePic);