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.

165 lines
3.7 KiB

  1. /*
  2. `<StatusPrepend>`
  3. =================
  4. Originally a part of `<Status>`, but extracted into a separate
  5. component for better documentation and maintainance by
  6. @kibi@glitch.social as a part of glitch-soc/mastodon.
  7. */
  8. /* * * * */
  9. /*
  10. Imports:
  11. --------
  12. */
  13. // Package imports //
  14. import React from 'react';
  15. import PropTypes from 'prop-types';
  16. import ImmutablePropTypes from 'react-immutable-proptypes';
  17. import escapeTextContentForBrowser from 'escape-html';
  18. import { FormattedMessage } from 'react-intl';
  19. // Mastodon imports //
  20. import emojify from '../../../mastodon/emoji';
  21. /* * * * */
  22. /*
  23. The `<StatusPrepend>` component:
  24. --------------------------------
  25. The `<StatusPrepend>` component holds a status's prepend, ie the text
  26. that says X reblogged this, etc. It is represented by an `<aside>`
  27. element.
  28. ### Props
  29. - __`type` (`PropTypes.string`) :__
  30. The type of prepend. One of `'reblogged_by'`, `'reblog'`,
  31. `'favourite'`.
  32. - __`account` (`ImmutablePropTypes.map`) :__
  33. The account associated with the prepend.
  34. - __`parseClick` (`PropTypes.func.isRequired`) :__
  35. Our click parsing function.
  36. */
  37. export default class StatusPrepend extends React.PureComponent {
  38. static propTypes = {
  39. type: PropTypes.string.isRequired,
  40. account: ImmutablePropTypes.map.isRequired,
  41. parseClick: PropTypes.func.isRequired,
  42. notificationId: PropTypes.number,
  43. };
  44. /*
  45. ### Implementation
  46. #### `handleClick()`.
  47. This is just a small wrapper for `parseClick()` that gets fired when
  48. an account link is clicked.
  49. */
  50. handleClick = (e) => {
  51. const { account, parseClick } = this.props;
  52. parseClick(e, `/accounts/${+account.get('id')}`);
  53. }
  54. /*
  55. #### `<Message>`.
  56. `<Message>` is a quick functional React component which renders the
  57. actual prepend message based on our provided `type`. First we create a
  58. `link` for the account's name, and then use `<FormattedMessage>` to
  59. generate the message.
  60. */
  61. Message = () => {
  62. const { type, account } = this.props;
  63. let link = (
  64. <a
  65. onClick={this.handleClick}
  66. href={account.get('url')}
  67. className='status__display-name'
  68. >
  69. <b
  70. dangerouslySetInnerHTML={{
  71. __html : emojify(escapeTextContentForBrowser(
  72. account.get('display_name') || account.get('username')
  73. )),
  74. }}
  75. />
  76. </a>
  77. );
  78. switch (type) {
  79. case 'reblogged_by':
  80. return (
  81. <FormattedMessage
  82. id='status.reblogged_by'
  83. defaultMessage='{name} boosted'
  84. values={{ name : link }}
  85. />
  86. );
  87. case 'favourite':
  88. return (
  89. <FormattedMessage
  90. id='notification.favourite'
  91. defaultMessage='{name} favourited your status'
  92. values={{ name : link }}
  93. />
  94. );
  95. case 'reblog':
  96. return (
  97. <FormattedMessage
  98. id='notification.reblog'
  99. defaultMessage='{name} boosted your status'
  100. values={{ name : link }}
  101. />
  102. );
  103. }
  104. return null;
  105. }
  106. /*
  107. #### `render()`.
  108. Our `render()` is incredibly simple; we just render the icon and then
  109. the `<Message>` inside of an <aside>.
  110. */
  111. render () {
  112. const { Message } = this;
  113. const { type } = this.props;
  114. return !type ? null : (
  115. <aside className={type === 'reblogged_by' ? 'status__prepend' : 'notification__message'}>
  116. <div className={type === 'reblogged_by' ? 'status__prepend-icon-wrapper' : 'notification__favourite-icon-wrapper'}>
  117. <i
  118. className={`fa fa-fw fa-${
  119. type === 'favourite' ? 'star star-icon' : 'retweet'
  120. } status__prepend-icon`}
  121. />
  122. </div>
  123. <Message />
  124. </aside>
  125. );
  126. }
  127. }