diff --git a/app/soapbox/features/ui/components/profile_media_panel.js b/app/soapbox/features/ui/components/profile_media_panel.js deleted file mode 100644 index 54482ad79..000000000 --- a/app/soapbox/features/ui/components/profile_media_panel.js +++ /dev/null @@ -1,128 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { FormattedMessage, injectIntl } from 'react-intl'; -import { connect } from 'react-redux'; - -import { openModal } from 'soapbox/actions/modals'; -import Icon from 'soapbox/components/icon'; -import { Spinner } from 'soapbox/components/ui'; -import { getAccountGallery } from 'soapbox/selectors'; - -import { expandAccountMediaTimeline } from '../../../actions/timelines'; -import MediaItem from '../../account_gallery/components/media_item'; - -class ProfileMediaPanel extends ImmutablePureComponent { - - static propTypes = { - account: ImmutablePropTypes.record, - attachments: ImmutablePropTypes.list, - 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') })); - } else { - const media = attachment.getIn(['status', 'media_attachments']); - const index = media.findIndex(x => x.get('id') === attachment.get('id')); - - this.props.dispatch(openModal('MEDIA', { media, index, status: attachment.get('status'), account: attachment.get('account') })); - } - } - - fetchMedia = () => { - const { account } = this.props; - - if (account) { - const accountId = account.get('id'); - - this.props.dispatch(expandAccountMediaTimeline(accountId)) - .then(() => this.setState({ isLoading: false })) - .catch(() => {}); - - } - } - - 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 ( -
-
- - - - -
- {account && -
- {isLoading ? ( - - ) : ( - this.renderAttachments() - )} -
- } -
- ); - } - -} - -const mapStateToProps = (state, { account }) => ({ - attachments: getAccountGallery(state, account.get('id')), -}); - -export default injectIntl( - connect(mapStateToProps, null, null, { - forwardRef: true, - }, - )(ProfileMediaPanel)); diff --git a/app/soapbox/features/ui/components/profile_media_panel.tsx b/app/soapbox/features/ui/components/profile_media_panel.tsx new file mode 100644 index 000000000..29738ec3f --- /dev/null +++ b/app/soapbox/features/ui/components/profile_media_panel.tsx @@ -0,0 +1,90 @@ +import { List as ImmutableList } from 'immutable'; +import React, { useState, useEffect } from 'react'; +import { FormattedMessage } from 'react-intl'; +import { useDispatch } from 'react-redux'; + +import { openModal } from 'soapbox/actions/modals'; +import { Spinner, Widget } from 'soapbox/components/ui'; +import { useAppSelector } from 'soapbox/hooks'; +import { getAccountGallery } from 'soapbox/selectors'; + +import { expandAccountMediaTimeline } from '../../../actions/timelines'; +import MediaItem from '../../account_gallery/components/media_item'; + +import type { Account, Attachment } from 'soapbox/types/entities'; + +interface IProfileMediaPanel { + account?: Account, +} + +const ProfileMediaPanel: React.FC = ({ account }) => { + const dispatch = useDispatch(); + + const [loading, setLoading] = useState(true); + + const attachments: ImmutableList = useAppSelector((state) => account ? getAccountGallery(state, account?.id) : ImmutableList()); + + const handleOpenMedia = (attachment: Attachment): void => { + if (attachment.type === 'video') { + dispatch(openModal('VIDEO', { media: attachment, status: attachment.status })); + } else { + const media = attachment.getIn(['status', 'media_attachments']) as ImmutableList; + const index = media.findIndex(x => x.id === attachment.id); + + dispatch(openModal('MEDIA', { media, index, status: attachment.status, account: attachment.account })); + } + }; + + useEffect(() => { + setLoading(true); + + if (account) { + dispatch(expandAccountMediaTimeline(account.id)) + // @ts-ignore yes it does + .then(() => setLoading(false)) + .catch(() => {}); + } + }, [account?.id]); + + const renderAttachments = () => { + 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 ( +
+ +
+ ); + } + }; + + return ( + }> + {account && ( +
+ {loading ? ( + + ) : ( + renderAttachments() + )} +
+ )} +
+ ); +}; + +export default ProfileMediaPanel; diff --git a/app/soapbox/pages/profile_page.js b/app/soapbox/pages/profile_page.js index 05960b6fe..b4b3854c2 100644 --- a/app/soapbox/pages/profile_page.js +++ b/app/soapbox/pages/profile_page.js @@ -13,6 +13,7 @@ import { WhoToFollowPanel, TrendsPanel, ProfileInfoPanel, + ProfileMediaPanel, SignUpPanel, } from 'soapbox/features/ui/util/async-components'; import { findAccountByUsername } from 'soapbox/selectors'; @@ -155,6 +156,9 @@ class ProfilePage extends ImmutablePureComponent { {Component => } )} + + {Component => } + {showTrendsPanel && ( {Component => } diff --git a/app/styles/components/profile-media-panel.scss b/app/styles/components/profile-media-panel.scss index fb0b6a502..ca13ec4ba 100644 --- a/app/styles/components/profile-media-panel.scss +++ b/app/styles/components/profile-media-panel.scss @@ -47,13 +47,11 @@ } &__list { - padding: 0 5px; display: flex; flex-wrap: wrap; } &__empty { - padding: 0 15px 10px 15px; font-size: 14px; color: var(--primary-text-color--faint); }