<commit_before>// @flow

import React from 'react'
import {StyleSheet} from 'react-native'
import type {BusLineType} from './types'
import MapView from 'react-native-maps'
import moment from 'moment-timezone'
import {NoticeView} from '../../components/notice'
import type {TopLevelViewPropsType} from '../../types'
import {getScheduleForNow} from './lib'
import zip from 'lodash/zip'
import uniqBy from 'lodash/uniqBy'

import {data as defaultBusLines} from '../../../../docs/bus-times.json'

const TIMEZONE = 'America/Winnipeg'

const styles = StyleSheet.create({
  map: {...StyleSheet.absoluteFillObject},
})

export class BusMapView extends React.PureComponent {
  static navigationOptions = ({navigation}) => ({
    title: `${navigation.state.params.line} Map`,
  })

  static defaultProps = {
    busLines: defaultBusLines,
  }

  state = {
    intervalId: 0,
    now: moment.tz(TIMEZONE),
    region: {
      latitude: 44.44946671480875,
      latitudeDelta: 0.06175530810822494,
      longitude: -93.17014753996669,
      longitudeDelta: 0.05493163793703104,
    },
  }

  componentWillMount() {
    // This updates the screen every second, so that the "next bus" times are
    // updated without needing to leave and come back.
    this.setState(() => ({intervalId: setInterval(this.updateTime, 5000)}))
  }

  componentWillUnmount() {
    clearTimeout(this.state.intervalId)
  }

  props: TopLevelViewPropsType & {
    busLines: BusLineType[],
    navigation: {
      state: {
        params: {
          line: string,
        },
      },
    },
  }

  onRegionChange = (region: {
    latitude: number,
    latitudeDelta: number,
    longitude: number,
    longitudeDelta: number,
  }) => {
    this.setState(() => ({region}))
  }

  updateTime = () => {
    this.setState(() => ({now: moment.tz(TIMEZONE)}))
  }

  render() {
    let {now} = this.state
    // now = moment.tz('Fri 8:13pm', 'ddd h:mma', true, TIMEZONE)
    const busLines = this.props.busLines
    const lineToDisplay = this.props.navigation.state.params.line
    const activeBusLine = busLines.find(({line}) => line === lineToDisplay)

    if (!activeBusLine) {
      const lines = busLines.map(({line}) => line).join(', ')
      const notice = `The line "${lineToDisplay}" was not found among ${lines}`
      return <NoticeView text={notice} />
    }

    const schedule = getScheduleForNow(activeBusLine.schedules, now)
    if (!schedule) {
      const notice = `No schedule was found for today, ${now.format('dddd')}`
      return <NoticeView text={notice} />
    }

    const coords = schedule.coordinates || []
    if (!coords.length) {
      const notice = `No coordinates have been provided for today's (${now.format(
        'dddd',
      )}) schedule on the "${lineToDisplay}" line`
      return <NoticeView text={notice} />
    }

    const markers = uniqBy(
      zip(coords, schedule.stops),
      ([[lat, lng]]) => `${lat},${lng}`,
    )

    return (
      <MapView
        region={this.state.region}
        style={styles.map}
        onRegionChange={this.onRegionChange}
        loadingEnabled={true}
      >
        {markers.map(([[latitude, longitude], title], i) =>
          <MapView.Marker
            key={i}
            coordinate={{latitude, longitude}}
            title={title}
            // description={marker.description}
            // TODO: add "next arrival" time as the description
          />,
        )}
      </MapView>
    )
  }
}<commit_msg>Initial region state logic to bus map<commit_after>// @flow

import React from 'react'
import {StyleSheet} from 'react-native'
import type {BusLineType} from './types'
import MapView from 'react-native-maps'
import moment from 'moment-timezone'
import {NoticeView} from '../../components/notice'
import type {TopLevelViewPropsType} from '../../types'
import {getScheduleForNow} from './lib'
import zip from 'lodash/zip'
import uniqBy from 'lodash/uniqBy'
import isEqual from 'lodash/isEqual'

import {data as defaultBusLines} from '../../../../docs/bus-times.json'

const TIMEZONE = 'America/Winnipeg'

const styles = StyleSheet.create({
  map: {...StyleSheet.absoluteFillObject},
})

export class BusMapView extends React.PureComponent {
  static navigationOptions = ({navigation}) => ({
    title: `${navigation.state.params.line} Map`,
  })

  static defaultProps = {
    busLines: defaultBusLines,
  }

  state = {
    intervalId: 0,
    now: moment.tz(TIMEZONE),
    initialRegion: {
      latitude: 44.44946671480875,
      latitudeDelta: 0.06175530810822494,
      longitude: -93.17014753996669,
      longitudeDelta: 0.05493163793703104,
    },
  }

  componentWillMount() {
    // This updates the screen every second, so that the "next bus" times are
    // updated without needing to leave and come back.
    this.setState(() => ({intervalId: setInterval(this.updateTime, 5000)}))
  }

  componentWillUnmount() {
    clearTimeout(this.state.intervalId)
  }

  props: TopLevelViewPropsType & {
    busLines: BusLineType[],
    navigation: {
      state: {
        params: {
          line: string,
        },
      },
    },
  }

  onRegionChangeComplete = (region: {
    latitude: number,
    latitudeDelta: number,
    longitude: number,
    longitudeDelta: number,
  }) => {
    this.setState(state => {
      const initialRegion = state.initialRegion

      if (initialRegion && isEqual(initialRegion, region)) {
        return state
      }

      return {initialRegion: region}
    })
  }

  updateTime = () => {
    this.setState(() => ({now: moment.tz(TIMEZONE)}))
  }

  render() {
    let {now} = this.state
    // now = moment.tz('Fri 8:13pm', 'ddd h:mma', true, TIMEZONE)
    const busLines = this.props.busLines
    const lineToDisplay = this.props.navigation.state.params.line
    const activeBusLine = busLines.find(({line}) => line === lineToDisplay)

    if (!activeBusLine) {
      const lines = busLines.map(({line}) => line).join(', ')
      const notice = `The line "${lineToDisplay}" was not found among ${lines}`
      return <NoticeView text={notice} />
    }

    const schedule = getScheduleForNow(activeBusLine.schedules, now)
    if (!schedule) {
      const notice = `No schedule was found for today, ${now.format('dddd')}`
      return <NoticeView text={notice} />
    }

    const coords = schedule.coordinates || []
    if (!coords.length) {
      const notice = `No coordinates have been provided for today's (${now.format(
        'dddd',
      )}) schedule on the "${lineToDisplay}" line`
      return <NoticeView text={notice} />
    }

    const markers = uniqBy(
      zip(coords, schedule.stops),
      ([[lat, lng]]) => `${lat},${lng}`,
    )

    return (
      <MapView
        region={this.state.initialRegion}
        style={styles.map}
        onRegionChangeComplete={this.onRegionChangeComplete}
        loadingEnabled={true}
      >
        {markers.map(([[latitude, longitude], title], i) =>
          <MapView.Marker
            key={i}
            coordinate={{latitude, longitude}}
            title={title}
            // description={marker.description}
            // TODO: add "next arrival" time as the description
          />,
        )}
      </MapView>
    )
  }
}
{'fraction_non_alphanumeric': 0.14196329254727474, 'fraction_numerical': 0.021134593993325918, 'mean_word_length': 2.7541753653444676, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 35, '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': '7543097', 'n_tokens_mistral': 2319, 'n_tokens_neox': 2192, 'n_words': 533}