Files
OpenFlare/frontend/components/common/file-image-preview.tsx
T
ryan 1f391e9ec2 fix(storage): apply driver switch on save and repoint upload records
Saving storage settings now activates the selected driver immediately
instead of staging it until migration. When the driver changes, existing
upload rows are repointed to the new storage_driver so /f/{id} reads use
the correct backend. ForDriver can also open non-active drivers from the
saved multi-backend config.
2026-06-18 13:40:29 +08:00

62 lines
1.4 KiB
TypeScript

"use client"
import * as React from "react"
import {ImageOff} from "lucide-react"
import {cn} from "@/lib/utils"
import {getFileUrl, type ImageQuality} from "@/lib/services/upload/utils"
type FileImagePreviewProps = {
fileId: string | number
alt: string
quality?: ImageQuality
className?: string
fallbackClassName?: string
variant?: "compact" | "default"
}
export function FileImagePreview({
fileId,
alt,
quality = "low",
className,
fallbackClassName,
variant = "default",
}: FileImagePreviewProps) {
const [failed, setFailed] = React.useState(false)
const src = getFileUrl(fileId, quality)
React.useEffect(() => {
setFailed(false)
}, [fileId, quality])
if (!src || failed) {
return (
<div
role="img"
aria-label={`${alt} 加载失败`}
className={cn(
"flex size-full flex-col items-center justify-center gap-1 bg-muted/50 text-muted-foreground",
fallbackClassName,
)}
>
<ImageOff className={cn("shrink-0 opacity-70", variant === "compact" ? "size-3.5" : "size-5")} />
{variant === "default" && (
<span className="text-[10px] leading-none">加载失败</span>
)}
</div>
)
}
return (
// eslint-disable-next-line @next/next/no-img-element
<img
src={src}
alt={alt}
loading="lazy"
decoding="async"
className={className}
onError={() => setFailed(true)}
/>
)
}