diff options
5 files changed, 38 insertions, 6 deletions
diff --git a/app/javascript/flavours/glitch/actions/timelines.js b/app/javascript/flavours/glitch/actions/timelines.js index 46645752d..b0c19222c 100644 --- a/app/javascript/flavours/glitch/actions/timelines.js +++ b/app/javascript/flavours/glitch/actions/timelines.js @@ -101,6 +101,7 @@ export function expandTimelineRequest(timeline) { return { type: TIMELINE_EXPAND_REQUEST, timeline, + skipLoading: true, }; }; @@ -111,6 +112,7 @@ export function expandTimelineSuccess(timeline, statuses, next, partial) { statuses, next, partial, + skipLoading: true, }; }; @@ -119,6 +121,7 @@ export function expandTimelineFail(timeline, error) { type: TIMELINE_EXPAND_FAIL, timeline, error, + skipLoading: true, }; }; diff --git a/app/javascript/flavours/glitch/components/scrollable_list.js b/app/javascript/flavours/glitch/components/scrollable_list.js index 3ee710dc9..3a6893b01 100644 --- a/app/javascript/flavours/glitch/components/scrollable_list.js +++ b/app/javascript/flavours/glitch/components/scrollable_list.js @@ -8,6 +8,7 @@ import { throttle } from 'lodash'; import { List as ImmutableList } from 'immutable'; import classNames from 'classnames'; import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from 'flavours/glitch/util/fullscreen'; +import LoadingIndicator from './loading_indicator'; export default class ScrollableList extends PureComponent { @@ -23,6 +24,7 @@ export default class ScrollableList extends PureComponent { trackScroll: PropTypes.bool, shouldUpdateScroll: PropTypes.func, isLoading: PropTypes.bool, + showLoading: PropTypes.bool, hasMore: PropTypes.bool, prepend: PropTypes.node, emptyMessage: PropTypes.node, @@ -131,12 +133,14 @@ export default class ScrollableList extends PureComponent { getFirstChildKey (props) { const { children } = props; - let firstChild = children; + let firstChild = children; + if (children instanceof ImmutableList) { firstChild = children.get(0); } else if (Array.isArray(children)) { firstChild = children[0]; } + return firstChild && firstChild.key; } @@ -144,7 +148,7 @@ export default class ScrollableList extends PureComponent { this.node = c; } - handleLoadMore = (e) => { + handleLoadMore = e => { e.preventDefault(); this.props.onLoadMore(); } @@ -155,14 +159,26 @@ export default class ScrollableList extends PureComponent { } render () { - const { children, scrollKey, trackScroll, shouldUpdateScroll, isLoading, hasMore, prepend, emptyMessage, onLoadMore } = this.props; + const { children, scrollKey, trackScroll, shouldUpdateScroll, showLoading, isLoading, hasMore, prepend, 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; let scrollableArea = null; - if (isLoading || childrenCount > 0 || !emptyMessage) { + if (showLoading) { + scrollableArea = ( + <div className='scrollable scrollable--flex' ref={this.setRef}> + <div role='feed' className='item-list'> + {prepend} + </div> + + <div className='scrollable__append'> + <LoadingIndicator /> + </div> + </div> + ); + } else if (isLoading || childrenCount > 0 || !emptyMessage) { scrollableArea = ( <div className={classNames('scrollable', { fullscreen })} ref={this.setRef}> <div role='feed' className='item-list'> diff --git a/app/javascript/flavours/glitch/components/status_list.js b/app/javascript/flavours/glitch/components/status_list.js index aa902db47..d13bd72f6 100644 --- a/app/javascript/flavours/glitch/components/status_list.js +++ b/app/javascript/flavours/glitch/components/status_list.js @@ -24,7 +24,7 @@ export default class StatusList extends ImmutablePureComponent { hasMore: PropTypes.bool, prepend: PropTypes.node, emptyMessage: PropTypes.node, - timelineId: PropTypes.string.isRequired, + timelineId: PropTypes.string, }; static defaultProps = { @@ -121,7 +121,7 @@ export default class StatusList extends ImmutablePureComponent { } return ( - <ScrollableList {...other} onLoadMore={onLoadMore && this.handleLoadOlder} ref={this.setRef}> + <ScrollableList {...other} showLoading={isLoading && statusIds.size === 0} onLoadMore={onLoadMore && this.handleLoadOlder} ref={this.setRef}> {scrollableContent} </ScrollableList> ); diff --git a/app/javascript/flavours/glitch/features/account_timeline/index.js b/app/javascript/flavours/glitch/features/account_timeline/index.js index 2216f9153..6f887a145 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/index.js +++ b/app/javascript/flavours/glitch/features/account_timeline/index.js @@ -11,6 +11,7 @@ import HeaderContainer from './containers/header_container'; import ColumnBackButton from '../../components/column_back_button'; import { List as ImmutableList } from 'immutable'; import ImmutablePureComponent from 'react-immutable-pure-component'; +import { FormattedMessage } from 'react-intl'; const mapStateToProps = (state, { params: { accountId }, withReplies = false }) => { const path = withReplies ? `${accountId}:with_replies` : accountId; @@ -77,12 +78,14 @@ export default class AccountTimeline extends ImmutablePureComponent { <StatusList prepend={<HeaderContainer accountId={this.props.params.accountId} />} + alwaysPrepend scrollKey='account_timeline' statusIds={statusIds} featuredStatusIds={featuredStatusIds} isLoading={isLoading} hasMore={hasMore} onLoadMore={this.handleLoadMore} + emptyMessage={<FormattedMessage id='empty_column.account_timeline' defaultMessage='No toots here!' />} /> </Column> ); diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss index 7d71f0d1d..b16b13d87 100644 --- a/app/javascript/flavours/glitch/styles/components/index.scss +++ b/app/javascript/flavours/glitch/styles/components/index.scss @@ -597,6 +597,16 @@ @supports(display: grid) { // hack to fix Chrome <57 contain: strict; } + + &--flex { + display: flex; + flex-direction: column; + } + + &__append { + flex: 1 1 auto; + position: relative; + } } .scrollable.fullscreen { |