diff --git a/src/components/WebMCP.astro b/src/components/WebMCP.astro new file mode 100644 index 0000000..f1639c9 --- /dev/null +++ b/src/components/WebMCP.astro @@ -0,0 +1,375 @@ +--- +import { getCollection } from "astro:content"; + +type EpisodeToolData = { + id: string; + slug: string; + url: string; + title: string; + author: string; + status: string; + publicationDate: string; + categories: string[]; + xyzLink: string | null; + youtubeId: string | null; + youtubeUrl: string | null; + biliUrl: string | null; + preview: string; +}; + +const siteUrl = Astro.site?.toString().replace(/\/$/, "") ?? "https://asynctalk.com"; +const posts = await getCollection("posts"); + +function normalizeId(id: string) { + return id.replace(/^\/?posts\//, "").replace(/\.mdx$/, ""); +} + +function normalizeExternalUrl(url: string | undefined) { + if (!url) { + return null; + } + + if (url.startsWith("//")) { + return `https:${url}`; + } + + return url; +} + +function stripMarkdown(value: string) { + return value + .replace(/^---[\s\S]*?---/, "") + .replace(/```[\s\S]*?```/g, " ") + .replace(/`([^`]+)`/g, "$1") + .replace(/!\[[^\]]*]\([^)]*\)/g, " ") + .replace(/\[([^\]]+)]\([^)]*\)/g, "$1") + .replace(/[#>*_~\-]+/g, " ") + .replace(/\s+/g, " ") + .trim() + .slice(0, 500); +} + +function serializeForInlineScript(value: unknown) { + return JSON.stringify(value).replace(/((post) => { + const id = normalizeId(post.id); + const slug = `/posts/${id}`; + const youtubeId = post.data.youtubeId ?? null; + + return { + id, + slug, + url: new URL(slug, siteUrl).toString(), + title: post.data.title, + author: post.data.author, + status: post.data.status, + publicationDate: post.data.publicationDate.toISOString(), + categories: post.data.categories, + xyzLink: post.data.xyzLink || null, + youtubeId, + youtubeUrl: youtubeId ? `https://www.youtube.com/watch?v=${youtubeId}` : null, + biliUrl: normalizeExternalUrl(post.data.biliUrl), + preview: stripMarkdown(post.body ?? ""), + }; + }) + .sort((a, b) => { + return ( + new Date(b.publicationDate).valueOf() - + new Date(a.publicationDate).valueOf() + ); + }); + +const subscriptionLinks = { + rss: new URL("/rss.xml", siteUrl).toString(), + applePodcasts: "https://podcasts.apple.com/cn/podcast/asynctalk-s01/id1590369272", + xiaoyuzhou: "https://www.xiaoyuzhoufm.com/podcast/61684ce4d8fa23fb00fc4d3a", + spotify: "https://open.spotify.com/show/6AMzdZxcztIoKlZrGX79lX", +}; +--- + +