fix(media-preview): solve image cls

Signed-off-by: Innei <i@innei.in>
This commit is contained in:
Innei 2024-09-27 12:33:37 +08:00
parent c8cdfd1e94
commit e0bcb718ae
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
6 changed files with 70 additions and 26 deletions

View File

@ -76,6 +76,7 @@
"path-to-regexp": "8.1.0",
"posthog-js": "1.163.0",
"re-resizable": "6.9.18",
"react-blurhash": "^0.3.0",
"react-error-boundary": "4.0.13",
"react-fast-marquee": "1.6.5",
"react-hook-form": "7.53.0",

View File

@ -56,7 +56,7 @@ const HTMLImpl = <A extends keyof JSX.IntrinsicElements = "div">(
useEffect(() => {
setRemarkOptions((options) => {
if (renderInlineStyle === options.renderInlineStyle || noMedia === options.noMedia) {
if (JSON.stringify(options) === JSON.stringify({ renderInlineStyle, noMedia })) {
return options
}

View File

@ -25,6 +25,6 @@ export const usePreviewMedia = (entryId?: string) => {
clickOutsideToDismiss: true,
})
},
[present],
[entryId, present],
)
}

View File

@ -1,6 +1,7 @@
import type { MediaModel } from "@follow/shared/hono"
import type { FC } from "react"
import { Fragment, useCallback, useEffect, useRef, useState } from "react"
import { Blurhash } from "react-blurhash"
import { Keyboard, Mousewheel } from "swiper/modules"
import type { SwiperRef } from "swiper/react"
import { Swiper, SwiperSlide } from "swiper/react"
@ -125,6 +126,9 @@ export const PreviewMediaContent: FC<{
className="h-full w-auto object-contain"
alt="cover"
src={src}
height={media[0].height}
width={media[0].width}
blurhash={media[0].blurhash}
/>
)}
</Wrapper>
@ -236,8 +240,9 @@ const FallbackableImage: FC<
src: string
containerClassName?: string
fallbackUrl?: string
blurhash?: string
}
> = ({ src, onError, fallbackUrl, containerClassName, ...props }) => {
> = ({ src, onError, fallbackUrl, containerClassName, blurhash, ...props }) => {
const [currentSrc, setCurrentSrc] = useState(() => replaceImgUrlIfNeed(src))
const [isAllError, setIsAllError] = useState(false)
@ -281,11 +286,32 @@ const FallbackableImage: FC<
<div className={cn("flex size-full flex-col", containerClassName)}>
{isLoading && !isAllError && (
<div className="center absolute inset-0 size-full">
<i className="i-mgc-loading-3-cute-re size-8 animate-spin text-white/80" />
{blurhash ? (
<Blurhash
hash={blurhash}
resolutionX={32}
resolutionY={32}
className="!size-full"
style={{ aspectRatio: `${props.width} / ${props.height}` }}
/>
) : (
<i className="i-mgc-loading-3-cute-re size-8 animate-spin text-white/80" />
)}
</div>
)}
{!isAllError && (
<img src={currentSrc} onLoad={() => setIsLoading(false)} onError={handleError} {...props} />
<img
src={currentSrc}
onLoad={() => setIsLoading(false)}
onError={handleError}
height={props.height}
width={props.width}
{...props}
className={cn(
blurhash && !isLoading ? "duration-500 ease-in-out animate-in fade-in-0" : "",
props.className,
)}
/>
)}
{isAllError && (
<div

View File

@ -1,4 +1,5 @@
import type { Element, Text } from "hast"
import type { Schema } from "hast-util-sanitize"
import type { Components } from "hast-util-to-jsx-runtime"
import { toJsxRuntime } from "hast-util-to-jsx-runtime"
import { toText } from "hast-util-to-text"
@ -32,29 +33,26 @@ export const parseHtml = (
const file = new VFile(content)
const { renderInlineStyle = false, noMedia = false } = options || {}
const rehypeSchema: Schema = { ...defaultSchema }
if (noMedia) {
rehypeSchema.tagNames = rehypeSchema.tagNames?.filter(
(tag) => tag !== "img" && tag !== "picture",
)
} else {
rehypeSchema.tagNames = [...rehypeSchema.tagNames!, "video", "style"]
rehypeSchema.attributes = {
...rehypeSchema.attributes,
"*": renderInlineStyle
? [...rehypeSchema.attributes!["*"], "style", "class"]
: rehypeSchema.attributes!["*"],
video: ["src", "poster"],
}
}
const pipeline = unified()
.use(rehypeParse, { fragment: true })
.use(
rehypeSanitize,
noMedia
? {
...defaultSchema,
tagNames: defaultSchema.tagNames?.filter((tag) => tag !== "img" && tag !== "picture"),
}
: {
...defaultSchema,
tagNames: [...defaultSchema.tagNames!, "video", "style"],
attributes: {
...defaultSchema.attributes,
"*": renderInlineStyle
? [...defaultSchema.attributes!["*"], "style", "class"]
: defaultSchema.attributes!["*"],
video: ["src", "poster"],
},
},
)
.use(rehypeSanitize, rehypeSchema)
.use(rehypeInferDescriptionMeta)
.use(rehypeStringify)

View File

@ -522,6 +522,9 @@ importers:
re-resizable:
specifier: 6.9.18
version: 6.9.18(patch_hash=yitcmpfwcomg2fky72uc3lhk2i)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-blurhash:
specifier: ^0.3.0
version: 0.3.0(blurhash@2.0.5)(react@18.3.1)
react-error-boundary:
specifier: 4.0.13
version: 4.0.13(react@18.3.1)
@ -3958,6 +3961,9 @@ packages:
bluebird@3.7.2:
resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
blurhash@2.0.5:
resolution: {integrity: sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w==}
bn.js@4.12.0:
resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==}
@ -7370,6 +7376,12 @@ packages:
react: ^16.13.1 || ^17.0.0 || ^18.0.0
react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0
react-blurhash@0.3.0:
resolution: {integrity: sha512-XlKr4Ns1iYFRnk6DkAblNbAwN/bTJvxTVoxMvmTcURdc5oLoXZwqAF9N3LZUh/HT+QFlq5n6IS6VsDGsviYAiQ==}
peerDependencies:
blurhash: ^2.0.3
react: '>=15'
react-dom@18.3.1:
resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
peerDependencies:
@ -12851,6 +12863,8 @@ snapshots:
bluebird@3.7.2: {}
blurhash@2.0.5: {}
bn.js@4.12.0: {}
bn.js@5.2.1: {}
@ -16971,6 +16985,11 @@ snapshots:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
react-blurhash@0.3.0(blurhash@2.0.5)(react@18.3.1):
dependencies:
blurhash: 2.0.5
react: 18.3.1
react-dom@18.3.1(react@18.3.1):
dependencies:
loose-envify: 1.4.0