You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
2.7 KiB

  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import ImmutablePropTypes from 'react-immutable-proptypes';
  4. import ImmutablePureComponent from 'react-immutable-pure-component';
  5. import { connect } from 'react-redux';
  6. import { makeGetAccount } from 'mastodon/selectors';
  7. import Avatar from 'mastodon/components/avatar';
  8. import DisplayName from 'mastodon/components/display_name';
  9. import { Link } from 'react-router-dom';
  10. import IconButton from 'mastodon/components/icon_button';
  11. import { injectIntl, defineMessages } from 'react-intl';
  12. import { followAccount, unfollowAccount } from 'mastodon/actions/accounts';
  13. const messages = defineMessages({
  14. follow: { id: 'account.follow', defaultMessage: 'Follow' },
  15. unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
  16. });
  17. const makeMapStateToProps = () => {
  18. const getAccount = makeGetAccount();
  19. const mapStateToProps = (state, props) => ({
  20. account: getAccount(state, props.id),
  21. });
  22. return mapStateToProps;
  23. };
  24. const getFirstSentence = str => {
  25. const arr = str.split(/(([.?!]+\s)|[.。?!\n•])/);
  26. return arr[0];
  27. };
  28. class Account extends ImmutablePureComponent {
  29. static propTypes = {
  30. account: ImmutablePropTypes.map.isRequired,
  31. intl: PropTypes.object.isRequired,
  32. dispatch: PropTypes.func.isRequired,
  33. };
  34. handleFollow = () => {
  35. const { account, dispatch } = this.props;
  36. if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
  37. dispatch(unfollowAccount(account.get('id')));
  38. } else {
  39. dispatch(followAccount(account.get('id')));
  40. }
  41. };
  42. render () {
  43. const { account, intl } = this.props;
  44. let button;
  45. if (account.getIn(['relationship', 'following'])) {
  46. button = <IconButton icon='check' title={intl.formatMessage(messages.unfollow)} active onClick={this.handleFollow} />;
  47. } else {
  48. button = <IconButton icon='plus' title={intl.formatMessage(messages.follow)} onClick={this.handleFollow} />;
  49. }
  50. return (
  51. <div className='account follow-recommendations-account'>
  52. <div className='account__wrapper'>
  53. <Link className='account__display-name account__display-name--with-note' title={account.get('acct')} to={`/@${account.get('acct')}`}>
  54. <div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
  55. <DisplayName account={account} />
  56. <div className='account__note'>{getFirstSentence(account.get('note_plain'))}</div>
  57. </Link>
  58. <div className='account__relationship'>
  59. {button}
  60. </div>
  61. </div>
  62. </div>
  63. );
  64. }
  65. }
  66. export default connect(makeMapStateToProps)(injectIntl(Account));