Place the new message indicator at the top of the screen (#2943)

* Place the new message indicator at the top of the screen

* Add unit tests for channel postVisibility reducer
This commit is contained in:
Elias Nahum
2019-07-02 12:28:13 -04:00
parent e7a2f4d6b1
commit dd28c38196
5 changed files with 141 additions and 8 deletions

View File

@@ -89,6 +89,7 @@ export default class PostAttachmentOpenGraph extends PureComponent {
const bestImage = getNearestPoint(bestDimensions, data.images, 'width', 'height');
const imageUrl = bestImage.secure_url || bestImage.url;
let ogImage;
if (imagesMetadata && imagesMetadata[imageUrl]) {
ogImage = imagesMetadata[imageUrl];
@@ -98,6 +99,12 @@ export default class PostAttachmentOpenGraph extends PureComponent {
ogImage = data.images.find((i) => i.url === imageUrl || i.secure_url === imageUrl);
}
// Fallback when the ogImage does not have dimensions but there is a metaImage defined
const metaImages = imagesMetadata ? Object.values(imagesMetadata) : null;
if ((!ogImage?.width || !ogImage?.height) && metaImages?.length) {
ogImage = metaImages[0];
}
let dimensions = bestDimensions;
if (ogImage?.width && ogImage?.height) {
dimensions = calculateDimensions(ogImage.height, ogImage.width, this.getViewPostWidth());
@@ -139,9 +146,16 @@ export default class PostAttachmentOpenGraph extends PureComponent {
ogImage = openGraphData.images.find((i) => i.url === openGraphImageUrl || i.secure_url === openGraphImageUrl);
}
// Fallback when the ogImage does not have dimensions but there is a metaImage defined
const metaImages = imagesMetadata ? Object.values(imagesMetadata) : null;
if ((!ogImage?.width || !ogImage?.height) && metaImages?.length) {
ogImage = metaImages[0];
}
if (ogImage?.width && ogImage?.height) {
this.setImageSize(imageUrl, ogImage.width, ogImage.height);
} else {
// if we get to this point there can be a scroll pop
Image.getSize(imageUrl, (width, height) => {
this.setImageSize(imageUrl, width, height);
}, () => null);

View File

@@ -179,11 +179,12 @@ export default class PostBodyAdditionalContent extends PureComponent {
};
generateStaticEmbed = (isYouTube, isImage) => {
if (isYouTube || isImage) {
const {isReplyPost, link, metadata, navigator, openGraphData, showLinkPreviews, theme} = this.props;
if (isYouTube || (isImage && !openGraphData)) {
return null;
}
const {isReplyPost, link, metadata, navigator, openGraphData, showLinkPreviews, theme} = this.props;
const attachments = this.getMessageAttachment();
if (attachments) {
return attachments;

View File

@@ -294,11 +294,13 @@ export default class PostList extends PureComponent {
this.props.initialIndex > 0 &&
!this.hasDoneInitialScroll
) {
this.flatListRef.current.scrollToIndex({
animated: false,
index: this.props.initialIndex,
viewOffset: 50,
viewPosition: 0.5,
requestAnimationFrame(() => {
this.flatListRef.current.scrollToIndex({
animated: false,
index: this.props.initialIndex,
viewOffset: 0,
viewPosition: 1, // 0 is at bottom
});
});
this.hasDoneInitialScroll = true;
}

View File

@@ -266,7 +266,11 @@ function postVisibility(state = {}, action) {
}
case ViewTypes.INCREASE_POST_VISIBILITY: {
const nextState = {...state};
nextState[action.data] += action.amount;
if (nextState[action.data]) {
nextState[action.data] += action.amount;
} else {
nextState[action.data] = action.amount;
}
return nextState;
}
case ViewTypes.RECEIVED_FOCUSED_POST: {

View File

@@ -0,0 +1,112 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import channelReducer from './channel';
import {ViewTypes} from 'app/constants';
describe('Reducers.channel', () => {
const initialState = {
displayName: '',
drafts: {},
loading: false,
refreshing: false,
postCountInChannel: {},
postVisibility: {},
loadingPosts: {},
lastGetPosts: {},
retryFailed: false,
loadMorePostsVisible: true,
lastChannelViewTime: {},
keepChannelIdAsUnread: null,
};
test('Initial state', () => {
const nextState = channelReducer(
{
displayName: '',
drafts: {},
loading: false,
refreshing: false,
postCountInChannel: {},
postVisibility: {},
loadingPosts: {},
lastGetPosts: {},
retryFailed: false,
loadMorePostsVisible: true,
lastChannelViewTime: {},
keepChannelIdAsUnread: null,
},
{}
);
expect(nextState).toEqual(initialState);
});
test('should set the postVisibility amount for a channel', () => {
const channelId = 'channel_id';
const amount = 15;
const nextState = channelReducer(
{
displayName: '',
drafts: {},
loading: false,
refreshing: false,
postCountInChannel: {},
postVisibility: {},
loadingPosts: {},
lastGetPosts: {},
retryFailed: false,
loadMorePostsVisible: true,
lastChannelViewTime: {},
keepChannelIdAsUnread: null,
},
{
type: ViewTypes.INCREASE_POST_VISIBILITY,
data: channelId,
amount,
}
);
expect(nextState).toEqual({
...initialState,
postVisibility: {
[channelId]: amount,
},
});
});
test('should increase the postVisibility amount for a channel', () => {
const channelId = 'channel_id';
const amount = 15;
const nextState = channelReducer(
{
displayName: '',
drafts: {},
loading: false,
refreshing: false,
postCountInChannel: {},
postVisibility: {
[channelId]: amount,
},
loadingPosts: {},
lastGetPosts: {},
retryFailed: false,
loadMorePostsVisible: true,
lastChannelViewTime: {},
keepChannelIdAsUnread: null,
},
{
type: ViewTypes.INCREASE_POST_VISIBILITY,
data: channelId,
amount,
}
);
expect(nextState).toEqual({
...initialState,
postVisibility: {
[channelId]: 2 * amount,
},
});
});
});