<commit_before>/* global CONFIG */
import React, { Suspense } from 'react';
import { IndexLink, Link } from 'react-router';
import { connect } from 'react-redux';
import { Helmet } from 'react-helmet';
import classnames from 'classnames';

import { unauthenticated, home } from '../redux/action-creators';
import { getCurrentRouteName } from '../utils';
import Footer from './footer';
import Sidebar from './sidebar';
import LoaderContainer from './loader-container';
import SearchForm from './search-form';
import ErrorBoundary from './error-boundary';
import { ColorSchemeSetter } from './color-theme-setter';
import { SVGSymbolDeclarations } from './fontawesome-icons';
import MediaViewer from './media-viewer';
import { Throbber } from './throbber';
import { Delayed } from './lazy-component';

const loadingPageMessage = (
  <Delayed>
    <div className="content">
      <div className="content">
        <div className="box">
          <div className="box-body">
            <p>
              Loading page... <Throbber />
            </p>
          </div>
        </div>
      </div>
    </div>
  </Delayed>
);

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

const logoHandler = (routeName, cb) => () => {
  if (routeName === 'home') {
    return cb();
  }
  return false;
};

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.handleDragOver = this.handleDragOver.bind(this);
    this.handleDrop = this.handleDrop.bind(this);

    this.dragFirstLevel = false;
    this.dragSecondLevel = false;
  }

  containsFiles(e) {
    if (e.dataTransfer && e.dataTransfer.types) {
      // Event.dataTransfer.types is DOMStringList (not Array) in Firefox,
      // so we can't just use indexOf().
      for (let i = 0; i < e.dataTransfer.types.length; i++) {
        if (e.dataTransfer.types[i] === 'Files') {
          return true;
        }
      }
    }
    return false;
  }

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

      this.setState({ isDragOver: true });

      e.preventDefault();
    }
  }

  handleDragLeave(e) {
    if (this.containsFiles(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) {
    if (this.containsFiles(e)) {
      e.preventDefault();
    }
  }
  handleDrop(e) {
    if (this.containsFiles(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() {
    const { props } = this;

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

    return (
      <div className={layoutClassNames}>
        <ErrorBoundary>
          <Helmet title={props.title} defer={false} />
          <ColorSchemeSetter />
          <SVGSymbolDeclarations />

          <header className="row">
            <div className="col-xs-9 col-sm-4 col-md-4">
              <h1 className="site-logo">
                <IndexLink
                  className="site-logo-link"
                  to="/"
                  onClick={logoHandler(props.routeName, props.home)}
                >
                  {CONFIG.siteTitle}
                </IndexLink>
              </h1>
            </div>

            {props.authenticated ? (
              <div className="col-xs-12 col-sm-8 hidden-md hidden-lg">
                <div className="mobile-shortcuts">
                  <Link className="mobile-shortcut-link" to="/filter/discussions">
                    Discussions<commit_msg>Remove logotype click handler<commit_after>/* global CONFIG */
import React, { Suspense } from 'react';
import { IndexLink, Link } from 'react-router';
import { connect } from 'react-redux';
import { Helmet } from 'react-helmet';
import classnames from 'classnames';

import { unauthenticated, home } from '../redux/action-creators';
import { getCurrentRouteName } from '../utils';
import Footer from './footer';
import Sidebar from './sidebar';
import LoaderContainer from './loader-container';
import SearchForm from './search-form';
import ErrorBoundary from './error-boundary';
import { ColorSchemeSetter } from './color-theme-setter';
import { SVGSymbolDeclarations } from './fontawesome-icons';
import MediaViewer from './media-viewer';
import { Throbber } from './throbber';
import { Delayed } from './lazy-component';

const loadingPageMessage = (
  <Delayed>
    <div className="content">
      <div className="content">
        <div className="box">
          <div className="box-body">
            <p>
              Loading page... <Throbber />
            </p>
          </div>
        </div>
      </div>
    </div>
  </Delayed>
);

const InternalLayout = ({ authenticated, children }) => (
  <div className={authenticated ? 'col-md-9' : 'col-md-12'}>
    <div className="content">
      <Suspense fallback={loadingPageMessage}>{children}</Suspense>
    </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.handleDragOver = this.handleDragOver.bind(this);
    this.handleDrop = this.handleDrop.bind(this);

    this.dragFirstLevel = false;
    this.dragSecondLevel = false;
  }

  containsFiles(e) {
    if (e.dataTransfer && e.dataTransfer.types) {
      // Event.dataTransfer.types is DOMStringList (not Array) in Firefox,
      // so we can't just use indexOf().
      for (let i = 0; i < e.dataTransfer.types.length; i++) {
        if (e.dataTransfer.types[i] === 'Files') {
          return true;
        }
      }
    }
    return false;
  }

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

      this.setState({ isDragOver: true });

      e.preventDefault();
    }
  }

  handleDragLeave(e) {
    if (this.containsFiles(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) {
    if (this.containsFiles(e)) {
      e.preventDefault();
    }
  }
  handleDrop(e) {
    if (this.containsFiles(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() {
    const { props } = this;

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

    return (
      <div className={layoutClassNames}>
        <ErrorBoundary>
          <Helmet title={props.title} defer={false} />
          <ColorSchemeSetter />
          <SVGSymbolDeclarations />

          <header className="row">
            <div className="col-xs-9 col-sm-4 col-md-4">
              <h1 className="site-logo">
                <IndexLink className="site-logo-link" to="/">
                  {CONFIG.siteTitle}
                </IndexLink>
              </h1>
            </div>

            {props.authenticated ? (
              <div className="col-xs-12 col-sm-8 hidden-md hidden-lg">
                <div className="mobile-shortcuts">
                  <Link className="mobile-shortcut-link" to="/filter/discussions">
                    Discussions
{'fraction_non_alphanumeric': 0.13626460685284214, 'fraction_numerical': 0.0023767082590612004, 'mean_word_length': 2.6327338129496405, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 77, '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': '4007162', 'n_tokens_mistral': 3004, 'n_tokens_neox': 2924, 'n_words': 649}