<commit_before>// This file is part of Indico.
// Copyright (C) 2002 - 2020 CERN
//
// Indico is free software; you can redistribute it and/or
// modify it under the terms of the MIT License; see the
// LICENSE file for more details.

import React, {useCallback, useRef, useState} from 'react';
import PropTypes from 'prop-types';
import Dropzone from 'react-dropzone';
import {Button, Card, Divider, Grid, Header, Icon, Segment} from 'semantic-ui-react';

import {TooltipIfTruncated} from 'indico/react/components';
import {Param, Translate} from 'indico/react/i18n';

import './FileSubmission.module.scss';

function humanReadableBytes(bytes) {
  const kiloBytes = 1000;
  const megaBytes = 1000 * kiloBytes;

  if (bytes < kiloBytes) {
    return (
      <Translate>
        <Param name="size" value={bytes} /> bytes
      </Translate>
    );
  } else if (bytes < megaBytes) {
    return (
      <Translate>
        <Param name="size" value={(bytes / kiloBytes).toFixed(2)} /> kB
      </Translate>
    );
  } else {
    return (
      <Translate>
        <Param name="size" value={(bytes / megaBytes).toFixed(2)} /> MB
      </Translate>
    );
  }
}

export default function FileSubmission({onChange, disabled}) {
  const [files, setFiles] = useState([]);
  const onDrop = useCallback(
    acceptedFiles => {
      const newFilenames = new Set(acceptedFiles.map(f => f.name));
      acceptedFiles = files.filter(f => !newFilenames.has(f.name)).concat(acceptedFiles);
      setFiles(acceptedFiles);
      if (onChange) {
        onChange(acceptedFiles);
      }
    },
    [files, setFiles, onChange]
  );

  const removeFile = file => {
    const newFiles = files.filter(f => f !== file);
    setFiles(newFiles);
    if (onChange) {
      onChange(newFiles);
    }
  };

  const dropzoneRef = useRef();
  const openFileDialog = () => {
    if (dropzoneRef.current && !disabled) {
      dropzoneRef.current.open();
    }
  };

  return (
    <Dropzone ref={dropzoneRef} onDrop={onDrop} disabled={disabled} multiple noClick noKeyboard>
      {({getRootProps, getInputProps, isDragActive}) => (
        <div {...getRootProps()} styleName="dropzone-area">
          <input {...getInputProps()} />
          <Segment textAlign="center" placeholder>
            <Grid celled="internally">
              <Grid.Row columns={files.length === 0 ? 1 : 2}>
                {!isDragActive && files.length !== 0 && (
                  <Grid.Column width={10} verticalAlign="middle">
                    <Card.Group itemsPerRow={files.length === 1 ? 1 : 2} centered>
                      {files.map(file => (
                        <Card
                          styleName="file-card"
                          key={file.name}
                          centered={files.length === 1}
                          raised
                        >
                          {!disabled && (
                            <Icon name="trash" onClick={() => removeFile(file)} color="red" />
                          )}
                          <Card.Content>
                            <TooltipIfTruncated>
                              <Card.Header textAlign="center">{file.name}</Card.Header>
                            </TooltipIfTruncated>
                            <Card.Meta textAlign="center">
                              {humanReadableBytes(file.size)}
                            </Card.Meta>
                          </Card.Content>
                        </Card>
                      ))}
                    </Card.Group>
                  </Grid.Column>
                )}
                <Grid.Column
                  verticalAlign="middle"
                  width={files.length === 0 || isDragActive ? 16 : 6}
                >
                  <Header><commit_msg>Fix TooltipIfTruncated in FileSubmission<commit_after>// This file is part of Indico.
// Copyright (C) 2002 - 2020 CERN
//
// Indico is free software; you can redistribute it and/or
// modify it under the terms of the MIT License; see the
// LICENSE file for more details.

import React, {useCallback, useRef, useState} from 'react';
import PropTypes from 'prop-types';
import Dropzone from 'react-dropzone';
import {Button, Card, Divider, Grid, Header, Icon, Segment} from 'semantic-ui-react';

import {TooltipIfTruncated} from 'indico/react/components';
import {Param, Translate} from 'indico/react/i18n';

import './FileSubmission.module.scss';

function humanReadableBytes(bytes) {
  const kiloBytes = 1000;
  const megaBytes = 1000 * kiloBytes;

  if (bytes < kiloBytes) {
    return (
      <Translate>
        <Param name="size" value={bytes} /> bytes
      </Translate>
    );
  } else if (bytes < megaBytes) {
    return (
      <Translate>
        <Param name="size" value={(bytes / kiloBytes).toFixed(2)} /> kB
      </Translate>
    );
  } else {
    return (
      <Translate>
        <Param name="size" value={(bytes / megaBytes).toFixed(2)} /> MB
      </Translate>
    );
  }
}

export default function FileSubmission({onChange, disabled}) {
  const [files, setFiles] = useState([]);
  const onDrop = useCallback(
    acceptedFiles => {
      const newFilenames = new Set(acceptedFiles.map(f => f.name));
      acceptedFiles = files.filter(f => !newFilenames.has(f.name)).concat(acceptedFiles);
      setFiles(acceptedFiles);
      if (onChange) {
        onChange(acceptedFiles);
      }
    },
    [files, setFiles, onChange]
  );

  const removeFile = file => {
    const newFiles = files.filter(f => f !== file);
    setFiles(newFiles);
    if (onChange) {
      onChange(newFiles);
    }
  };

  const dropzoneRef = useRef();
  const openFileDialog = () => {
    if (dropzoneRef.current && !disabled) {
      dropzoneRef.current.open();
    }
  };

  return (
    <Dropzone ref={dropzoneRef} onDrop={onDrop} disabled={disabled} multiple noClick noKeyboard>
      {({getRootProps, getInputProps, isDragActive}) => (
        <div {...getRootProps()} styleName="dropzone-area">
          <input {...getInputProps()} />
          <Segment textAlign="center" placeholder>
            <Grid celled="internally">
              <Grid.Row columns={files.length === 0 ? 1 : 2}>
                {!isDragActive && files.length !== 0 && (
                  <Grid.Column width={10} verticalAlign="middle">
                    <Card.Group itemsPerRow={files.length === 1 ? 1 : 2} centered>
                      {files.map(file => (
                        <Card
                          styleName="file-card"
                          key={file.name}
                          centered={files.length === 1}
                          raised
                        >
                          <Card.Content>
                            <Card.Header textAlign="center">
                              <TooltipIfTruncated>
                                <div style={{textOverflow: 'ellipsis', overflow: 'hidden'}}>
                                  {file.name}
                                </div>
                              </TooltipIfTruncated>
                            </Card.Header>
                            <Card.Meta textAlign="center">
                              {humanReadableBytes(file.size)}
                            </Card.Meta>
                          </Card.Content>
                          {!disabled && (
                            <Icon
                              name="trash"
                              color="red"
                              style={{cursor: 'pointer'}}
                              onClick={() => removeFile(file)}
                            />
                          )}
                        </Card>
                      ))}
                    </Card.Group>
                  </Grid.Column>
                )}
                <Grid.Column
                  verticalAlign="middle"
                  width={files.length === 0 || isDragActive ? 16 : 6}
                >
                  <Header>
{'fraction_non_alphanumeric': 0.12746948534038002, 'fraction_numerical': 0.008556688058386813, 'mean_word_length': 1.5696734561913999, 'pattern_counts': {'":': 0, '<': 73, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6199154', 'n_tokens_mistral': 2223, 'n_tokens_neox': 2142, 'n_words': 480}