DiscussionPost.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import React, { useState } from 'react';
  2. import { Button, Icon } from 'semantic-ui-react';
  3. import { ParsedPost } from '@polkadot/joy-utils/types/proposals';
  4. import MemberProfilePreview from '@polkadot/joy-utils/MemberProfilePreview';
  5. import DiscussionPostForm from './DiscussionPostForm';
  6. import { MemberId } from '@joystream/types/members';
  7. import { useTransport } from '@polkadot/joy-utils/react/hooks';
  8. import styled from 'styled-components';
  9. import ReactMarkdown from 'react-markdown';
  10. const StyledComment = styled.div`
  11. display: flex;
  12. margin-bottom: 1rem;
  13. flex-direction: column;
  14. `;
  15. const AuthorAndDate = styled.div`
  16. display: flex;
  17. justify-content: space-between;
  18. width: 100%;
  19. @media screen and (max-width: 767px) {
  20. flex-direction: column;
  21. }
  22. `;
  23. const Author = styled.div`
  24. margin-bottom: 0.5rem;
  25. `;
  26. const CreationDate = styled.div`
  27. color: rgba(0,0,0,.4);
  28. `;
  29. const ContentAndActions = styled.div`
  30. display: flex;
  31. flex-grow: 1;
  32. `;
  33. const CommentContent = styled.div`
  34. flex-grow: 1;
  35. padding: 0.5rem;
  36. padding-left: 1rem;
  37. `;
  38. const CommentActions = styled.div`
  39. `;
  40. const CommentAction = styled(Button)`
  41. `;
  42. type ProposalDiscussionPostProps = {
  43. post: ParsedPost;
  44. memberId?: MemberId;
  45. refreshDiscussion: () => void;
  46. }
  47. export default function DiscussionPost ({
  48. post,
  49. memberId,
  50. refreshDiscussion
  51. }: ProposalDiscussionPostProps) {
  52. const { author, authorId, text, createdAt, editsCount } = post;
  53. const [editing, setEditing] = useState(false);
  54. const constraints = useTransport().proposals.discussionContraints();
  55. const canEdit = (
  56. memberId &&
  57. post.postId &&
  58. authorId.toNumber() === memberId.toNumber() &&
  59. editsCount < constraints.maxPostEdits
  60. );
  61. const onEditSuccess = () => {
  62. setEditing(false);
  63. refreshDiscussion();
  64. };
  65. return (
  66. (memberId && editing) ? (
  67. <DiscussionPostForm
  68. memberId={memberId}
  69. threadId={post.threadId}
  70. post={post}
  71. onSuccess={onEditSuccess}
  72. constraints={constraints}/>
  73. ) : (
  74. <StyledComment>
  75. <AuthorAndDate>
  76. { author && (
  77. <Author>
  78. <MemberProfilePreview
  79. avatar_uri={author.avatar_uri.toString()}
  80. handle={author.handle.toString()}
  81. root_account={author.root_account.toString()}/>
  82. </Author>
  83. ) }
  84. <CreationDate>
  85. <span>{ createdAt.toLocaleString() }</span>
  86. </CreationDate>
  87. </AuthorAndDate>
  88. <ContentAndActions>
  89. <CommentContent>
  90. <ReactMarkdown source={text} linkTarget='_blank' />
  91. </CommentContent>
  92. { canEdit && (
  93. <CommentActions>
  94. <CommentAction
  95. onClick={() => setEditing(true)}
  96. primary
  97. size="tiny"
  98. icon>
  99. <Icon name="pencil" />
  100. </CommentAction>
  101. </CommentActions>
  102. ) }
  103. </ContentAndActions>
  104. </StyledComment>
  105. )
  106. );
  107. }