Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React from 'react';
- import gql from 'graphql-tag';
- import { Mutation, ApolloConsumer, Query } from 'react-apollo';
- import Dropzone from 'react-dropzone';
- import mixpanel from 'mixpanel-browser';
- import classNames from 'classnames';
- import styled from 'react-emotion';
- import { withRouter } from 'react-router';
- import { uploadBox, uploadS3, hashFile } from '../../../services/uploadFile';
- import { TopicItem } from './TopicItem';
- import { FolderConsumer } from '../FolderConsumer';
- import Uploading from '../../Folder/StartTopic/Uploading/Uploading';
- import { Loading } from '../../../cmp/Loading';
- import TopicsDoubledOnBoarding from '../StartTopic/TopicsDoubledOnBoarding/TopicsDoubledOnBoarding';
- import { PlaceConsumer } from '../../../cmp/PlaceConsumer';
- import { HiddenInRecycleBin } from '../../../cmp/HiddenInRecycleBin';
- import { TopicChanger } from './TopicChanger';
- import keydown from 'react-keydown';
- import ADD_TOPIC from '../../../graphql/topic/mutations/addTopic';
- import * as ADD_TOPIC_UPLOAD_LOADING from '../../../graphql/topic/mutations/addTopicUploadLoading';
- import { Icon } from '@blueprintjs/core';
- const CREATE_S3_PRESIGNED_URL = gql`
- mutation createS3PreSigndedURL($name: String!) {
- createS3PreSigndedURL(name: $name) {
- id
- preSignedURL
- }
- }
- `;
- export const GET_FOLDER_ID = gql`
- {
- location @client {
- folderId
- }
- }
- `;
- export const GET_LOCATION = gql`
- {
- location @client {
- folderId
- isInRecycleBin
- }
- }
- `;
- const GET_DROPZONE_STATE = gql`
- {
- activeDropZone @client {
- activeDropZone
- }
- }
- `;
- const Container = styled('div')`
- overflow-x: hidden;
- overflow-y: auto;
- height: 100%;
- margin-top: 25px;
- `;
- const SubContainer = styled('div')`
- overflow-x: hidden;
- overflow-y: hidden;
- `;
- const DropzoneContainer = styled('div')<{ isActiveDropZone: boolean }>`
- height: 100%;
- .file-dropzone {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- color: $lightgrey;
- position: relative;
- &:hover {
- cursor: default;
- }
- &.with-topic {
- align-items: flex-start;
- justify-content: flex-start;
- display: flex;
- z-index: 498;
- &.fullHeight {
- flex: 1;
- min-height: calc(100vh - 220px);
- height: 100%;
- }
- & .file-icon {
- display: none;
- margin-top: 100px;
- align-content: center;
- justify-content: center;
- }
- }
- &.empty {
- overflow: hidden;
- }
- &.active::before {
- content: '';
- background: '$lightcyan';
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- z-index: 700;
- display: ${props => (props.isActiveDropZone ? 'flex' : 'none')};
- }
- &.active::after {
- content: '+';
- background: white;
- color: ${props => (props.isActiveDropZone ? '$lightcyan' : 'white')};
- text-align: center;
- font-weight: bold;
- line-height: 55px;
- font-size: 60px;
- position: absolute;
- top: 50%;
- left: 0;
- right: 0;
- margin: 0 auto;
- width: 60px;
- height: 60px;
- z-index: 710;
- }
- }
- `;
- const TopicItemBloc = styled('div')`
- width: 100%;
- max-height: 100%;
- overflow: auto;
- padding: 0 25px;
- `;
- const MaskTopic = styled('div')`
- flex: 1;
- display: flex;
- flex-direction: column;
- height: 100%;
- overflow: hidden;
- .upload-area {
- width: 100%;
- text-align: center;
- padding: 20px 0;
- color: $lightgrey;
- font-family: 'robotoregular';
- font-size: 13px;
- p {
- margin: 10px 0;
- }
- }
- `;
- const IconContainer = styled('div')`
- text-align: center;
- margin-bottom: 10px;
- `;
- class TopicList extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- isTopicsDoubled: false,
- duplicateFiles: [],
- preview: false,
- };
- this.uploadNewFiles = this.uploadNewFiles.bind(this);
- this.closeModalTopicDoubled = this.closeModalTopicDoubled.bind(this);
- this.keepTopic = this.keepTopic.bind(this);
- this.createTopicWithFile = this.createTopicWithFile.bind(this);
- this.reactivateDropzone = this.reactivateDropzone.bind(this);
- }
- componentDidMount() {
- this.subscribe();
- }
- componentWillUnmount() {
- this.unsubscribe();
- }
- subscribe() {
- this.unsubscribeToNewTopic = this.props.subscribeToNewTopic();
- this.unsubscribeToEditTopic = this.props.subscribeToEditTopic();
- this.unsubscribeToDeleteDiscussion = this.props.subscribeToDeleteDiscussion();
- this.unsubscribeToNewTopicParticipant = this.props.subscribeToNewTopicParticipant();
- this.unsubscribeToRestoreDiscussion = this.props.subscribeToRestoreDiscussion();
- this.unsubscribeToNewRestoreTopic = this.props.subscribeToNewRestoreTopic();
- }
- unsubscribe() {
- this.unsubscribeToNewTopic();
- this.unsubscribeToEditTopic();
- this.unsubscribeToDeleteDiscussion();
- this.unsubscribeToNewTopicParticipant();
- this.unsubscribeToRestoreDiscussion();
- this.unsubscribeToNewRestoreTopic();
- }
- reactivateDropzone(client) {
- client.writeData({
- data: {
- activeDropZone: {
- activeDropZone: true,
- __typename: 'activeDropZone',
- },
- },
- });
- }
- uploadNewFiles(addDiscussion, files, folderId, addUploadTopicLoading, topics, place, client) {
- this.setState({ onBoardingIsActive: false });
- if (files.length > 0) {
- if (addUploadTopicLoading) {
- addUploadTopicLoading({
- variables: {
- action: 'add',
- id: folderId,
- progress: 0,
- fileName: '',
- filesToSendCount: files.length,
- filesSentCount: 0,
- },
- });
- }
- for (let index = 0; index < files.length; index++) {
- const singleFile = files[index];
- const { name, size } = singleFile;
- if (size < 2147483648) {
- const exist = topics.find(element => name == element.title);
- if (exist != undefined) {
- this.setState({ isTopicsDoubled: true });
- this.setState(prevState => {
- let finaleResult = singleFile;
- finaleResult.discussionId = exist.id;
- return {
- duplicateFiles: [...prevState.duplicateFiles, finaleResult],
- };
- });
- continue;
- } else {
- this.createTopicWithFile(
- addDiscussion,
- singleFile,
- folderId,
- addUploadTopicLoading,
- null,
- place,
- client,
- );
- }
- } else {
- this.oneUploadFileIsCanceling(folderId, addUploadTopicLoading);
- client.writeData({
- data: {
- snackBar: {
- open: true,
- message: 'The file max size you can upload is 2 Go.',
- __typename: 'SnackBar',
- },
- },
- });
- }
- }
- }
- }
- keepTopic(index) {
- if (index > -1) {
- this.setState(prevState => ({
- duplicateFiles: [
- ...prevState.duplicateFiles.slice(0, index),
- ...prevState.duplicateFiles.slice(index + 1),
- ],
- }));
- }
- }
- createTopicWithFile(
- addDiscussion,
- singleFile,
- folderId,
- addUploadTopicLoading,
- index,
- place,
- client,
- ) {
- this.keepTopic(index);
- const { name, size } = singleFile;
- let hash;
- let generatedFileId;
- const type =
- singleFile.type && singleFile.type !== '' ? singleFile.type : 'application/octet-stream';
- const { boxStorage, boxAccessToken } = place;
- hashFile(singleFile)
- .then(hashResult => {
- hash = hashResult;
- return client.mutate({
- mutation: CREATE_S3_PRESIGNED_URL,
- variables: {
- name,
- },
- });
- })
- .then(({ data }) => {
- generatedFileId = data.createS3PreSigndedURL.id;
- if (boxStorage && boxAccessToken) {
- return uploadBox(
- singleFile,
- type,
- 'edit',
- addUploadTopicLoading,
- folderId,
- name,
- JSON.parse(boxAccessToken).accessToken,
- place,
- generatedFileId,
- );
- }
- return uploadS3(singleFile, data.createS3PreSigndedURL.preSignedURL, type);
- })
- .then(({ data }) => {
- this.uploadFileIsDone(folderId, addUploadTopicLoading);
- this.addMixPanelTraking(name, 'file');
- addDiscussion({
- variables: {
- fileName: name,
- title: name,
- discussionStartType: 'file',
- folderId,
- fileSize: size,
- fileId: generatedFileId,
- fileType: type,
- boxFileId: boxStorage && data && data.entries.length ? data.entries[0].id : null,
- checksum: hash,
- },
- });
- })
- .catch(() => {
- this.oneUploadFileIsCanceling(folderId, addUploadTopicLoading);
- });
- }
- addMixPanelTraking(title: String, discussionStartType: String) {
- mixpanel.track('Topic created ', {
- type: 'new_topic',
- title,
- discussionStartType,
- });
- }
- uploadFileIsDone(folderId, addUploadTopicLoading) {
- if (folderId && addUploadTopicLoading) {
- addUploadTopicLoading({
- variables: {
- action: 'increment',
- id: folderId,
- },
- });
- }
- }
- oneUploadFileIsCanceling(folderId, addUploadTopicLoading) {
- if (folderId && addUploadTopicLoading) {
- addUploadTopicLoading({
- variables: {
- action: 'decrement',
- id: folderId,
- },
- });
- }
- }
- closeModalTopicDoubled(folderId, addUploadTopicLoading) {
- if (
- folderId &&
- addUploadTopicLoading &&
- this.state.duplicateFiles &&
- this.state.duplicateFiles.length > 0
- ) {
- addUploadTopicLoading({
- variables: {
- action: 'decrement',
- decrementationValue: this.state.duplicateFiles.length,
- id: folderId,
- },
- });
- }
- this.setState({
- duplicateFiles: [],
- isTopicsDoubled: false,
- });
- }
- @keydown('space')
- togglePreview() {
- if (this.state.preview) {
- this.closePreview();
- } else {
- this.openPreview();
- }
- }
- openPreview() {
- this.setState({ preview: true });
- }
- closePreview() {
- this.setState({ preview: false });
- }
- render() {
- let isActiveDropZone;
- let dropzoneRef;
- if (!this.state.isTopicsDoubled && this.state.duplicateFiles.length > 0) {
- this.setState({ isTopicsDoubled: true });
- }
- if (this.state.isTopicsDoubled && this.state.duplicateFiles.length == 0) {
- this.setState({ isTopicsDoubled: false });
- }
- return (
- <Query query={GET_DROPZONE_STATE} fetchPolicy="cache-only">
- {({ data }) => {
- isActiveDropZone = data.activeDropZone.activeDropZone;
- return (
- <FolderConsumer>
- {cache => {
- if (!cache || !Array.isArray(cache.topics)) {
- return null;
- }
- return (
- <ApolloConsumer>
- {client => {
- const state = client.readQuery({
- query: GET_LOCATION,
- });
- const folderId = state.location.folderId;
- const isInRecycleBin = state.location.isInRecycleBin;
- return (
- <Container>
- <TopicChanger
- topicIds={cache.topics.map(topic => {
- return topic.id;
- })}
- {...this.props}
- />
- <Uploading />
- <SubContainer>
- <FolderConsumer>
- {cache => {
- const topics = isInRecycleBin ? cache.removedTopics : cache.topics;
- return (
- <Mutation mutation={ADD_TOPIC}>
- {addDiscussion => {
- return (
- <Mutation mutation={ADD_TOPIC_UPLOAD_LOADING}>
- {(addUploadTopicLoading, { data, loading }) => {
- if (loading) {
- return <Loading />;
- }
- return (
- <PlaceConsumer>
- {place => (
- <MaskTopic>
- <TopicsDoubledOnBoarding
- isShowing={this.state.isTopicsDoubled}
- duplicateFiles={this.state.duplicateFiles}
- closeModalTopicDoubled={() =>
- this.closeModalTopicDoubled(
- folderId,
- addUploadTopicLoading,
- )
- }
- oneUploadFileIsCanceling={() =>
- this.oneUploadFileIsCanceling(
- folderId,
- addUploadTopicLoading,
- )
- }
- uploadFileIsDone={() =>
- this.uploadFileIsDone(
- folderId,
- addUploadTopicLoading,
- )
- }
- keepTopic={i => this.keepTopic(i)}
- createNewTopic={(file, index) => {
- this.createTopicWithFile(
- addDiscussion,
- file,
- folderId,
- addUploadTopicLoading,
- index,
- place,
- client,
- );
- }}
- />
- <DropzoneContainer
- isActiveDropZone={isActiveDropZone}
- >
- <Dropzone
- disableClick={true}
- disablePreview={true}
- onDrop={files => {
- if (
- files &&
- folderId &&
- isActiveDropZone === true
- ) {
- this.uploadNewFiles(
- addDiscussion,
- files,
- folderId,
- addUploadTopicLoading,
- topics,
- place,
- client,
- );
- } else {
- this.reactivateDropzone(client);
- }
- }}
- className={classNames(
- 'file-dropzone with-topic',
- {
- fullHeight:
- cache.topics &&
- cache.topics.length >= 0,
- },
- {
- displayUploadArea:
- cache.topics &&
- cache.topics.length >= 19,
- },
- )}
- activeClassName="active"
- disableClick
- ref={node => {
- dropzoneRef = node;
- }}
- >
- <TopicItemBloc>
- {topics.map((e, i) => {
- return (
- <TopicItem
- key={i}
- topic={e}
- currentTopic={
- this.props.match.params
- .discussion === e.id
- }
- preview={this.state.preview}
- onPreviewClose={this.closePreview.bind(
- this,
- )}
- onPreviewOpen={this.openPreview.bind(
- this,
- )}
- />
- );
- })}
- </TopicItemBloc>
- <HiddenInRecycleBin>
- <div className="file-dropzone empty">
- <React.Fragment>
- <IconContainer>
- <Icon icon="import" />
- </IconContainer>
- <p>Drag‘n drop files</p>
- </React.Fragment>
- </div>
- </HiddenInRecycleBin>
- </Dropzone>
- </DropzoneContainer>
- </MaskTopic>
- )}
- </PlaceConsumer>
- );
- }}
- </Mutation>
- );
- }}
- </Mutation>
- );
- }}
- </FolderConsumer>
- </SubContainer>
- </Container>
- );
- }}
- </ApolloConsumer>
- );
- }}
- </FolderConsumer>
- );
- }}
- </Query>
- );
- }
- }
- export default withRouter(TopicList);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement