From ab67f6e257f6e8f08145a02a7b93550f99641be4 Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Sun, 18 Jun 2017 14:42:32 -0400 Subject: PLT-6215 Major post list refactor (#6501) * Major post list refactor * Fix post and thread deletion * Fix preferences not selecting correctly * Fix military time displaying * Fix UP key for editing posts * Fix ESLint error * Various fixes and updates per feedback * Fix for permalink view * Revert to old scrolling method and various fixes * Add floating timestamp, new message indicator, scroll arrows * Update post loading for focus mode and add visibility limit * Fix pinning posts and a react warning * Add loading UI updates from Asaad * Fix refreshing loop * Temporarily bump post visibility limit * Update infinite scrolling * Remove infinite scrolling --- .../post_view/post_body_additional_content.jsx | 229 +++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 webapp/components/post_view/post_body_additional_content.jsx (limited to 'webapp/components/post_view/post_body_additional_content.jsx') diff --git a/webapp/components/post_view/post_body_additional_content.jsx b/webapp/components/post_view/post_body_additional_content.jsx new file mode 100644 index 000000000..bf8380912 --- /dev/null +++ b/webapp/components/post_view/post_body_additional_content.jsx @@ -0,0 +1,229 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import PostAttachmentList from './post_attachment_list.jsx'; +import PostAttachmentOpenGraph from './post_attachment_opengraph'; +import PostImage from './post_image.jsx'; +import YoutubeVideo from 'components/youtube_video'; + +import Constants from 'utils/constants.jsx'; +import * as Utils from 'utils/utils.jsx'; + +import React from 'react'; +import PropTypes from 'prop-types'; + +export default class PostBodyAdditionalContent extends React.PureComponent { + static propTypes = { + + /** + * The post to render the content of + */ + post: PropTypes.object.isRequired, + + /** + * The post's message + */ + message: PropTypes.element.isRequired, + + /** + * Set to collapse image and video previews + */ + previewCollapsed: PropTypes.string + } + + static defaultProps = { + previewCollapsed: '' + } + + constructor(props) { + super(props); + + this.getSlackAttachment = this.getSlackAttachment.bind(this); + this.generateToggleableEmbed = this.generateToggleableEmbed.bind(this); + this.generateStaticEmbed = this.generateStaticEmbed.bind(this); + this.toggleEmbedVisibility = this.toggleEmbedVisibility.bind(this); + this.isLinkToggleable = this.isLinkToggleable.bind(this); + this.handleLinkLoadError = this.handleLinkLoadError.bind(this); + this.handleLinkLoaded = this.handleLinkLoaded.bind(this); + + this.state = { + embedVisible: props.previewCollapsed.startsWith('false'), + link: Utils.extractFirstLink(props.post.message), + linkLoadError: false, + linkLoaded: false + }; + } + + componentWillReceiveProps(nextProps) { + this.setState({ + embedVisible: nextProps.previewCollapsed.startsWith('false'), + link: Utils.extractFirstLink(nextProps.post.message) + }); + } + + toggleEmbedVisibility() { + this.setState({embedVisible: !this.state.embedVisible}); + } + + getSlackAttachment() { + let attachments = []; + if (this.props.post.props && this.props.post.props.attachments) { + attachments = this.props.post.props.attachments; + } + + return ( + + ); + } + + isLinkImage(link) { + const regex = /.+\/(.+\.(?:jpg|gif|bmp|png|jpeg))(?:\?.*)?$/i; + const match = link.match(regex); + if (match && match[1]) { + return true; + } + + return false; + } + + isLinkToggleable() { + const link = this.state.link; + if (!link) { + return false; + } + + if (YoutubeVideo.isYoutubeLink(link)) { + return true; + } + + if (this.isLinkImage(link)) { + return true; + } + + return false; + } + + handleLinkLoadError() { + this.setState({ + linkLoadError: true + }); + } + + handleLinkLoaded() { + this.setState({ + linkLoaded: true + }); + } + + generateToggleableEmbed() { + const link = this.state.link; + if (!link) { + return null; + } + + if (YoutubeVideo.isYoutubeLink(link)) { + return ( + + ); + } + + if (this.isLinkImage(link)) { + return ( + + ); + } + + return null; + } + + generateStaticEmbed() { + if (this.props.post.props && this.props.post.props.attachments) { + return this.getSlackAttachment(); + } + + const link = Utils.extractFirstLink(this.props.post.message); + if (link && Utils.isFeatureEnabled(Constants.PRE_RELEASE_FEATURES.EMBED_PREVIEW)) { + return ( + + ); + } + + return null; + } + + render() { + if (this.isLinkToggleable() && !this.state.linkLoadError) { + // if message has only one line and starts with a link place toggle in this only line + // else - place it in new line between message and embed + const prependToggle = (/^\s*https?:\/\/.*$/).test(this.props.post.message); + + const toggle = ( + + ); + const message = ( +
+ {this.props.message} +
+ ); + + const contents = [message]; + if (this.state.linkLoaded) { + if (prependToggle) { + contents.unshift(toggle); + } else { + contents.push(toggle); + } + } + + if (this.state.embedVisible) { + contents.push( +
+ {this.generateToggleableEmbed()} +
+ ); + } + + return ( +
+ {contents} +
+ ); + } + + const staticEmbed = this.generateStaticEmbed(); + + if (staticEmbed) { + return ( +
+ {this.props.message} + {staticEmbed} +
+ ); + } + + return this.props.message; + } +} -- cgit v1.2.3-1-g7c22