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.

92 lines
2.4 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. import ImmutablePropTypes from 'react-immutable-proptypes';
  2. import PureRenderMixin from 'react-addons-pure-render-mixin';
  3. import emojify from '../emoji';
  4. const StatusContent = React.createClass({
  5. contextTypes: {
  6. router: React.PropTypes.object
  7. },
  8. propTypes: {
  9. status: ImmutablePropTypes.map.isRequired,
  10. onClick: React.PropTypes.func
  11. },
  12. mixins: [PureRenderMixin],
  13. componentDidMount () {
  14. const node = ReactDOM.findDOMNode(this);
  15. const links = node.querySelectorAll('a');
  16. for (var i = 0; i < links.length; ++i) {
  17. let link = links[i];
  18. let mention = this.props.status.get('mentions').find(item => link.href === item.get('url'));
  19. if (mention) {
  20. link.addEventListener('click', this.onMentionClick.bind(this, mention), false);
  21. } else if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) {
  22. link.addEventListener('click', this.onHashtagClick.bind(this, link.text), false);
  23. } else {
  24. link.setAttribute('target', '_blank');
  25. link.setAttribute('rel', 'noopener');
  26. }
  27. link.addEventListener('click', this.onNormalClick, false);
  28. }
  29. },
  30. onMentionClick (mention, e) {
  31. if (e.button === 0) {
  32. e.preventDefault();
  33. this.context.router.push(`/accounts/${mention.get('id')}`);
  34. }
  35. },
  36. onHashtagClick (hashtag, e) {
  37. hashtag = hashtag.replace(/^#/, '').toLowerCase();
  38. if (e.button === 0) {
  39. e.preventDefault();
  40. this.context.router.push(`/timelines/tag/${hashtag}`);
  41. }
  42. },
  43. onNormalClick (e) {
  44. e.stopPropagation();
  45. },
  46. handleMouseDown (e) {
  47. this.startXY = [e.clientX, e.clientY];
  48. },
  49. handleMouseUp (e) {
  50. const [ startX, startY ] = this.startXY;
  51. const [ deltaX, deltaY ] = [Math.abs(e.clientX - startX), Math.abs(e.clientY - startY)];
  52. if (deltaX + deltaY < 5) {
  53. this.props.onClick();
  54. }
  55. this.startXY = null;
  56. },
  57. render () {
  58. const { status } = this.props;
  59. const content = { __html: emojify(status.get('content')) };
  60. return (
  61. <div
  62. className='status__content'
  63. style={{ cursor: 'pointer' }}
  64. dangerouslySetInnerHTML={content}
  65. onMouseDown={this.handleMouseDown}
  66. onMouseUp={this.handleMouseUp}
  67. />
  68. );
  69. },
  70. });
  71. export default StatusContent;