import React, { Component } from 'react' import { ScrollView, View, TouchableOpacity, TouchableHighlight, Dimensions } from 'react-native' import { LocalDate, ChronoUnit } from 'js-joda' import Icon from 'react-native-vector-icons/Entypo' import { secondaryColor, cycleDayColor, periodColor } from '../styles' import { home as labels, bleedingPrediction as predictLabels, shared } from './labels' import CycleCircle from '../assets/home-circle' import Drop from '../assets/home-drop' import cycleModule from '../lib/cycle' import { getOrCreateCycleDay, getCycleDaysSortedByDate } from '../db' import { getFertilityStatusForDay } from '../lib/sympto-adapter' import styles from '../styles' import AppText, { AppTextLight } from './app-text' import nothingChanged from '../db/db-unchanged' export default class Home extends Component { constructor(props) { super(props) this.getCycleDayNumber = cycleModule().getCycleDayNumber this.getBleedingPrediction = cycleModule().getPredictedMenses this.todayDateString = LocalDate.now().toString() const prediction = this.getBleedingPrediction() const fertilityStatus = getFertilityStatusForDay(this.todayDateString) this.state = { cycleDayNumber: this.getCycleDayNumber(this.todayDateString), predictionText: determinePredictionText(prediction), bleedingPredictionRange: getBleedingPredictionRange(prediction), ...fertilityStatus } this.cycleDays = getCycleDaysSortedByDate() this.cycleDays.addListener(this.updateState) } updateState = (_, changes) => { if (nothingChanged(changes)) return const prediction = this.getBleedingPrediction() const fertilityStatus = getFertilityStatusForDay(this.todayDateString) this.setState({ cycleDayNumber: this.getCycleDayNumber(this.todayDateString), predictionText: determinePredictionText(prediction), bleedingPredictionRange: getBleedingPredictionRange(prediction), ...fertilityStatus }) } componentWillUnmount() { this.cycleDays.removeListener(this.updateState) } passTodayTo(componentName) { const todayDateString = LocalDate.now().toString() const cycleDay = getOrCreateCycleDay(todayDateString) const navigate = this.props.navigate navigate(componentName, { cycleDay }) } render() { const cycleDayMoreText = this.state.cycleDayNumber ? labels.cycleDayKnown(this.state.cycleDayNumber) : labels.cycleDayNotEnoughInfo const {height, width} = Dimensions.get('window') return ( this.passTodayTo('CycleDay')} style={styles.homeIconElement} > {this.state.cycleDayNumber || labels.unknown} { this.state.showMore && {cycleDayMoreText} } {labels.editToday} this.passTodayTo('BleedingEditView')} style={styles.homeIconElement} > {this.state.bleedingPredictionRange} {this.state.showMore && {this.state.predictionText} } {labels.trackPeriod} this.props.navigate('Chart')} style={styles.homeIconElement} > {this.state.phase ? this.state.phase.toString() : labels.unknown } {this.state.phase && {`${labels.phase(this.state.phase)} (${this.state.status})`} } {this.state.showMore && {this.state.statusText} } {labels.checkFertility} {!this.state.showMore && this.setState({showMore: true})} style={[styles.showMore, { top: height / 2 - styles.header.height - 30, left: width - 40 }]} > {shared.more} } {this.state.showMore && this.setState({showMore: false})} style={[styles.showLess, { top: height / 2 - styles.header.height - 30, left: 10 }]} > {shared.less} } ) } } function determinePredictionText(bleedingPrediction) { if (!bleedingPrediction.length) return predictLabels.noPrediction const todayDate = LocalDate.now() const bleedingStart = LocalDate.parse(bleedingPrediction[0][0]) const bleedingEnd = LocalDate.parse( bleedingPrediction[0][ bleedingPrediction[0].length - 1 ] ) if (todayDate.isBefore(bleedingStart)) { return predictLabels.predictionInFuture( todayDate.until(bleedingStart, ChronoUnit.DAYS), todayDate.until(bleedingEnd, ChronoUnit.DAYS) ) } if (todayDate.isAfter(bleedingEnd)) { return predictLabels.predictionInPast( bleedingStart.toString(), bleedingEnd.toString() ) } const daysToEnd = todayDate.until(bleedingEnd, ChronoUnit.DAYS) if (daysToEnd === 0) { return predictLabels.predictionStartedNoDaysLeft } else if (daysToEnd === 1) { return predictLabels.predictionStarted1DayLeft } else { return predictLabels.predictionStartedXDaysLeft(daysToEnd) } } 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' }