diff --git a/app/soapbox/actions/timelines.js b/app/soapbox/actions/timelines.js index 5ef4ae733..0ae23a0ed 100644 --- a/app/soapbox/actions/timelines.js +++ b/app/soapbox/actions/timelines.js @@ -138,7 +138,7 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) { if (timeline.get('isLoading')) { done(); - return; + return dispatch(noOp); } if (!params.max_id && !params.pinned && timeline.get('items', ImmutableOrderedSet()).size > 0) { @@ -149,7 +149,7 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) { dispatch(expandTimelineRequest(timelineId, isLoadingMore)); - api(getState).get(path, { params }).then(response => { + return api(getState).get(path, { params }).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedStatuses(response.data)); dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206, isLoadingRecent, isLoadingMore)); diff --git a/app/soapbox/features/ui/components/profile_media_panel.js b/app/soapbox/features/ui/components/profile_media_panel.js index 108af12cd..7f41e976d 100644 --- a/app/soapbox/features/ui/components/profile_media_panel.js +++ b/app/soapbox/features/ui/components/profile_media_panel.js @@ -9,6 +9,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePropTypes from 'react-immutable-proptypes'; import MediaItem from '../../account_gallery/components/media_item'; import Icon from 'soapbox/components/icon'; +import LoadingIndicator from 'soapbox/components/loading_indicator'; class ProfileMediaPanel extends ImmutablePureComponent { @@ -18,6 +19,10 @@ class ProfileMediaPanel extends ImmutablePureComponent { dispatch: PropTypes.func.isRequired, }; + state = { + isLoading: true, + } + handleOpenMedia = attachment => { if (attachment.get('type') === 'video') { this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status') })); @@ -29,17 +34,64 @@ class ProfileMediaPanel extends ImmutablePureComponent { } } - componentDidMount() { + fetchMedia = () => { const { account } = this.props; - const accountId = account.get('id'); - this.props.dispatch(expandAccountMediaTimeline(accountId)); + + if (account) { + const accountId = account.get('id'); + + this.props.dispatch(expandAccountMediaTimeline(accountId)) + .then(() => this.setState({ isLoading: false })) + .catch(() => {}); + + } } - render() { - const { attachments, account } = this.props; + componentDidMount() { + this.fetchMedia(); + } + + componentDidUpdate(prevProps) { + const oldId = prevProps.account && prevProps.account.get('id'); + const newId = this.props.account && this.props.account.get('id'); + + if (newId !== oldId) { + this.setState({ isLoading: true }); + this.fetchMedia(); + } + } + + renderAttachments() { + const { attachments } = this.props; const publicAttachments = attachments.filter(attachment => attachment.getIn(['status', 'visibility']) === 'public'); const nineAttachments = publicAttachments.slice(0, 9); + if (!nineAttachments.isEmpty()) { + return ( +
+ {nineAttachments.map((attachment, index) => ( + + ))} +
+ ); + } else { + return ( +
+ +
+ ); + } + } + + render() { + const { account } = this.props; + const { isLoading } = this.state; + return (
@@ -50,16 +102,11 @@ class ProfileMediaPanel extends ImmutablePureComponent {
{account &&
-
- {!nineAttachments.isEmpty() && nineAttachments.map((attachment, index) => ( - - ))} -
+ {isLoading ? ( + + ) : ( + this.renderAttachments() + )}
}
diff --git a/app/styles/components/profile-media-panel.scss b/app/styles/components/profile-media-panel.scss index 782cbc275..fb0b6a502 100644 --- a/app/styles/components/profile-media-panel.scss +++ b/app/styles/components/profile-media-panel.scss @@ -51,4 +51,14 @@ display: flex; flex-wrap: wrap; } + + &__empty { + padding: 0 15px 10px 15px; + font-size: 14px; + color: var(--primary-text-color--faint); + } + + .loading-indicator { + margin: 0 auto; + } }