<commit_before>import PropTypes from 'prop-types';
import React from 'react';
import DragReorderable from 'drag-reorderable';
import AutoSave from '../../components/auto-save.coffee';
import SOCIAL_ICONS from '../../lib/social-icons';

export default class SocialLinksEditor extends React.Component {
  constructor(props) {
    super(props);
    const socialOrder = Object.keys(SOCIAL_ICONS).map(key => key);
    this.state = {
      socialOrder
    };
    this.reorderDefault = this.reorderDefault.bind(this);
    this.handleNewLink = this.handleNewLink.bind(this);
    this.handleLinkReorder = this.handleLinkReorder.bind(this);
    this.handleRemoveLink = this.handleRemoveLink.bind(this);
    this.renderRow = this.renderRow.bind(this);
  }

  componentDidMount() {
    this.reorderDefault();
  }

  reorderDefault() {
    const socialUrls = this.props.project.urls.filter(url => url.path);
    const newOrder = [];
    socialUrls.map(link => newOrder.push(link.site));
    this.state.socialOrder.map((item) => {
      if (newOrder.indexOf(item) < 0) {
        newOrder.push(item);
      }
    });
    this.setState({ socialOrder: newOrder });
  }

  handleNewLink(site, e) {
    let index = this.indexFinder(this.props.project.urls, site);
    if (index < 0) { index = this.props.project.urls.length; }

    if (e.target.value) {
      const changes = {
        [`urls.${index}`]: {
          label: '',
          path: e.target.value,
          site,
          url: `https://${site}${e.target.value}`
        }
      };
      this.props.project.update(changes);
    } else {
      this.handleRemoveLink(site);
    }
  }

  handleLinkReorder(newLinkOrder) {
    const externalUrls = this.props.project.urls.filter(url => !url.path);
    const socialUrls = this.props.project.urls.filter(url => url.path);
    const newSocialUrls = socialUrls.sort((a, b) => newLinkOrder.indexOf(a.site) - newLinkOrder.indexOf(b.site));
    const changes = { urls: externalUrls.concat(newSocialUrls) };
    this.props.project.update(changes).save();
    this.setState({ socialOrder: newLinkOrder });
  }

  handleRemoveLink(linkToRemove) {
    const urls = this.props.project.urls.slice();
    const indexToRemove = this.indexFinder(urls, linkToRemove);
    if (indexToRemove > -1) {
      urls.splice(indexToRemove, 1);
      this.props.project.update({ urls }).save();
    }
  }

  handleDisableDrag(event) {
    event.target.parentElement.parentElement.setAttribute('draggable', false);
  }

  handleEnableDrag(event) {
    event.target.parentElement.parentElement.setAttribute('draggable', true);
  }

  indexFinder(toSearch, toFind) {
    return toSearch.findIndex(i => (i.site === toFind));
  }

  renderRow(site, i) {
    const index = this.indexFinder(this.props.project.urls, site);
    const value = index >= 0 ? this.props.project.urls[index].path : '';

    return (
      <tr key={i}>
        <td>{site}</td>
        <AutoSave tag="td" resource={this.props.project}>
          <input
            type="text"
            name={`urls.${site}.url`}
            value={value}
            onChange={this.handleNewLink.bind(this, site)}
            onMouseDown={this.handleDisableDrag}
            onMouseUp={this.handleEnableDrag}
          />
        </AutoSave>
        <td>
          <button type="button" onClick={this.handleRemoveLink.bind(this, site)}>
            <i className="fa fa-remove" />
          </button>
        </td>
      </tr>
    );
  }

  render() {
    return (
      <table className="edit-social-links">
        <DragReorderable
          tag="tbody"
          items={this.state.socialOrder}
          render={this.renderRow}
          onChange={this.handleLinkReorder}
        />
      </table>
    );
  }
}

SocialLinksEditor.defaultProps = {
  project: {}
};

SocialLinksEditor.propTypes = {
  project: PropTypes.shape({
    save: PropTypes.func,
    update: PropTypes.func,
    urls: PropTypes.array
  })
};<commit_msg>Handle Social Sites with Preceding Routes<commit_after>import PropTypes from 'prop-types';
import React from 'react';
import DragReorderable from 'drag-reorderable';
import AutoSave from '../../components/auto-save.coffee';
import SOCIAL_ICONS from '../../lib/social-icons';

const ROUTE_BEFORE_DOMAIN = ['wordpress'];

