/* eslint-disable react/prop-types */ /* eslint-disable @typescript-eslint/no-explicit-any */ import React from 'react'; import Languages from '@features/global/services/languages-service'; import { Upload } from 'react-feather'; import classNames from 'classnames'; import './uploads.scss'; import { Typography } from 'antd'; type PropsType = { [key: string]: any; onAddFiles: (files: File[], event: Event & { dataTransfer: DataTransfer }) => void; }; type StateType = { [key: string]: any }; type FileInputType = any; let sharedFileInput: any = null; let sharedFolderInput: any = null; export default class UploadZone extends React.Component { file_input: FileInputType = {}; stopHoverTimeout: ReturnType | undefined; node: HTMLDivElement | null = null; constructor(props: PropsType) { super(props); this.state = {}; } componentDidMount() { this.node && this.watch(this.node, document.body); if ( (this.props.directory && !sharedFolderInput) || (!this.props.directory && !sharedFileInput) ) { this.file_input = document.createElement('input'); this.file_input.type = 'file'; this.file_input.style.position = 'absolute'; this.file_input.style.top = '-10000px'; this.file_input.style.left = '-10000px'; this.file_input.style.width = '100px'; this.file_input.multiple = this.props.multiple ? true : false; this.file_input.directory = this.props.directory ? true : false; this.file_input.webkitdirectory = this.props.directory ? true : false; this.setCallback(); document.body.appendChild(this.file_input); if (this.props.directory) { sharedFolderInput = this.file_input; } else { sharedFileInput = this.file_input; } } else { this.file_input = sharedFileInput; } } setCallback() { this.file_input.onchange = (e: any) => { this.change(e); e.target.value = null; }; } open() { if (this.props.disabled) { return; } this.setCallback(); this.file_input.click(); } /** * * @param event */ change(event: any) { if (this.props.disabled) return; event.preventDefault(); this.hover(false); const files = event.target.files || event.dataTransfer.files || []; if (this.props.onAddFiles && files.length > 0) return this.props.onAddFiles([...files], event); } /** * * @param currentNode * @param body */ watch(currentNode: HTMLElement, body: HTMLElement) { /** * DRAGOVER EVENT */ currentNode.addEventListener('dragover', () => currentNode.classList.add('input-drag-focus')); body.addEventListener('dragover', (e: DragEvent) => { body.classList.add('body-drag-focus'); this.hover(true, e); e.preventDefault(); }); /** * DRAGLEAVE EVENT */ currentNode.addEventListener('dragleave', () => currentNode.classList.remove('input-drag-focus'), ); body.addEventListener('dragleave', (e: DragEvent) => { body.classList.remove('body-drag-focus'); if (this.props.onDragLeave) { this.props.onDragLeave(); } this.hover(false, e); e.preventDefault(); }); /** * DROP EVENT */ currentNode.addEventListener('drop', (e: DragEvent) => { currentNode.classList.contains('input-drag-focus') && this.change(e); e.preventDefault(); }); body.addEventListener('drop', (e: DragEvent) => { this.hover(false, e); e.preventDefault(); }); /** * DRAGENTER EVENT */ body.addEventListener('dragenter', (e: DragEvent) => { if (!this.props.disabled && this.props.onDragEnter) { this.props.onDragEnter(); } this.hover(true, e); e.preventDefault(); this.setCallback(); }); } /** * * @param state * @param event */ hover(state: any, event?: any) { if ( !this.state.dragover && (!event || !event.dataTransfer || (event.dataTransfer.types || []).indexOf('Files') < 0) ) { return; } if (!state) { this.stopHoverTimeout = setTimeout(() => { this.setState({ dragover: false }); }, 200); return; } if (this.stopHoverTimeout) clearTimeout(this.stopHoverTimeout); if (this.state.dragover !== state) { this.setState({ dragover: state }); } } render() { return (
node && (this.node = node)} style={this.props.style} className={classNames('upload_drop_zone', this.props.className)} onClick={() => { if (!this.props.disableClick) { this.open(); } }} > {!this.props.disabled && (
{Languages.t('components.upload.drop_files')}
)} {this.props.children}
); } }