Add comments

This commit is contained in:
Nathan McCarty 2025-02-12 21:26:00 -05:00
parent b307eb391b
commit 4de44c7e8c
3 changed files with 388 additions and 6 deletions

View file

@ -13,9 +13,20 @@ unit class Config;
method generate-post(Int:D $id, Post:D $post, $db) {
my $meta = $db.meta;
my $content = $post.render-html;
my $cactus-script = qq
document.addEventListener('DOMContentLoaded', () => \{
initComments(\{
node: document.getElementById("comment-section"),
defaultHomeserverUrl: "https://matrix.cactus.chat",
serverName: "cactus.chat",
siteName: "stranger.systems",
commentSectionId: "post-$id"
\})\})」;
my $head =
head [
# Generate the universal header components
generate-head($meta, $post.title, $post.description);
# Open graph tags for embedding
meta :property<og:title>, :content($post.title);
meta :property<og:url>, :content(post-link-abs $db.meta, $id, $post);
meta :property<og:site_name>, :content($db.meta.title);
@ -26,6 +37,14 @@ method generate-post(Int:D $id, Post:D $post, $db) {
$post.tags.map(-> $tag {
meta :property<article:tag>, :content($tag)
});
# Cactus comments support
link :rel<stylesheet>,
:href</resources/cactus.css>,
:type<text/css>;
script :src<https://gateway.pinata.cloud/ipfs/QmSiWN27KZZ1XE32jKwifBnS3nWTUcFGNArKzur2nmDgoL/v0.13.0/cactus.js>;
# Only actually load the script if the post isn't hidden
optl !$post.hidden, -> {script $cactus-script};
];
my $body =
body [
@ -34,8 +53,10 @@ method generate-post(Int:D $id, Post:D $post, $db) {
post-header $id, $post, $db;
div :class<post-body>, [
$content;
]
]
];
];
# Only actually have the comment section if the post isn't hidden
optl !$post.hidden, -> {div :id<comment-section>, :class<comments>};
];
# TODO: Setup Comments
# TODO: Setup footer

View file

@ -159,10 +159,11 @@ class PostDB {
mkdir $res-dir unless $res-dir.e;
# symlink the resources directory to make "interactive" styling eaiser
# TODO: Directories support
%?RESOURCES<colors.css>.IO.symlink: $res-dir.add('colors.css') unless %?RESOURCES<colors.css>.IO.e;
%?RESOURCES<main.css>.IO.symlink: $res-dir.add('main.css') unless %?RESOURCES<main.css>.IO.e;
%?RESOURCES<code.css>.IO.symlink: $res-dir.add('code.css') unless %?RESOURCES<code.css>.IO.e;
%?RESOURCES<admonitions.css>.IO.symlink: $res-dir.add('admonitions.css') unless %?RESOURCES<admonitions.css>.IO.e;
%?RESOURCES<colors.css>.IO.symlink: $res-dir.add('colors.css') unless $res-dir.add('colors.css').e;
%?RESOURCES<main.css>.IO.symlink: $res-dir.add('main.css') unless $res-dir.add('main.css').e;
%?RESOURCES<code.css>.IO.symlink: $res-dir.add('code.css') unless $res-dir.add('code.css').e;
%?RESOURCES<admonitions.css>.IO.symlink: $res-dir.add('admonitions.css') unless $res-dir.add('admonitions.css').e;
%?RESOURCES<cactus.css>.IO.symlink: $res-dir.add('cactus.css') unless $res-dir.add('cactus.css').e;
}
#| Get a list of posts sorted by date

360
resources/cactus.css Normal file
View file

