<commit_before>import React from 'react'
import {Link} from 'react-router'
import {connect} from 'react-redux'
import classnames from 'classnames'

import {unauthenticated} from '../redux/action-creators'
import Footer from './footer'
import Sidebar from './sidebar'
import LoaderContainer from './loader-container'

const InternalLayout = ({authenticated, children}) => (
  <div className={authenticated ? 'col-md-9' : 'col-md-12'}>
    <div className='content'>
      {children}
    </div>
  </div>
)


class Layout extends React.Component {
  // Here we have some handling of drag-n-drop, because standard dragenter
  // and dragleave events suck. Current implementation is using ideas from
  // <NAME>, see http://bensmithett.github.io/dragster/ for details

  constructor(props) {
    super(props)

    this.state = { isDragOver: false }

    this.handleDragEnter = this.handleDragEnter.bind(this)
    this.handleDragLeave = this.handleDragLeave.bind(this)
    this.handleDrop = this.handleDrop.bind(this)

    this.dragFirstLevel = false
    this.dragSecondLevel = false
  }

  handleDragEnter(e) {
    if (this.dragFirstLevel) {
      this.dragSecondLevel = true
      return
    }
    this.dragFirstLevel = true

    this.setState({ isDragOver: true })

    e.preventDefault()
  }

  handleDragLeave(e) {
    if (this.dragSecondLevel) {
      this.dragSecondLevel = false
    } else if (this.dragFirstLevel) {
      this.dragFirstLevel = false
    }

    if (!this.dragFirstLevel && !this.dragSecondLevel) {
      this.setState({ isDragOver: false })
    }

    e.preventDefault()
  }

  // Prevent browser from loading the file if user drops it outside of a dropzone
  // (both `handleDragOver` and `handleDrop` are necessary)
  handleDragOver(e) {
    e.preventDefault()
  }
  handleDrop(e) {
    this.setState({ isDragOver: false })
    this.dragFirstLevel = false
    this.dragSecondLevel = false
    e.preventDefault()
  }

  componentDidMount() {
    window.addEventListener('dragenter', this.handleDragEnter)
    window.addEventListener('dragleave', this.handleDragLeave)
    window.addEventListener('dragover', this.handleDragOver)
    window.addEventListener('drop', this.handleDrop)
  }

  componentWillUnmount() {
    window.removeEventListener('dragenter', this.handleDragEnter)
    window.removeEventListener('dragleave', this.handleDragLeave)
    window.removeEventListener('dragover', this.handleDragOver)
    window.removeEventListener('drop', this.handleDrop)
  }