export default class SocialLinksEditor extends React.Component {
  constructor(props) {
    super(props);
    const socialOrder = Object.keys(SOCIAL_ICONS).map(key => key);
    this.state = {
      socialOrder
    };
    this.reorderDefault = this.reorderDefault.bind(this);
    this.handleNewLink = this.handleNewLink.bind(this);
    this.handleLinkReorder = this.handleLinkReorder.bind(this);
    this.handleRemoveLink = this.handleRemoveLink.bind(this);
    this.renderRow = this.renderRow.bind(this);
  }

  componentDidMount() {
    this.reorderDefault();
  }

  reorderDefault() {
    const socialUrls = this.props.project.urls.filter(url => url.path);
    const newOrder = [];
    socialUrls.map(link => newOrder.push(link.site));
    this.state.socialOrder.map((item) => {
      if (newOrder.indexOf(item) < 0) {
        newOrder.push(item);
      }
    });
    this.setState({ socialOrder: newOrder });
  }

  handleNewLink(site, e) {
    let index = this.indexFinder(this.props.project.urls, site);
    if (index < 0) { index = this.props.project.urls.length; }
    let url = `https://${site}${e.target.value}`;
    if (ROUTE_BEFORE_DOMAIN.some(el => site.indexOf(el) >= 0)) {
      url = `https://${e.target.value}.${site}`;
    }

    if (e.target.value) {
      const changes = {
        [`urls.${index}`]: {
          label: '',
          path: e.target.value,
          site,
          url
        }
      };
      this.props.project.update(changes);
    } else {
      this.handleRemoveLink(site);
    }
  }

  handleLinkReorder(newLinkOrder) {
    const externalUrls = this.props.project.urls.filter(url => !url.path);
    const socialUrls = this.props.project.urls.filter(url => url.path);
    const newSocialUrls = socialUrls.sort((a, b) => newLinkOrder.indexOf(a.site) - newLinkOrder.indexOf(b.site));
    const changes = { urls: externalUrls.concat(newSocialUrls) };
    this.props.project.update(changes).save();
    this.setState({ socialOrder: newLinkOrder });
  }

  handleRemoveLink(linkToRemove) {
    const urls = this.props.project.urls.slice();
    const indexToRemove = this.indexFinder(urls, linkToRemove);
    if (indexToRemove > -1) {
      urls.splice(indexToRemove, 1);
      this.props.project.update({ urls }).save();
    }
  }

  handleDisableDrag(event) {
    event.target.parentElement.parentElement.setAttribute('draggable', false);
  }

  handleEnableDrag(event) {
    event.target.parentElement.parentElement.setAttribute('draggable', true);
  }

  indexFinder(toSearch, toFind) {
    return toSearch.findIndex(i => (i.site === toFind));
  }

  renderRow(site, i) {
    const index = this.indexFinder(this.props.project.urls, site);
    const value = index >= 0 ? this.props.project.urls[index].path : '';
    const precedeSiteName = ROUTE_BEFORE_DOMAIN.some(el => site.indexOf(el) >= 0);

    return (
      <tr key={i}>
        {!precedeSiteName && (
          <td>{site}</td>
        )}
        <AutoSave tag="td" resource={this.props.project}>
          <input
            type="text"
            name={`urls.${site}.url`}
            value={value}
            onChange={this.handleNewLink.bind(this, site)}
            onMouseDown={this.handleDisableDrag}
            onMouseUp={this.handleEnableDrag}
          />
        </AutoSave>
        {precedeSiteName && (
          <td>.{site}</td>
        )}
        <td>
          <button type="button" onClick={this.handleRemoveLink.bind(this, site)}>
            <i className="fa fa-remove" />
          </button>
        </td>
      </tr>
    );
  }

  render() {
    return (
      <table className="edit-social-links">
        <DragReorderable
          tag="tbody"
          items={this.state.socialOrder}
          render={this.renderRow}
          onChange={this.handleLinkReorder}
        />
      </table>
    );
  }
}

SocialLinksEditor.defaultProps = {
  project: {}
};

SocialLinksEditor.propTypes = {
  project: PropTypes.shape({
    save: PropTypes.func,
    update: PropTypes.func,
    urls: PropTypes.array
  })
};

{'fraction_non_alphanumeric': 0.14981905910735827, 'fraction_numerical': 0.0014475271411338963, 'mean_word_length': 2.724618149146451, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 59, 'https://': 3, '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': '3295547', 'n_tokens_mistral': 2649, 'n_tokens_neox': 2658, 'n_words': 420}