ProfileMediaPanel: fix navigating between profiles, display LoadingIndicator, display empty message

merge-requests/788/head
Alex Gleason 3 years ago
parent 8e1600e179
commit 2d42995e6f
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7

@ -138,7 +138,7 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
if (timeline.get('isLoading')) { if (timeline.get('isLoading')) {
done(); done();
return; return dispatch(noOp);
} }
if (!params.max_id && !params.pinned && timeline.get('items', ImmutableOrderedSet()).size > 0) { 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)); 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'); const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data)); dispatch(importFetchedStatuses(response.data));
dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206, isLoadingRecent, isLoadingMore)); dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206, isLoadingRecent, isLoadingMore));

@ -9,6 +9,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import MediaItem from '../../account_gallery/components/media_item'; import MediaItem from '../../account_gallery/components/media_item';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
import LoadingIndicator from 'soapbox/components/loading_indicator';
class ProfileMediaPanel extends ImmutablePureComponent { class ProfileMediaPanel extends ImmutablePureComponent {
@ -18,6 +19,10 @@ class ProfileMediaPanel extends ImmutablePureComponent {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
}; };
state = {
isLoading: true,
}
handleOpenMedia = attachment => { handleOpenMedia = attachment => {
if (attachment.get('type') === 'video') { if (attachment.get('type') === 'video') {
this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status') })); this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status') }));
@ -29,29 +34,42 @@ class ProfileMediaPanel extends ImmutablePureComponent {
} }
} }
componentDidMount() { fetchMedia = () => {
const { account } = this.props; const { account } = this.props;
if (account) {
const accountId = account.get('id'); const accountId = account.get('id');
this.props.dispatch(expandAccountMediaTimeline(accountId));
this.props.dispatch(expandAccountMediaTimeline(accountId))
.then(() => this.setState({ isLoading: false }))
.catch(() => {});
}
} }
render() { componentDidMount() {
const { attachments, account } = this.props; 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 publicAttachments = attachments.filter(attachment => attachment.getIn(['status', 'visibility']) === 'public');
const nineAttachments = publicAttachments.slice(0, 9); const nineAttachments = publicAttachments.slice(0, 9);
if (!nineAttachments.isEmpty()) {
return ( return (
<div className='media-panel'>
<div className='media-panel-header'>
<Icon src={require('@tabler/icons/icons/camera.svg')} className='media-panel-header__icon' />
<span className='media-panel-header__label'>
<FormattedMessage id='media_panel.title' defaultMessage='Media' />
</span>
</div>
{account &&
<div className='media-panel__content'>
<div className='media-panel__list'> <div className='media-panel__list'>
{!nineAttachments.isEmpty() && nineAttachments.map((attachment, index) => ( {nineAttachments.map((attachment, index) => (
<MediaItem <MediaItem
key={`${attachment.getIn(['status', 'id'])}+${attachment.get('id')}`} key={`${attachment.getIn(['status', 'id'])}+${attachment.get('id')}`}
attachment={attachment} attachment={attachment}
@ -60,6 +78,35 @@ class ProfileMediaPanel extends ImmutablePureComponent {
/> />
))} ))}
</div> </div>
);
} else {
return (
<div className='media-panel__empty'>
<FormattedMessage id='media_panel.empty_message' defaultMessage='No media found.' />
</div>
);
}
}
render() {
const { account } = this.props;
const { isLoading } = this.state;
return (
<div className='media-panel'>
<div className='media-panel-header'>
<Icon src={require('@tabler/icons/icons/camera.svg')} className='media-panel-header__icon' />
<span className='media-panel-header__label'>
<FormattedMessage id='media_panel.title' defaultMessage='Media' />
</span>
</div>
{account &&
<div className='media-panel__content'>
{isLoading ? (
<LoadingIndicator />
) : (
this.renderAttachments()
)}
</div> </div>
} }
</div> </div>

@ -51,4 +51,14 @@
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
} }
&__empty {
padding: 0 15px 10px 15px;
font-size: 14px;
color: var(--primary-text-color--faint);
}
.loading-indicator {
margin: 0 auto;
}
} }

Loading…
Cancel
Save