feat: posts cover

This commit is contained in:
DIYgod 2022-09-16 02:33:30 +01:00
parent b0fb6a64a8
commit 86f4496d75
No known key found for this signature in database
GPG Key ID: D159328F47A80DCA
6 changed files with 49 additions and 14 deletions

View File

@ -17,16 +17,28 @@ export const SiteHome: React.FC<{
const excerpt = post.summary?.content
return (
<Link key={post.id} href={`/${post.slug || post.id}`}>
<a className="xlog-post block hover:bg-zinc-100 transition-colors p-5 -mx-5 first:-mt-5 md:rounded-xl">
<h3 className="xlog-post-title text-2xl font-bold">
{post.title}
</h3>
<div className="xlog-post-date text-sm text-zinc-400 mt-1">
{formatDate(post.date_published)}
<a className="xlog-post hover:bg-zinc-100 transition-colors p-5 -mx-5 first:-mt-5 md:rounded-xl flex">
<div className="flex-1 flex justify-center flex-col">
<h3 className="xlog-post-title text-2xl font-bold">
{post.title}
</h3>
<div className="xlog-post-date text-sm text-zinc-400 mt-1">
{formatDate(post.date_published)}
</div>
<div className="xlog-post-excerpt mt-3 text-zinc-500">
{excerpt}
{excerpt && "..."}
</div>
</div>
<div className="xlog-post-excerpt mt-3 text-zinc-500">
{excerpt}
{excerpt && "..."}
<div className="xlog-post-cover flex items-center">
{/* eslint-disable-next-line @next/next/no-img-element */}
{post.cover && (
<img
className="object-cover w-24 h-24 rounded ml-4"
alt="cover"
src={post.cover}
></img>
)}
</div>
</a>
</Link>

View File

@ -45,7 +45,7 @@ export const SiteLayout: React.FC<SiteLayoutProps> = ({
description={
ogDescription ?? site?.description?.replace(/<[^>]*>/g, "")
}
image={getUserContentsUrl(site?.avatars?.[0])}
image={page?.cover || getUserContentsUrl(site?.avatars?.[0])}
/>
<SiteHeader site={site} />
<style>{site?.css}</style>

View File

@ -74,6 +74,7 @@ export type SiteNavigationItem = {
export type Note = UniNote & {
slug?: string
character?: Profile
cover?: string
}
export type Notes = {

View File

@ -20,12 +20,14 @@ export type MarkdownEnv = {
excerpt: string
frontMatter: Record<string, any>
__internal: Record<string, any>
cover: string
}
export type Rendered = {
contentHTML: string
excerpt: string
frontMatter: Record<string, any>
cover: string
}
refractor.alias("html", ["svelte", "vue"])
@ -33,7 +35,12 @@ refractor.alias("html", ["svelte", "vue"])
const rehypePrism = rehypePrismGenerator(refractor)
export const renderPageContent = async (content: string): Promise<Rendered> => {
const env: MarkdownEnv = { excerpt: "", __internal: {}, frontMatter: {} }
const env: MarkdownEnv = {
excerpt: "",
__internal: {},
frontMatter: {},
cover: "",
}
const result = await unified()
.use(remarkParse)
@ -55,7 +62,7 @@ export const renderPageContent = async (content: string): Promise<Rendered> => {
.use(remarkCallout)
.use(remarkRehype, { allowDangerousHtml: true })
.use(rehypeRaw)
.use(rehypeImage)
.use(rehypeImage, { env })
.use(rehypeSanitize, {
...defaultSchema,
tagNames: [...(defaultSchema.tagNames || []), "video", "iframe"],
@ -94,5 +101,10 @@ export const renderPageContent = async (content: string): Promise<Rendered> => {
const contentHTML = result.toString()
return { contentHTML, excerpt: env.excerpt, frontMatter: env.frontMatter }
return {
contentHTML,
excerpt: env.excerpt,
frontMatter: env.frontMatter,
cover: env.cover,
}
}

View File

@ -3,11 +3,15 @@ import { Plugin } from "unified"
import { visit } from "unist-util-visit"
import { getUserContentsUrl } from "~/lib/user-contents"
import { toGateway } from "~/lib/ipfs-parser"
import { MarkdownEnv } from "."
const isExternLink = (url: string) => /^https?:\/\//.test(url)
export const rehypeImage: Plugin<Array<void>, Root> = () => {
export const rehypeImage: Plugin<Array<{ env: MarkdownEnv }>, Root> = ({
env,
}) => {
return (tree) => {
let first = true
visit(tree, { tagName: "img" }, (node) => {
if (!node.properties) return
@ -21,6 +25,11 @@ export const rehypeImage: Plugin<Array<void>, Root> = () => {
node.properties.src = ipfsUrl
url = ipfsUrl
if (first) {
env.cover = url
first = false
}
if (isExternLink(url)) {
if (!url.startsWith("https:")) {
throw new Error(`External image url must start with https`)

View File

@ -131,6 +131,7 @@ const expandPage = async (page: Note, render: boolean) => {
mime_type: "text/html",
}
}
page.cover = rendered.cover
}
page.slug =
page.attributes?.find((a) => a.trait_type === "xlog_slug")?.value ||