Fix load more feature on the Account media gallery (#3293)
* Add load more button for large screens * Fix `next` state value on the first loading * Don't load if `isLoading || !hasMore` * Start load on near the bottom
This commit is contained in:
		@@ -17,6 +17,7 @@ import MediaItem from './components/media_item';
 | 
			
		||||
import HeaderContainer from '../account_timeline/containers/header_container';
 | 
			
		||||
import { FormattedMessage } from 'react-intl';
 | 
			
		||||
import { ScrollContainer } from 'react-router-scroll';
 | 
			
		||||
import LoadMore from '../../components/load_more';
 | 
			
		||||
 | 
			
		||||
const mapStateToProps = (state, props) => ({
 | 
			
		||||
  medias: getAccountGallery(state, Number(props.params.accountId)),
 | 
			
		||||
@@ -48,16 +49,30 @@ class AccountGallery extends ImmutablePureComponent {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleScroll = (e) => {
 | 
			
		||||
    const { scrollTop, scrollHeight, clientHeight } = e.target;
 | 
			
		||||
 | 
			
		||||
    if (scrollTop === scrollHeight - clientHeight) {
 | 
			
		||||
  handleScrollToBottom = () => {
 | 
			
		||||
    if (this.props.hasMore) {
 | 
			
		||||
      this.props.dispatch(expandAccountMediaTimeline(Number(this.props.params.accountId)));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleScroll = (e) => {
 | 
			
		||||
    const { scrollTop, scrollHeight, clientHeight } = e.target;
 | 
			
		||||
    const offset = scrollHeight - scrollTop - clientHeight;
 | 
			
		||||
 | 
			
		||||
    if (150 > offset && !this.props.isLoading) {
 | 
			
		||||
      this.handleScrollToBottom();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleLoadMore = (e) => {
 | 
			
		||||
    e.preventDefault();
 | 
			
		||||
    this.handleScrollToBottom();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    const { medias, autoPlayGif, isLoading } = this.props;
 | 
			
		||||
    const { medias, autoPlayGif, isLoading, hasMore } = this.props;
 | 
			
		||||
 | 
			
		||||
    let loadMore = null;
 | 
			
		||||
 | 
			
		||||
    if (!medias && isLoading) {
 | 
			
		||||
      return (
 | 
			
		||||
@@ -67,6 +82,10 @@ class AccountGallery extends ImmutablePureComponent {
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!isLoading && medias.size > 0 && hasMore) {
 | 
			
		||||
      loadMore = <LoadMore onClick={this.handleLoadMore} />;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <Column>
 | 
			
		||||
        <ColumnBackButton />
 | 
			
		||||
@@ -87,6 +106,7 @@ class AccountGallery extends ImmutablePureComponent {
 | 
			
		||||
                  autoPlayGif={autoPlayGif}
 | 
			
		||||
                />
 | 
			
		||||
              )}
 | 
			
		||||
              {loadMore}
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </ScrollContainer>
 | 
			
		||||
 
 | 
			
		||||
@@ -155,7 +155,7 @@ const normalizeAccountTimeline = (state, accountId, statuses, replace = false) =
 | 
			
		||||
    .update('items', Immutable.List(), list => (replace ? ids : ids.concat(list))));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const normalizeAccountMediaTimeline = (state, accountId, statuses, next) => {
 | 
			
		||||
const normalizeAccountMediaTimeline = (state, accountId, statuses) => {
 | 
			
		||||
  let ids = Immutable.List();
 | 
			
		||||
 | 
			
		||||
  statuses.forEach((status, i) => {
 | 
			
		||||
@@ -165,7 +165,7 @@ const normalizeAccountMediaTimeline = (state, accountId, statuses, next) => {
 | 
			
		||||
 | 
			
		||||
  return state.updateIn(['accounts_media_timelines', accountId], Immutable.Map(), map => map
 | 
			
		||||
    .set('isLoading', false)
 | 
			
		||||
    .set('next', next)
 | 
			
		||||
    .set('next', true)
 | 
			
		||||
    .update('items', Immutable.List(), list => ids.concat(list)));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -345,7 +345,7 @@ export default function timelines(state = initialState, action) {
 | 
			
		||||
  case ACCOUNT_MEDIA_TIMELINE_EXPAND_FAIL:
 | 
			
		||||
    return state.updateIn(['accounts_media_timelines', action.id], Immutable.Map(), map => map.set('isLoading', false));
 | 
			
		||||
  case ACCOUNT_MEDIA_TIMELINE_FETCH_SUCCESS:
 | 
			
		||||
    return normalizeAccountMediaTimeline(state, action.id, Immutable.fromJS(action.statuses), action.next);
 | 
			
		||||
    return normalizeAccountMediaTimeline(state, action.id, Immutable.fromJS(action.statuses));
 | 
			
		||||
  case ACCOUNT_MEDIA_TIMELINE_EXPAND_SUCCESS:
 | 
			
		||||
    return appendNormalizedAccountMediaTimeline(state, action.id, Immutable.fromJS(action.statuses), action.next);
 | 
			
		||||
  case ACCOUNT_BLOCK_SUCCESS:
 | 
			
		||||
 
 | 
			
		||||
@@ -1962,6 +1962,7 @@ button.icon-button.active i.fa-retweet {
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  padding: 15px;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  clear: both;
 | 
			
		||||
 | 
			
		||||
  &:hover {
 | 
			
		||||
    background: lighten($ui-base-color, 2%);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user