import React from 'react' import PropTypes from 'prop-types' import ImmutablePropTypes from 'react-immutable-proptypes' import ImmutablePureComponent from 'react-immutable-pure-component' import { NavLink } from 'react-router-dom' import { decode } from 'blurhash' import { autoPlayGif, displayMedia } from '../initial_state' import { CX } from '../constants' import Icon from './icon' import Image from './image' import Text from './text' class MediaItem extends ImmutablePureComponent { state = { loaded: false, visible: true, } componentDidMount() { const { attachment } = this.props if (!attachment) return if (attachment.get('blurhash')) { this._decode() } this.setState({ visible: displayMedia !== 'hide_all' && !this.props.attachment.getIn(['status', 'sensitive']) || displayMedia === 'show_all', }) } componentDidUpdate(prevProps) { const { attachment } = this.props const { prevAttachment } = prevProps if (prevAttachment !== attachment) { this._decode() return } if (prevAttachment.get('blurhash') !== attachment.get('blurhash') && attachment.get('blurhash')) { this._decode() } } _decode = () => { const { attachment } = this.props if (!attachment) return const hash = attachment.get('blurhash') if (!hash) return const pixels = decode(hash, 160, 160) if (pixels && this.canvas) { const ctx = this.canvas.getContext('2d') const imageData = new ImageData(pixels, 160, 160) ctx.putImageData(imageData, 0, 0) } } setCanvasRef = (c) => { this.canvas = c } handleImageLoad = () => { this.setState({ loaded: true }) } hoverToPlay() { const { attachment } = this.props if (!attachment) return return !autoPlayGif && ['gifv', 'video'].indexOf(attachment.get('type')) !== -1 } render() { const { account, attachment, isSmall, } = this.props const { visible, loaded } = this.state if (!attachment || !account) return null const status = attachment.get('status') const title = status.get('spoiler_text') || attachment.get('description') const attachmentType = attachment.get('type') const aspectRatio = attachment.getIn(['meta', 'aspect']) const isVideo = attachmentType === 'video' let badge = null if (isVideo) { const duration = attachment.getIn(['meta', 'duration']) badge = (duration / 60).toFixed(2) } else if (attachmentType === 'gifv') { badge = 'GIF' } const statusUrl = `/${account.getIn(['acct'])}/posts/${status.get('id')}` const isSmallRatio = aspectRatio < 1 const isSquare = aspectRatio === 1 || isSmall const containerClasses = CX({ d: 1, px5: 1, flex1: !isSmallRatio && !isSquare, minW198PX: !isVideo && !isSmallRatio && !isSquare, minW232PX: isVideo && !isSmallRatio && !isSquare, minW120PX: isSmallRatio, minW162PX: isSquare, }) const paddedContainerClasses = CX({ d: 1, h100PC: isSmallRatio || isSquare, pt100PC: isSmallRatio || isSquare || !isVideo, pt5625PC: isVideo && !isSmallRatio && !isSquare, }) return (