react-dropzone#DropzoneOptions TypeScript Examples

The following examples show how to use react-dropzone#DropzoneOptions. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DropPad.tsx    From slippi-stats with MIT License 6 votes vote down vote up
DropPad: React.FC<Partial<DropzoneOptions>> = (props) => {
  const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject } = useDropzone(props);

  return (
    <Container {...getRootProps({ isDragActive, isDragAccept, isDragReject })}>
      <input {...getInputProps()} />
      <p>Drag SLP files here or click to select</p>
    </Container>
  );
}
Example #2
Source File: UploadStatus.tsx    From atlas with GNU General Public License v3.0 4 votes vote down vote up
UploadStatus: React.FC<UploadStatusProps> = ({ isLast = false, asset, size }) => {
  const navigate = useNavigate()
  const startFileUpload = useStartFileUpload()
  const uploadStatus = useUploadsStore((state) => state.uploadsStatus[asset.id])
  const { setUploadStatus } = useUploadsStore((state) => state.actions)

  const thumbnailDialogRef = useRef<ImageCropModalImperativeHandle>(null)
  const avatarDialogRef = useRef<ImageCropModalImperativeHandle>(null)
  const coverDialogRef = useRef<ImageCropModalImperativeHandle>(null)

  const [openDifferentFileDialog, closeDifferentFileDialog] = useConfirmationModal({
    title: 'Different file was selected!',
    description: `We detected that you selected a different file than the one you uploaded previously. Select the same file to continue the upload or edit ${
      asset.parentObject.type === 'channel' ? 'your channel' : 'the video'
    } to use the new file.`,
    iconType: 'warning',
    primaryButton: {
      text: 'Reselect file',
      onClick: () => {
        reselectFile()
        closeDifferentFileDialog()
      },
    },
    secondaryButton: {
      text: `Edit ${asset.parentObject.type === 'channel' ? 'channel' : 'video'}`,
      onClick: () => {
        if (asset.parentObject.type === 'video') {
          navigate(absoluteRoutes.studio.videoWorkspace())
        }
        if (asset.parentObject.type === 'channel') {
          navigate(absoluteRoutes.studio.editChannel())
        }
        closeDifferentFileDialog()
      },
    },
  })
  const [openMissingCropDataDialog, closeMissingCropDataDialog] = useConfirmationModal({
    title: 'Missing asset details',
    description:
      "It seems you've published this asset from a different device or you've cleared your browser history. All image assets require crop data to reconstruct, otherwise they end up being different files. Please try re-uploading from the original device or overwrite this asset.",
    iconType: 'warning',
    secondaryButton: {
      text: 'Close',
      onClick: () => {
        closeMissingCropDataDialog()
      },
    },
  })

  const onDrop: DropzoneOptions['onDrop'] = useCallback(
    async (acceptedFiles) => {
      const [file] = acceptedFiles
      setUploadStatus(asset.id, { lastStatus: 'inProgress', progress: 0 })
      const fileHash = await computeFileHash(file)
      if (fileHash !== asset.ipfsHash) {
        setUploadStatus(asset.id, { lastStatus: undefined })
        openDifferentFileDialog()
      } else {
        startFileUpload(
          file,
          {
            id: asset.id,
            owner: asset.owner,
            parentObject: {
              type: asset.parentObject.type,
              id: asset.parentObject.id,
            },
            type: asset.type,
          },
          {
            isReUpload: true,
          }
        )
      }
    },
    [asset, openDifferentFileDialog, setUploadStatus, startFileUpload]
  )

  const isVideo = asset.type === 'video'
  const {
    getRootProps,
    getInputProps,
    open: openFileSelect,
  } = useDropzone({
    onDrop,
    maxFiles: 1,
    multiple: false,
    noClick: true,
    noKeyboard: true,
    accept: isVideo ? 'video/*' : 'image/*',
  })

  const fileTypeText = isVideo ? 'Video file' : `${asset.type.charAt(0).toUpperCase() + asset.type.slice(1)} image`

  const handleChangeHost = () => {
    startFileUpload(
      null,
      {
        id: asset.id,
        owner: asset.owner,
        parentObject: {
          type: asset.parentObject.type,
          id: asset.parentObject.id,
        },
        type: asset.type,
      },
      {
        changeHost: true,
      }
    )
  }

  const handleCropConfirm = async (croppedBlob: Blob) => {
    const fileHash = await computeFileHash(croppedBlob)
    if (fileHash !== asset.ipfsHash) {
      openDifferentFileDialog()
    } else {
      startFileUpload(
        croppedBlob,
        {
          id: asset.id,
          owner: asset.owner,
          parentObject: {
            type: asset.parentObject.type,
            id: asset.parentObject.id,
          },
          type: asset.type,
        },
        {
          isReUpload: true,
        }
      )
    }
  }

  const assetDimension =
    asset.dimensions?.width && asset.dimensions.height
      ? `${Math.floor(asset.dimensions.width)}x${Math.floor(asset.dimensions.height)}`
      : ''
  const assetSize = formatBytes(Number(asset.size))

  const assetsDialogs = {
    avatar: avatarDialogRef,
    cover: coverDialogRef,
    thumbnail: thumbnailDialogRef,
  }
  const reselectFile = () => {
    if (asset.type === 'video') {
      openFileSelect()
      return
    }
    if (!asset.imageCropData) {
      openMissingCropDataDialog()
      return
    }
    assetsDialogs[asset.type].current?.open(undefined, asset.imageCropData)
  }

  const renderStatusMessage = () => {
    const failedStatusText = size === 'compact' ? 'Upload failed' : 'Asset upload failed'
    if (uploadStatus?.lastStatus === 'error') {
      return (
        <FailedStatusWrapper>
          <StatusText variant="t200" secondary size={size}>
            {failedStatusText}
          </StatusText>
          <RetryButton size="small" variant="secondary" icon={<SvgActionUpload />} onClick={handleChangeHost}>
            Try again
          </RetryButton>
        </FailedStatusWrapper>
      )
    }
    if (!uploadStatus?.lastStatus) {
      return (
        <FailedStatusWrapper>
          <StatusText variant="t200" secondary size={size}>
            {failedStatusText}
          </StatusText>
          <div {...getRootProps()}>
            <input {...getInputProps()} />
            <RetryButton size="small" variant="secondary" icon={<SvgActionUpload />} onClick={reselectFile}>
              Reconnect file
            </RetryButton>
          </div>
        </FailedStatusWrapper>
      )
    }
  }

  const renderStatusIndicator = () => {
    if (uploadStatus?.lastStatus === 'completed') {
      return <SvgAlertsSuccess24 />
    }
    if (uploadStatus?.lastStatus === 'error' || !uploadStatus?.lastStatus) {
      return <SvgAlertsWarning24 />
    }
    if (uploadStatus?.lastStatus === 'processing') {
      return <Loader variant="small" />
    }
    return (
      <ProgressbarContainer>
        <CircularProgress strokeWidth={10} value={uploadStatus?.progress ?? 0} />
      </ProgressbarContainer>
    )
  }
  const isReconnecting = uploadStatus?.lastStatus === 'reconnecting'
  return (
    <>
      <FileLineContainer isLast={isLast} size={size}>
        <FileInfoContainer>
          {isLast ? <FileLineLastPoint size={size} /> : <FileLinePoint size={size} />}
          <FileStatusContainer>
            <SwitchTransition>
              <CSSTransition
                key={uploadStatus?.lastStatus || 'no-status'}
                classNames={transitions.names.fade}
                timeout={200}
              >
                {renderStatusIndicator()}
              </CSSTransition>
            </SwitchTransition>
          </FileStatusContainer>
          <FileInfo size={size}>
            <FileInfoType warning={isReconnecting && size === 'compact'}>
              {isVideo ? <SvgActionVideoFile /> : <SvgActionImageFile />}
              <Text variant="t200">{fileTypeText}</Text>
            </FileInfoType>
            {size === 'compact' && isReconnecting ? (
              <Text variant="t200" secondary>
                Trying to reconnect...({uploadStatus.retries})
              </Text>
            ) : (
              <FileInfoDetails size={size}>
                {assetDimension && (
                  <Text variant="t200" secondary>
                    {assetDimension}
                  </Text>
                )}
                {assetSize && (
                  <Text variant="t200" secondary>
                    {assetSize}
                  </Text>
                )}
              </FileInfoDetails>
            )}
          </FileInfo>
        </FileInfoContainer>
        {renderStatusMessage()}
      </FileLineContainer>
      <ImageCropModal ref={thumbnailDialogRef} imageType="videoThumbnail" onConfirm={handleCropConfirm} />
      <ImageCropModal ref={avatarDialogRef} imageType="avatar" onConfirm={handleCropConfirm} />
      <ImageCropModal ref={coverDialogRef} imageType="cover" onConfirm={handleCropConfirm} />
    </>
  )
}
Example #3
Source File: FileSelect.tsx    From atlas with GNU General Public License v3.0 3 votes vote down vote up
FileSelect: React.FC<FileSelectProps> = ({
  onUploadFile,
  fileType,
  maxSize,
  title,
  paragraph,
  thumbnailUrl,
  onReAdjustThumbnail,
  onDropRejected,
  onError,
  error,
  isLoading,
}) => {
  const selectedFileTransition = useTransition(isLoading, {
    from: { opacity: 0, transform: 'scale(1.5)', x: '0%' },
    enter: { opacity: 1, transform: 'scale(1)', x: '0%' },
    leave: { opacity: 0, transform: 'scale(1)', x: '-200%' },
    config: {
      duration: 400,
      easing: beazierEasing(0, 0, 0.58, 1),
    },
  })

  const innerContainerTransition = useTransition(fileType, {
    from: { x: '200%' },
    enter: { x: '0%' },
    leave: { x: '-200%' },
    immediate: fileType === 'video',
    config: {
      duration: 400,
      easing: beazierEasing(0, 0, 0.58, 1),
    },
  })

  const onDropAccepted: DropzoneOptions['onDropAccepted'] = useCallback(
    (acceptedFiles) => {
      const [file] = acceptedFiles
      onUploadFile(file)
    },
    [onUploadFile]
  )

  const { getRootProps, getInputProps, isDragAccept, isFileDialogActive, open, acceptedFiles } = useDropzone({
    onDropAccepted,
    onDropRejected,
    maxFiles: 1,
    multiple: false,
    accept: fileType + '/*',
    maxSize,
    noClick: true,
    noKeyboard: true,
  })

  const [openErrorDialog, closeErrorDialog] = useConfirmationModal()

  useEffect(() => {
    if (!error) {
      return
    }
    openErrorDialog({
      title: 'Unsupported file type selected',
      description: error,
      iconType: 'warning',
      primaryButton: {
        onClick: () => {
          closeErrorDialog()
          onError?.(null, fileType)
          open()
        },
        text: 'Reselect file',
      },
      secondaryButton: {
        text: 'Cancel',
        onClick: () => {
          onError?.(null, fileType)
          closeErrorDialog()
        },
      },
    })
  }, [closeErrorDialog, error, fileType, onError, open, openErrorDialog])

  const handleReAdjustThumbnail = (e: React.MouseEvent<HTMLImageElement, MouseEvent>) => {
    e.stopPropagation()
    onReAdjustThumbnail?.()
  }

  return (
    <DragAndDropArea {...getRootProps()} isDragAccept={isDragAccept} isFileDialogActive={isFileDialogActive}>
      <input {...getInputProps()} />
      {selectedFileTransition(
        (styles, item) =>
          item && (
            <SelectedFileInfo style={{ opacity: styles.opacity }}>
              <SelectedFileInfoBackground />
              <SelectedFileInfoInnerContainer style={{ transform: styles.transform, x: styles.x }}>
                <SvgIllustrativeFileSelected />
                <SelectedFileInfoHeading variant="t100">selected</SelectedFileInfoHeading>
                {acceptedFiles.length !== 0 && <Text variant="t200">{acceptedFiles[0].name}</Text>}
              </SelectedFileInfoInnerContainer>
            </SelectedFileInfo>
          )
      )}
      {innerContainerTransition((style, item) =>
        thumbnailUrl && fileType === 'image' ? (
          <Thumbnail
            isLoading={isLoading}
            src={thumbnailUrl}
            alt="video thumbnail"
            onClick={handleReAdjustThumbnail}
            title="Click to readjust"
          />
        ) : (
          <InnerContainer key={item} style={style} isLoading={isLoading}>
            {fileType === 'video' ? <SvgIllustrativeVideo /> : <SvgIllustrativeImage />}
            <Title variant="h400">{title}</Title>
            <Paragraph variant="t200" as="p" secondary>
              {paragraph}
            </Paragraph>
            <ButtonsGroup>
              <DragDropText variant="t100" secondary>
                Drag and drop or
              </DragDropText>
              <Button size="medium" onClick={() => open()} icon={<SvgActionUpload />}>
                Select a file
              </Button>
            </ButtonsGroup>
          </InnerContainer>
        )
      )}
    </DragAndDropArea>
  )
}