Advertisement
Guest User

Bug Kant

a guest
Jan 21st, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React from 'react';
  2. import gql from 'graphql-tag';
  3. import { Mutation, ApolloConsumer, Query } from 'react-apollo';
  4. import Dropzone from 'react-dropzone';
  5. import mixpanel from 'mixpanel-browser';
  6. import classNames from 'classnames';
  7. import styled from 'react-emotion';
  8. import { withRouter } from 'react-router';
  9. import { uploadBox, uploadS3, hashFile } from '../../../services/uploadFile';
  10. import { TopicItem } from './TopicItem';
  11. import { FolderConsumer } from '../FolderConsumer';
  12. import Uploading from '../../Folder/StartTopic/Uploading/Uploading';
  13. import { Loading } from '../../../cmp/Loading';
  14. import TopicsDoubledOnBoarding from '../StartTopic/TopicsDoubledOnBoarding/TopicsDoubledOnBoarding';
  15. import { PlaceConsumer } from '../../../cmp/PlaceConsumer';
  16. import { HiddenInRecycleBin } from '../../../cmp/HiddenInRecycleBin';
  17. import { TopicChanger } from './TopicChanger';
  18. import keydown from 'react-keydown';
  19. import ADD_TOPIC from '../../../graphql/topic/mutations/addTopic';
  20. import * as ADD_TOPIC_UPLOAD_LOADING from '../../../graphql/topic/mutations/addTopicUploadLoading';
  21. import { Icon } from '@blueprintjs/core';
  22.  
  23. const CREATE_S3_PRESIGNED_URL = gql`
  24.   mutation createS3PreSigndedURL($name: String!) {
  25.     createS3PreSigndedURL(name: $name) {
  26.       id
  27.       preSignedURL
  28.     }
  29.   }
  30. `;
  31.  
  32. export const GET_FOLDER_ID = gql`
  33.   {
  34.     location @client {
  35.       folderId
  36.     }
  37.   }
  38. `;
  39.  
  40. export const GET_LOCATION = gql`
  41.   {
  42.     location @client {
  43.       folderId
  44.       isInRecycleBin
  45.     }
  46.   }
  47. `;
  48.  
  49. const GET_DROPZONE_STATE = gql`
  50.   {
  51.     activeDropZone @client {
  52.       activeDropZone
  53.     }
  54.   }
  55. `;
  56.  
  57. const Container = styled('div')`
  58.   overflow-x: hidden;
  59.   overflow-y: auto;
  60.   height: 100%;
  61.   margin-top: 25px;
  62. `;
  63.  
  64. const SubContainer = styled('div')`
  65.   overflow-x: hidden;
  66.   overflow-y: hidden;
  67. `;
  68.  
  69. const DropzoneContainer = styled('div')<{ isActiveDropZone: boolean }>`
  70.   height: 100%;
  71.   .file-dropzone {
  72.     display: flex;
  73.     flex-direction: column;
  74.     align-items: center;
  75.     justify-content: center;
  76.     color: $lightgrey;
  77.     position: relative;
  78.  
  79.     &:hover {
  80.       cursor: default;
  81.     }
  82.  
  83.     &.with-topic {
  84.       align-items: flex-start;
  85.       justify-content: flex-start;
  86.       display: flex;
  87.       z-index: 498;
  88.  
  89.       &.fullHeight {
  90.         flex: 1;
  91.         min-height: calc(100vh - 220px);
  92.         height: 100%;
  93.       }
  94.  
  95.       & .file-icon {
  96.         display: none;
  97.         margin-top: 100px;
  98.         align-content: center;
  99.         justify-content: center;
  100.       }
  101.     }
  102.  
  103.     &.empty {
  104.       overflow: hidden;
  105.     }
  106.  
  107.     &.active::before {
  108.       content: '';
  109.       background: '$lightcyan';
  110.       position: absolute;
  111.       top: 0;
  112.       left: 0;
  113.       width: 100%;
  114.       height: 100%;
  115.       z-index: 700;
  116.       display: ${props => (props.isActiveDropZone ? 'flex' : 'none')};
  117.     }
  118.  
  119.     &.active::after {
  120.       content: '+';
  121.       background: white;
  122.       color: ${props => (props.isActiveDropZone ? '$lightcyan' : 'white')};
  123.       text-align: center;
  124.       font-weight: bold;
  125.       line-height: 55px;
  126.       font-size: 60px;
  127.       position: absolute;
  128.       top: 50%;
  129.       left: 0;
  130.       right: 0;
  131.       margin: 0 auto;
  132.       width: 60px;
  133.       height: 60px;
  134.       z-index: 710;
  135.     }
  136.   }
  137. `;
  138.  
  139. const TopicItemBloc = styled('div')`
  140.   width: 100%;
  141.   max-height: 100%;
  142.   overflow: auto;
  143.   padding: 0 25px;
  144. `;
  145.  
  146. const MaskTopic = styled('div')`
  147.   flex: 1;
  148.   display: flex;
  149.   flex-direction: column;
  150.   height: 100%;
  151.   overflow: hidden;
  152.  
  153.   .upload-area {
  154.     width: 100%;
  155.     text-align: center;
  156.     padding: 20px 0;
  157.     color: $lightgrey;
  158.     font-family: 'robotoregular';
  159.     font-size: 13px;
  160.  
  161.     p {
  162.       margin: 10px 0;
  163.     }
  164.   }
  165. `;
  166.  
  167. const IconContainer = styled('div')`
  168.   text-align: center;
  169.   margin-bottom: 10px;
  170. `;
  171.  
  172. class TopicList extends React.Component {
  173.   constructor(props) {
  174.     super(props);
  175.     this.state = {
  176.       isTopicsDoubled: false,
  177.       duplicateFiles: [],
  178.       preview: false,
  179.     };
  180.     this.uploadNewFiles = this.uploadNewFiles.bind(this);
  181.     this.closeModalTopicDoubled = this.closeModalTopicDoubled.bind(this);
  182.     this.keepTopic = this.keepTopic.bind(this);
  183.     this.createTopicWithFile = this.createTopicWithFile.bind(this);
  184.     this.reactivateDropzone = this.reactivateDropzone.bind(this);
  185.   }
  186.  
  187.   componentDidMount() {
  188.     this.subscribe();
  189.   }
  190.  
  191.   componentWillUnmount() {
  192.     this.unsubscribe();
  193.   }
  194.  
  195.   subscribe() {
  196.     this.unsubscribeToNewTopic = this.props.subscribeToNewTopic();
  197.     this.unsubscribeToEditTopic = this.props.subscribeToEditTopic();
  198.     this.unsubscribeToDeleteDiscussion = this.props.subscribeToDeleteDiscussion();
  199.     this.unsubscribeToNewTopicParticipant = this.props.subscribeToNewTopicParticipant();
  200.     this.unsubscribeToRestoreDiscussion = this.props.subscribeToRestoreDiscussion();
  201.     this.unsubscribeToNewRestoreTopic = this.props.subscribeToNewRestoreTopic();
  202.   }
  203.  
  204.   unsubscribe() {
  205.     this.unsubscribeToNewTopic();
  206.     this.unsubscribeToEditTopic();
  207.     this.unsubscribeToDeleteDiscussion();
  208.     this.unsubscribeToNewTopicParticipant();
  209.     this.unsubscribeToRestoreDiscussion();
  210.     this.unsubscribeToNewRestoreTopic();
  211.   }
  212.  
  213.   reactivateDropzone(client) {
  214.     client.writeData({
  215.       data: {
  216.         activeDropZone: {
  217.           activeDropZone: true,
  218.           __typename: 'activeDropZone',
  219.         },
  220.       },
  221.     });
  222.   }
  223.  
  224.   uploadNewFiles(addDiscussion, files, folderId, addUploadTopicLoading, topics, place, client) {
  225.     this.setState({ onBoardingIsActive: false });
  226.     if (files.length > 0) {
  227.       if (addUploadTopicLoading) {
  228.         addUploadTopicLoading({
  229.           variables: {
  230.             action: 'add',
  231.             id: folderId,
  232.             progress: 0,
  233.             fileName: '',
  234.             filesToSendCount: files.length,
  235.             filesSentCount: 0,
  236.           },
  237.         });
  238.       }
  239.       for (let index = 0; index < files.length; index++) {
  240.         const singleFile = files[index];
  241.         const { name, size } = singleFile;
  242.         if (size < 2147483648) {
  243.           const exist = topics.find(element => name == element.title);
  244.           if (exist != undefined) {
  245.             this.setState({ isTopicsDoubled: true });
  246.             this.setState(prevState => {
  247.               let finaleResult = singleFile;
  248.               finaleResult.discussionId = exist.id;
  249.               return {
  250.                 duplicateFiles: [...prevState.duplicateFiles, finaleResult],
  251.               };
  252.             });
  253.             continue;
  254.           } else {
  255.             this.createTopicWithFile(
  256.               addDiscussion,
  257.               singleFile,
  258.               folderId,
  259.               addUploadTopicLoading,
  260.               null,
  261.               place,
  262.               client,
  263.             );
  264.           }
  265.         } else {
  266.           this.oneUploadFileIsCanceling(folderId, addUploadTopicLoading);
  267.           client.writeData({
  268.             data: {
  269.               snackBar: {
  270.                 open: true,
  271.                 message: 'The file max size you can upload is 2 Go.',
  272.                 __typename: 'SnackBar',
  273.               },
  274.             },
  275.           });
  276.         }
  277.       }
  278.     }
  279.   }
  280.  
  281.   keepTopic(index) {
  282.     if (index > -1) {
  283.       this.setState(prevState => ({
  284.         duplicateFiles: [
  285.           ...prevState.duplicateFiles.slice(0, index),
  286.           ...prevState.duplicateFiles.slice(index + 1),
  287.         ],
  288.       }));
  289.     }
  290.   }
  291.  
  292.   createTopicWithFile(
  293.     addDiscussion,
  294.     singleFile,
  295.     folderId,
  296.     addUploadTopicLoading,
  297.     index,
  298.     place,
  299.     client,
  300.   ) {
  301.     this.keepTopic(index);
  302.     const { name, size } = singleFile;
  303.     let hash;
  304.  
  305.     let generatedFileId;
  306.     const type =
  307.       singleFile.type && singleFile.type !== '' ? singleFile.type : 'application/octet-stream';
  308.     const { boxStorage, boxAccessToken } = place;
  309.     hashFile(singleFile)
  310.       .then(hashResult => {
  311.         hash = hashResult;
  312.         return client.mutate({
  313.           mutation: CREATE_S3_PRESIGNED_URL,
  314.           variables: {
  315.             name,
  316.           },
  317.         });
  318.       })
  319.  
  320.       .then(({ data }) => {
  321.         generatedFileId = data.createS3PreSigndedURL.id;
  322.         if (boxStorage && boxAccessToken) {
  323.           return uploadBox(
  324.             singleFile,
  325.             type,
  326.             'edit',
  327.             addUploadTopicLoading,
  328.             folderId,
  329.             name,
  330.             JSON.parse(boxAccessToken).accessToken,
  331.             place,
  332.             generatedFileId,
  333.           );
  334.         }
  335.         return uploadS3(singleFile, data.createS3PreSigndedURL.preSignedURL, type);
  336.       })
  337.       .then(({ data }) => {
  338.         this.uploadFileIsDone(folderId, addUploadTopicLoading);
  339.         this.addMixPanelTraking(name, 'file');
  340.         addDiscussion({
  341.           variables: {
  342.             fileName: name,
  343.             title: name,
  344.             discussionStartType: 'file',
  345.             folderId,
  346.             fileSize: size,
  347.             fileId: generatedFileId,
  348.             fileType: type,
  349.             boxFileId: boxStorage && data && data.entries.length ? data.entries[0].id : null,
  350.             checksum: hash,
  351.           },
  352.         });
  353.       })
  354.       .catch(() => {
  355.         this.oneUploadFileIsCanceling(folderId, addUploadTopicLoading);
  356.       });
  357.   }
  358.  
  359.   addMixPanelTraking(title: String, discussionStartType: String) {
  360.     mixpanel.track('Topic created ', {
  361.       type: 'new_topic',
  362.       title,
  363.       discussionStartType,
  364.     });
  365.   }
  366.   uploadFileIsDone(folderId, addUploadTopicLoading) {
  367.     if (folderId && addUploadTopicLoading) {
  368.       addUploadTopicLoading({
  369.         variables: {
  370.           action: 'increment',
  371.           id: folderId,
  372.         },
  373.       });
  374.     }
  375.   }
  376.  
  377.   oneUploadFileIsCanceling(folderId, addUploadTopicLoading) {
  378.     if (folderId && addUploadTopicLoading) {
  379.       addUploadTopicLoading({
  380.         variables: {
  381.           action: 'decrement',
  382.           id: folderId,
  383.         },
  384.       });
  385.     }
  386.   }
  387.  
  388.   closeModalTopicDoubled(folderId, addUploadTopicLoading) {
  389.     if (
  390.       folderId &&
  391.       addUploadTopicLoading &&
  392.       this.state.duplicateFiles &&
  393.       this.state.duplicateFiles.length > 0
  394.     ) {
  395.       addUploadTopicLoading({
  396.         variables: {
  397.           action: 'decrement',
  398.           decrementationValue: this.state.duplicateFiles.length,
  399.           id: folderId,
  400.         },
  401.       });
  402.     }
  403.     this.setState({
  404.       duplicateFiles: [],
  405.       isTopicsDoubled: false,
  406.     });
  407.   }
  408.  
  409.   @keydown('space')
  410.   togglePreview() {
  411.     if (this.state.preview) {
  412.       this.closePreview();
  413.     } else {
  414.       this.openPreview();
  415.     }
  416.   }
  417.  
  418.   openPreview() {
  419.     this.setState({ preview: true });
  420.   }
  421.   closePreview() {
  422.     this.setState({ preview: false });
  423.   }
  424.  
  425.   render() {
  426.     let isActiveDropZone;
  427.     let dropzoneRef;
  428.     if (!this.state.isTopicsDoubled && this.state.duplicateFiles.length > 0) {
  429.       this.setState({ isTopicsDoubled: true });
  430.     }
  431.     if (this.state.isTopicsDoubled && this.state.duplicateFiles.length == 0) {
  432.       this.setState({ isTopicsDoubled: false });
  433.     }
  434.  
  435.     return (
  436.       <Query query={GET_DROPZONE_STATE} fetchPolicy="cache-only">
  437.         {({ data }) => {
  438.           isActiveDropZone = data.activeDropZone.activeDropZone;
  439.           return (
  440.             <FolderConsumer>
  441.               {cache => {
  442.                 if (!cache || !Array.isArray(cache.topics)) {
  443.                   return null;
  444.                 }
  445.                 return (
  446.                   <ApolloConsumer>
  447.                     {client => {
  448.                       const state = client.readQuery({
  449.                         query: GET_LOCATION,
  450.                       });
  451.                       const folderId = state.location.folderId;
  452.                       const isInRecycleBin = state.location.isInRecycleBin;
  453.  
  454.                       return (
  455.                         <Container>
  456.                           <TopicChanger
  457.                             topicIds={cache.topics.map(topic => {
  458.                               return topic.id;
  459.                             })}
  460.                             {...this.props}
  461.                           />
  462.                           <Uploading />
  463.                           <SubContainer>
  464.                             <FolderConsumer>
  465.                               {cache => {
  466.                                 const topics = isInRecycleBin ? cache.removedTopics : cache.topics;
  467.                                 return (
  468.                                   <Mutation mutation={ADD_TOPIC}>
  469.                                     {addDiscussion => {
  470.                                       return (
  471.                                         <Mutation mutation={ADD_TOPIC_UPLOAD_LOADING}>
  472.                                           {(addUploadTopicLoading, { data, loading }) => {
  473.                                             if (loading) {
  474.                                               return <Loading />;
  475.                                             }
  476.                                             return (
  477.                                               <PlaceConsumer>
  478.                                                 {place => (
  479.                                                   <MaskTopic>
  480.                                                     <TopicsDoubledOnBoarding
  481.                                                       isShowing={this.state.isTopicsDoubled}
  482.                                                       duplicateFiles={this.state.duplicateFiles}
  483.                                                       closeModalTopicDoubled={() =>
  484.                                                         this.closeModalTopicDoubled(
  485.                                                           folderId,
  486.                                                           addUploadTopicLoading,
  487.                                                         )
  488.                                                       }
  489.                                                       oneUploadFileIsCanceling={() =>
  490.                                                         this.oneUploadFileIsCanceling(
  491.                                                           folderId,
  492.                                                           addUploadTopicLoading,
  493.                                                         )
  494.                                                       }
  495.                                                       uploadFileIsDone={() =>
  496.                                                         this.uploadFileIsDone(
  497.                                                           folderId,
  498.                                                           addUploadTopicLoading,
  499.                                                         )
  500.                                                       }
  501.                                                       keepTopic={i => this.keepTopic(i)}
  502.                                                       createNewTopic={(file, index) => {
  503.                                                         this.createTopicWithFile(
  504.                                                           addDiscussion,
  505.                                                           file,
  506.                                                           folderId,
  507.                                                           addUploadTopicLoading,
  508.                                                           index,
  509.                                                           place,
  510.                                                           client,
  511.                                                         );
  512.                                                       }}
  513.                                                     />
  514.                                                     <DropzoneContainer
  515.                                                       isActiveDropZone={isActiveDropZone}
  516.                                                     >
  517.                                                       <Dropzone
  518.                                                         disableClick={true}
  519.                                                         disablePreview={true}
  520.                                                         onDrop={files => {
  521.                                                           if (
  522.                                                             files &&
  523.                                                             folderId &&
  524.                                                             isActiveDropZone === true
  525.                                                           ) {
  526.                                                             this.uploadNewFiles(
  527.                                                               addDiscussion,
  528.                                                               files,
  529.                                                               folderId,
  530.                                                               addUploadTopicLoading,
  531.                                                               topics,
  532.                                                               place,
  533.                                                               client,
  534.                                                             );
  535.                                                           } else {
  536.                                                             this.reactivateDropzone(client);
  537.                                                           }
  538.                                                         }}
  539.                                                         className={classNames(
  540.                                                           'file-dropzone with-topic',
  541.                                                           {
  542.                                                             fullHeight:
  543.                                                               cache.topics &&
  544.                                                               cache.topics.length >= 0,
  545.                                                           },
  546.                                                           {
  547.                                                             displayUploadArea:
  548.                                                               cache.topics &&
  549.                                                               cache.topics.length >= 19,
  550.                                                           },
  551.                                                         )}
  552.                                                         activeClassName="active"
  553.                                                         disableClick
  554.                                                         ref={node => {
  555.                                                           dropzoneRef = node;
  556.                                                         }}
  557.                                                       >
  558.                                                         <TopicItemBloc>
  559.                                                           {topics.map((e, i) => {
  560.                                                             return (
  561.                                                               <TopicItem
  562.                                                                 key={i}
  563.                                                                 topic={e}
  564.                                                                 currentTopic={
  565.                                                                   this.props.match.params
  566.                                                                     .discussion === e.id
  567.                                                                 }
  568.                                                                 preview={this.state.preview}
  569.                                                                 onPreviewClose={this.closePreview.bind(
  570.                                                                   this,
  571.                                                                 )}
  572.                                                                 onPreviewOpen={this.openPreview.bind(
  573.                                                                   this,
  574.                                                                 )}
  575.                                                               />
  576.                                                             );
  577.                                                           })}
  578.                                                         </TopicItemBloc>
  579.                                                         <HiddenInRecycleBin>
  580.                                                           <div className="file-dropzone empty">
  581.                                                             <React.Fragment>
  582.                                                               <IconContainer>
  583.                                                                 <Icon icon="import" />
  584.                                                               </IconContainer>
  585.                                                               <p>Drag‘n drop files</p>
  586.                                                             </React.Fragment>
  587.                                                           </div>
  588.                                                         </HiddenInRecycleBin>
  589.                                                       </Dropzone>
  590.                                                     </DropzoneContainer>
  591.                                                   </MaskTopic>
  592.                                                 )}
  593.                                               </PlaceConsumer>
  594.                                             );
  595.                                           }}
  596.                                         </Mutation>
  597.                                       );
  598.                                     }}
  599.                                   </Mutation>
  600.                                 );
  601.                               }}
  602.                             </FolderConsumer>
  603.                           </SubContainer>
  604.                         </Container>
  605.                       );
  606.                     }}
  607.                   </ApolloConsumer>
  608.                 );
  609.               }}
  610.             </FolderConsumer>
  611.           );
  612.         }}
  613.       </Query>
  614.     );
  615.   }
  616. }
  617.  
  618. export default withRouter(TopicList);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement