import clsx from 'clsx'; import React, { useRef } from 'react'; import { useSettings } from 'soapbox/hooks'; interface IStillImage { /** Image alt text. */ alt?: string /** Extra class names for the outer
container. */ className?: string /** URL to the image */ src: string /** Extra CSS styles on the outer
element. */ style?: React.CSSProperties /** Whether to display the image contained vs filled in its container. */ letterboxed?: boolean /** Whether to show the file extension in the corner. */ showExt?: boolean } /** Renders images on a canvas, only playing GIFs if autoPlayGif is enabled. */ const StillImage: React.FC = ({ alt, className, src, style, letterboxed = false, showExt = false }) => { const settings = useSettings(); const autoPlayGif = settings.get('autoPlayGif'); const canvas = useRef(null); const img = useRef(null); const hoverToPlay = ( src && !autoPlayGif && (src.endsWith('.gif') || src.startsWith('blob:')) ); const handleImageLoad = () => { if (hoverToPlay && canvas.current && img.current) { canvas.current.width = img.current.naturalWidth; canvas.current.height = img.current.naturalHeight; canvas.current.getContext('2d')?.drawImage(img.current, 0, 0); } }; /** ClassNames shared between the `` and `` elements. */ const baseClassName = clsx('block h-full w-full', { 'object-contain': letterboxed, 'object-cover': !letterboxed, }); return (
{alt} {hoverToPlay && ( )} {(hoverToPlay && showExt) && (
)}
); }; interface IExtensionBadge { /** File extension. */ ext: string } /** Badge displaying a file extension. */ const ExtensionBadge: React.FC = ({ ext }) => { return (
{ext}
); }; export default StillImage;