From 4de44c7e8ca9b23daaf21b2183e3a457389fb772 Mon Sep 17 00:00:00 2001 From: Nathan McCarty Date: Wed, 12 Feb 2025 21:26:00 -0500 Subject: [PATCH] Add comments --- lib/Config.rakumod | 25 ++- lib/DB.rakumod | 9 +- resources/cactus.css | 360 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 388 insertions(+), 6 deletions(-) create mode 100644 resources/cactus.css diff --git a/lib/Config.rakumod b/lib/Config.rakumod index e988aa4..a7bdc67 100644 --- a/lib/Config.rakumod +++ b/lib/Config.rakumod @@ -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, :content($post.title); meta :property, :content(post-link-abs $db.meta, $id, $post); meta :property, :content($db.meta.title); @@ -26,6 +37,14 @@ method generate-post(Int:D $id, Post:D $post, $db) { $post.tags.map(-> $tag { meta :property, :content($tag) }); + + # Cactus comments support + link :rel, + :href, + :type; + script :src; + # 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, [ $content; - ] - ] + ]; + ]; + # Only actually have the comment section if the post isn't hidden + optl !$post.hidden, -> {div :id, :class}; ]; # TODO: Setup Comments # TODO: Setup footer diff --git a/lib/DB.rakumod b/lib/DB.rakumod index e30ae1d..4373000 100644 --- a/lib/DB.rakumod +++ b/lib/DB.rakumod @@ -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.IO.symlink: $res-dir.add('colors.css') unless %?RESOURCES.IO.e; - %?RESOURCES.IO.symlink: $res-dir.add('main.css') unless %?RESOURCES.IO.e; - %?RESOURCES.IO.symlink: $res-dir.add('code.css') unless %?RESOURCES.IO.e; - %?RESOURCES.IO.symlink: $res-dir.add('admonitions.css') unless %?RESOURCES.IO.e; + %?RESOURCES.IO.symlink: $res-dir.add('colors.css') unless $res-dir.add('colors.css').e; + %?RESOURCES.IO.symlink: $res-dir.add('main.css') unless $res-dir.add('main.css').e; + %?RESOURCES.IO.symlink: $res-dir.add('code.css') unless $res-dir.add('code.css').e; + %?RESOURCES.IO.symlink: $res-dir.add('admonitions.css') unless $res-dir.add('admonitions.css').e; + %?RESOURCES.IO.symlink: $res-dir.add('cactus.css') unless $res-dir.add('cactus.css').e; } #| Get a list of posts sorted by date diff --git a/resources/cactus.css b/resources/cactus.css new file mode 100644 index 0000000..48b87cd --- /dev/null +++ b/resources/cactus.css @@ -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 */