diff --git a/components/app-wrapper.js b/components/app-wrapper.js index 1c3a8d8..fc70bcd 100644 --- a/components/app-wrapper.js +++ b/components/app-wrapper.js @@ -9,17 +9,8 @@ import PasswordPrompt from './password-prompt' import License from './license' import AppLoadingView from './app-loading' -import { combineReducers } from 'redux' -import { configureStore } from 'redux-starter-kit' +import store from "../store" import { Provider } from 'react-redux' -import dateReducer from '../slices/date' - -const rootReducer = combineReducers({ - dateReducer, -}) - -const store = configureStore({ reducer: rootReducer }) - export default class AppWrapper extends Component { constructor() { diff --git a/components/app.js b/components/app.js index 3fd7bf4..b9838de 100644 --- a/components/app.js +++ b/components/app.js @@ -1,5 +1,9 @@ import React, { Component } from 'react' import { View, BackHandler } from 'react-native' +import { connect } from 'react-redux' + +import { getDate } from '../slices/date' + import Header from './header' import Menu from './menu' import Home from './home' @@ -25,7 +29,7 @@ const HOME_PAGE = 'Home' const CYCLE_DAY_PAGE = 'CycleDay' const SETTINGS_MENU_PAGE = 'SettingsMenu' -export default class App extends Component { +class App extends Component { constructor(props) { super(props) this.state = { @@ -55,14 +59,14 @@ export default class App extends Component { } handleBackButtonPress = () => { - const { currentPage, currentProps } = this.state + const { currentPage } = this.state if (currentPage === HOME_PAGE) { closeDb() return false } if (this.isSymptomView()) { this.navigate( - this.originForSymptomView, { date: currentProps.date } + this.originForSymptomView, { date: this.props.date } ) } else if (this.isSettingsView()) { this.navigate(SETTINGS_MENU_PAGE) @@ -92,7 +96,7 @@ export default class App extends Component { } render() { - const { currentPage, currentProps } = this.state + const { currentPage } = this.state const pages = { Home, Calendar, @@ -121,7 +125,6 @@ export default class App extends Component { @@ -132,3 +135,14 @@ export default class App extends Component { ) } } + +const mapStateToProps = (state) => { + return({ + date: getDate(state) + }) +} + +export default connect( + mapStateToProps, + null +)(App) \ No newline at end of file diff --git a/components/calendar.js b/components/calendar.js index 6c4ec69..faf4bea 100644 --- a/components/calendar.js +++ b/components/calendar.js @@ -1,5 +1,9 @@ import React, { Component } from 'react' import { CalendarList } from 'react-native-calendars' +import { connect } from 'react-redux' + +import { setDate } from '../slices/date' + import { LocalDate } from 'js-joda' import { getBleedingDaysSortedByDate } from '../db' import cycleModule from '../lib/cycle' @@ -7,7 +11,7 @@ import { shadesOfRed, calendarTheme } from '../styles/index' import styles from '../styles/index' import nothingChanged from '../db/db-unchanged' -export default class CalendarView extends Component { +class CalendarView extends Component { constructor(props) { super(props) this.bleedingDays = getBleedingDaysSortedByDate() @@ -36,9 +40,10 @@ export default class CalendarView extends Component { } passDateToDayView = (result) => { - const navigate = this.props.navigate - navigate('CycleDay', { date: result.dateString }) + this.props.setDate(result.dateString) + this.props.navigate('CycleDay') } + render() { return ( { + return({ + setDate: (date) => dispatch(setDate(date)), + }) +} + +export default connect( + null, + mapDispatchToProps, +)(CalendarView) + + function toCalFormat(bleedingDaysSortedByDate) { const todayDateString = LocalDate.now().toString() return bleedingDaysSortedByDate.reduce((acc, day) => { diff --git a/components/chart/day-column.js b/components/chart/day-column.js index 825cb69..834a618 100644 --- a/components/chart/day-column.js +++ b/components/chart/day-column.js @@ -2,7 +2,16 @@ import React, { Component } from 'react' import { Text, View, TouchableOpacity } from 'react-native' -import { Surface, Group as G, Path, Shape } from 'react-native/Libraries/ART/ReactNativeART' +import { + Surface, + Group as G, + Path, + Shape +} from 'react-native/Libraries/ART/ReactNativeART' +import { connect } from 'react-redux' + +import { setDate } from '../../slices/date' + import { LocalDate } from 'js-joda' import moment from 'moment' import styles from './styles' @@ -14,7 +23,7 @@ import { normalizeToScale } from './y-axis' const label = styles.column.label -export default class DayColumn extends Component { +class DayColumn extends Component { constructor(props) { super() const dateString = props.dateString @@ -61,6 +70,11 @@ export default class DayColumn extends Component { ) } + onDaySelect = (date) => { + this.props.setDate(date) + this.props.navigate('CycleDay') + } + shouldComponentUpdate() { return false } @@ -246,7 +260,7 @@ export default class DayColumn extends Component { return ( this.props.navigate('CycleDay', { date: dateString })} + onPress={() => this.onDaySelect(dateString)} activeOpacity={1} > @@ -268,6 +282,18 @@ export default class DayColumn extends Component { } } +const mapDispatchToProps = (dispatch) => { + return({ + setDate: (date) => dispatch(setDate(date)), + }) +} + +export default connect( + null, + mapDispatchToProps, +)(DayColumn) + + function SymptomIconView(props) { const style = [styles.symptomRow, {height: props.symptomHeight}] diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 2961f81..24ec3e0 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -1,5 +1,9 @@ import React, { Component } from 'react' import { ScrollView, View } from 'react-native' + +import { connect } from 'react-redux' +import { getDate } from '../../slices/date' + import { LocalDate } from 'js-joda' import Header from '../header' import FillerBoxes from './FillerBoxes' @@ -9,18 +13,16 @@ import { getCycleDay } from '../../db' import cycleModule from '../../lib/cycle' import styles from '../../styles' -export default class CycleDayOverView extends Component { +class CycleDayOverView extends Component { constructor(props) { super(props) - const { date } = this.props this.state = { - date, - cycleDay: getCycleDay(date) + cycleDay: getCycleDay(props.date) } } goToCycleDay = (target) => { - const localDate = LocalDate.parse(this.state.date) + const localDate = LocalDate.parse(this.props.date) const targetDate = target === 'before' ? localDate.minusDays(1).toString() : localDate.plusDays(1).toString() @@ -31,12 +33,14 @@ export default class CycleDayOverView extends Component { } navigate(symptom) { - this.props.navigate(symptom, this.state) + this.props.navigate(symptom) } render() { - const { date, cycleDay } = this.state const { getCycleDayNumber } = cycleModule() + const { cycleDay } = this.state + const { date } = this.props + const cycleDayNumber = getCycleDayNumber(date) const dateInFuture = LocalDate.now().isBefore(LocalDate.parse(date)) @@ -89,3 +93,14 @@ export default class CycleDayOverView extends Component { ) } } + +const mapStateToProps = (state) => { + return({ + date: getDate(state), + }) +} + +export default connect( + mapStateToProps, + null, +)(CycleDayOverView) diff --git a/components/cycle-day/symptoms/bleeding.js b/components/cycle-day/symptoms/bleeding.js index 6893bfa..1d9cf71 100644 --- a/components/cycle-day/symptoms/bleeding.js +++ b/components/cycle-day/symptoms/bleeding.js @@ -1,15 +1,16 @@ import React from 'react' -import { - Switch, - ScrollView -} from 'react-native' +import { Switch, ScrollView } from 'react-native' +import { connect } from 'react-redux' + +import { getDate } from '../../../slices/date' + import styles from '../../../styles' import { bleeding } from '../../../i18n/en/cycle-day' import SelectTabGroup from '../select-tab-group' import SymptomSection from './symptom-section' import SymptomView from './symptom-view' -export default class Bleeding extends SymptomView { +class Bleeding extends SymptomView { constructor(props) { super(props) const cycleDay = props.cycleDay @@ -67,4 +68,15 @@ export default class Bleeding extends SymptomView { ) } -} \ No newline at end of file +} + +const mapStateToProps = (state) => { + return({ + date: getDate(state) + }) +} + +export default connect( + mapStateToProps, + null +)(Bleeding) \ No newline at end of file diff --git a/components/cycle-day/symptoms/cervix.js b/components/cycle-day/symptoms/cervix.js index 4515f5d..58fddf6 100644 --- a/components/cycle-day/symptoms/cervix.js +++ b/components/cycle-day/symptoms/cervix.js @@ -3,13 +3,17 @@ import { Switch, ScrollView } from 'react-native' +import { connect } from 'react-redux' + +import { getDate } from '../../../slices/date' + import styles from '../../../styles' import { cervix as labels } from '../../../i18n/en/cycle-day' import SelectTabGroup from '../select-tab-group' import SymptomSection from './symptom-section' import SymptomView from './symptom-view' -export default class Cervix extends SymptomView { +class Cervix extends SymptomView { constructor(props) { super(props) const cycleDay = props.cycleDay @@ -99,3 +103,14 @@ export default class Cervix extends SymptomView { ) } } + +const mapStateToProps = (state) => { + return({ + date: getDate(state) + }) +} + +export default connect( + mapStateToProps, + null +)(Cervix) diff --git a/components/cycle-day/symptoms/desire.js b/components/cycle-day/symptoms/desire.js index f28ff85..b395cb2 100644 --- a/components/cycle-day/symptoms/desire.js +++ b/components/cycle-day/symptoms/desire.js @@ -2,13 +2,17 @@ import React from 'react' import { ScrollView } from 'react-native' +import { connect } from 'react-redux' + +import { getDate } from '../../../slices/date' + import styles from '../../../styles' import { intensity, desire } from '../../../i18n/en/cycle-day' import SelectTabGroup from '../select-tab-group' import SymptomSection from './symptom-section' import SymptomView from './symptom-view' -export default class Desire extends SymptomView { +class Desire extends SymptomView { constructor(props) { super(props) const cycleDay = props.cycleDay @@ -49,3 +53,14 @@ export default class Desire extends SymptomView { ) } } + +const mapStateToProps = (state) => { + return({ + date: getDate(state) + }) +} + +export default connect( + mapStateToProps, + null +)(Desire) diff --git a/components/cycle-day/symptoms/mood.js b/components/cycle-day/symptoms/mood.js index 6b78891..eef3b18 100644 --- a/components/cycle-day/symptoms/mood.js +++ b/components/cycle-day/symptoms/mood.js @@ -2,13 +2,17 @@ import React from 'react' import { ScrollView, TextInput} from 'react-native' +import { connect } from 'react-redux' + +import { getDate } from '../../../slices/date' + import { mood as labels } from '../../../i18n/en/cycle-day' import SelectBoxGroup from '../select-box-group' import SymptomSection from './symptom-section' import styles from '../../../styles' import SymptomView from './symptom-view' -export default class Mood extends SymptomView { +class Mood extends SymptomView { constructor(props) { super(props) const cycleDay = props.cycleDay @@ -72,3 +76,14 @@ export default class Mood extends SymptomView { ) } } + +const mapStateToProps = (state) => { + return({ + date: getDate(state) + }) +} + +export default connect( + mapStateToProps, + null +)(Mood) diff --git a/components/cycle-day/symptoms/mucus.js b/components/cycle-day/symptoms/mucus.js index cc73591..ea9d5e6 100644 --- a/components/cycle-day/symptoms/mucus.js +++ b/components/cycle-day/symptoms/mucus.js @@ -3,6 +3,10 @@ import { Switch, ScrollView } from 'react-native' +import { connect } from 'react-redux' + +import { getDate } from '../../../slices/date' + import styles from '../../../styles' import { mucus as labels } from '../../../i18n/en/cycle-day' import computeNfpValue from '../../../lib/nfp-mucus' @@ -10,7 +14,7 @@ import SelectTabGroup from '../select-tab-group' import SymptomSection from './symptom-section' import SymptomView from './symptom-view' -export default class Mucus extends SymptomView { +class Mucus extends SymptomView { constructor(props) { super(props) const cycleDay = props.cycleDay @@ -89,3 +93,14 @@ export default class Mucus extends SymptomView { ) } } + +const mapStateToProps = (state) => { + return({ + date: getDate(state) + }) +} + +export default connect( + mapStateToProps, + null +)(Mucus) diff --git a/components/cycle-day/symptoms/note.js b/components/cycle-day/symptoms/note.js index e9a2df6..d7febcb 100644 --- a/components/cycle-day/symptoms/note.js +++ b/components/cycle-day/symptoms/note.js @@ -3,6 +3,9 @@ import { ScrollView, TextInput, } from 'react-native' +import { connect } from 'react-redux' + +import { getDate } from '../../../slices/date' import styles from '../../../styles' import SymptomSection from './symptom-section' @@ -10,7 +13,7 @@ import { noteExplainer } from '../../../i18n/en/cycle-day' import { shared as sharedLabels } from '../../../i18n/en/labels' import SymptomView from './symptom-view' -export default class Note extends SymptomView { +class Note extends SymptomView { constructor(props) { super(props) const cycleDay = props.cycleDay @@ -53,3 +56,14 @@ export default class Note extends SymptomView { ) } } + +const mapStateToProps = (state) => { + return({ + date: getDate(state) + }) +} + +export default connect( + mapStateToProps, + null +)(Note) diff --git a/components/cycle-day/symptoms/pain.js b/components/cycle-day/symptoms/pain.js index fdf3fec..a45a633 100644 --- a/components/cycle-day/symptoms/pain.js +++ b/components/cycle-day/symptoms/pain.js @@ -3,6 +3,10 @@ import { ScrollView, TextInput, } from 'react-native' +import { connect } from 'react-redux' + +import { getDate } from '../../../slices/date' + import { pain as labels } from '../../../i18n/en/cycle-day' import { shared as sharedLabels } from '../../../i18n/en/labels' import SelectBoxGroup from '../select-box-group' @@ -10,7 +14,7 @@ import SymptomSection from './symptom-section' import styles from '../../../styles' import SymptomView from './symptom-view' -export default class Pain extends SymptomView { +class Pain extends SymptomView { constructor(props) { super(props) const cycleDay = props.cycleDay @@ -74,3 +78,14 @@ export default class Pain extends SymptomView { ) } } + +const mapStateToProps = (state) => { + return({ + date: getDate(state) + }) +} + +export default connect( + mapStateToProps, + null +)(Pain) diff --git a/components/cycle-day/symptoms/sex.js b/components/cycle-day/symptoms/sex.js index 140afa3..5bdbd05 100644 --- a/components/cycle-day/symptoms/sex.js +++ b/components/cycle-day/symptoms/sex.js @@ -3,6 +3,10 @@ import { TextInput, ScrollView } from 'react-native' +import { connect } from 'react-redux' + +import { getDate } from '../../../slices/date' + import styles from '../../../styles' import { sex as sexLabels, contraceptives as contraceptivesLabels } from '../../../i18n/en/cycle-day' import { shared as sharedLabels } from '../../../i18n/en/labels' @@ -10,7 +14,7 @@ import SelectBoxGroup from '../select-box-group' import SymptomSection from './symptom-section' import SymptomView from './symptom-view' -export default class Sex extends SymptomView { +class Sex extends SymptomView { constructor(props) { super(props) const cycleDay = props.cycleDay @@ -87,3 +91,14 @@ export default class Sex extends SymptomView { ) } } + +const mapStateToProps = (state) => { + return({ + date: getDate(state) + }) +} + +export default connect( + mapStateToProps, + null +)(Sex) diff --git a/components/cycle-day/symptoms/symptom-view.js b/components/cycle-day/symptoms/symptom-view.js index d78b995..d2e9e3f 100644 --- a/components/cycle-day/symptoms/symptom-view.js +++ b/components/cycle-day/symptoms/symptom-view.js @@ -2,6 +2,7 @@ import React, { Component } from 'react' import { View, Alert, TouchableOpacity } from 'react-native' + import { saveSymptom } from '../../../db' import InfoPopUp from './info-symptom' import Header from '../../header/symptom-view' @@ -10,9 +11,10 @@ import { sharedDialogs } from '../../../i18n/en/cycle-day' import Icon from 'react-native-vector-icons/Entypo' import styles, { iconStyles } from '../../../styles' -export default class SymptomView extends Component { - constructor(props) { +class SymptomView extends Component { + constructor(props, symptomName) { super() + this.symptomName = symptomName this.date = props.date this.navigate = props.navigate this.state = { @@ -95,4 +97,6 @@ export default class SymptomView extends Component { ) } -} \ No newline at end of file +} + +export default SymptomView diff --git a/components/cycle-day/symptoms/temperature.js b/components/cycle-day/symptoms/temperature.js index 66715c8..f0db45a 100644 --- a/components/cycle-day/symptoms/temperature.js +++ b/components/cycle-day/symptoms/temperature.js @@ -5,6 +5,10 @@ import { Keyboard, ScrollView } from 'react-native' +import { connect } from 'react-redux' + +import { getDate } from '../../../slices/date' + import DateTimePicker from 'react-native-modal-datetime-picker-nevo' import padWithZeros from '../../helpers/pad-time-with-zeros' @@ -22,7 +26,7 @@ import SymptomView from './symptom-view' const minutes = ChronoUnit.MINUTES -export default class Temp extends SymptomView { +class Temp extends SymptomView { constructor(props) { super(props) const cycleDay = props.cycleDay @@ -175,6 +179,17 @@ export default class Temp extends SymptomView { } } +const mapStateToProps = (state) => { + return({ + date: getDate(state) + }) +} + +export default connect( + mapStateToProps, + null +)(Temp) + function makeOutOfRangeWarningMessage(temperature) { if (temperature === '') return const value = Number(temperature) diff --git a/components/header/cycle-day.js b/components/header/cycle-day.js index 33abfb1..a4a4c3a 100644 --- a/components/header/cycle-day.js +++ b/components/header/cycle-day.js @@ -6,7 +6,7 @@ import styles from '../../styles' import NavigationArrow from './navigation-arrow' import formatDate from '../helpers/format-date' -export default function CycleDayHeader({ date, ...props }) { +export default function CycleDayHeader({ date, cycleDayNumber, ...props }) { return ( {formatDate(date)} - {props.cycleDayNumber && + { cycleDayNumber && - {`Cycle day ${props.cycleDayNumber}`.toLowerCase()} - } + {`Cycle day ${cycleDayNumber}`.toLowerCase()} + + } diff --git a/components/header/symptom-view.js b/components/header/symptom-view.js index f2797de..a1d5e10 100644 --- a/components/header/symptom-view.js +++ b/components/header/symptom-view.js @@ -26,9 +26,11 @@ export default function SymptomViewHeader(props) { {props.title} - - {formatDate(props.date)} - + { props.date && + + {formatDate(props.date)} + + } { props.deleteIconActive && { ) } -export default class Home extends Component { +class Home extends Component { constructor(props) { super(props) const { getCycleDayNumber, getPredictedMenses } = cycleModule() @@ -68,12 +70,18 @@ export default class Home extends Component { } } - passTodayTo(componentName) { - const { navigate } = this.props - navigate(componentName, { - date: this.todayDateString, - cycleDay: getCycleDay(this.todayDateString) - }) + setTodayDate = () => { + this.props.setDate(this.todayDateString) + } + + navigateToCycleDayView = () => { + this.setTodayDate() + this.props.navigate('CycleDay') + } + + navigateToBleedingEditView = () => { + this.setTodayDate() + this.props.navigate('BleedingEditView') } render() { @@ -91,7 +99,7 @@ export default class Home extends Component { this.passTodayTo('CycleDay') } + onPress={this.navigateToCycleDayView} buttonColor={ cycleDayColor } buttonLabel={ labels.editToday } > @@ -102,11 +110,13 @@ export default class Home extends Component { {cycleDayNumber || labels.unknown} - {cycleDayMoreText} + + {cycleDayMoreText} + this.passTodayTo('BleedingEditView') } + onPress={this.navigateToBleedingEditView} buttonColor={ periodColor } buttonLabel={ labels.trackPeriod } > @@ -148,18 +158,36 @@ export default class Home extends Component { } } +const mapDispatchToProps = (dispatch) => { + return({ + setDate: (date) => dispatch(setDate(date)), + }) +} + +export default connect( + null, + mapDispatchToProps, +)(Home) + + function getTimes(prediction) { const todayDate = LocalDate.now() const predictedBleedingStart = LocalDate.parse(prediction[0][0]) /* the range of predicted bleeding days can be either 3 or 5 */ - const predictedBleedingEnd = LocalDate.parse(prediction[0][ prediction[0].length - 1 ]) + const predictedBleedingEnd = + LocalDate.parse(prediction[0][ prediction[0].length - 1 ]) const daysToEnd = todayDate.until(predictedBleedingEnd, ChronoUnit.DAYS) return { todayDate, predictedBleedingStart, predictedBleedingEnd, daysToEnd } } function determinePredictionText(bleedingPrediction) { if (!bleedingPrediction.length) return predictLabels.noPrediction - const { todayDate, predictedBleedingStart, predictedBleedingEnd, daysToEnd } = getTimes(bleedingPrediction) + const { + todayDate, + predictedBleedingStart, + predictedBleedingEnd, + daysToEnd + } = getTimes(bleedingPrediction) if (todayDate.isBefore(predictedBleedingStart)) { return predictLabels.predictionInFuture( todayDate.until(predictedBleedingStart, ChronoUnit.DAYS), @@ -183,7 +211,12 @@ function determinePredictionText(bleedingPrediction) { function getBleedingPredictionRange(prediction) { if (!prediction.length) return labels.unknown - const { todayDate, predictedBleedingStart, predictedBleedingEnd, daysToEnd } = getTimes(prediction) + const { + todayDate, + predictedBleedingStart, + predictedBleedingEnd, + daysToEnd + } = getTimes(prediction) if (todayDate.isBefore(predictedBleedingStart)) { return `${todayDate.until(predictedBleedingStart, ChronoUnit.DAYS)}-${todayDate.until(predictedBleedingEnd, ChronoUnit.DAYS)}` } diff --git a/store.js b/store.js new file mode 100644 index 0000000..7aa713d --- /dev/null +++ b/store.js @@ -0,0 +1,11 @@ +import { combineReducers, createStore } from "redux" + +import date from "./slices/date" + +const reducer = combineReducers({ + date +}) + +const store = createStore(reducer) + +export default store