diff options
author | unarist <m.unarist@gmail.com> | 2017-05-25 12:22:46 +0900 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2017-05-25 05:22:46 +0200 |
commit | 807c192fcf3a6cd0f4c712ec43130fbffddcc6c6 (patch) | |
tree | 8956d82961a88cb8205e43d14a88fc017374a738 | |
parent | 3b59f9c6c254e34d95d917857ccbe79f6e1104b0 (diff) |
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
-rw-r--r-- | app/javascript/mastodon/features/account_gallery/index.js | 26 | ||||
-rw-r--r-- | app/javascript/mastodon/reducers/timelines.js | 6 | ||||
-rw-r--r-- | app/javascript/styles/components.scss | 1 |
3 files changed, 27 insertions, 6 deletions
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js index 6ddfcb0a0..a15419ac7 100644 --- a/app/javascript/mastodon/features/account_gallery/index.js +++ b/app/javascript/mastodon/features/account_gallery/index.js @@ -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 { } } + 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 (scrollTop === scrollHeight - clientHeight) { - this.props.dispatch(expandAccountMediaTimeline(Number(this.props.params.accountId))); + 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> diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js index 2e95d645e..49eb4756c 100644 --- a/app/javascript/mastodon/reducers/timelines.js +++ b/app/javascript/mastodon/reducers/timelines.js @@ -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: diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss index 3971a85bc..38fbda5a9 100644 --- a/app/javascript/styles/components.scss +++ b/app/javascript/styles/components.scss @@ -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%); |