bigbuffet-rw/app/soapbox/features/favourited_statuses/index.js

159 lines
5.2 KiB
JavaScript
Raw Normal View History

import debounce from 'lodash/debounce';
2020-03-27 13:59:38 -07:00
import PropTypes from 'prop-types';
import React from 'react';
2020-03-27 13:59:38 -07:00
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { fetchAccount, fetchAccountByUsername } from 'soapbox/actions/accounts';
import { fetchFavouritedStatuses, expandFavouritedStatuses, fetchAccountFavouritedStatuses, expandAccountFavouritedStatuses } from 'soapbox/actions/favourites';
2020-05-28 15:52:07 -07:00
import MissingIndicator from 'soapbox/components/missing_indicator';
import StatusList from 'soapbox/components/status_list';
2022-03-21 11:09:01 -07:00
import { Spinner } from 'soapbox/components/ui';
2022-01-10 14:01:24 -08:00
import { findAccountByUsername } from 'soapbox/selectors';
import { getFeatures } from 'soapbox/utils/features';
import Column from '../ui/components/column';
2020-03-27 13:59:38 -07:00
const messages = defineMessages({
heading: { id: 'column.favourited_statuses', defaultMessage: 'Liked posts' },
});
const mapStateToProps = (state, { params }) => {
const username = params.username || '';
2020-04-17 15:14:04 -07:00
const me = state.get('me');
const meUsername = state.getIn(['accounts', me, 'username'], '');
const isMyAccount = (username.toLowerCase() === meUsername.toLowerCase());
const features = getFeatures(state.get('instance'));
if (isMyAccount) {
return {
isMyAccount,
statusIds: state.status_lists.get('favourites').items,
isLoading: state.status_lists.get('favourites').isLoading,
hasMore: !!state.status_lists.get('favourites').next,
};
}
2021-11-15 19:31:17 -08:00
const accountFetchError = ((state.getIn(['accounts', -1, 'username']) || '').toLowerCase() === username.toLowerCase());
let accountId = -1;
if (accountFetchError) {
accountId = null;
} else {
const account = findAccountByUsername(state, username);
accountId = account ? account.getIn(['id'], null) : -1;
}
const isBlocked = state.getIn(['relationships', accountId, 'blocked_by'], false);
const unavailable = (me === accountId) ? false : (isBlocked && !features.blockersVisible);
2020-03-27 13:59:38 -07:00
return {
isMyAccount,
accountId,
unavailable,
username,
isAccount: !!state.getIn(['accounts', accountId]),
statusIds: state.status_lists.get(`favourites:${accountId}`)?.items || [],
isLoading: state.status_lists.get(`favourites:${accountId}`)?.isLoading,
hasMore: !!state.status_lists.get(`favourites:${accountId}`)?.next,
2020-03-27 13:59:38 -07:00
};
};
export default @connect(mapStateToProps)
@injectIntl
class Favourites extends ImmutablePureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
statusIds: ImmutablePropTypes.orderedSet.isRequired,
2020-03-27 13:59:38 -07:00
intl: PropTypes.object.isRequired,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
isMyAccount: PropTypes.bool.isRequired,
};
componentDidMount() {
const { accountId, isMyAccount, username } = this.props;
if (isMyAccount)
this.props.dispatch(fetchFavouritedStatuses());
else {
if (accountId && accountId !== -1) {
this.props.dispatch(fetchAccount(accountId));
this.props.dispatch(fetchAccountFavouritedStatuses(accountId));
} else {
this.props.dispatch(fetchAccountByUsername(username));
}
}
}
componentDidUpdate(prevProps) {
const { accountId, isMyAccount } = this.props;
if (!isMyAccount && accountId && accountId !== -1 && (accountId !== prevProps.accountId && accountId)) {
this.props.dispatch(fetchAccount(accountId));
this.props.dispatch(fetchAccountFavouritedStatuses(accountId));
}
2020-03-27 13:59:38 -07:00
}
handleLoadMore = debounce(() => {
const { accountId, isMyAccount } = this.props;
if (isMyAccount) {
this.props.dispatch(expandFavouritedStatuses());
} else {
this.props.dispatch(expandAccountFavouritedStatuses(accountId));
}
2020-03-27 13:59:38 -07:00
}, 300, { leading: true })
render() {
const { intl, statusIds, isLoading, hasMore, isMyAccount, isAccount, accountId, unavailable } = this.props;
2020-03-27 13:59:38 -07:00
if (!isMyAccount && !isAccount && accountId !== -1) {
2020-03-27 13:59:38 -07:00
return (
2022-03-21 11:09:01 -07:00
<MissingIndicator />
2020-03-27 13:59:38 -07:00
);
}
if (accountId === -1) {
return (
<Column>
2022-03-21 11:09:01 -07:00
<Spinner />
</Column>
);
}
if (unavailable) {
return (
<Column>
<div className='empty-column-indicator'>
<FormattedMessage id='empty_column.account_unavailable' defaultMessage='Profile unavailable' />
</div>
</Column>
);
}
const emptyMessage = isMyAccount
? <FormattedMessage id='empty_column.favourited_statuses' defaultMessage="You don't have any liked posts yet. When you like one, it will show up here." />
: <FormattedMessage id='empty_column.account_favourited_statuses' defaultMessage="This user doesn't have any liked posts yet." />;
2020-03-27 13:59:38 -07:00
return (
2022-03-21 11:09:01 -07:00
<Column label={intl.formatMessage(messages.heading)} withHeader={false} transparent>
2020-03-27 13:59:38 -07:00
<StatusList
statusIds={statusIds}
scrollKey='favourited_statuses'
hasMore={hasMore}
isLoading={typeof isLoading === 'boolean' ? isLoading : true}
2020-03-27 13:59:38 -07:00
onLoadMore={this.handleLoadMore}
emptyMessage={emptyMessage}
/>
</Column>
);
}
}