<commit_before>
import * as React from "react";
import {connect, I18nProps} from "./connect";
import {createStructuredSelector} from "reselect";

import {map, first, rest} from "underscore";
import * as actions from "../actions";

import DownloadRow from "./download-row";

import {IAppState, IDownloadItem} from "../types";
import {dispatcher} from "../constants/action-types";

import {IMeatProps} from "./meats/types";

import styled, * as styles from "./styles";

const DownloadsDiv = styled.div`
  ${styles.meat()}

  overflow-y: auto;
  padding: 0 20px 20px 20px;

  .section-bar {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    align-content: center;
    margin: 20px 0 10px 10px;
    flex-shrink: 0;

    h2 {
      font-size: 22px;
    }

    .clear {
      margin-left: 8px;
      ${styles.clickable()}
    }
  }

  .game-actions .main-action {
    padding: 3px 10px;
  }
`;

const EmptyState = styled.div`
  font-size: ${props => props.theme.fontSizes.large};
  color: ${props => props.theme.secondaryText};

  margin: 20px;
`;

class Downloads extends React.PureComponent<IProps & IDerivedProps & I18nProps, void> {
  constructor () {
    super();
  }

  render () {
    const {t, items, finishedItems} = this.props;
    const {clearFinishedDownloads} = this.props;

    const hasItems = (items.length + finishedItems.length) > 0;
    if (!hasItems) {
      return <EmptyState>
          {t("status.downloads.no_active_downloads")}
      </EmptyState>;
    }

    const firstItem = first(items);
    const queuedItems = rest(items);

    return <DownloadsDiv>
    {firstItem
    ? <div className="section-bar">
      <h2>{t("status.downloads.category.active")}</h2>
    </div>
    : ""}

    {firstItem
    ? <DownloadRow key={firstItem.id} item={firstItem} first active/>
    : ""}

    {queuedItems.length > 0
    ? <div className="section-bar">
      <h2>{t("status.downloads.category.queued")}</h2>
    </div>
    : ""}
    {queuedItems.length > 0
    ? map(queuedItems, (item, i) =>
      <DownloadRow key={item.id} item={item} active/>,
    )
    : ""}

    {finishedItems.length > 0
      ? [
        <div className="section-bar">
          <h2 className="finished-header">
            {t("status.downloads.category.finished")}
          </h2>
          <span className="clear" data-rh-at="right" data-rh={t("status.downloads.clear_all_finished")}
              onClick={() => clearFinishedDownloads({})}>
            <span className="icon icon-delete"/>
          </span>
        </div>,
      ].concat(map(finishedItems, (item) =>
        <DownloadRow key={item.id} item={item}/>,
      ))
      : ""}

    </DownloadsDiv>;
  }
}

interface IProps extends IMeatProps {}

interface IDerivedProps {
  items: IDownloadItem[];
  finishedItems: IDownloadItem[];

  clearFinishedDownloads: typeof actions.clearFinishedDownloads;
}
<commit_msg>Add titlebar to downloads tab<commit_after>
import * as React from "react";
import {connect, I18nProps} from "./connect";
import {createStructuredSelector} from "reselect";

import {map, first, rest} from "underscore";
import * as actions from "../actions";

import DownloadRow from "./download-row";
import TitleBar from "./title-bar";

import {IAppState, IDownloadItem} from "../types";
import {dispatcher} from "../constants/action-types";

import {IMeatProps} from "./meats/types";

import styled, * as styles from "./styles";

const DownloadsDiv = styled.div`
  ${styles.meat()}
`;

const DownloadsContentDiv = styled.div`
  overflow-y: auto;
  padding: 0 20px 20px 20px;

  .section-bar {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    align-content: center;
    margin: 20px 0 10px 10px;
    flex-shrink: 0;

    h2 {
      font-size: 22px;
    }

    .clear {
      margin-left: 8px;
      ${styles.clickable()}
    }
  }

  .game-actions .main-action {
    padding: 3px 10px;
  }
`;

const EmptyState = styled.div`
  font-size: ${props => props.theme.fontSizes.large};
  color: ${props => props.theme.secondaryText};

  margin: 20px;
`;

class Downloads extends React.PureComponent<IProps & IDerivedProps & I18nProps, void> {
  constructor () {
    super();
  }

  render () {
    const {tab} = this.props;

    return <DownloadsDiv>
      <TitleBar tab={tab}/>
      <DownloadsContentDiv>{this.renderContents()}</DownloadsContentDiv>
    </DownloadsDiv>;
  }

  renderContents () {
    const {t, items, finishedItems} = this.props;
    const {clearFinishedDownloads} = this.props;

    const hasItems = (items.length + finishedItems.length) > 0;
    if (!hasItems) {
      return <EmptyState>
        {t("status.downloads.no_active_downloads")}
      </EmptyState>;
    }

    const firstItem = first(items);
    const queuedItems = rest(items);

    return <DownloadsContentDiv>
      {firstItem
      ? <div className="section-bar">
        <h2>{t("status.downloads.category.active")}</h2>
      </div>
      : ""}

      {firstItem
      ? <DownloadRow key={firstItem.id} item={firstItem} first active/>
      : ""}

      {queuedItems.length > 0
      ? <div className="section-bar">
        <h2>{t("status.downloads.category.queued")}</h2>
      </div>
      : ""}
      {queuedItems.length > 0
      ? map(queuedItems, (item, i) =>
        <DownloadRow key={item.id} item={item} active/>,
      )
      : ""}

      {finishedItems.length > 0
        ? [
          <div className="section-bar">
            <h2 className="finished-header">
              {t("status.downloads.category.finished")}
            </h2>
            <span className="clear" data-rh-at="right" data-rh={t("status.downloads.clear_all_finished")}
                onClick={() => clearFinishedDownloads({})}>
              <span className="icon icon-delete"/>
            </span>
          </div>,
        ].concat(map(finishedItems, (item) =>
          <DownloadRow key={item.id} item={item}/>,
        ))
        : ""}
    </DownloadsContentDiv>;
  }
}

interface IProps extends IMeatProps {}

interface IDerivedProps {
  items: IDownloadItem[];
  finishedItems: IDownloadItem[];

  clearFinishedDownloads: typeof actions.clearFinishedDownloads;
}

{'fraction_non_alphanumeric': 0.1538211382113821, 'fraction_numerical': 0.012357723577235772, 'mean_word_length': 2.7922318125770653, 'pattern_counts': {'":': 0, '<': 54, '<?xml version=': 0, '>': 72, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 50, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5654311', 'n_tokens_mistral': 2069, 'n_tokens_neox': 1986, 'n_words': 421}