import React, { FC, forwardRef, memo, Suspense, useMemo } from 'react'; import { createAsset } from 'use-asset'; import { cn } from '../../util/bem'; import { SizeType } from '../../util/global-props'; import { loadImage } from '../../util/loadImage'; import { Image } from '../img/img.component'; import { Lottie } from '../lottie/lottie.component'; import './media.component.scss'; export type MediaComponentPropsType = { className?: string; url?: string; animationData?: { [key: string]: any }; autoplay?: boolean; loop?: boolean; play?: boolean; placeholder?: string; style?: React.CSSProperties; // only for animation speed?: number; playFrom?: number padding?: SizeType; align?: 'start' | 'center' | 'end'; ratio?: 'auto' | 'full' | 'ratio-16-9' | 'ratio-4-3' | 'ratio-1-1' | 'ratio-3-4' | 'ratio-9-16'; size?: SizeType; type?: 'animation' | 'image' | 'video'; fit?: 'auto' | 'fit-content' | 'cover' | 'contain' | 'fill'; styles?: React.CSSProperties; onClick?: React.EventHandler>; onMouseDown?: React.EventHandler>; onMouseLeave?: React.EventHandler>; onMouseEnter?: React.EventHandler>; }; const loadedImage = createAsset(async (url) => loadImage(url)); const className = cn('media'); const Media = memo(forwardRef((props, ref: React.Ref) => { const { url, autoplay, loop, play, placeholder, speed, playFrom, align, ratio, size, type, fit, styles, style, padding, onClick, onMouseDown, onMouseLeave, onMouseEnter, animationData } = props; const processedUrl = type === 'image' ? loadedImage.read(url) : url; const content = useMemo(() => { switch (props.type) { case 'animation': return ( ); case 'video': case 'image': return ( <> { processedUrl && ( ) } { !processedUrl && !!placeholder && ( ) } ); default: return null; } }, [ processedUrl, autoplay, loop, play, placeholder, speed, playFrom, type ]); return (
{ (type === 'animation' || type === 'video') && placeholder ? ( ) : null } { content }
); })); Media.displayName = 'Media'; export const MediaContent: FC = memo(forwardRef((props, ref) => ( )));