Skip to content
Snippets Groups Projects
home.js 6.8 KiB
Newer Older
Julia Friesel's avatar
Julia Friesel committed
import React, { Component } from 'react'
import { ScrollView, View, TouchableHighlight, Dimensions } from 'react-native'
import { LocalDate, ChronoUnit } from 'js-joda'
Julia Friesel's avatar
Julia Friesel committed
import Icon from 'react-native-vector-icons/Entypo'
import { secondaryColor, cycleDayColor, periodColor } from '../styles'
import {
  home as labels,
  bleedingPrediction as predictLabels,
  shared,
} from '../i18n/en/labels'
import links from '../i18n/en/links'
import cycleModule from '../lib/cycle'
Julia Friesel's avatar
Julia Friesel committed
import { getFertilityStatusForDay } from '../lib/sympto-adapter'
import styles from '../styles'
Julia Friesel's avatar
Julia Friesel committed
import AppText from './app-text'
import DripHomeIcon from '../assets/drip-home-icons'
Julia Friesel's avatar
Julia Friesel committed
import Button from './button'
const ShowMoreToggler = ({ isShowingMore, onToggle }) => {
  const {height, width} = Dimensions.get('window')
  const leftPosition = isShowingMore ? 10 : width - 40
  const style = isShowingMore ? styles.showLess : styles.showMore
  const topPosition = height / 2 - styles.header.height - 30

  return (
    <TouchableHighlight
      onPress={onToggle}
      style={[style, { top: topPosition, left: leftPosition}]}
    >
      <View style={{alignItems: 'center'}}>
        <AppText>{isShowingMore ? shared.less : shared.more}</AppText>
        <Icon name='chevron-thin-down' />
      </View>
    </TouchableHighlight>
  )
}

const IconText = ({ children, wrapperStyles }) => {
  return (
    <View style={[styles.homeIconTextWrapper, wrapperStyles]}>
      <AppText style={styles.iconText}>
        { children }
    </View>
  )
}

