PageAttachment.jsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /* eslint-disable react/no-access-state-in-setstate */
  2. import React from 'react';
  3. import PropTypes from 'prop-types';
  4. import PageAttachmentList from './PageAttachment/PageAttachmentList';
  5. import DeleteAttachmentModal from './PageAttachment/DeleteAttachmentModal';
  6. import { createSubscribedElement } from './UnstatedUtils';
  7. import AppContainer from '../services/AppContainer';
  8. import PageContainer from '../services/PageContainer';
  9. class PageAttachment extends React.Component {
  10. constructor(props) {
  11. super(props);
  12. this.state = {
  13. attachments: [],
  14. inUse: {},
  15. attachmentToDelete: null,
  16. deleting: false,
  17. deleteError: '',
  18. };
  19. this.onAttachmentDeleteClicked = this.onAttachmentDeleteClicked.bind(this);
  20. this.onAttachmentDeleteClickedConfirm = this.onAttachmentDeleteClickedConfirm.bind(this);
  21. }
  22. componentDidMount() {
  23. const { pageId } = this.props.pageContainer.state;
  24. if (!pageId) {
  25. return;
  26. }
  27. this.props.appContainer.apiGet('/attachments.list', { page_id: pageId })
  28. .then((res) => {
  29. const attachments = res.attachments;
  30. const inUse = {};
  31. for (const attachment of attachments) {
  32. inUse[attachment._id] = this.checkIfFileInUse(attachment);
  33. }
  34. this.setState({
  35. attachments,
  36. inUse,
  37. });
  38. });
  39. }
  40. checkIfFileInUse(attachment) {
  41. const { markdown } = this.props.pageContainer.state;
  42. if (markdown.match(attachment.filePathProxied)) {
  43. return true;
  44. }
  45. return false;
  46. }
  47. onAttachmentDeleteClicked(attachment) {
  48. this.setState({
  49. attachmentToDelete: attachment,
  50. });
  51. }
  52. onAttachmentDeleteClickedConfirm(attachment) {
  53. const attachmentId = attachment._id;
  54. this.setState({
  55. deleting: true,
  56. });
  57. this.props.appContainer.apiPost('/attachments.remove', { attachment_id: attachmentId })
  58. .then((res) => {
  59. this.setState({
  60. attachments: this.state.attachments.filter((at) => {
  61. // comparing ObjectId
  62. // eslint-disable-next-line eqeqeq
  63. return at._id != attachmentId;
  64. }),
  65. attachmentToDelete: null,
  66. deleting: false,
  67. });
  68. }).catch((err) => {
  69. this.setState({
  70. deleteError: 'Something went wrong.',
  71. deleting: false,
  72. });
  73. });
  74. }
  75. isUserLoggedIn() {
  76. return this.props.appContainer.me != null;
  77. }
  78. render() {
  79. let deleteAttachmentModal = '';
  80. if (this.isUserLoggedIn()) {
  81. const attachmentToDelete = this.state.attachmentToDelete;
  82. const deleteModalClose = () => {
  83. this.setState({ attachmentToDelete: null, deleteError: '' });
  84. };
  85. const showModal = attachmentToDelete !== null;
  86. let deleteInUse = null;
  87. if (attachmentToDelete !== null) {
  88. deleteInUse = this.state.inUse[attachmentToDelete._id] || false;
  89. }
  90. deleteAttachmentModal = (
  91. <DeleteAttachmentModal
  92. show={showModal}
  93. animation={false}
  94. onHide={deleteModalClose}
  95. attachmentToDelete={attachmentToDelete}
  96. inUse={deleteInUse}
  97. deleting={this.state.deleting}
  98. deleteError={this.state.deleteError}
  99. onAttachmentDeleteClickedConfirm={this.onAttachmentDeleteClickedConfirm}
  100. />
  101. );
  102. }
  103. return (
  104. <div>
  105. <PageAttachmentList
  106. attachments={this.state.attachments}
  107. inUse={this.state.inUse}
  108. onAttachmentDeleteClicked={this.onAttachmentDeleteClicked}
  109. isUserLoggedIn={this.isUserLoggedIn()}
  110. />
  111. {deleteAttachmentModal}
  112. </div>
  113. );
  114. }
  115. }
  116. /**
  117. * Wrapper component for using unstated
  118. */
  119. const PageAttachmentWrapper = (props) => {
  120. return createSubscribedElement(PageAttachment, props, [AppContainer, PageContainer]);
  121. };
  122. PageAttachment.propTypes = {
  123. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  124. pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
  125. };
  126. export default PageAttachmentWrapper;