<commit_before>import React, { Component } from "react"
import Slider from "./slider"
import { options } from "../utils/typography"
import { scale, colors, space, radii } from "../utils/presets"
import Link from "gatsby-link"
import MdNavigateBefore from "react-icons/lib/md/navigate-before"
import MdNavigateNext from "react-icons/lib/md/navigate-next"
import { srOnly } from "../utils/styles"

const controlButtonStyles = {
  WebkitAppearance: `none`,
  color: colors.gray.calm,
  fontWeight: 700,
  border: 0,
  background: `transparent`,
  position: `absolute`,
  top: 0,
  bottom: 0,
  left: 0,
  padding: 0,
  fontSize: scale[5],
  width: space[8],
  textAlign: `center`,
  "&:hover": {
    cursor: `pointer`,
    color: colors.gatsby,
    background: colors.ui.whisper,
  },
  "&:active": { background: colors.ui.light },
}

class Rotator extends Component {
  state = {
    item: 0,
    size: {},
  }
  sliderContainer = React.createRef()
  intervalId = null

  _clearInterval() {
    if (this.intervalId) {
      clearInterval(this.intervalId)
      this.intervalId = null
    }
  }

  decrementItem = () => {
    this._clearInterval()
    this.setState({
      item:
        (this.state.item + this.props.items.length - 1) %
        this.props.items.length,
    })
  }

  incrementItemAndClearInterval = () => {
    this._clearInterval()
    this.incrementItem()
  }

  incrementItem = () => {
    this.setState(state => {
      return {
        item: (state.item + 1) % this.props.items.length,
      }
    })
  }

  componentDidMount() {
    if (this.shouldAnimate()) {
      requestAnimationFrame(() => {
        this.intervalId = setInterval(this.incrementItem, 5000)
        this.setState({ size: this.getDimensions() })
      })
    }
  }

  componentWillUnmount() {
    clearInterval(this.intervalId)
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.shouldAnimate() && prevState.item !== this.state.item) {
      requestAnimationFrame(() => {
        this.setState({ size: this.getDimensions() })
      })
    }
  }

  getDimensions() {
    if (this.sliderContainer.current === null) {
      return {
        width: `auto`,
        height: `auto`,
      }
    }

    return this.sliderContainer.current.getBoundingClientRect()
  }

  shouldAnimate() {
    const mediaQuery = window.matchMedia(`(prefers-reduced-motion)`)
    return !mediaQuery || !mediaQuery.matches
  }

  render() {
    const { text, pluginName } = this.props.items[this.state.item]
    const enableSlider = this.shouldAnimate() && this.intervalId

    return (
      <div
        css={{
          borderTop: `1px solid ${colors.gray.border}`,<commit_msg>fix(www): ensure rotator is ssr-friendly (#12726)<commit_after>import React, { Component } from "react"
import Slider from "./slider"
import { options } from "../utils/typography"
import { scale, colors, space, radii } from "../utils/presets"
import Link from "gatsby-link"
import MdNavigateBefore from "react-icons/lib/md/navigate-before"
import MdNavigateNext from "react-icons/lib/md/navigate-next"
import { srOnly } from "../utils/styles"

const controlButtonStyles = {
  WebkitAppearance: `none`,
  color: colors.gray.calm,
  fontWeight: 700,
  border: 0,
  background: `transparent`,
  position: `absolute`,
  top: 0,
  bottom: 0,
  left: 0,
  padding: 0,
  fontSize: scale[5],
  width: space[8],
  textAlign: `center`,
  "&:hover": {
    cursor: `pointer`,
    color: colors.gatsby,
    background: colors.ui.whisper,
  },
  "&:active": { background: colors.ui.light },
}

class Rotator extends Component {
  state = {
    shouldAnimate: false,
    item: 0,
    size: {},
  }
  sliderContainer = React.createRef()
  intervalId = null

  _clearInterval() {
    if (this.intervalId) {
      clearInterval(this.intervalId)
      this.intervalId = null
    }
  }

  decrementItem = () => {
    this._clearInterval()
    this.setState({
      item:
        (this.state.item + this.props.items.length - 1) %
        this.props.items.length,
    })
  }

  incrementItemAndClearInterval = () => {
    this._clearInterval()
    this.incrementItem()
  }

  incrementItem = () => {
    this.setState(state => {
      return {
        item: (state.item + 1) % this.props.items.length,
      }
    })
  }

  componentDidMount() {
    const shouldAnimate = this.shouldAnimate()
    if (shouldAnimate) {
      requestAnimationFrame(() => {
        this.intervalId = setInterval(this.incrementItem, 5000)
        this.setState({ shouldAnimate, size: this.getDimensions() })
      })
    }
  }

  componentWillUnmount() {
    clearInterval(this.intervalId)
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState.shouldAnimate && prevState.item !== this.state.item) {
      requestAnimationFrame(() => {
        this.setState({ size: this.getDimensions() })
      })
    }
  }

  getDimensions() {
    if (this.sliderContainer.current === null) {
      return {
        width: `auto`,
        height: `auto`,
      }
    }

    return this.sliderContainer.current.getBoundingClientRect()
  }

  shouldAnimate() {
    const mediaQuery = window.matchMedia(`(prefers-reduced-motion)`)
    return !mediaQuery || !mediaQuery.matches
  }

  render() {
    const { shouldAnimate } = this.state
    const { text, pluginName } = this.props.items[this.state.item]
    const enableSlider = shouldAnimate && this.intervalId

    return (
      <div
        css={{
          borderTop: `1px solid ${colors.gray.border}`,
{'fraction_non_alphanumeric': 0.1431185944363104, 'fraction_numerical': 0.007503660322108346, 'mean_word_length': 2.8485915492957745, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, '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': '7195489', 'n_tokens_mistral': 1810, 'n_tokens_neox': 1756, 'n_words': 345}