<commit_before>import React from "react"

const ResponsiveContext = React.createContext({})

const shallowEqual = (a, b) => {
  for (let key in a) {
    if (a[key] !== b[key]) return false
  }
  return true
}

export interface Breakpoints {
  [breakpoint: string]: string
}

export interface ResponsiveProviderProps {
  initialBreakpoint?: string
  breakpoints: Breakpoints
}

export interface BreakpointState {
  [breakpoint: string]: boolean
}

export interface ResponsiveProviderState {
  breakpoints: BreakpointState
  mediaMatchers: MediaQueryList[]
  mqHandler: MediaQueryListListener | null
}

export class ResponsiveProvider extends React.Component<
  ResponsiveProviderProps,
  ResponsiveProviderState
> {
  constructor(props) {
    super(props)
    this.state = {
      breakpoints: {
        ...Object.keys(props.breakpoints)
          .map(breakpoint => ({
            [breakpoint]: breakpoint === props.initialBreakpoint ? true : false,
          }))
          .reduce((acc, curr) => ({ ...acc, ...curr }), {}),
      },
      mediaMatchers: [],
      mqHandler: null,
    }
    this.setupObservers(this.props.breakpoints)
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.children !== this.props.children) return true
    if (shallowEqual(this.state.breakpoints, nextState.breakpoints)) {
      return false
    }
    return true
  }

  componentWillUnmount() {
    if (this.state.mqHandler) {
      this.state.mediaMatchers.forEach(mediaQuery =>
        mediaQuery.removeListener(this.state.mqHandler)
      )
    }
  }

  setupObservers = breakpoints => {
    const breakpointKeys = Object.keys(breakpoints)
    const mediaMatchers = breakpointKeys.map(breakpoint =>
      window.matchMedia(breakpoints[breakpoint])
    )
    const mqHandler = () => {
      for (let i = 0; i < mediaMatchers.length; ++i) {
        this.setState({
          breakpoints: {
            ...this.state.breakpoints,
            [breakpointKeys[i]]: mediaMatchers[i].matches,
          },
        })
      }
    }
    this.setState({ mediaMatchers, mqHandler })
    mediaMatchers.forEach(mediaQuery => {
      mediaQuery.addListener(mqHandler)
    })
    mqHandler()
  }

  render() {
    return (
      <ResponsiveContext.Provider value={this.state.breakpoints}>
        {this.props.children}
      </ResponsiveContext.Provider>
    )
  }
}

export const Responsive: React.ComponentType<
  React.ConsumerProps<BreakpointState>
> =
  ResponsiveContext.Consumer<commit_msg>Refactor Responsive component to correctly render the intial breakpoint<commit_after>import React from "react"

const ResponsiveContext = React.createContext({})

const shallowEqual = (a, b) => {
  for (let key in a) {
    if (a[key] !== b[key]) return false
  }
  return true
}

export interface Breakpoints {
  [breakpoint: string]: string
}

export interface ResponsiveProviderProps {
  initialBreakpoint?: string
  breakpoints: Breakpoints
}

export interface BreakpointState {
  [breakpoint: string]: boolean
}

export interface ResponsiveProviderState {
  breakpoints: BreakpointState
  breakpointKeys: string[]
  mediaMatchers: MediaQueryList[]
}

export class ResponsiveProvider extends React.Component<
  ResponsiveProviderProps,
  ResponsiveProviderState
> {
  constructor(props) {
    super(props)
    const breakpointKeys = Object.keys(props.breakpoints)

    // Build initial breakpoint map --> { breakpoint1: false, breakpoint2: false, ...etc}
    let breakpoints = breakpointKeys
      .map(breakpoint => ({
        [breakpoint]: breakpoint === props.initialBreakpoint ? true : false,
      }))
      .reduce((acc, curr) => ({ ...acc, ...curr }), {})

    // Build up the MediaQueryList objects that observe mq changes
    const mediaMatchers = this.setupMatchers(props.breakpoints, breakpointKeys)

    // Perform initial breakpoint check so that first render is correct
    breakpoints = this.checkBreakpoints(
      breakpoints,
      breakpointKeys,
      mediaMatchers
    )

    this.state = {
      breakpoints,
      breakpointKeys,
      mediaMatchers,
    }
  }

  /**
   * Create an array of media matchers that can validate each breakpoint
   */
  setupMatchers = (breakpoints, breakpointKeys) => {
    return breakpointKeys.map(breakpoint =>
      window.matchMedia(breakpoints[breakpoint])
    )
  }

  /**
   * Uses the mediaMatchers list to build a map of the states of each breakpoint
   */
  checkBreakpoints = (breakpoints, breakpointKeys, mediaMatchers) => {
    let nextBreakpoints = breakpoints
    for (let i = 0; i < mediaMatchers.length; ++i) {
      nextBreakpoints = {
        ...nextBreakpoints,
        [breakpointKeys[i]]: mediaMatchers[i].matches,
      }
    }
    return nextBreakpoints
  }

  /**
   * The function that will be called any time a breakpoint changes
   */
  breakpointChangedCallback = () => {
    this.setState({
      breakpoints: this.checkBreakpoints(
        this.state.breakpoints,
        this.state.breakpointKeys,
        this.state.mediaMatchers
      ),
    })
  }

  /**
   * Creates the event listeners for each breakpoint
   */
  setupObservers = () => {
    const { breakpointChangedCallback } = this
    this.state.mediaMatchers.forEach(mediaQuery => {
      mediaQuery.addListener(breakpointChangedCallback)
    })
  }

  // Lifecyle methods

  shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.children !== this.props.children) return true
    if (shallowEqual(this.state.breakpoints, nextState.breakpoints)) {
      return false
    }
    return true
  }

  componentWillUnmount() {
    this.state.mediaMatchers.forEach(mediaQuery =>
      mediaQuery.removeListener(this.breakpointChangedCallback)
    )
  }

  componentDidMount() {
    this.setupObservers()
  }

  render() {
    return (
      <ResponsiveContext.Provider value={this.state.breakpoints}>
        {this.props.children}
      </ResponsiveContext.Provider>
    )
  }
}

export const Responsive: React.ComponentType<
  React.ConsumerProps<BreakpointState>
> =
  ResponsiveContext.Consumer
{'fraction_non_alphanumeric': 0.10785288270377734, 'fraction_numerical': 0.0006626905235255136, 'mean_word_length': 3.1012228260869565, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 32, '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': '652667', 'n_tokens_mistral': 1781, 'n_tokens_neox': 1758, 'n_words': 377}