Various fixes to scrollable lists and media gallery (#9501)
* Always use the scrollable class for the ScrollList component Fixes #9499 as well as empty timelines' scrollbar “blinking” between loading state and empty state. * Do not display empty message when the list is known to have more elements Fixes #9500 * Fix LoadMore usage in account media gallery (Even though that codepath is probably never actually used…) * Make account media gallery more consistent with account timeline Fixes #9498 Display “load more” more consistently, add a loading indicator on first load. * Fix “load more” button when no data has been fetched
This commit is contained in:
		
							parent
							
								
									b048926e67
								
							
						
					
					
						commit
						55abff8af7
					
				| 
						 | 
				
			
			@ -30,7 +30,6 @@ export default class ScrollableList extends PureComponent {
 | 
			
		|||
    hasMore: PropTypes.bool,
 | 
			
		||||
    prepend: PropTypes.node,
 | 
			
		||||
    alwaysPrepend: PropTypes.bool,
 | 
			
		||||
    alwaysShowScrollbar: PropTypes.bool,
 | 
			
		||||
    emptyMessage: PropTypes.node,
 | 
			
		||||
    children: PropTypes.node,
 | 
			
		||||
  };
 | 
			
		||||
| 
						 | 
				
			
			@ -206,11 +205,11 @@ export default class ScrollableList extends PureComponent {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    const { children, scrollKey, trackScroll, shouldUpdateScroll, showLoading, isLoading, hasMore, prepend, alwaysPrepend, alwaysShowScrollbar, emptyMessage, onLoadMore } = this.props;
 | 
			
		||||
    const { children, scrollKey, trackScroll, shouldUpdateScroll, showLoading, isLoading, hasMore, prepend, alwaysPrepend, emptyMessage, onLoadMore } = this.props;
 | 
			
		||||
    const { fullscreen } = this.state;
 | 
			
		||||
    const childrenCount = React.Children.count(children);
 | 
			
		||||
 | 
			
		||||
    const loadMore     = (hasMore && childrenCount > 0 && onLoadMore) ? <LoadMore visible={!isLoading} onClick={this.handleLoadMore} /> : null;
 | 
			
		||||
    const loadMore     = (hasMore && onLoadMore) ? <LoadMore visible={!isLoading} onClick={this.handleLoadMore} /> : null;
 | 
			
		||||
    let scrollableArea = null;
 | 
			
		||||
 | 
			
		||||
    if (showLoading) {
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +224,7 @@ export default class ScrollableList extends PureComponent {
 | 
			
		|||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      );
 | 
			
		||||
    } else if (isLoading || childrenCount > 0 || !emptyMessage) {
 | 
			
		||||
    } else if (isLoading || childrenCount > 0 || hasMore || !emptyMessage) {
 | 
			
		||||
      scrollableArea = (
 | 
			
		||||
        <div className={classNames('scrollable', { fullscreen })} ref={this.setRef} onMouseMove={this.handleMouseMove}>
 | 
			
		||||
          <div role='feed' className='item-list'>
 | 
			
		||||
| 
						 | 
				
			
			@ -249,10 +248,8 @@ export default class ScrollableList extends PureComponent {
 | 
			
		|||
        </div>
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
      const scrollable = alwaysShowScrollbar;
 | 
			
		||||
 | 
			
		||||
      scrollableArea = (
 | 
			
		||||
        <div className={classNames({ scrollable, fullscreen })} ref={this.setRef} style={{ flex: '1 1 auto', display: 'flex', flexDirection: 'column' }}>
 | 
			
		||||
        <div className={classNames('scrollable scrollable--flex', { fullscreen })} ref={this.setRef}>
 | 
			
		||||
          {alwaysPrepend && prepend}
 | 
			
		||||
 | 
			
		||||
          <div className='empty-column-indicator'>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ export default class StatusList extends ImmutablePureComponent {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  handleLoadOlder = debounce(() => {
 | 
			
		||||
    this.props.onLoadMore(this.props.statusIds.last());
 | 
			
		||||
    this.props.onLoadMore(this.props.statusIds.size > 0 ? this.props.statusIds.last() : undefined);
 | 
			
		||||
  }, 300, { leading: true })
 | 
			
		||||
 | 
			
		||||
  _selectChild (index) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ class LoadMoreMedia extends ImmutablePureComponent {
 | 
			
		|||
    return (
 | 
			
		||||
      <LoadMore
 | 
			
		||||
        disabled={this.props.disabled}
 | 
			
		||||
        onLoadMore={this.handleLoadMore}
 | 
			
		||||
        onClick={this.handleLoadMore}
 | 
			
		||||
      />
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +68,7 @@ class AccountGallery extends ImmutablePureComponent {
 | 
			
		|||
 | 
			
		||||
  handleScrollToBottom = () => {
 | 
			
		||||
    if (this.props.hasMore) {
 | 
			
		||||
      this.handleLoadMore(this.props.medias.last().getIn(['status', 'id']));
 | 
			
		||||
      this.handleLoadMore(this.props.medias.size > 0 ? this.props.medias.last().getIn(['status', 'id']) : undefined);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -103,8 +103,8 @@ class AccountGallery extends ImmutablePureComponent {
 | 
			
		|||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!isLoading && medias.size > 0 && hasMore) {
 | 
			
		||||
      loadOlder = <LoadMore onClick={this.handleLoadOlder} />;
 | 
			
		||||
    if (hasMore) {
 | 
			
		||||
      loadOlder = <LoadMore visible={!isLoading} onClick={this.handleLoadOlder} />;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
| 
						 | 
				
			
			@ -112,14 +112,15 @@ class AccountGallery extends ImmutablePureComponent {
 | 
			
		|||
        <ColumnBackButton />
 | 
			
		||||
 | 
			
		||||
        <ScrollContainer scrollKey='account_gallery' shouldUpdateScroll={shouldUpdateScroll}>
 | 
			
		||||
          <div className='scrollable' onScroll={this.handleScroll}>
 | 
			
		||||
          <div className='scrollable scrollable--flex' onScroll={this.handleScroll}>
 | 
			
		||||
            <HeaderContainer accountId={this.props.params.accountId} />
 | 
			
		||||
 | 
			
		||||
            <div className='account-gallery__container'>
 | 
			
		||||
            <div role='feed' className='account-gallery__container'>
 | 
			
		||||
              {medias.map((media, index) => media === null ? (
 | 
			
		||||
                <LoadMoreMedia
 | 
			
		||||
                  key={'more:' + medias.getIn(index + 1, 'id')}
 | 
			
		||||
                  maxId={index > 0 ? medias.getIn(index - 1, 'id') : null}
 | 
			
		||||
                  onLoadMore={this.handleLoadMore}
 | 
			
		||||
                />
 | 
			
		||||
              ) : (
 | 
			
		||||
                <MediaItem
 | 
			
		||||
| 
						 | 
				
			
			@ -129,6 +130,12 @@ class AccountGallery extends ImmutablePureComponent {
 | 
			
		|||
              ))}
 | 
			
		||||
              {loadOlder}
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            {isLoading && medias.size === 0 && (
 | 
			
		||||
              <div className='scrollable__append'>
 | 
			
		||||
                <LoadingIndicator />
 | 
			
		||||
              </div>
 | 
			
		||||
            )}
 | 
			
		||||
          </div>
 | 
			
		||||
        </ScrollContainer>
 | 
			
		||||
      </Column>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,6 @@ class Followers extends ImmutablePureComponent {
 | 
			
		|||
          shouldUpdateScroll={shouldUpdateScroll}
 | 
			
		||||
          prepend={<HeaderContainer accountId={this.props.params.accountId} hideTabs />}
 | 
			
		||||
          alwaysPrepend
 | 
			
		||||
          alwaysShowScrollbar
 | 
			
		||||
          emptyMessage={emptyMessage}
 | 
			
		||||
        >
 | 
			
		||||
          {accountIds.map(id =>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,6 @@ class Following extends ImmutablePureComponent {
 | 
			
		|||
          shouldUpdateScroll={shouldUpdateScroll}
 | 
			
		||||
          prepend={<HeaderContainer accountId={this.props.params.accountId} hideTabs />}
 | 
			
		||||
          alwaysPrepend
 | 
			
		||||
          alwaysShowScrollbar
 | 
			
		||||
          emptyMessage={emptyMessage}
 | 
			
		||||
        >
 | 
			
		||||
          {accountIds.map(id =>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue