<commit_before>import React, { Component, PropTypes } from 'react';
import cx from 'classnames';

import mapStyle from '!!file!./mapStyle.json';
import mapboxgl from '../../utils/mapboxgl/mapboxgl';
import lngLat from '../../utils/propTypeValidations/lngLat';
import noop from '../../utils/noop';

import { DEFAULT_CENTER, DEFAULT_MAX_ZOOM, DEFAULT_ZOOM } from '../../constants/mapbox';

import css from './BaseMap.css';
import tile from './images/tile.jpg';

export default class BaseMap extends Component {
  static propTypes = {
    allowWrap: PropTypes.bool,
    center: lngLat,
    className: PropTypes.string,
    dragRotate: PropTypes.bool,
    mapClassName: PropTypes.string,
    mapboxStyle: React.PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.object,
    ]),
    maxZoom: PropTypes.number,
    onClick: PropTypes.func,
    onMapLoad: PropTypes.func,
    onMoveEnd: PropTypes.func,
    zoom: PropTypes.number,
  };

  static defaultProps = {
    allowWrap: true,
    center: DEFAULT_CENTER,
    dragRotate: false,
    mapboxStyle: mapStyle,
    maxZoom: DEFAULT_MAX_ZOOM,
    onClick: noop,
    onMapLoad: noop,
    onMoveEnd: noop,
    zoom: DEFAULT_ZOOM,
  };

  componentDidMount() {
    const {
      allowWrap,
      center,
      dragRotate,
      mapboxStyle,
      maxZoom,
      onClick,
      onMapLoad,
      zoom,
    } = this.props;

    this.map = new mapboxgl.Map({
      container: this.mapContainer,
      renderWorldCopies: allowWrap,
      style: mapboxStyle,
      center,
      dragRotate,
      maxZoom,
      zoom,
    });

    this.map.on('click', onClick);
    this.map.on('moveend', this.handleMoveEnd);
    this.map.on('load', (event) => { onMapLoad(event.target); });
  }

  componentWillReceiveProps(nextProps) {
    const { center, zoom } = this.props;
    const { center: nextCenter, zoom: nextZoom } = nextProps;

    if (center[0] !== nextCenter[0] || center[1] !== nextCenter[1]) this.map.setCenter(nextCenter);
    if (zoom !== nextZoom) this.map.setZoom(nextZoom);
  }

  componentWillUnmount() {
    const { onClick } = this.props;

    this.map.off('click', onClick);
    this.map.off('moveend', this.handleMoveEnd);
    this.map.remove();
  }

  getMaboxGL() {
    return this.map;
  }

  easeTo(options) {
    this.map.easeTo(options, { user: false });
  }

  fitBounds(bounds, options) {
    this.map.fitBounds(bounds, options, { user: false });
  }

  handleMoveEnd = (data) => {
    const { onMoveEnd } = this.props;
    const { user, ...rest } = data;<commit_msg>Fix programmatic centering of the map when the `center` prop changes<commit_after>import React, { Component, PropTypes } from 'react';
import cx from 'classnames';

import mapStyle from '!!file!./mapStyle.json';
import mapboxgl from '../../utils/mapboxgl/mapboxgl';
import lngLat from '../../utils/propTypeValidations/lngLat';
import noop from '../../utils/noop';

import { DEFAULT_CENTER, DEFAULT_MAX_ZOOM, DEFAULT_ZOOM } from '../../constants/mapbox';

import css from './BaseMap.css';
import tile from './images/tile.jpg';

export default class BaseMap extends Component {
  static propTypes = {
    allowWrap: PropTypes.bool,
    center: lngLat,
    className: PropTypes.string,
    dragRotate: PropTypes.bool,
    mapClassName: PropTypes.string,
    mapboxStyle: React.PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.object,
    ]),
    maxZoom: PropTypes.number,
    onClick: PropTypes.func,
    onMapLoad: PropTypes.func,
    onMoveEnd: PropTypes.func,
    zoom: PropTypes.number,
  };

  static defaultProps = {
    allowWrap: true,
    center: DEFAULT_CENTER,
    dragRotate: false,
    mapboxStyle: mapStyle,
    maxZoom: DEFAULT_MAX_ZOOM,
    onClick: noop,
    onMapLoad: noop,
    onMoveEnd: noop,
    zoom: DEFAULT_ZOOM,
  };

  componentDidMount() {
    const {
      allowWrap,
      center,
      dragRotate,
      mapboxStyle,
      maxZoom,
      onClick,
      onMapLoad,
      zoom,
    } = this.props;

    this.map = new mapboxgl.Map({
      container: this.mapContainer,
      renderWorldCopies: allowWrap,
      style: mapboxStyle,
      center,
      dragRotate,
      maxZoom,
      zoom,
    });

    this.map.on('click', onClick);
    this.map.on('moveend', this.handleMoveEnd);
    this.map.on('load', (event) => { onMapLoad(event.target); });
  }

  componentWillReceiveProps(nextProps) {
    const { center, zoom } = this.props;
    const { center: nextCenter, zoom: nextZoom } = nextProps;

    if (center[0] !== nextCenter[0] || center[1] !== nextCenter[1]) {
      this.map.setCenter(nextCenter, { user: false });
    }
    if (zoom !== nextZoom) this.map.setZoom(nextZoom, { user: false });
  }

  componentWillUnmount() {
    const { onClick } = this.props;

    this.map.off('click', onClick);
    this.map.off('moveend', this.handleMoveEnd);
    this.map.remove();
  }

  getMaboxGL() {
    return this.map;
  }

  easeTo(options) {
    this.map.easeTo(options, { user: false });
  }

  fitBounds(bounds, options) {
    this.map.fitBounds(bounds, options, { user: false });
  }

  handleMoveEnd = (data) => {
    const { onMoveEnd } = this.props;
    const { user, ...rest } = data;
{'fraction_non_alphanumeric': 0.1393458486549255, 'fraction_numerical': 0.00154828720727695, 'mean_word_length': 2.9723289777094544, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '7428220', 'n_tokens_mistral': 1701, 'n_tokens_neox': 1703, 'n_words': 363}