[MM-23241] Use expanded link from state (#4029)

* Get expanded link from state

* No need to await getRedirectLocation
This commit is contained in:
Miguel Alatzar 2020-03-13 11:03:37 -07:00 committed by GitHub
parent 50fc7d6896
commit d1add3c743
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 104 additions and 50 deletions

View file

@ -7,7 +7,7 @@ import {bindActionCreators} from 'redux';
import {getRedirectLocation} from 'mattermost-redux/actions/general';
import {Preferences} from 'mattermost-redux/constants';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {getOpenGraphMetadataForUrl} from 'mattermost-redux/selectors/entities/posts';
import {getOpenGraphMetadataForUrl, getExpandedLink} from 'mattermost-redux/selectors/entities/posts';
import {getBool, getTheme} from 'mattermost-redux/selectors/entities/preferences';
import {ViewTypes} from 'app/constants';
@ -46,6 +46,10 @@ function makeMapStateToProps() {
return function mapStateToProps(state, ownProps) {
const config = getConfig(state);
const link = getFirstLink(ownProps.message);
let expandedLink;
if (link) {
expandedLink = getExpandedLink(state, link);
}
// Link previews used to be an advanced settings until server version 4.4 when it was changed to be a display setting.
// We are checking both here until we bump the server requirement for the mobile apps.
@ -64,6 +68,7 @@ function makeMapStateToProps() {
...getDimensions(state),
googleDeveloperKey: config.GoogleDeveloperKey,
link,
expandedLink,
openGraphData,
showLinkPreviews: previewsEnabled && config.EnableLinkPreviews === 'true' && !removeLinkPreview,
theme: getTheme(state),

View file

@ -38,23 +38,24 @@ export default class PostBodyAdditionalContent extends PureComponent {
actions: PropTypes.shape({
getRedirectLocation: PropTypes.func.isRequired,
}).isRequired,
baseTextStyle: CustomPropTypes.Style,
blockStyles: PropTypes.object,
googleDeveloperKey: PropTypes.string,
link: PropTypes.string.isRequired,
message: PropTypes.string.isRequired,
deviceHeight: PropTypes.number.isRequired,
deviceWidth: PropTypes.number.isRequired,
metadata: PropTypes.object,
isReplyPost: PropTypes.bool,
link: PropTypes.string,
message: PropTypes.string.isRequired,
onHashtagPress: PropTypes.func,
onPermalinkPress: PropTypes.func,
openGraphData: PropTypes.object,
postId: PropTypes.string.isRequired,
postProps: PropTypes.object.isRequired,
showLinkPreviews: PropTypes.bool.isRequired,
textStyles: PropTypes.object,
theme: PropTypes.object.isRequired,
baseTextStyle: CustomPropTypes.Style,
blockStyles: PropTypes.object,
googleDeveloperKey: PropTypes.string,
metadata: PropTypes.object,
isReplyPost: PropTypes.bool,
onHashtagPress: PropTypes.func,
onPermalinkPress: PropTypes.func,
openGraphData: PropTypes.object,
textStyles: PropTypes.object,
expandedLink: PropTypes.string,
};
static contextTypes = {
@ -79,7 +80,6 @@ export default class PostBodyAdditionalContent extends PureComponent {
this.state = {
linkLoadError: false,
linkLoaded: false,
shortenedLink: null,
...dimensions,
};
@ -89,12 +89,12 @@ export default class PostBodyAdditionalContent extends PureComponent {
componentDidMount() {
this.mounted = true;
this.load(this.props);
this.load();
}
componentDidUpdate(prevProps) {
if (prevProps.link !== this.props.link) {
this.load(this.props);
this.load(true);
}
}
@ -116,33 +116,30 @@ export default class PostBodyAdditionalContent extends PureComponent {
return false;
};
load = async (props) => {
const {link} = props;
getImageUrl = (link) => {
let imageUrl;
if (this.isImage()) {
imageUrl = link;
} else if (isYoutubeLink(link)) {
const videoId = getYouTubeVideoId(link);
imageUrl = `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;
}
return imageUrl;
}
load = (linkChanged = false) => {
const {link, expandedLink, actions} = this.props;
if (link) {
let imageUrl;
if (this.isImage()) {
imageUrl = link;
} else if (isYoutubeLink(link)) {
const videoId = getYouTubeVideoId(link);
imageUrl = `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;
} else {
const {data} = await this.props.actions.getRedirectLocation(link);
let imageUrl = this.getImageUrl(link);
let shortenedLink;
if (data && data.location) {
shortenedLink = data.location;
}
if (shortenedLink) {
if (this.isImage(shortenedLink)) {
imageUrl = shortenedLink;
} else if (isYoutubeLink(shortenedLink)) {
const videoId = getYouTubeVideoId(shortenedLink);
imageUrl = `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;
}
if (this.mounted) {
this.setState({shortenedLink});
}
if (!imageUrl) {
if (!expandedLink || linkChanged) {
actions.getRedirectLocation(link);
} else {
imageUrl = this.getImageUrl(expandedLink);
}
}
@ -215,9 +212,9 @@ export default class PostBodyAdditionalContent extends PureComponent {
generateToggleableEmbed = (isImage, isYouTube) => {
let {link} = this.props;
const {shortenedLink} = this.state;
if (shortenedLink) {
link = shortenedLink;
const {expandedLink} = this.props;
if (expandedLink) {
link = expandedLink;
}
const {width, height, uri} = this.state;
@ -407,10 +404,10 @@ export default class PostBodyAdditionalContent extends PureComponent {
};
handlePreviewImage = (imageRef) => {
const {shortenedLink} = this.state;
let {link} = this.props;
if (shortenedLink) {
link = shortenedLink;
const {expandedLink} = this.props;
if (expandedLink) {
link = expandedLink;
}
const {
originalHeight,
@ -485,10 +482,10 @@ export default class PostBodyAdditionalContent extends PureComponent {
render() {
let {link} = this.props;
const {openGraphData, postProps} = this.props;
const {linkLoadError, shortenedLink} = this.state;
if (shortenedLink) {
link = shortenedLink;
const {openGraphData, postProps, expandedLink} = this.props;
const {linkLoadError} = this.state;
if (expandedLink) {
link = expandedLink;
}
const {attachments} = postProps;

View file

@ -0,0 +1,52 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {Preferences} from 'mattermost-redux/constants';
import {shallowWithIntl} from 'test/intl-test-helper';
import PostBodyAdditionalContent from './post_body_additional_content.js';
describe('PostBodyAdditionalContent', () => {
const baseProps = {
actions: {
getRedirectLocation: jest.fn(),
},
link: 'http://short.ened/123',
deviceHeight: 100,
deviceWidth: 100,
message: 'message',
postId: 'post-id',
postProps: {},
showLinkPreviews: false,
theme: Preferences.THEMES.default,
};
test('should call getRedirectLocation only if expandedLink has not been set', () => {
const wrapper = shallowWithIntl(<PostBodyAdditionalContent {...baseProps}/>);
const instance = wrapper.instance();
expect(baseProps.actions.getRedirectLocation).toHaveBeenCalledTimes(1);
wrapper.setProps({expandedLink: 'http://expanded.com/123'});
instance.load();
expect(baseProps.actions.getRedirectLocation).toHaveBeenCalledTimes(1);
});
test('should call getRedirectLocation if expandedLink is set but link changed', () => {
const props = {
...baseProps,
expandedLink: 'http://expanded.com/123',
};
const wrapper = shallowWithIntl(<PostBodyAdditionalContent {...props}/>);
const instance = wrapper.instance();
expect(baseProps.actions.getRedirectLocation).toHaveBeenCalledTimes(0);
wrapper.setProps({link: `${baseProps.link}/456`});
instance.load();
expect(baseProps.actions.getRedirectLocation).toHaveBeenCalledTimes(1);
});
});