feat: blur data and fixed size for post images, close #440
This commit is contained in:
parent
ed4da52f2e
commit
40810d76c1
|
|
@ -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
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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'}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,12 +219,6 @@ export const renderPageContent = (
|
|||
}
|
||||
},
|
||||
})
|
||||
// .use(rehypeRewrite, {
|
||||
// selector: "h1",
|
||||
// rewrite: (node: any) => {
|
||||
// node.tagName = "h2"
|
||||
// },
|
||||
// })
|
||||
.use(rehypePrism, {
|
||||
ignoreMissing: true,
|
||||
showLineNumbers: true,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue