diff --git a/webapp/components/post_view/components/post_attachment_opengraph.jsx b/webapp/components/post_view/components/post_attachment_opengraph.jsx index b83150839a..12437e672e 100644 --- a/webapp/components/post_view/components/post_attachment_opengraph.jsx +++ b/webapp/components/post_view/components/post_attachment_opengraph.jsx @@ -11,29 +11,47 @@ 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: 150, - width: 150 + height: 80, + width: 80 }; - this.maxDescriptionLength = 300; - this.descriptionEllipsis = '...'; + 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); + this.setImageWidth = this.setImageWidth.bind(this); + } + + IMAGE_LOADED = { + LOADING: 'loading', + YES: 'yes', + ERROR: 'error' } componentWillMount() { this.setState({ data: {}, - imageLoaded: false, - imageVisible: this.props.previewCollapsed.startsWith('false') + imageLoaded: this.IMAGE_LOADED.LOADING, + imageVisible: this.props.previewCollapsed.startsWith('false'), + hasLargeImage: false }); this.fetchData(this.props.link); } componentWillReceiveProps(nextProps) { - this.setState({imageVisible: nextProps.previewCollapsed.startsWith('false')}); if (!Utils.areObjectsEqual(nextProps.link, this.props.link)) { this.fetchData(nextProps.link); } @@ -43,6 +61,9 @@ export default class PostAttachmentOpenGraph extends React.Component { if (nextState.imageVisible !== this.state.imageVisible) { return true; } + if (nextState.hasLargeImage !== this.state.hasLargeImage) { + return true; + } if (nextState.imageLoaded !== this.state.imageLoaded) { return true; } @@ -54,16 +75,20 @@ export default class PostAttachmentOpenGraph extends React.Component { componentDidMount() { OpenGraphStore.addUrlDataChangeListener(this.onOpenGraphMetadataChange); + this.setImageWidth(); + window.addEventListener('resize', this.setImageWidth); } componentDidUpdate() { if (this.props.childComponentDidUpdateFunction) { this.props.childComponentDidUpdateFunction(); } + this.setImageWidth(); } componentWillUnmount() { OpenGraphStore.removeUrlDataChangeListener(this.onOpenGraphMetadataChange); + window.removeEventListener('resize', this.setImageWidth); } onOpenGraphMetadataChange(url) { @@ -74,53 +99,54 @@ export default class PostAttachmentOpenGraph extends React.Component { fetchData(url) { const data = OpenGraphStore.getOgInfo(url); - this.setState({data, imageLoaded: false}); + this.setState({data, imageLoaded: this.IMAGE_LOADED.LOADING}); if (Utils.isEmptyObject(data)) { requestOpenGraphMetadata(url); } } getBestImageUrl() { - if (this.state.data.images == null) { + if (Utils.isEmptyObject(this.state.data.images)) { return null; } - const nearestPointData = CommonUtils.getNearestPoint(this.imageDimentions, this.state.data.images, 'width', 'height'); - - const bestImage = nearestPointData.nearestPoint; - const bestImageLte = nearestPointData.nearestPointLte; // Best image <= 150px height and width - - let finalBestImage; - - if ( - !Utils.isEmptyObject(bestImageLte) && - bestImageLte.height <= this.imageDimentions.height && - bestImageLte.width <= this.imageDimentions.width - ) { - finalBestImage = bestImageLte; - } else { - finalBestImage = bestImage; - } - - return finalBestImage.secure_url || finalBestImage.url; + 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() { - this.setState({imageLoaded: true}); + 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) { + if (imageUrl && this.state.hasLargeImage) { return ( + wrapInSmallImageContainer(imageElement) { + return ( +