@ -0,0 +1,360 @@
:root{
--cactus-text-color--soft: var(--dim-0);
--cactus-background-color--strong: var(--bg-1);
--cactus-border-color: var(--dim-0);
--cactus-box-shadow-color: transparent;
--cactus-button-text-color:inherit;
--cactus-button-color: var(--bg-2);
--cactus-button-color--strong: var(--bg-2);
--cactus-button-color--stronger: var(--bg-2);
--cactus-login-form-text-color:inherit;
--cactus-border-width:1px;
--cactus-border-radius:0.4em;
--cactus-text-color:inherit;
--cactus-background-color: var(--bg-0);
--cactus-error-color: var(--red)
}
.cactus-comment-header a {
color: var(--blue);
}
.cactus-container{
display:flex;
width: 100%;
max-width: var(--content-width);
padding: var(--box-padding-vert) var(--box-padding-horz);
border-radius: var(--box-radius);
flex-direction:column;
gap:1em;
color:var(--cactus-text-color);
background-color:var(--cactus-background-color)
}
.cactus-error{
padding:.5em;
padding-inline-end:1.5em;
border:var(--cactus-border-width) solid var(--cactus-error-color);
border-radius:var(--cactus-border-radius);
position:relative
}
.cactus-error-close{
position:absolute;
right:.2em;
top:0;
color:var(--cactus-button-color);
background-color:transparent;
border:none
}
.cactus-error-close:hover:not([disabled]){
color:var(--cactus-button-color--strong);
cursor:pointer
}
.cactus-error-close:active:not([disabled]){
color:var(--cactus-button-color--stronger);
cursor:pointer
}
.cactus-error-close-icon{
inline-size:20px;
block-size:20px
}
.cactus-error-text{
color:var(--cactus-error-color);
font-weight:700;
margin:0
}
.cactus-editor{
display:flex;
flex-direction:column;
gap:.5em
}
.cactus-editor>span{
display:flex
}
.cactus-editor-textarea{
display:flex;
flex:1;
height:9rem;
border-radius:var(--cactus-border-radius);
border:solid var(--cactus-border-width) var(--green);
padding:.5em;
box-sizing:content-box;
background-color:transparent;
color:inherit;
font:inherit
}
.cactus-editor-textarea::placeholder{
text-align:center;
line-height:8rem;
font-size:1.5rem;
color:var(--cactus-text-color--soft)
}
.cactus-editor-below{
display:flex;
flex-wrap:wrap;
gap:.5em;
justify-content:flex-end
}
.cactus-editor-name{
display:flex;
flex:1
}
.cactus-editor-name>span{
display:flex;
flex:1;
min-inline-size:20ch;
max-inline-size:40ch
}
.cactus-editor-name>span>input{
inline-size:100%;
border-radius:var(--cactus-border-radius);
border:solid var(--cactus-border-width) var(--green);
padding:.5em;
background-color:transparent;
color:inherit;
font-size:inherit
}
.cactus-editor-name>span>input::placeholder{
color:var(--cactus-text-color--soft)
}
.cactus-editor-buttons{
display:flex;
gap:.5em
}
.cactus-matrixdotto-only{
align-self:center;
text-decoration:none
}
.cactus-login-form-wrapper{
position:fixed;
top:0;
bottom:0;
left:0;
right:0;
z-index:1;
display:flex;
align-items:center;
justify-content:center
}
.cactus-login-form{
display:flex;
flex-direction:column;
gap:2em;
padding:2rem;
border-radius:var(--cactus-border-radius);
background-color:var(--cactus-background-color--strong);
color:var(--cactus-login-form-text-color);
box-shadow:0 .5em 1em .5em var(--cactus-box-shadow-color);
box-sizing:border-box;
inline-size:100%;
max-inline-size:300px
}
.cactus-login-close{
align-self:flex-end;
position:relative;
margin:-2em;
padding:0;
color:var(--cactus-button-color);
scale:2;
background-color:transparent;
border:none
}
.cactus-login-close:hover:not([disabled]){
color:var(--cactus-button-color--strong);
cursor:pointer
}
.cactus-login-close:active:not([disabled]){
color:var(--cactus-button-color--stronger);
cursor:pointer
}
.cactus-login-close-icon{
inline-size:20px;
block-size:20px
}
.cactus-login-title{
align-self:center;
font-size:1.17em;
font-weight:700;
margin:0
}
.cactus-login-client{
display:flex;
flex-direction:column;
gap:1em
}
.cactus-login-client-title{
font-size:1em;
font-weight:700;
margin:0
}
.cactus-matrixdotto-button{
justify-content:center;
text-decoration:none
}
.cactus-login-credentials{
display:flex;
flex-direction:column;
gap:1em
}
.cactus-login-credentials-title{
font-size:1em;
font-weight:700;
margin:0
}
.cactus-login-field{
display:flex;
flex-direction:column;
gap:.25em
}
.cactus-login-label{
font-size:1em;
padding-bottom:.25em;
color:var(--cactus-text-color--soft)
}
.cactus-login-error{
margin:0;
font-size:.8em;
color:var(--cactus-text-color--soft)
}
.cactus-login-field>input{
border-radius:var(--cactus-border-radius);
border:solid var(--cactus-border-width) var(--cactus-border-color);
padding:.5em;
background-color:transparent;
color:inherit;
font-size:inherit
}
.cactus-login-field>input::placeholder{
color:var(--cactus-text-color--soft)
}
.cactus-login-credentials-button{
justify-content:center
}
.cactus-comments-container{
display:flex;
flex-direction:column;
gap:1em
}
.cactus-comments-list{
display:flex;
flex-direction:column;
gap:.5em
}
.cactus-comment{
display:flex;
flex-direction:row;
gap:1em;
padding-block-end:.5em;
border-block-end: 2px dotted var(--dim-0);
}
.cactus-comment-avatar{
display:flex
}
.cactus-comment-avatar>*{
width:2.5rem;
height:2.5rem;
border-radius:50%;
margin:0
}
.cactus-comment-avatar-placeholder{
display:flex;
justify-content:center;
align-items:center;
background-color:var(--cactus-border-color);
color:var(--bg-2);
}
.cactus-comment-avatar-placeholder:before{
content:"?"
}
.cactus-comment-content{
display:flex;
flex-direction:column;
gap:.5em
}
.cactus-comment-header{
display:flex;
gap:.5em;
flex-wrap:wrap
}
.cactus-comment-displayname{
font-weight:700;
cursor:pointer;
text-decoration:none;
color:inherit
}
.cactus-comment-time{
color:var(--cactus-text-color--soft)
}
.cactus-message-text>:first-child{
margin-block-start:0
}
.cactus-message-text>:last-child{
margin-block-end:0
}
.cactus-message-emote{
padding-top:.5em;
color:var(--cactus-text-color--soft)
}
.cactus-message-image{
max-width:100%;
height:auto
}
.cactus-message-file{
line-height:3em;
margin-left:1em
}
.cactus-message-video{
max-width:100%
}
.cactus-button{
display:flex;
align-items:center;
padding-block:.6em;
padding-inline:1em;
background-color:var(--cactus-button-color);
font-weight:700;
border-radius:var(--cactus-border-radius);
color:var(--cactus-button-text-color);
font-size:inherit;
border:none
}
.cactus-button:hover:not([disabled]){
background-color:var(--cactus-button-color--strong);
cursor:pointer
}
.cactus-button:active:not([disabled]){
background-color:var(--cactus-button-color--stronger);
cursor:pointer
}
.cactus-view-more{
display:flex;
justify-content:center
}
.spinner{
align-self:center;
width:2em;
height:2em;
display:flex;
gap:.3em
}
.spinner>div{
flex:1;
background-color:var(--cactus-border-color);
animation:sk-stretchdelay 2.4s ease-in-out infinite
}
.spinner .rect2{
animation-delay:-2.2s
}
.spinner .rect3{
animation-delay:-2s
}
.spinner .rect4{
animation-delay:-1.8s
}
@keyframes sk-stretchdelay{
0%,40%,to{
transform:scaleY(.4)
}
20%{
transform:scaleY(1)
}
}
/*# sourceMappingURL=/style.css.map */