// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import React from 'react'; import OpenGraphStore from 'stores/opengraph_store.jsx'; import * as Utils from 'utils/utils.jsx'; import * as CommonUtils from 'utils/commons.jsx'; import {requestOpenGraphMetadata} from 'actions/global_actions.jsx'; export default class PostAttachmentOpenGraph extends React.Component { constructor(props) { super(props); this.largeImageMinWidth = 150; this.imageDimentions = { // Image dimentions in pixels. height: 80, width: 80 }; this.textMaxLenght = 300; this.textEllipsis = '...'; this.largeImageMinRatio = 16 / 9; this.smallImageContainerLeftPadding = 15; this.imageRatio = null; this.smallImageContainer = null; this.smallImageElement = null; this.fetchData = this.fetchData.bind(this); this.onOpenGraphMetadataChange = this.onOpenGraphMetadataChange.bind(this); this.toggleImageVisibility = this.toggleImageVisibility.bind(this); this.onImageLoad = this.onImageLoad.bind(this); this.onImageError = this.onImageError.bind(this); this.truncateText = this.truncateText.bind(this); } IMAGE_LOADED = { LOADING: 'loading', YES: 'yes', ERROR: 'error' } componentWillMount() { this.setState({ data: {}, imageLoaded: this.IMAGE_LOADED.LOADING, imageVisible: this.props.previewCollapsed.startsWith('false'), hasLargeImage: false }); this.fetchData(this.props.link); } componentWillReceiveProps(nextProps) { if (!Utils.areObjectsEqual(nextProps.link, this.props.link)) { this.fetchData(nextProps.link); } } shouldComponentUpdate(nextProps, nextState) { if (nextState.imageVisible !== this.state.imageVisible) { return true; } if (nextState.hasLargeImage !== this.state.hasLargeImage) { return true; } if (nextState.imageLoaded !== this.state.imageLoaded) { return true; } if (!Utils.areObjectsEqual(nextState.data, this.state.data)) { return true; } return false; } componentDidMount() { OpenGraphStore.addUrlDataChangeListener(this.onOpenGraphMetadataChange); } componentDidUpdate() { if (this.props.childComponentDidUpdateFunction) { this.props.childComponentDidUpdateFunction(); } } componentWillUnmount() { OpenGraphStore.removeUrlDataChangeListener(this.onOpenGraphMetadataChange); } onOpenGraphMetadataChange(url) { if (url === this.props.link) { this.fetchData(url); } } fetchData(url) { const data = OpenGraphStore.getOgInfo(url); this.setState({data, imageLoaded: this.IMAGE_LOADED.LOADING}); if (Utils.isEmptyObject(data)) { requestOpenGraphMetadata(url); } } getBestImageUrl() { if (Utils.isEmptyObject(this.state.data.images)) { return null; } const bestImage = CommonUtils.getNearestPoint(this.imageDimentions, this.state.data.images, 'width', 'height'); return bestImage.secure_url || bestImage.url; } toggleImageVisibility() { this.setState({imageVisible: !this.state.imageVisible}); } onImageLoad(image) { this.imageRatio = image.target.naturalWidth / image.target.naturalHeight; if ( image.target.naturalWidth >= this.largeImageMinWidth && this.imageRatio >= this.largeImageMinRatio && !this.state.hasLargeImage ) { this.setState({ hasLargeImage: true }); } this.setState({ imageLoaded: this.IMAGE_LOADED.YES }); } onImageError() { this.setState({imageLoaded: this.IMAGE_LOADED.ERROR}); } loadImage(src) { const img = new Image(); img.onload = this.onImageLoad; img.onerror = this.onImageError; img.src = src; } imageToggleAnchoreTag(imageUrl) { if (imageUrl && this.state.hasLargeImage) { return ( ); } return null; } wrapInSmallImageContainer(imageElement) { return (