import classNames from 'clsx'; import React, { useState } from 'react'; import Blurhash from 'soapbox/components/blurhash'; import Icon from 'soapbox/components/icon'; import StillImage from 'soapbox/components/still-image'; import { useSettings } from 'soapbox/hooks'; import { isIOS } from 'soapbox/is-mobile'; import type { Attachment } from 'soapbox/types/entities'; interface IMediaItem { attachment: Attachment, displayWidth: number, onOpenMedia: (attachment: Attachment) => void, } const MediaItem: React.FC = ({ attachment, displayWidth, onOpenMedia }) => { const settings = useSettings(); const autoPlayGif = settings.get('autoPlayGif'); const displayMedia = settings.get('displayMedia'); const [visible, setVisible] = useState(displayMedia !== 'hide_all' && !attachment.status?.sensitive || displayMedia === 'show_all'); const handleMouseEnter: React.MouseEventHandler = e => { const video = e.target as HTMLVideoElement; if (hoverToPlay()) { video.play(); } }; const handleMouseLeave: React.MouseEventHandler = e => { const video = e.target as HTMLVideoElement; if (hoverToPlay()) { video.pause(); video.currentTime = 0; } }; const hoverToPlay = () => { return !autoPlayGif && ['gifv', 'video'].includes(attachment.type); }; const handleClick: React.MouseEventHandler = e => { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { e.preventDefault(); if (visible) { onOpenMedia(attachment); } else { setVisible(true); } } }; const width = `${Math.floor((displayWidth - 4) / 3) - 4}px`; const height = width; const status = attachment.get('status'); const title = status.get('spoiler_text') || attachment.get('description'); let thumbnail: React.ReactNode = ''; let icon; if (attachment.type === 'unknown') { // Skip } else if (attachment.type === 'image') { const focusX = Number(attachment.getIn(['meta', 'focus', 'x'])) || 0; const focusY = Number(attachment.getIn(['meta', 'focus', 'y'])) || 0; const x = ((focusX / 2) + .5) * 100; const y = ((focusY / -2) + .5) * 100; thumbnail = ( ); } else if (['gifv', 'video'].indexOf(attachment.type) !== -1) { const conditionalAttributes: React.VideoHTMLAttributes = {}; if (isIOS()) { conditionalAttributes.playsInline = true; } if (autoPlayGif) { conditionalAttributes.autoPlay = true; } thumbnail = (
); } else if (attachment.type === 'audio') { const remoteURL = attachment.remote_url || ''; const fileExtensionLastIndex = remoteURL.lastIndexOf('.'); const fileExtension = remoteURL.substr(fileExtensionLastIndex + 1).toUpperCase(); thumbnail = (
{fileExtension}
); } if (!visible) { icon = ( ); } return ( ); }; export default MediaItem;