const HomeElement = ({ children, onPress, buttonColor, buttonLabel  }) => {
  return (
      onPress={ onPress }
      style={ styles.homeIconElement }
    >
      { children }
      <Button
        style={styles.homeButton}
        onPress={ onPress }
        backgroundColor={ buttonColor }>
        { buttonLabel }
      </Button>
export default class Home extends Component {
Julia Friesel's avatar
Julia Friesel committed
  constructor(props) {
    super(props)
    const { getCycleDayNumber, getPredictedMenses } = cycleModule()
    this.getCycleDayNumber = getCycleDayNumber
    this.getBleedingPrediction = getPredictedMenses
    this.todayDateString = LocalDate.now().toString()
Julia Friesel's avatar
Julia Friesel committed
    const prediction = this.getBleedingPrediction()
    const fertilityStatus = getFertilityStatusForDay(this.todayDateString)
      isShowingMore: false,
Julia Friesel's avatar
Julia Friesel committed
      cycleDayNumber: this.getCycleDayNumber(this.todayDateString),
      predictionText: determinePredictionText(prediction),
      bleedingPredictionRange: getBleedingPredictionRange(prediction),
      ...fertilityStatus
Julia Friesel's avatar
Julia Friesel committed
  }

Julia Friesel's avatar
Julia Friesel committed
  passTodayTo(componentName) {
    const { navigate } = this.props
    navigate(componentName, { date: LocalDate.now().toString() })
  toggleShowingMore = () => {
    this.setState({ isShowingMore: !this.state.isShowingMore })
  }

Julia Friesel's avatar
Julia Friesel committed
  render() {
    const { isShowingMore, cycleDayNumber, phase, status } = this.state
    const { navigate } = this.props
    const cycleDayMoreText = cycleDayNumber ?
      labels.cycleDayKnown(cycleDayNumber) :
Julia Friesel's avatar
Julia Friesel committed
      labels.cycleDayNotEnoughInfo

    const { statusText } = this.state
Sofiya Tepikin's avatar
Sofiya Tepikin committed

Julia Friesel's avatar
Julia Friesel committed
    return (
Julia Friesel's avatar
Julia Friesel committed
      <View flex={1}>
        <ScrollView>
          <View style={styles.homeView}>

            <HomeElement
              onPress={ () => this.passTodayTo('CycleDay') }
              buttonColor={ cycleDayColor }
              buttonLabel={ labels.editToday }
Julia Friesel's avatar
Julia Friesel committed
            >
                <DripHomeIcon name="circle" size={80} color={cycleDayColor}/>
Julia Friesel's avatar
Julia Friesel committed
              </View>
              <IconText wrapperStyles={styles.wrapperCycle}>
                {cycleDayNumber || labels.unknown}
              </IconText>
              { isShowingMore &&
Julia Friesel's avatar
Julia Friesel committed
                  <AppText style={styles.paragraph}>{cycleDayMoreText}</AppText>
              }
            </HomeElement>
            <HomeElement
              onPress={ () => this.passTodayTo('BleedingEditView') }
              buttonColor={ periodColor }
              buttonLabel={ labels.trackPeriod }
Julia Friesel's avatar
Julia Friesel committed
            >
                <DripHomeIcon name="drop" size={105} color={periodColor} />
Julia Friesel's avatar
Julia Friesel committed
              </View>

              <IconText wrapperStyles={styles.wrapperDrop}>
                {this.state.bleedingPredictionRange}
              </IconText>

              { isShowingMore &&
Julia Friesel's avatar
Julia Friesel committed
                <AppText style={styles.paragraph}>
                  {this.state.predictionText}
                </AppText>
              }
            </HomeElement>
            <HomeElement
              onPress={ () => navigate('Chart') }
              buttonColor={ secondaryColor }
              buttonLabel={ labels.checkFertility }
Julia Friesel's avatar
Julia Friesel committed
            >
              <View style={styles.homeCircle}/>
              <IconText wrapperStyles={styles.wrapperCircle}>
                { phase ? phase.toString() : labels.unknown }
              </IconText>

              { phase &&
                <AppText>{`${labels.phase(phase)} (${status})`}</AppText>
Julia Friesel's avatar
Julia Friesel committed
              }
              { isShowingMore &&
                <View>
                  <AppText styles={styles.paragraph}>
emelko's avatar
emelko committed
                    { `${statusText} ${links.wiki.url}.` }
Julia Friesel's avatar
Julia Friesel committed
              }
            </HomeElement>
Julia Friesel's avatar
Julia Friesel committed
        </ScrollView>
        <ShowMoreToggler
          isShowingMore={isShowingMore}
          onToggle={this.toggleShowingMore}
        />
Julia Friesel's avatar
Julia Friesel committed
      </View>
Julia Friesel's avatar
Julia Friesel committed
    )
  }
Julia Friesel's avatar
Julia Friesel committed
function determinePredictionText(bleedingPrediction) {
  if (!bleedingPrediction.length) return predictLabels.noPrediction
  const todayDate = LocalDate.now()
  const bleedingStart = LocalDate.parse(bleedingPrediction[0][0])
Julia Friesel's avatar
Julia Friesel committed
  const bleedingEnd = LocalDate.parse(
    bleedingPrediction[0][ bleedingPrediction[0].length - 1 ]
  )
  if (todayDate.isBefore(bleedingStart)) {
Julia Friesel's avatar
Julia Friesel committed
    return predictLabels.predictionInFuture(
      todayDate.until(bleedingStart, ChronoUnit.DAYS),
      todayDate.until(bleedingEnd, ChronoUnit.DAYS)
    )
  }
  if (todayDate.isAfter(bleedingEnd)) {
Julia Friesel's avatar
Julia Friesel committed
    return predictLabels.predictionInPast(
      bleedingStart.toString(), bleedingEnd.toString()
    )
  }
  const daysToEnd = todayDate.until(bleedingEnd, ChronoUnit.DAYS)
  if (daysToEnd === 0) {
Julia Friesel's avatar
Julia Friesel committed
    return predictLabels.predictionStartedNoDaysLeft
  } else if (daysToEnd === 1) {
Julia Friesel's avatar
Julia Friesel committed
    return predictLabels.predictionStarted1DayLeft
Julia Friesel's avatar
Julia Friesel committed
    return predictLabels.predictionStartedXDaysLeft(daysToEnd)
emelko's avatar
emelko committed
}
Julia Friesel's avatar
Julia Friesel committed

function getBleedingPredictionRange(prediction) {
  if (!prediction.length) return labels.unknown
  const todayDate = LocalDate.now()
  const bleedingStart = LocalDate.parse(prediction[0][0])
  const bleedingEnd = LocalDate.parse(prediction[0][ prediction[0].length - 1 ])
  if (todayDate.isBefore(bleedingStart)) {
    return `${todayDate.until(bleedingStart, ChronoUnit.DAYS)}-${todayDate.until(bleedingEnd, ChronoUnit.DAYS)}`
  }
  if (todayDate.isAfter(bleedingEnd)) {
    return labels.unknown
  }
  return '0'
}