<commit_before>import clsx from 'clsx';
import React from 'react';
import throttle from 'lodash-es/throttle';
import debounce from 'lodash-es/debounce';
import isEqual from 'react-fast-compare';
import ResizeObserver from 'resize-observer-polyfill';
import {
  LEFT,
  RIGHT,
  UP,
  DOWN,
} from 'react-swipeable';
import {
  arrayOf,
  bool,
  func,
  number,
  oneOf,
  shape,
  string,
} from 'prop-types';
import Item from 'src/Item';
import Fullscreen from 'src/controls/Fullscreen';
import LeftNav from 'src/controls/LeftNav';
import RightNav from 'src/controls/RightNav';
import PlayPause from 'src/controls/PlayPause';
import SwipeWrapper from 'src/SwipeWrapper';

const screenChangeEvents = [
  'fullscreenchange',
  'MSFullscreenChange',
  'mozfullscreenchange',
  'webkitfullscreenchange',
];

const imageSetType = arrayOf(shape({
  srcSet: string,
  media: string,
}));

function isEnterOrSpaceKey(event) {
  const key = parseInt(event.keyCode || event.which || 0, 10);
  const ENTER_KEY_CODE = 66;
  const SPACEBAR_KEY_CODE = 62;
  return key === ENTER_KEY_CODE || key === SPACEBAR_KEY_CODE;
}

