diff --git a/src/lib/components/Comments.svelte b/src/lib/components/Comments.svelte
index 0446682..672174d 100644
--- a/src/lib/components/Comments.svelte
+++ b/src/lib/components/Comments.svelte
@@ -400,8 +400,8 @@
{:else}
{#if topLevel.length === 0}
-
-
+
{:else}
diff --git a/src/lib/components/PostActions.svelte b/src/lib/components/PostActions.svelte
index 9b28a60..6e12a8f 100644
--- a/src/lib/components/PostActions.svelte
+++ b/src/lib/components/PostActions.svelte
@@ -64,7 +64,9 @@
});
function onCommentClick(e: MouseEvent) {
- const el = document.getElementById(commentTargetId) as HTMLDetailsElement | null;
+ const el = document.getElementById(
+ commentTargetId,
+ ) as HTMLDetailsElement | null;
if (!el) return;
e.preventDefault();
el.open = true;
@@ -76,6 +78,17 @@
let copyTimer: ReturnType
| null = null;
let shareTimer: ReturnType | null = null;
+ // Share button only renders when the browser actually has a native share-
+ // sheet — otherwise it would just be a duplicate of "Link kopieren".
+ // SSR has no `navigator`, so this stays false until client mount.
+ let canShare = $state(false);
+ $effect(() => {
+ canShare =
+ typeof navigator !== "undefined" &&
+ typeof (navigator as Navigator & { share?: unknown }).share ===
+ "function";
+ });
+
function flashCopied() {
copied = true;
if (copyTimer) clearTimeout(copyTimer);
@@ -110,17 +123,16 @@
}
async function share() {
- const w = window as unknown as { navigator: Navigator & { share?: (data: ShareData) => Promise } };
- if (typeof w.navigator.share === "function") {
- try {
- await w.navigator.share({ title, url });
- flashShared();
- return;
- } catch {
- // user cancelled or share failed → fall through to copy
- }
+ const nav = navigator as Navigator & {
+ share?: (data: ShareData) => Promise;
+ };
+ if (typeof nav.share !== "function") return;
+ try {
+ await nav.share({ title, url });
+ flashShared();
+ } catch {
+ // user cancelled — no fallback, copy-link button covers that case
}
- await copyLink();
}
function print() {
@@ -128,56 +140,71 @@
}
-
+
+
{#if commentPageId}
-
+
{commentCount ?? "…"}
{/if}
-
-
-
-
-
+
+ {#if canShare}
+
+ {/if}
+
+
+
{#if readingTimeMinutes != null && readingTimeMinutes > 0}
-
- {t(T.post_action_reading_time, { minutes: readingTimeMinutes })}
+
+ {t(T.post_action_reading_time, { minutes: readingTimeMinutes })}
{/if}
diff --git a/src/routes/post/[slug]/+page.server.ts b/src/routes/post/[slug]/+page.server.ts
index 21e523c..7452ce8 100644
--- a/src/routes/post/[slug]/+page.server.ts
+++ b/src/routes/post/[slug]/+page.server.ts
@@ -237,10 +237,36 @@ export const load: PageServerLoad = async ({ params, locals, url, setHeaders })
}
// Reading-time estimate. ~200 words per minute for German non-fiction.
- // Strips HTML tags, then counts whitespace-separated tokens. Includes only
- // the prose body (headline + content); rows aren't part of the prose flow.
+ // Pulls text from headline + body markdown AND from referenced row blocks
+ // (Termin-Posts have an empty body; their text lives in row1Content
+ // markdown/text references). Walks the post tree once, collecting any
+ // `content` / `body` / `text` string fields below row*Content. HTML tags
+ // get stripped before the word count.
const readingTimeMinutes = (() => {
- const plain = (contentHeadlineHtml + " " + contentBodyHtml)
+ const parts: string[] = [contentHeadlineHtml, contentBodyHtml];
+ const collect = (node: unknown) => {
+ if (!node || typeof node !== "object") return;
+ if (Array.isArray(node)) {
+ for (const item of node) collect(item);
+ return;
+ }
+ const obj = node as Record
;
+ for (const [key, value] of Object.entries(obj)) {
+ if (typeof value === "string") {
+ if (key === "content" || key === "body" || key === "text") {
+ parts.push(value);
+ }
+ } else {
+ collect(value);
+ }
+ }
+ };
+ collect((post as { row1Content?: unknown }).row1Content);
+ collect((post as { row2Content?: unknown }).row2Content);
+ collect((post as { row3Content?: unknown }).row3Content);
+
+ const plain = parts
+ .join(" ")
.replace(/<[^>]+>/g, " ")
.replace(/\s+/g, " ")
.trim();
diff --git a/src/routes/post/[slug]/+page.svelte b/src/routes/post/[slug]/+page.svelte
index e2b2bca..40d11ed 100644
--- a/src/routes/post/[slug]/+page.svelte
+++ b/src/routes/post/[slug]/+page.svelte
@@ -24,10 +24,10 @@
{/if}
-
+
{#if data.rawPostImageUrl}
{:else if data.postImageUrl}
{/if}
-
- {#if data.postDate || data.commentPageId}
-
- {#if data.postDate}
-
- {/if}
+
+
+
+ {#if data.postDate}
+
+
{/if}
-
-
-
+ {#if (data.post.postTag ?? []).length > 0}
+
+
+
+ {/if}
+
-