summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorhmhealey <harrisonmhealey@gmail.com>2016-02-23 16:28:16 -0500
committerhmhealey <harrisonmhealey@gmail.com>2016-02-23 17:01:24 -0500
commit9b50fb855350ea1e747ee946ab3f955430abeb75 (patch)
tree79d36f3d78d3a4ee352f224644a31754fb6b51d8 /web
parent52767d9dcdc84fca4cd7a5b5c7ece2650691b91d (diff)
downloadchat-9b50fb855350ea1e747ee946ab3f955430abeb75.tar.gz
chat-9b50fb855350ea1e747ee946ab3f955430abeb75.tar.bz2
chat-9b50fb855350ea1e747ee946ab3f955430abeb75.zip
Refactored embedded image/video code and prevented them from being displayed on deleted posts
Diffstat (limited to 'web')
-rw-r--r--web/react/components/post_body.jsx137
-rw-r--r--web/react/components/post_body_additional_content.jsx123
-rw-r--r--web/react/components/post_image.jsx62
3 files changed, 155 insertions, 167 deletions
diff --git a/web/react/components/post_body.jsx b/web/react/components/post_body.jsx
index 506b38ce6..70cf86748 100644
--- a/web/react/components/post_body.jsx
+++ b/web/react/components/post_body.jsx
@@ -6,13 +6,9 @@ import UserStore from '../stores/user_store.jsx';
import * as Utils from '../utils/utils.jsx';
import * as Emoji from '../utils/emoticons.jsx';
import Constants from '../utils/constants.jsx';
-const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES;
import * as TextFormatting from '../utils/text_formatting.jsx';
import twemoji from 'twemoji';
import PostBodyAdditionalContent from './post_body_additional_content.jsx';
-import YoutubeVideo from './youtube_video.jsx';
-
-import providers from './providers.json';
import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'mm-intl';
@@ -31,19 +27,7 @@ class PostBody extends React.Component {
constructor(props) {
super(props);
- this.isImgLoading = false;
-
this.parseEmojis = this.parseEmojis.bind(this);
- this.createEmbed = this.createEmbed.bind(this);
- this.createImageEmbed = this.createImageEmbed.bind(this);
- this.loadImg = this.loadImg.bind(this);
-
- const linkData = Utils.extractLinks(this.props.post.message);
-
- this.state = {
- links: linkData,
- post: this.props.post
- };
}
getAllChildNodes(nodeIn) {
@@ -69,120 +53,10 @@ class PostBody extends React.Component {
});
}
- componentWillMount() {
- if (this.props.post.filenames.length === 0 && this.state.links && this.state.links.length > 0) {
- this.embed = this.createEmbed(this.state.links[0]);
- }
- }
-
componentDidMount() {
this.parseEmojis();
}
- componentDidUpdate() {
- this.parseEmojis();
- }
-
- componentWillReceiveProps(nextProps) {
- const linkData = Utils.extractLinks(nextProps.post.message);
- if (this.props.post.filenames.length === 0 && this.state.links && this.state.links.length > 0) {
- this.embed = this.createEmbed(linkData[0]);
- }
- this.setState({
- links: linkData
- });
- }
-
- createEmbed(link) {
- const post = this.state.post;
-
- if (!link) {
- if (post.type === 'oEmbed') {
- post.props.oEmbedLink = '';
- post.type = '';
- }
- return null;
- }
-
- const trimmedLink = link.trim();
-
- if (Utils.isFeatureEnabled(PreReleaseFeatures.EMBED_PREVIEW)) {
- const provider = this.getOembedProvider(trimmedLink);
- if (provider != null) {
- post.props.oEmbedLink = trimmedLink;
- post.type = 'oEmbed';
- this.setState({post, provider});
- return '';
- }
- }
-
- if (YoutubeVideo.isYoutubeLink(link)) {
- return (
- <YoutubeVideo
- channelId={post.channel_id}
- link={link}
- />
- );
- }
-
- for (let i = 0; i < Constants.IMAGE_TYPES.length; i++) {
- const imageType = Constants.IMAGE_TYPES[i];
- const suffix = link.substring(link.length - (imageType.length + 1));
- if (suffix === '.' + imageType || suffix === '=' + imageType) {
- return this.createImageEmbed(link, this.state.imgLoaded);
- }
- }
-
- return null;
- }
-
- getOembedProvider(link) {
- for (let i = 0; i < providers.length; i++) {
- for (let j = 0; j < providers[i].patterns.length; j++) {
- if (link.match(providers[i].patterns[j])) {
- return providers[i];
- }
- }
- }
- return null;
- }
-
- loadImg(src) {
- if (this.isImgLoading) {
- return;
- }
-
- this.isImgLoading = true;
-
- const img = new Image();
- img.onload = (
- () => {
- this.embed = this.createImageEmbed(src, true);
- this.setState({imgLoaded: true});
- }
- );
- img.src = src;
- }
-
- createImageEmbed(link, isLoaded) {
- if (!isLoaded) {
- this.loadImg(link);
- return (
- <img
- className='img-div placeholder'
- height='500px'
- />
- );
- }
-
- return (
- <img
- className='img-div'
- src={link}
- />
- );
- }
-
render() {
const {formatMessage} = this.props.intl;
const post = this.props.post;
@@ -295,6 +169,7 @@ class PostBody extends React.Component {
}
let message;
+ let additionalContent = null;
if (this.props.post.state === Constants.POST_DELETED) {
message = (
<FormattedMessage
@@ -309,6 +184,10 @@ class PostBody extends React.Component {
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.props.post.message)}}
/>
);
+
+ additionalContent = (
+ <PostBodyAdditionalContent post={this.props.post}/>
+ );
}
return (
@@ -323,12 +202,8 @@ class PostBody extends React.Component {
{loading}
{message}
</div>
- <PostBodyAdditionalContent
- post={this.state.post}
- provider={this.state.provider}
- />
{fileAttachmentHolder}
- {this.embed}
+ {additionalContent}
</div>
</div>
);
diff --git a/web/react/components/post_body_additional_content.jsx b/web/react/components/post_body_additional_content.jsx
index 4871eea4f..c0a52dc92 100644
--- a/web/react/components/post_body_additional_content.jsx
+++ b/web/react/components/post_body_additional_content.jsx
@@ -3,72 +3,123 @@
import PostAttachmentList from './post_attachment_list.jsx';
import PostAttachmentOEmbed from './post_attachment_oembed.jsx';
+import PostImage from './post_image.jsx';
+import YoutubeVideo from './youtube_video.jsx';
+
+import Constants from '../utils/constants.jsx';
+import OEmbedProviders from './providers.json';
+import * as Utils from '../utils/utils.jsx';
export default class PostBodyAdditionalContent extends React.Component {
constructor(props) {
super(props);
this.getSlackAttachment = this.getSlackAttachment.bind(this);
- this.getOembedAttachment = this.getOembedAttachment.bind(this);
- this.getComponent = this.getComponent.bind(this);
+ this.getOEmbedProvider = this.getOEmbedProvider.bind(this);
+
+ this.state = {
+ link: Utils.extractLinks(props.post.message)[0]
+ };
}
- componentWillMount() {
- this.setState({type: this.props.post.type, shouldRender: Boolean(this.props.post.type)});
+ componentWillReceiveProps(nextProps) {
+ if (this.props.post.message !== nextProps.post.message) {
+ this.setState({
+ link: Utils.extractLinks(nextProps.post.message)[0]
+ });
+ }
+ }
+
+ shouldComponentUpdate(nextProps, nextState) {
+ if (nextState.link !== this.state.link) {
+ return true;
+ }
+
+ if (nextProps.post.type !== this.props.post.type) {
+ return true;
+ }
+
+ if (!Utils.areObjectsEqual(nextProps.post.props, this.props.post.props)) {
+ return true;
+ }
+
+ return false;
}
getSlackAttachment() {
- const attachments = this.props.post.props && this.props.post.props.attachments || [];
+ let attachments = [];
+ if (this.props.post.props && this.props.post.props.attachments) {
+ attachments = this.props.post.props.attachments;
+ }
+
return (
<PostAttachmentList
- key={'post_body_additional_content' + this.props.post.id}
attachments={attachments}
/>
);
}
- getOembedAttachment() {
- const link = this.props.post.props && this.props.post.props.oEmbedLink || '';
- return (
- <PostAttachmentOEmbed
- key={'post_body_additional_content' + this.props.post.id}
- provider={this.props.provider}
- link={link}
- />
- );
+ getOEmbedProvider(link) {
+ for (let i = 0; i < OEmbedProviders.length; i++) {
+ for (let j = 0; j < OEmbedProviders[i].patterns.length; j++) {
+ if (link.match(OEmbedProviders[i].patterns[j])) {
+ return OEmbedProviders[i];
+ }
+ }
+ }
+
+ return null;
}
- getComponent() {
- switch (this.props.post.type) {
- case 'slack_attachment':
+ render() {
+ if (this.props.post.type === 'slack_attachment') {
return this.getSlackAttachment();
- case 'oEmbed':
- return this.getOembedAttachment();
- default:
- return '';
}
- }
- render() {
- let content = [];
+ const link = this.state.link;
+ if (!link) {
+ return null;
+ }
- if (this.props.post.type) {
- const component = this.getComponent();
+ if (Utils.isFeatureEnabled(Constants.PRE_RELEASE_FEATURES.EMBED_PREVIEW)) {
+ const provider = this.getOEmbedProvider(link);
- if (component) {
- content = component;
+ if (provider) {
+ return (
+ <PostAttachmentOEmbed
+ provider={provider}
+ link={link}
+ />
+ );
}
}
- return (
- <div>
- {content}
- </div>
- );
+ if (YoutubeVideo.isYoutubeLink(link)) {
+ return (
+ <YoutubeVideo
+ channelId={this.props.post.channel_id}
+ link={link}
+ />
+ );
+ }
+
+ for (let i = 0; i < Constants.IMAGE_TYPES.length; i++) {
+ const imageType = Constants.IMAGE_TYPES[i];
+ const suffix = link.substring(link.length - (imageType.length + 1));
+ if (suffix === '.' + imageType || suffix === '=' + imageType) {
+ return (
+ <PostImage
+ channelId={this.props.post.channel_id}
+ link={link}
+ />
+ );
+ }
+ }
+
+ return null;
}
}
PostBodyAdditionalContent.propTypes = {
- post: React.PropTypes.object.isRequired,
- provider: React.PropTypes.object
+ post: React.PropTypes.object.isRequired
};
diff --git a/web/react/components/post_image.jsx b/web/react/components/post_image.jsx
new file mode 100644
index 000000000..b35f6d1de
--- /dev/null
+++ b/web/react/components/post_image.jsx
@@ -0,0 +1,62 @@
+// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+export default class PostImageEmbed extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ loaded: false
+ };
+ }
+
+ componentWillMount() {
+ this.loadImg(this.props.link);
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.link !== this.props.link) {
+ this.setState({
+ loaded: false
+ });
+ }
+ }
+
+ componentDidUpdate(prevProps) {
+ if (!this.state.loaded && prevProps.link !== this.props.link) {
+ this.loadImg(this.props.link);
+ }
+ }
+
+ loadImg(src) {
+ const img = new Image();
+ img.onload = () => {
+ this.setState({
+ loaded: true
+ });
+ };
+ img.src = src;
+ }
+
+ render() {
+ if (!this.state.loaded) {
+ return (
+ <img
+ className='img-div placeholder'
+ height='500px'
+ />
+ );
+ }
+
+ return (
+ <img
+ className='img-div'
+ src={this.props.link}
+ />
+ );
+ }
+}
+
+PostImageEmbed.propTypes = {
+ link: React.PropTypes.string.isRequired
+};