  render() {
    let props = this.props

    let layoutClassNames = classnames({
      'container': true,
      'dragover': this.state.isDragOver
    })

    return (
      <div className={layoutClassNames}>
        <div className='row header-row'>
          <div className='col-md-4'>
            <div className='header'>
              <h1 className='title'>
                <Link to='/'>FreeFeed-beta</Link>
              </h1>
            </div>
          </div>

          <div className='col-md-8'>
            <div className='row'>
              <div className='col-md-6 search-field'>
                <div className='form-inline'>
                {/*<input className='form-control input-sm search-input p-search-input' />
                <button className='btn btn-default btn-sm p-search-action'>Search</button>*/}
                </div>
              </div>
              <div className='col-md-6'>
                {props.authenticated ? false : (
                  <div className='signin-toolbar'>
                    <Link to='/signin'>Sign In</Link>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>

        <LoaderContainer loading={props.loadingView} fullPage={true}>
          <div className='row'>
            <InternalLayout {...props}/>
            {props.authenticated ? <Sidebar {...props}/> : false}
          </div>
        </LoaderContainer>

        <div className='row'>
          <div className='col-md-12'>
          <Footer/>
          </div>
        </div>
      </div>
    )
  }
}

function select(state) {
  return {
    user: state.user,
    authenticated: state.authenticated,
    loadingView: state.routeLoadingState,
    recentGroups: state.recentGroups,
  }
}

function mapDispatchToProps(dispatch){
  return {
    signOut: ()=>dispatch(unauthenticated())
  }
}

export default connect(select, mapDispatchToProps)(Layout)
<commit_msg>Make sure "dragover" class only activates for files (not texts, links etc.)<commit_after>import React from 'react'
import {Link} from 'react-router'
import {connect} from 'react-redux'
import classnames from 'classnames'

import {unauthenticated} from '../redux/action-creators'
import Footer from './footer'
import Sidebar from './sidebar'
import LoaderContainer from './loader-container'

const InternalLayout = ({authenticated, children}) => (
  <div className={authenticated ? 'col-md-9' : 'col-md-12'}>
    <div className='content'>
      {children}
    </div>
  </div>
)


class Layout extends React.Component {
  // Here we have some handling of drag-n-drop, because standard dragenter
  // and dragleave events suck. Current implementation is using ideas from
  // <NAME>, see http://bensmithett.github.io/dragster/ for details

  constructor(props) {
    super(props)

    this.state = { isDragOver: false }

    this.handleDragEnter = this.handleDragEnter.bind(this)
    this.handleDragLeave = this.handleDragLeave.bind(this)
    this.handleDrop = this.handleDrop.bind(this)

    this.dragFirstLevel = false
    this.dragSecondLevel = false
  }

  containsFiles(e) {
    if (e.dataTransfer && e.dataTransfer.types) {
      return (e.dataTransfer.types.indexOf('Files') !== -1)
    }
    return false
  }

  handleDragEnter(e) {
    if (this.dragFirstLevel) {
      this.dragSecondLevel = true
      return
    }
    this.dragFirstLevel = true

    if (this.containsFiles(e)) {
      this.setState({ isDragOver: true })
    }

    e.preventDefault()
  }

  handleDragLeave(e) {
    if (this.dragSecondLevel) {
      this.dragSecondLevel = false
    } else if (this.dragFirstLevel) {
      this.dragFirstLevel = false
    }

    if (!this.dragFirstLevel && !this.dragSecondLevel) {
      this.setState({ isDragOver: false })
    }

    e.preventDefault()
  }

  // Prevent browser from loading the file if user drops it outside of a dropzone
  // (both `handleDragOver` and `handleDrop` are necessary)
  handleDragOver(e) {
    e.preventDefault()
  }
  handleDrop(e) {
    this.setState({ isDragOver: false })
    this.dragFirstLevel = false
    this.dragSecondLevel = false
    e.preventDefault()
  }

  componentDidMount() {
    window.addEventListener('dragenter', this.handleDragEnter)
    window.addEventListener('dragleave', this.handleDragLeave)
    window.addEventListener('dragover', this.handleDragOver)
    window.addEventListener('drop', this.handleDrop)
  }

  componentWillUnmount() {
    window.removeEventListener('dragenter', this.handleDragEnter)
    window.removeEventListener('dragleave', this.handleDragLeave)
    window.removeEventListener('dragover', this.handleDragOver)
    window.removeEventListener('drop', this.handleDrop)
  }

  render() {
    let props = this.props

    let layoutClassNames = classnames({
      'container': true,
      'dragover': this.state.isDragOver
    })

    return (
      <div className={layoutClassNames}>
        <div className='row header-row'>
          <div className='col-md-4'>
            <div className='header'>
              <h1 className='title'>
                <Link to='/'>FreeFeed-beta</Link>
              </h1>
            </div>
          </div>

          <div className='col-md-8'>
            <div className='row'>
              <div className='col-md-6 search-field'>
                <div className='form-inline'>
                {/*<input className='form-control input-sm search-input p-search-input' />
                <button className='btn btn-default btn-sm p-search-action'>Search</button>*/}
                </div>
              </div>
              <div className='col-md-6'>
                {props.authenticated ? false : (
                  <div className='signin-toolbar'>
                    <Link to='/signin'>Sign In</Link>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>

        <LoaderContainer loading={props.loadingView} fullPage={true}>
          <div className='row'>
            <InternalLayout {...props}/>
            {props.authenticated ? <Sidebar {...props}/> : false}
          </div>
        </LoaderContainer>

        <div className='row'>
          <div className='col-md-12'>
          <Footer/>
          </div>
        </div>
      </div>
    )
  }
}

function select(state) {
  return {
    user: state.user,
    authenticated: state.authenticated,
    loadingView: state.routeLoadingState,
    recentGroups: state.recentGroups,
  }
}

function mapDispatchToProps(dispatch){
  return {
    signOut: ()=>dispatch(unauthenticated())
  }
}

export default connect(select, mapDispatchToProps)(Layout)

{'fraction_non_alphanumeric': 0.1286748573935937, 'fraction_numerical': 0.002523036419482229, 'mean_word_length': 2.4864244741873804, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 97, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6312501', 'n_tokens_mistral': 2687, 'n_tokens_neox': 2614, 'n_words': 564}