summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--webapp/components/post_view/components/post_body_additional_content.jsx30
-rw-r--r--webapp/components/post_view/components/post_image.jsx34
-rw-r--r--webapp/components/post_view/components/post_list.jsx5
-rw-r--r--webapp/components/youtube_video.jsx26
-rw-r--r--webapp/stores/scroll_store.jsx24
-rw-r--r--webapp/utils/markdown.jsx3
6 files changed, 90 insertions, 32 deletions
diff --git a/webapp/components/post_view/components/post_body_additional_content.jsx b/webapp/components/post_view/components/post_body_additional_content.jsx
index 130031233..180681100 100644
--- a/webapp/components/post_view/components/post_body_additional_content.jsx
+++ b/webapp/components/post_view/components/post_body_additional_content.jsx
@@ -23,19 +23,20 @@ export default class PostBodyAdditionalContent extends React.Component {
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
+ linkLoadError: false,
+ linkLoaded: false
};
}
componentWillReceiveProps(nextProps) {
this.setState({
embedVisible: nextProps.previewCollapsed.startsWith('false'),
- link: Utils.extractFirstLink(nextProps.post.message),
- linkLoadError: false
+ link: Utils.extractFirstLink(nextProps.post.message)
});
}
@@ -52,6 +53,9 @@ export default class PostBodyAdditionalContent extends React.Component {
if (nextState.linkLoadError !== this.state.linkLoadError) {
return true;
}
+ if (nextState.linkLoaded !== this.state.linkLoaded) {
+ return true;
+ }
return false;
}
@@ -105,6 +109,12 @@ export default class PostBodyAdditionalContent extends React.Component {
});
}
+ handleLinkLoaded() {
+ this.setState({
+ linkLoaded: true
+ });
+ }
+
generateToggleableEmbed() {
const link = this.state.link;
if (!link) {
@@ -127,6 +137,8 @@ export default class PostBodyAdditionalContent extends React.Component {
channelId={this.props.post.channel_id}
link={link}
onLinkLoadError={this.handleLinkLoadError}
+ onLinkLoaded={this.handleLinkLoaded}
+ childComponentDidUpdateFunction={this.props.childComponentDidUpdateFunction}
/>
);
}
@@ -174,11 +186,13 @@ export default class PostBodyAdditionalContent extends React.Component {
</div>
);
- let contents;
- if (prependToggle) {
- contents = [toggle, message];
- } else {
- contents = [message, toggle];
+ const contents = [message];
+ if (this.state.linkLoaded) {
+ if (prependToggle) {
+ contents.unshift(toggle);
+ } else {
+ contents.push(toggle);
+ }
}
if (this.state.embedVisible) {
diff --git a/webapp/components/post_view/components/post_image.jsx b/webapp/components/post_view/components/post_image.jsx
index 2bdc5efc0..1268c9df2 100644
--- a/webapp/components/post_view/components/post_image.jsx
+++ b/webapp/components/post_view/components/post_image.jsx
@@ -32,6 +32,9 @@ export default class PostImageEmbed extends React.Component {
}
componentDidUpdate(prevProps) {
+ if (this.state.loaded && this.props.childComponentDidUpdateFunction) {
+ this.props.childComponentDidUpdateFunction();
+ }
if (!this.state.loaded && prevProps.link !== this.props.link) {
this.loadImg(this.props.link);
}
@@ -46,8 +49,12 @@ export default class PostImageEmbed extends React.Component {
handleLoadComplete() {
this.setState({
- loaded: true
+ loaded: true,
+ errored: false
});
+ if (this.props.onLinkLoaded) {
+ this.props.onLinkLoaded();
+ }
}
handleLoadError() {
@@ -61,29 +68,26 @@ export default class PostImageEmbed extends React.Component {
}
render() {
- if (this.state.errored) {
+ if (this.state.errored || !this.state.loaded) {
return null;
}
- if (!this.state.loaded) {
- return (
+ return (
+ <div
+ className='post__embed-container'
+ >
<img
- className='img-div placeholder'
- height='500px'
+ className='img-div'
+ src={this.props.link}
/>
- );
- }
-
- return (
- <img
- className='img-div'
- src={this.props.link}
- />
+ </div>
);
}
}
PostImageEmbed.propTypes = {
link: PropTypes.string.isRequired,
- onLinkLoadError: PropTypes.func
+ onLinkLoadError: PropTypes.func,
+ onLinkLoaded: PropTypes.func,
+ childComponentDidUpdateFunction: PropTypes.func
};
diff --git a/webapp/components/post_view/components/post_list.jsx b/webapp/components/post_view/components/post_list.jsx
index 403e26f84..ec3c8dc6a 100644
--- a/webapp/components/post_view/components/post_list.jsx
+++ b/webapp/components/post_view/components/post_list.jsx
@@ -23,7 +23,7 @@ const ScrollTypes = Constants.ScrollTypes;
import PostStore from 'stores/post_store.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
-
+import ScrollStore from 'stores/scroll_store.jsx';
import {FormattedDate, FormattedMessage} from 'react-intl';
import PropTypes from 'prop-types';
@@ -49,6 +49,7 @@ export default class PostList extends React.Component {
this.scrollToBottomAnimated = this.scrollToBottomAnimated.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.childComponentDidUpdate = this.childComponentDidUpdate.bind(this);
+ this.checkAndUpdateScrolling = this.checkAndUpdateScrolling.bind(this);
this.jumpToPostNode = null;
this.wasAtBottom = true;
@@ -536,6 +537,7 @@ export default class PostList extends React.Component {
window.addEventListener('keydown', this.handleKeyDown);
PostStore.addPostDraftChangeListener(this.props.channelId, this.handlePostDraftChange);
+ ScrollStore.addPostScrollListener(this.checkAndUpdateScrolling);
}
handlePostDraftChange = (draft) => {
@@ -550,6 +552,7 @@ export default class PostList extends React.Component {
window.cancelAnimationFrame(this.animationFrameId);
window.removeEventListener('resize', this.handleResize);
window.removeEventListener('keydown', this.handleKeyDown);
+ ScrollStore.removePostScrollListener(this.checkAndUpdateScrolling);
this.scrollStopAction.cancel();
PostStore.removePostDraftChangeListener(this.props.channelId, this.handlePostDraftChange);
diff --git a/webapp/components/youtube_video.jsx b/webapp/components/youtube_video.jsx
index 0127fcb88..49f490bda 100644
--- a/webapp/components/youtube_video.jsx
+++ b/webapp/components/youtube_video.jsx
@@ -156,7 +156,13 @@ export default class YoutubeVideo extends React.Component {
render() {
if (!this.state.loaded) {
- return <div className='video-loading'/>;
+ return (
+ <div
+ className='post__embed-container'
+ >
+ <div className='video-loading'/>
+ </div>
+ );
}
let header;
@@ -217,13 +223,17 @@ export default class YoutubeVideo extends React.Component {
}
return (
- <div>
- {header}
- <div
- className='video-div embed-responsive-item'
- onClick={this.play}
- >
- {content}
+ <div
+ className='post__embed-container'
+ >
+ <div>
+ {header}
+ <div
+ className='video-div embed-responsive-item'
+ onClick={this.play}
+ >
+ {content}
+ </div>
</div>
</div>
);
diff --git a/webapp/stores/scroll_store.jsx b/webapp/stores/scroll_store.jsx
new file mode 100644
index 000000000..03a5f4e08
--- /dev/null
+++ b/webapp/stores/scroll_store.jsx
@@ -0,0 +1,24 @@
+// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import EventEmitter from 'events';
+
+const UPDATE_POST_SCROLL_EVENT = 'update_post_scroll';
+
+class ScrollStoreClass extends EventEmitter {
+ emitPostScroll() {
+ this.emit(UPDATE_POST_SCROLL_EVENT);
+ }
+
+ addPostScrollListener(callback) {
+ this.on(UPDATE_POST_SCROLL_EVENT, callback);
+ }
+
+ removePostScrollLisener(callback) {
+ this.removeListener(UPDATE_POST_SCROLL_EVENT, callback);
+ }
+}
+
+var ScrollStore = new ScrollStoreClass();
+export default ScrollStore;
+
diff --git a/webapp/utils/markdown.jsx b/webapp/utils/markdown.jsx
index 0d9e977d7..f47c45d10 100644
--- a/webapp/utils/markdown.jsx
+++ b/webapp/utils/markdown.jsx
@@ -7,6 +7,8 @@ import * as SyntaxHighlighting from './syntax_highlighting.jsx';
import marked from 'marked';
import katex from 'katex';
+import ScrollStore from 'stores/scroll_store.jsx';
+
function markdownImageLoaded(image) {
if (image.hasAttribute('height') && image.attributes.height.value !== 'auto') {
const maxHeight = parseInt(global.getComputedStyle(image).maxHeight, 10);
@@ -20,6 +22,7 @@ function markdownImageLoaded(image) {
} else {
image.style.height = 'auto';
}
+ ScrollStore.emitPostScroll();
}
global.markdownImageLoaded = markdownImageLoaded;