mirror of
https://github.com/dsec-hub/dsec-notebook.git
synced 2026-09-22 07:24:27 +00:00
Merge pull request #10 from dsec-hub/feature/post-preview
add preview to posts
This commit is contained in:
commit
1452beeb39
9 changed files with 59 additions and 0 deletions
|
|
@ -1,10 +1,12 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { previewMarkdown } from "$lib/markdown";
|
||||||
import { unitPath } from "$lib/paths";
|
import { unitPath } from "$lib/paths";
|
||||||
import VoteStack from "./VoteStack.svelte";
|
import VoteStack from "./VoteStack.svelte";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
href,
|
href,
|
||||||
title,
|
title,
|
||||||
|
content,
|
||||||
unitCode,
|
unitCode,
|
||||||
meta,
|
meta,
|
||||||
voteCount = 0,
|
voteCount = 0,
|
||||||
|
|
@ -14,6 +16,7 @@
|
||||||
}: {
|
}: {
|
||||||
href: string;
|
href: string;
|
||||||
title: string;
|
title: string;
|
||||||
|
content?: string;
|
||||||
unitCode?: string;
|
unitCode?: string;
|
||||||
meta: string;
|
meta: string;
|
||||||
voteCount?: number;
|
voteCount?: number;
|
||||||
|
|
@ -40,6 +43,11 @@
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
</a>
|
</a>
|
||||||
|
{#if content?.trim()}
|
||||||
|
<p class="text-muted mt-1 line-clamp-2 text-sm leading-relaxed">
|
||||||
|
{previewMarkdown(content)}
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
<p class="kicker mt-1.5">{meta}</p>
|
<p class="kicker mt-1.5">{meta}</p>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
|
||||||
14
src/lib/markdown.spec.ts
Normal file
14
src/lib/markdown.spec.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { previewMarkdown } from "./markdown";
|
||||||
|
|
||||||
|
describe("previewMarkdown", () => {
|
||||||
|
it("returns readable text without markdown formatting", () => {
|
||||||
|
expect(previewMarkdown("# Heading\n\nA **bold** [link](https://example.com).")).toBe(
|
||||||
|
"Heading A bold link.",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("includes code and truncates long previews", () => {
|
||||||
|
expect(previewMarkdown("Use `const value = 1` here.", 18)).toBe("Use const value =…");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -9,3 +9,30 @@ const md = new MarkdownIt({
|
||||||
export function renderMarkdown(source: string): string {
|
export function renderMarkdown(source: string): string {
|
||||||
return md.render(source ?? "");
|
return md.render(source ?? "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function previewMarkdown(source: string, maxLength = 180): string {
|
||||||
|
const text = md
|
||||||
|
.parse(source ?? "", {})
|
||||||
|
.map((token) => {
|
||||||
|
console.log(token);
|
||||||
|
if (token.type === "inline") {
|
||||||
|
return (token.children ?? [])
|
||||||
|
.filter((child) => child.type !== "image")
|
||||||
|
.map((child) =>
|
||||||
|
child.type === "softbreak" || child.type === "hardbreak"
|
||||||
|
? " "
|
||||||
|
: child.content,
|
||||||
|
)
|
||||||
|
.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.type === "fence" || token.type === "code_block") return token.content;
|
||||||
|
return "";
|
||||||
|
})
|
||||||
|
.join(" ")
|
||||||
|
.replace(/\s+/g, " ")
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
if (text.length <= maxLength) return text;
|
||||||
|
return `${text.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@
|
||||||
<FeedRow
|
<FeedRow
|
||||||
href={postPath(note.unit!.code, note._id)}
|
href={postPath(note.unit!.code, note._id)}
|
||||||
title={note.title}
|
title={note.title}
|
||||||
|
content={note.content}
|
||||||
unitCode={note.unit
|
unitCode={note.unit
|
||||||
? note.unit.code + (note.unit.code2 ? ` / ${note.unit.code2}` : "")
|
? note.unit.code + (note.unit.code2 ? ` / ${note.unit.code2}` : "")
|
||||||
: undefined}
|
: undefined}
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@
|
||||||
<FeedRow
|
<FeedRow
|
||||||
href={postPath(question.unit!.code, question._id)}
|
href={postPath(question.unit!.code, question._id)}
|
||||||
title={question.title}
|
title={question.title}
|
||||||
|
content={question.content}
|
||||||
unitCode={question.unit
|
unitCode={question.unit
|
||||||
? question.unit.code + (question.unit.code2 ? ` / ${question.unit.code2}` : "")
|
? question.unit.code + (question.unit.code2 ? ` / ${question.unit.code2}` : "")
|
||||||
: undefined}
|
: undefined}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@
|
||||||
<FeedRow
|
<FeedRow
|
||||||
href={postPath(result.unit!.code, result._id)}
|
href={postPath(result.unit!.code, result._id)}
|
||||||
title={result.title}
|
title={result.title}
|
||||||
|
content={result.content}
|
||||||
unitCode={result.unit
|
unitCode={result.unit
|
||||||
? result.unit.code + (result.unit.code2 ? ` / ${result.unit.code2}` : "")
|
? result.unit.code + (result.unit.code2 ? ` / ${result.unit.code2}` : "")
|
||||||
: undefined}
|
: undefined}
|
||||||
|
|
@ -69,6 +70,7 @@
|
||||||
<FeedRow
|
<FeedRow
|
||||||
href={postPath(result.unit!.code, result._id)}
|
href={postPath(result.unit!.code, result._id)}
|
||||||
title={result.title}
|
title={result.title}
|
||||||
|
content={result.content}
|
||||||
unitCode={result.unit
|
unitCode={result.unit
|
||||||
? result.unit.code + (result.unit.code2 ? ` / ${result.unit.code2}` : "")
|
? result.unit.code + (result.unit.code2 ? ` / ${result.unit.code2}` : "")
|
||||||
: undefined}
|
: undefined}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@
|
||||||
<FeedRow
|
<FeedRow
|
||||||
href={postPath(note.unit!.code, note._id)}
|
href={postPath(note.unit!.code, note._id)}
|
||||||
title={note.title}
|
title={note.title}
|
||||||
|
content={note.content}
|
||||||
unitCode={note.unit
|
unitCode={note.unit
|
||||||
? note.unit.code + (note.unit.code2 ? ` / ${note.unit.code2}` : "")
|
? note.unit.code + (note.unit.code2 ? ` / ${note.unit.code2}` : "")
|
||||||
: undefined}
|
: undefined}
|
||||||
|
|
@ -67,6 +68,7 @@
|
||||||
<FeedRow
|
<FeedRow
|
||||||
href={postPath(question.unit!.code, question._id)}
|
href={postPath(question.unit!.code, question._id)}
|
||||||
title={question.title}
|
title={question.title}
|
||||||
|
content={question.content}
|
||||||
unitCode={question.unit
|
unitCode={question.unit
|
||||||
? question.unit.code +
|
? question.unit.code +
|
||||||
(question.unit.code2 ? ` / ${question.unit.code2}` : "")
|
(question.unit.code2 ? ` / ${question.unit.code2}` : "")
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,7 @@
|
||||||
<FeedRow
|
<FeedRow
|
||||||
href={postPath(selectedUnit.code, note._id)}
|
href={postPath(selectedUnit.code, note._id)}
|
||||||
title={note.title}
|
title={note.title}
|
||||||
|
content={note.content}
|
||||||
unitCode={selectedUnit.code +
|
unitCode={selectedUnit.code +
|
||||||
(selectedUnit.code2 ? ` / ${selectedUnit.code2}` : "")}
|
(selectedUnit.code2 ? ` / ${selectedUnit.code2}` : "")}
|
||||||
meta="{note.authorName} · {timeAgo(
|
meta="{note.authorName} · {timeAgo(
|
||||||
|
|
@ -114,6 +115,7 @@
|
||||||
<FeedRow
|
<FeedRow
|
||||||
href={postPath(selectedUnit.code, question._id)}
|
href={postPath(selectedUnit.code, question._id)}
|
||||||
title={question.title}
|
title={question.title}
|
||||||
|
content={question.content}
|
||||||
unitCode={selectedUnit.code +
|
unitCode={selectedUnit.code +
|
||||||
(selectedUnit.code2 ? ` / ${selectedUnit.code2}` : "")}
|
(selectedUnit.code2 ? ` / ${selectedUnit.code2}` : "")}
|
||||||
meta="{question.authorName} · {timeAgo(
|
meta="{question.authorName} · {timeAgo(
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@
|
||||||
<FeedRow
|
<FeedRow
|
||||||
href={postPath(unit.code, note._id)}
|
href={postPath(unit.code, note._id)}
|
||||||
title={note.title}
|
title={note.title}
|
||||||
|
content={note.content}
|
||||||
unitCode={unit.code + (unit.code2 ? ` / ${unit.code2}` : "")}
|
unitCode={unit.code + (unit.code2 ? ` / ${unit.code2}` : "")}
|
||||||
meta="{note.authorName} · {timeAgo(
|
meta="{note.authorName} · {timeAgo(
|
||||||
note.createdAt,
|
note.createdAt,
|
||||||
|
|
@ -68,6 +69,7 @@
|
||||||
<FeedRow
|
<FeedRow
|
||||||
href={postPath(unit.code, question._id)}
|
href={postPath(unit.code, question._id)}
|
||||||
title={question.title}
|
title={question.title}
|
||||||
|
content={question.content}
|
||||||
unitCode={unit.code + (unit.code2 ? ` / ${unit.code2}` : "")}
|
unitCode={unit.code + (unit.code2 ? ` / ${unit.code2}` : "")}
|
||||||
meta="{question.authorName} · {timeAgo(
|
meta="{question.authorName} · {timeAgo(
|
||||||
question.createdAt,
|
question.createdAt,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue