feat: blur data and fixed size for post images, close #440

This commit is contained in:
DIYgod 2023-06-07 22:00:15 +01:00
parent ed4da52f2e
commit 40810d76c1
No known key found for this signature in database
7 changed files with 77 additions and 8 deletions

View File

@ -88,7 +88,7 @@ module.exports = withBundleAnalyzer(
// https://github.com/kkomelin/isomorphic-dompurify/issues/54
// Fix isomorphic-dompurify in app router
config.externals = [...config.externals, "canvas", "jsdom"]
config.externals = [...config.externals, "canvas", "jsdom", "sharp"]
return config
},

View File

@ -101,6 +101,7 @@
"pangu": "4.0.7",
"path-to-regexp": "6.2.1",
"pinyin-pro": "3.14.0",
"plaiceholder": "3.0.0",
"prismjs": "1.29.0",
"qier-progress": "1.0.4",
"rc-dplayer": "0.1.0",

View File

@ -224,6 +224,9 @@ dependencies:
pinyin-pro:
specifier: 3.14.0
version: 3.14.0
plaiceholder:
specifier: 3.0.0
version: 3.0.0(sharp@0.32.1)
prismjs:
specifier: 1.29.0
version: 1.29.0
@ -11070,6 +11073,14 @@ packages:
find-up: 4.1.0
dev: true
/plaiceholder@3.0.0(sharp@0.32.1):
resolution: {integrity: sha512-jwHxxHPnr1BwRzPCeZgEK2BMsEy2327sWynw3qb6XC/oGgGDUTPtR8pFxFQmNArhMBwhkUbUr5OPhhIJpCa8eQ==}
peerDependencies:
sharp: '>= 0.30.6'
dependencies:
sharp: 0.32.1
dev: false
/pngjs@5.0.0:
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
engines: {node: '>=10.13.0'}

View File

@ -0,0 +1,37 @@
import { getPlaiceholder } from "plaiceholder"
import { cacheGet } from "~/lib/redis.server"
import { NextServerResponse, getQuery } from "~/lib/server-helper"
const getImage = async (src: string) => {
return cacheGet({
key: ["getImage", src],
noUpdate: true,
getValueFun: async () => {
const buffer = await fetch(src).then(async (res) =>
Buffer.from(await res.arrayBuffer()),
)
const {
metadata: { height, width },
...plaiceholder
} = await getPlaiceholder(buffer, { size: 10 })
return {
base64: plaiceholder.base64,
size: { height, width },
}
},
})
}
export async function GET(req: Request) {
let { url } = getQuery(req)
if (!url) {
return new NextServerResponse()
.status(400)
.json({ error: "url is required" })
}
const res = new NextServerResponse()
return res.status(200).json(await getImage(url))
}

View File

@ -6,6 +6,7 @@ import React, { useEffect } from "react"
import { useGetState } from "~/hooks/useGetState"
import { useIsMobileLayout } from "~/hooks/useMobileLayout"
import { toGateway, toIPFS } from "~/lib/ipfs-parser"
import { useGetImageInfo } from "~/queries/page"
type TImageProps = {
className?: string
@ -152,10 +153,20 @@ export const Image: React.FC<TImageProps> = ({
}
export const ZoomedImage: React.FC<TImageProps> = (props) => {
const info = useGetImageInfo(props.src)
const autoProps = info?.data
? {
width: info.data.size?.width,
height: info.data.size?.height,
blurDataURL: info.data.base64,
placeholder: "blur" as const,
}
: {}
return (
<span className="text-center block">
{/* eslint-disable-next-line jsx-a11y/alt-text */}
<Image {...props} zoom />
<Image {...props} {...autoProps} zoom />
</span>
)
}

View File

@ -219,12 +219,6 @@ export const renderPageContent = (
}
},
})
// .use(rehypeRewrite, {
// selector: "h1",
// rewrite: (node: any) => {
// node.tagName = "h2"
// },
// })
.use(rehypePrism, {
ignoreMissing: true,
showLineNumbers: true,

View File

@ -419,3 +419,18 @@ export function useCheckMirror(characterId?: number) {
return pageModel.checkMirror(characterId)
})
}
export function useGetImageInfo(src?: string) {
return useQuery(["getImageInfo", src], async () => {
if (!src) {
return
}
return (await (await fetch(`/api/image?url=${src}`)).json()) as {
size: {
width: number
height: number
}
base64: string
}
})
}