feat: replace Cusdis with own comment plugin
Deploy / verify (push) Failing after 45s
Deploy / deploy (push) Has been skipped

Drops the Cusdis embed (postCommentSlot in pageConfig) in favour of the
new RustyCMS comment plugin. New Comments.svelte renders the thread,
form, replies and inline edit/delete via /api/comments. Count-badge near
the post date links to the accordion and uses /api/comments/:id/count.

Accordion gets a `lazy` mode so the comment iframe / fetch happens only
on first open (avoids the previous "empty on first render" issue with
hidden details).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Peter Meier
2026-04-28 11:17:10 +02:00
parent 9b4191151c
commit febc027e6b
5 changed files with 498 additions and 39 deletions
+15 -18
View File
@@ -5,21 +5,13 @@
import EventBadges from '$lib/components/EventBadges.svelte';
import EventMap from '$lib/components/EventMap.svelte';
import Accordion from '$lib/components/Accordion.svelte';
import CommentCountBadge from '$lib/components/CommentCountBadge.svelte';
import Comments from '$lib/components/Comments.svelte';
import RustyImage from '$lib/components/RustyImage.svelte';
import { t, T } from '$lib/translations';
import type { PageData } from './$types';
let { data }: { data: PageData } = $props();
function executeScripts(node: HTMLElement) {
const scripts = node.querySelectorAll("script");
scripts.forEach((old) => {
const s = document.createElement("script");
for (const { name, value } of old.attributes) s.setAttribute(name, value);
s.text = old.textContent ?? "";
old.replaceWith(s);
});
}
</script>
<svelte:head>
@@ -34,7 +26,7 @@
<div class="md:flex gap-2 items-end">
{#if data.rawPostImageUrl}
<div class="overflow-hidden inline-block my-4 border border-white self-start ring-1 ring-black/50 shadow-lg">
<div class="overflow-hidden inline-block my-4 border border-white self-start ring-1 ring-black/50 shadow-lg aspect-square">
<RustyImage
src={data.rawPostImageUrl}
focal={data.postImageFocal}
@@ -49,7 +41,7 @@
/>
</div>
{:else if data.postImageUrl}
<div class="overflow-hidden inline-block my-4 border border-white self-start ring-1 ring-black/50 shadow-lg">
<div class="overflow-hidden inline-block my-4 border border-white self-start ring-1 ring-black/50 shadow-lg aspect-square">
<img
src={data.postImageUrl}
alt=""
@@ -62,9 +54,14 @@
</div>
{/if}
<div class="mt-2 mb-4! md:mb-1 min-w-0 gap-2">
{#if data.postDate}
{#if data.postDate || data.commentPageId}
<div class="flex flex-nowrap gap-2 items-center shrink-0 mb-2">
<Tag label={data.postDate} variant="date" />
{#if data.postDate}
<Tag label={data.postDate} variant="date" />
{/if}
{#if data.commentPageId}
<CommentCountBadge pageId={data.commentPageId} targetId="comments-section" />
{/if}
</div>
{/if}
<div class="flex flex-nowrap gap-2 items-center shrink-0 p-1 pb-4 -ml-1 overflow-x-auto overflow-y-hidden">
@@ -148,10 +145,10 @@
/>
{/if}
{#if data.commentSlot}
<Accordion label={t(data.translations, T.post_comments)} class="mt-6">
<div class="p-8 border border-zinc-200 rounded-lg" use:executeScripts>
{@html data.commentSlot}
{#if data.commentPageId}
<Accordion id="comments-section" label={t(data.translations, T.post_comments)} lazy class="mt-6">
<div class="p-8 border border-zinc-200 rounded-lg">
<Comments pageId={data.commentPageId} />
</div>
</Accordion>
{/if}