From a6d9632cad865e708f997899cd11aafbd1c4d752 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Fri, 26 Jan 2018 11:29:28 -0500 Subject: [PATCH] ICU-562 Explicitly store whether or not 'load more posts' should be visible (#1379) --- app/actions/views/channel.js | 63 +++++++++++++------ app/components/post_list/post_list.js | 5 +- app/constants/view.js | 1 + app/reducers/views/channel.js | 13 +++- .../channel_post_list/channel_post_list.js | 12 ++-- .../channel/channel_post_list/index.js | 1 + app/store/index.js | 2 +- 7 files changed, 67 insertions(+), 30 deletions(-) diff --git a/app/actions/views/channel.js b/app/actions/views/channel.js index 0c7d23a44..0301dee2f 100644 --- a/app/actions/views/channel.js +++ b/app/actions/views/channel.js @@ -149,10 +149,13 @@ export function loadPostsIfNecessaryWithRetry(channelId) { const time = Date.now(); + let loadMorePostsVisible; let received; if (!postsIds || postsIds.length < ViewTypes.POST_VISIBILITY_CHUNK_SIZE) { // Get the first page of posts if it appears we haven't gotten it yet, like the webapp received = await retryGetPostsAction(getPosts(channelId), dispatch, getState); + + loadMorePostsVisible = received.order.length >= ViewTypes.POST_VISIBILITY_CHUNK_SIZE; } else { const {lastConnectAt} = state.device.websocket; const lastGetPosts = state.views.channel.lastGetPosts[channelId]; @@ -169,6 +172,8 @@ export function loadPostsIfNecessaryWithRetry(channelId) { } received = await retryGetPostsAction(getPostsSince(channelId, since), dispatch, getState); + + loadMorePostsVisible = postsIds.length + received.order.length >= ViewTypes.POST_VISIBILITY_CHUNK_SIZE; } if (received) { @@ -178,6 +183,8 @@ export function loadPostsIfNecessaryWithRetry(channelId) { time }); } + + dispatch(setLoadMorePostsVisible(loadMorePostsVisible)); }; } @@ -266,8 +273,11 @@ export function handleSelectChannel(channelId) { return async (dispatch, getState) => { const {currentTeamId} = getState().entities.teams; + dispatch(setLoadMorePostsVisible(true)); + loadPostsIfNecessaryWithRetry(channelId)(dispatch, getState); selectChannel(channelId)(dispatch, getState); + dispatch(batchActions([ { type: ViewTypes.SET_INITIAL_POST_VISIBILITY, @@ -279,7 +289,7 @@ export function handleSelectChannel(channelId) { teamId: currentTeamId, channelId } - ]), 'BATCH_CHANNEL_LOADED'); + ])); }; } @@ -465,11 +475,10 @@ export function increasePostVisibility(channelId, focusedPostId) { if (loadedPostCount >= desiredPostVisibility) { // We already have the posts, so we just need to show them - dispatch({ - type: ViewTypes.INCREASE_POST_VISIBILITY, - data: channelId, - amount: ViewTypes.POST_VISIBILITY_CHUNK_SIZE - }); + dispatch(batchActions([ + doIncreasePostVisibility(channelId), + setLoadMorePostsVisible(true) + ])); return; } @@ -481,30 +490,46 @@ export function increasePostVisibility(channelId, focusedPostId) { channelId }); - const page = Math.floor(currentPostVisibility / ViewTypes.POST_VISIBILITY_CHUNK_SIZE); + const pageSize = ViewTypes.POST_VISIBILITY_CHUNK_SIZE; + const page = Math.floor(currentPostVisibility / pageSize); let result; if (focusedPostId) { - result = await getPostsBefore(channelId, focusedPostId, page, ViewTypes.POST_VISIBILITY_CHUNK_SIZE)(dispatch, getState); + result = await getPostsBefore(channelId, focusedPostId, page, pageSize)(dispatch, getState); } else { - result = await getPosts(channelId, page, ViewTypes.POST_VISIBILITY_CHUNK_SIZE)(dispatch, getState); + result = await getPosts(channelId, page, pageSize)(dispatch, getState); } + const actions = [{ + type: ViewTypes.LOADING_POSTS, + data: false, + channelId + }]; + const posts = result.data; if (posts) { // make sure to increment the posts visibility // only if we got results - dispatch({ - type: ViewTypes.INCREASE_POST_VISIBILITY, - data: channelId, - amount: ViewTypes.POST_VISIBILITY_CHUNK_SIZE - }); + actions.push(doIncreasePostVisibility(channelId)); + + actions.push(setLoadMorePostsVisible(posts.order.length >= pageSize)); } - dispatch({ - type: ViewTypes.LOADING_POSTS, - data: false, - channelId - }); + dispatch(batchActions(actions)); + }; +} + +function doIncreasePostVisibility(channelId) { + return { + type: ViewTypes.INCREASE_POST_VISIBILITY, + data: channelId, + amount: ViewTypes.POST_VISIBILITY_CHUNK_SIZE + }; +} + +function setLoadMorePostsVisible(visible) { + return { + type: ViewTypes.SET_LOAD_MORE_POSTS_VISIBLE, + data: visible }; } diff --git a/app/components/post_list/post_list.js b/app/components/post_list/post_list.js index 17718e3e7..2337b89b0 100644 --- a/app/components/post_list/post_list.js +++ b/app/components/post_list/post_list.js @@ -295,7 +295,8 @@ export default class PostList extends PureComponent { channelId, highlightPostId, loadMore, - postIds + postIds, + showLoadMore } = this.props; const refreshControl = { @@ -311,7 +312,7 @@ export default class PostList extends PureComponent { onLayout={this.onLayout} ref='list' data={postIds} - extraData={this.makeExtraData(channelId, highlightPostId)} + extraData={this.makeExtraData(channelId, highlightPostId, showLoadMore)} initialNumToRender={INITAL_BATCH_TO_RENDER} maxToRenderPerBatch={INITAL_BATCH_TO_RENDER + 1} inverted={true} diff --git a/app/constants/view.js b/app/constants/view.js index 9114be382..289af6fa8 100644 --- a/app/constants/view.js +++ b/app/constants/view.js @@ -54,6 +54,7 @@ const ViewTypes = keyMirror({ INCREASE_POST_VISIBILITY: null, RECEIVED_FOCUSED_POST: null, LOADING_POSTS: null, + SET_LOAD_MORE_POSTS_VISIBLE: null, RECEIVED_POSTS_FOR_CHANNEL_AT_TIME: null, diff --git a/app/reducers/views/channel.js b/app/reducers/views/channel.js index 8c239599e..80caa5e60 100644 --- a/app/reducers/views/channel.js +++ b/app/reducers/views/channel.js @@ -313,6 +313,16 @@ function lastGetPosts(state = {}, action) { } } +function loadMorePostsVisible(state = true, action) { + switch (action.type) { + case ViewTypes.SET_LOAD_MORE_POSTS_VISIBLE: + return action.data; + + default: + return state; + } +} + export default combineReducers({ displayName, drafts, @@ -321,5 +331,6 @@ export default combineReducers({ postVisibility, loadingPosts, lastGetPosts, - retryFailed + retryFailed, + loadMorePostsVisible }); diff --git a/app/screens/channel/channel_post_list/channel_post_list.js b/app/screens/channel/channel_post_list/channel_post_list.js index 4ba4e6bbf..18d5e5d51 100644 --- a/app/screens/channel/channel_post_list/channel_post_list.js +++ b/app/screens/channel/channel_post_list/channel_post_list.js @@ -28,6 +28,7 @@ export default class ChannelPostList extends PureComponent { channelRefreshingFailed: PropTypes.bool, currentUserId: PropTypes.string, lastViewedAt: PropTypes.number, + loadMorePostsVisible: PropTypes.bool.isRequired, navigator: PropTypes.object, postIds: PropTypes.array.isRequired, postVisibility: PropTypes.number, @@ -42,15 +43,13 @@ export default class ChannelPostList extends PureComponent { super(props); this.state = { - visiblePostIds: this.getVisiblePostIds(props), - showLoadMore: props.postIds.length >= props.postVisibility + visiblePostIds: this.getVisiblePostIds(props) }; } componentWillReceiveProps(nextProps) { const {postIds: nextPostIds} = nextProps; - const showLoadMore = nextPostIds.length >= nextProps.postVisibility; let visiblePostIds = this.state.visiblePostIds; if (nextPostIds !== this.props.postIds || nextProps.postVisibility !== this.props.postVisibility) { @@ -58,7 +57,6 @@ export default class ChannelPostList extends PureComponent { } this.setState({ - showLoadMore, visiblePostIds }); } @@ -104,7 +102,7 @@ export default class ChannelPostList extends PureComponent { }; loadMorePosts = () => { - if (this.state.showLoadMore) { + if (this.props.loadMorePostsVisible) { const {actions, channelId} = this.props; actions.increasePostVisibility(channelId); } @@ -122,13 +120,13 @@ export default class ChannelPostList extends PureComponent { channelRefreshingFailed, currentUserId, lastViewedAt, + loadMorePostsVisible, navigator, postIds, theme } = this.props; const { - showLoadMore, visiblePostIds } = this.state; @@ -145,7 +143,7 @@ export default class ChannelPostList extends PureComponent { { const channel = {};