mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Remove fake img preview before loaded (#5854)
Remove fake img preview and collapse toggle before it is loaded, only show img and toggle after it is fully loaded. Fix markdown img size and add scroll down behaviour.
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 (
|
||||
<img
|
||||
className='img-div placeholder'
|
||||
height='500px'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<img
|
||||
className='img-div'
|
||||
src={this.props.link}
|
||||
/>
|
||||
<div
|
||||
className='post__embed-container'
|
||||
>
|
||||
<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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
24
webapp/stores/scroll_store.jsx
Normal file
24
webapp/stores/scroll_store.jsx
Normal file
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user