class ImageGallery extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      currentIndex: props.startIndex,
      thumbsTranslate: 0,
      thumbsSwipedTranslate: 0,
      currentSlideOffset: 0,
      galleryWidth: 0,
      thumbnailsWrapperWidth: 0,
      thumbnailsWrapperHeight: 0,
      thumbsStyle: { transition: `all ${props.slideDuration}ms ease-out` },
      isFullscreen: false,
      isSwipingThumbnail: false,
      isPlaying: false,
    };
    this.loadedImages = {};
    this.imageGallery = React.createRef();
    this.thumbnailsWrapper = React.createRef();
    this.thumbnails = React.createRef();
    this.imageGallerySlideWrapper = React.createRef();

    // bindings
    this.handleImageLoaded = this.handleImageLoaded.bind(this);
    this.handleKeyDown = this.handleKeyDown.bind(this);
    this.handleMouseDown = this.handleMouseDown.bind(this);
    this.handleTouchMove = this.handleTouchMove.bind(this);
    this.handleOnSwiped = this.handleOnSwiped.bind(this);
    this.handleScreenChange = this.handleScreenChange.bind(this);
    this.handleSwiping = this.handleSwiping.bind(this);
    this.handleThumbnailSwiping = this.handleThumbnailSwiping.bind(this);
    this.handleOnThumbnailSwiped = this.handleOnThumbnailSwiped.bind(this);
    this.onThumbnailMouseLeave = this.onThumbnailMouseLeave.bind(this);
    this.handleImageError = this.handleImageError.bind(this);
    this.pauseOrPlay = this.pauseOrPlay.bind(this);
    this.renderThumbInner = this.renderThumbInner.bind(this);
    this.renderItem = this.renderItem.bind(this);
    this.slideLeft = this.slideLeft.bind(this);
    this.slideRight = this.slideRight.bind(this);
    this.toggleFullScreen = this.toggleFullScreen.bind(this);
    this.togglePlay = this.togglePlay.bind(this);

    // Used to update the throttle if slideDuration changes
    this.unthrottledSlideToIndex = this.slideToIndex;
    this.slideToIndex = throttle(
      this.unthrottledSlideToIndex, props.slideDuration, { trailing: false },
    );

    if (props.lazyLoad) {
      this.lazyLoaded = [];
    }
  }

  componentDidMount() {
    const { autoPlay, useWindowKeyDown } = this.props;
    if (autoPlay) {
      this.play();
    }
    if (useWindowKeyDown) {
      window.addEventListener('keydown', this.handleKeyDown);
    } else {
      this.imageGallery.current.addEventListener('keydown', this.handleKeyDown);
    }
    window.addEventListener('mousedown', this.handleMouseDown);
    window.addEventListener('touchmove', this.handleTouchMove, { passive: false });
    this.initResizeObserver(this.imageGallerySlideWrapper);
    this.addScreenChangeEvent();
  }

  componentDidUpdate(prevProps, prevState) {
    const {
      items,
      lazyLoad,
      slideDuration,
      slideInterval,
      startIndex,
      thumbnailPosition,
      showThumbnails,
      useWindowKeyDown,
    } = this.props;
    const { currentIndex } = this.state;
    const itemsSizeChanged = prevProps.items.length !== items.length;
    const itemsChanged = !isEqual(prevProps.items, items);
    const startIndexUpdated = prevProps.startIndex !== startIndex;
    const thumbnailsPositionChanged = prevProps.thumbnailPosition !== thumbnailPosition;
    const showThumbnailsChanged = prevProps.showThumbnails !== showThumbnails;

    if (slideInterval !== prevProps.slideInterval || slideDuration !== prevProps.slideDuration) {
      // refresh setInterval
      this.pause();
      this.play();
    }

    if (thumbnailsPositionChanged) {
      // re-initialize resizeObserver because slides was unmounted and mounted again
      this.removeResizeObserver();
      this.initResizeObserver(this.imageGallerySlideWrapper);
    }

    if (itemsSizeChanged || showThumbnailsChanged) {
      this.handleResize();
    }
    if (prevState.currentIndex !== currentIndex) {
      this.slideThumbnailBar();
    }
    // if slideDuration changes, update slideToIndex throttle
    if (prevProps.slideDuration !== slideDuration) {
      this.slideToIndex = throttle(
        this.unthrottledSlideToIndex, slideDuration, { trailing: false },
      );
    }
    if (lazyLoad && (!prevProps.lazyLoad || itemsChanged)) {
      this.lazyLoaded = [];
    }

    if (useWindowKeyDown !== prevProps.useWindowKeyDown) {
      if (useWindowKeyDown) {<commit_msg>prevent start playing on interval or duration change (#637)<commit_after>import clsx from 'clsx';
import React from 'react';
import throttle from 'lodash-es/throttle';
import debounce from 'lodash-es/debounce';
import isEqual from 'react-fast-compare';
import ResizeObserver from 'resize-observer-polyfill';
import {
  LEFT,
  RIGHT,
  UP,
  DOWN,
} from 'react-swipeable';
import {
  arrayOf,
  bool,
  func,
  number,
  oneOf,
  shape,
  string,
} from 'prop-types';
import Item from 'src/Item';
import Fullscreen from 'src/controls/Fullscreen';
import LeftNav from 'src/controls/LeftNav';
import RightNav from 'src/controls/RightNav';
import PlayPause from 'src/controls/PlayPause';
import SwipeWrapper from 'src/SwipeWrapper';

const screenChangeEvents = [
  'fullscreenchange',
  'MSFullscreenChange',
  'mozfullscreenchange',
  'webkitfullscreenchange',
];

const imageSetType = arrayOf(shape({
  srcSet: string,
  media: string,
}));

function isEnterOrSpaceKey(event) {
  const key = parseInt(event.keyCode || event.which || 0, 10);
  const ENTER_KEY_CODE = 66;
  const SPACEBAR_KEY_CODE = 62;
  return key === ENTER_KEY_CODE || key === SPACEBAR_KEY_CODE;
}

class ImageGallery extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      currentIndex: props.startIndex,
      thumbsTranslate: 0,
      thumbsSwipedTranslate: 0,
      currentSlideOffset: 0,
      galleryWidth: 0,
      thumbnailsWrapperWidth: 0,
      thumbnailsWrapperHeight: 0,
      thumbsStyle: { transition: `all ${props.slideDuration}ms ease-out` },
      isFullscreen: false,
      isSwipingThumbnail: false,
      isPlaying: false,
    };
    this.loadedImages = {};
    this.imageGallery = React.createRef();
    this.thumbnailsWrapper = React.createRef();
    this.thumbnails = React.createRef();
    this.imageGallerySlideWrapper = React.createRef();

    // bindings
    this.handleImageLoaded = this.handleImageLoaded.bind(this);
    this.handleKeyDown = this.handleKeyDown.bind(this);
    this.handleMouseDown = this.handleMouseDown.bind(this);
    this.handleTouchMove = this.handleTouchMove.bind(this);
    this.handleOnSwiped = this.handleOnSwiped.bind(this);
    this.handleScreenChange = this.handleScreenChange.bind(this);
    this.handleSwiping = this.handleSwiping.bind(this);
    this.handleThumbnailSwiping = this.handleThumbnailSwiping.bind(this);
    this.handleOnThumbnailSwiped = this.handleOnThumbnailSwiped.bind(this);
    this.onThumbnailMouseLeave = this.onThumbnailMouseLeave.bind(this);
    this.handleImageError = this.handleImageError.bind(this);
    this.pauseOrPlay = this.pauseOrPlay.bind(this);
    this.renderThumbInner = this.renderThumbInner.bind(this);
    this.renderItem = this.renderItem.bind(this);
    this.slideLeft = this.slideLeft.bind(this);
    this.slideRight = this.slideRight.bind(this);
    this.toggleFullScreen = this.toggleFullScreen.bind(this);
    this.togglePlay = this.togglePlay.bind(this);

    // Used to update the throttle if slideDuration changes
    this.unthrottledSlideToIndex = this.slideToIndex;
    this.slideToIndex = throttle(
      this.unthrottledSlideToIndex, props.slideDuration, { trailing: false },
    );

    if (props.lazyLoad) {
      this.lazyLoaded = [];
    }
  }

  componentDidMount() {
    const { autoPlay, useWindowKeyDown } = this.props;
    if (autoPlay) {
      this.play();
    }
    if (useWindowKeyDown) {
      window.addEventListener('keydown', this.handleKeyDown);
    } else {
      this.imageGallery.current.addEventListener('keydown', this.handleKeyDown);
    }
    window.addEventListener('mousedown', this.handleMouseDown);
    window.addEventListener('touchmove', this.handleTouchMove, { passive: false });
    this.initResizeObserver(this.imageGallerySlideWrapper);
    this.addScreenChangeEvent();
  }

  componentDidUpdate(prevProps, prevState) {
    const {
      items,
      lazyLoad,
      slideDuration,
      slideInterval,
      startIndex,
      thumbnailPosition,
      showThumbnails,
      useWindowKeyDown,
    } = this.props;
    const { currentIndex, isPlaying } = this.state;
    const itemsSizeChanged = prevProps.items.length !== items.length;
    const itemsChanged = !isEqual(prevProps.items, items);
    const startIndexUpdated = prevProps.startIndex !== startIndex;
    const thumbnailsPositionChanged = prevProps.thumbnailPosition !== thumbnailPosition;
    const showThumbnailsChanged = prevProps.showThumbnails !== showThumbnails;

    if (slideInterval !== prevProps.slideInterval || slideDuration !== prevProps.slideDuration) {
      // refresh setInterval
      if (isPlaying) {
        this.pause();
        this.play();
      }
    }

    if (thumbnailsPositionChanged) {
      // re-initialize resizeObserver because slides was unmounted and mounted again
      this.removeResizeObserver();
      this.initResizeObserver(this.imageGallerySlideWrapper);
    }

    if (itemsSizeChanged || showThumbnailsChanged) {
      this.handleResize();
    }
    if (prevState.currentIndex !== currentIndex) {
      this.slideThumbnailBar();
    }
    // if slideDuration changes, update slideToIndex throttle
    if (prevProps.slideDuration !== slideDuration) {
      this.slideToIndex = throttle(
        this.unthrottledSlideToIndex, slideDuration, { trailing: false },
      );
    }
    if (lazyLoad && (!prevProps.lazyLoad || itemsChanged)) {
      this.lazyLoaded = [];
    }

    if (useWindowKeyDown !== prevProps.useWindowKeyDown) {
      if (useWindowKeyDown) {
{'fraction_non_alphanumeric': 0.11180237877401647, 'fraction_numerical': 0.0026532479414455626, 'mean_word_length': 3.790096406660824, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '725404', 'n_tokens_mistral': 3418, 'n_tokens_neox': 3329, 'n_words': 625}