diff --git a/components/cervix.js b/components/cervix.js new file mode 100644 index 0000000000000000000000000000000000000000..0d9eb36bc3bf6f794798ff7f8327ced737c8d182 --- /dev/null +++ b/components/cervix.js @@ -0,0 +1,155 @@ +import React, { Component } from 'react' +import { + View, + Button, + Text, + Switch +} from 'react-native' +import RadioForm from 'react-native-simple-radio-button' +import { saveCervix } from '../db' +import styles from '../styles/index' +import { + cervixPosition as positionLabels, + cervixConsistency as consistencyLabels +} from '../labels/labels' +import computeSensiplanValue from '../lib/sensiplan-cervix' + +export default class Cervix extends Component { + constructor(props) { + super(props) + this.cycleDay = props.cycleDay + this.showView = props.showView + + let currentPositionValue = this.cycleDay.cervix && this.cycleDay.cervix.position + if (typeof currentPositionValue !== 'number') { + currentPositionValue = -1 + } + let currentConsistencyValue = this.cycleDay.cervix && this.cycleDay.cervix.consistency + if (typeof currentConsistencyValue !== 'number') { + currentConsistencyValue = -1 + } + + this.state = { + currentPositionValue, + currentConsistencyValue, + computeSensiplanValue, + exclude: this.cycleDay.cervix ? this.cycleDay.cervix.exclude : false + } + + } + + render() { + const cervixPositionRadioProps = [ + {label: positionLabels[0], value: 0 }, + {label: positionLabels[1], value: 1 }, + {label: positionLabels[2], value: 2 } + ] + const cervixConsistencyRadioProps = [ + {label: consistencyLabels[0], value: 0 }, + {label: consistencyLabels[1], value: 1 } + ] + return( + <View style={ styles.symptomEditView }> + <View style={ styles.symptomEditSplitSymptomsAndLastRowButtons }> + <View style={ styles.symptomEditListedSymptomView }> + + <View style={{flex: 1}}> + <Text style={styles.symptomDayView}>Cervix</Text> + </View> + + <View style={{flex: 1}}> + <Text style={styles.symptomDayView}>Position</Text> + </View> + + <View style={{flex: 1}}> + <RadioForm + radio_props={cervixPositionRadioProps} + initial={this.state.currentPositionValue} + formHorizontal={true} + labelHorizontal={false} + labelStyle={styles.radioButton} + onPress={(itemValue) => { + this.setState({currentPositionValue: itemValue}) + }} + /> + </View> + + <View style={{flex: 1}}> + <Text style={styles.symptomDayView}>Consistency</Text> + </View> + + <View style={{flex: 1}}> + <RadioForm + radio_props={cervixConsistencyRadioProps} + initial={this.state.currentConsistencyValue} + formHorizontal={true} + labelHorizontal={false} + labelStyle={styles.radioButton} + onPress={(itemValue) => { + this.setState({currentConsistencyValue: itemValue}) + }} + /> + </View> + + </View> + + <View style={ styles.itemsInRowSeparatedView }> + + <View style={ styles.singleButtonView }> + <Text style={ styles.symptomDayView }>Exclude</Text> + </View> + + <View style={ styles.singleButtonView }> + <Switch + onValueChange={(val) => { + this.setState({exclude: val}) + }} + value={this.state.exclude} + /> + </View> + + </View> + + </View> + + <View style={ styles.itemsInRowSeparatedView }> + + <View style={ styles.singleButtonView }> + <Button + onPress={() => this.showView('dayView')} + title="Cancel"> + </Button> + </View> + + <View style={ styles.singleButtonView }> + <Button + onPress={() => { + saveCervix(this.cycleDay) + this.showView('dayView') + }} + title="Delete"> + </Button> + </View> + + <View style={ styles.singleButtonView }> + <Button + onPress={() => { + saveCervix(this.cycleDay, { + position: this.state.currentPositionValue, + consistency: this.state.currentConsistencyValue, + computedNfp: computeSensiplanValue(this.state.currentPositionValue, this.state.currentConsistencyValue), + exclude: this.state.exclude + }) + this.showView('dayView') + }} + disabled={ this.state.currentPositionValue === -1 || this.state.currentConsistencyValue === -1 } + title="Save"> + </Button> + </View> + + </View> + + </View> + ) + } +} diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 13d43a45b53099c21ca81d08a749678b002353dc..82a2d42cafbdd300bf66c1c26a4582310b82897d 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -10,6 +10,9 @@ import { mucusFeeling as feelingLabels, mucusTexture as textureLabels, mucusNFP as computeSensiplanMucusLabels, + cervixOpening as openingLabels, + cervixFirmness as firmnessLabels, + cervixPosition as positionLabels } from './labels/labels' import cycleDayModule from '../../lib/get-cycle-day-number' import { bleedingDaysSortedByDate } from '../../db' @@ -49,6 +52,7 @@ export default class DayView extends Component { } else { bleedingLabel = 'edit' } + const temperatureValue = this.cycleDay.temperature && this.cycleDay.temperature.value let temperatureLabel if (typeof temperatureValue === 'number') { @@ -71,6 +75,17 @@ export default class DayView extends Component { mucusLabel = 'edit' } + const cervixOpeningValue = this.cycleDay.cervix && this.cycleDay.cervix.opening + const cervixFirmnessValue = this.cycleDay.cervix && this.cycleDay.cervix.firmness + const cervixPositionValue = this.cycleDay.cervix && this.cycleDay.cervix.position + let cervixLabel + if (typeof cervixPositionValue === 'number' && typeof cervixOpeningValue === 'number') { + cervixLabel = `${openingLabels[cervixOpeningValue]} + ${firmnessLabels[cervixFirmnessValue]} ( ${positionLabels[cervixPositionValue]} )` + if (this.cycleDay.cervix.exclude) cervixLabel = "( " + cervixLabel + " )" + } else { + cervixLabel = 'edit' + } + return ( <View style={styles.symptomEditView}> <View style={styles.symptomViewRowInline}> @@ -100,6 +115,17 @@ export default class DayView extends Component { </Button> </View> </View> + <View style={ styles.itemsInRowSeparatedView }> + <View style={{flex: 1}}> + <Text style={styles.symptomDayView}>Cervix</Text> + </View> + <View style={ styles.singleButtonView }> + <Button + onPress={() => this.showView('cervixEditView')} + title={cervixLabel}> + </Button> + </View> + </View> </View > ) } diff --git a/components/cycle-day/index.js b/components/cycle-day/index.js index 758fa1da048ed574daed8681044205dd08a40c5a..3d2ffde8bb8e007723499c84d4be538c2506e3ef 100644 --- a/components/cycle-day/index.js +++ b/components/cycle-day/index.js @@ -10,6 +10,7 @@ import BleedingEditView from './symptoms/bleeding' import TemperatureEditView from './symptoms/temperature' import MucusEditView from './symptoms/mucus' import { formatDateForViewHeader } from './labels/format' +import CervixEditView from './symptoms/cervix' import styles from '../../styles' import actionButtonModule from './action-buttons' @@ -48,7 +49,8 @@ export default class Day extends Component { { dayView: <DayView cycleDay={this.cycleDay} showView={this.showView} />, bleedingEditView: <BleedingEditView cycleDay={this.cycleDay} makeActionButtons={this.makeActionButtons}/>, temperatureEditView: <TemperatureEditView cycleDay={this.cycleDay} makeActionButtons={this.makeActionButtons}/>, - mucusEditView: <MucusEditView cycleDay={this.cycleDay} makeActionButtons={this.makeActionButtons}/> + mucusEditView: <MucusEditView cycleDay={this.cycleDay} makeActionButtons={this.makeActionButtons}/>, + cervixEditView: <CervixEditView cycleDay={this.cycleDay} makeActionButtons={this.makeActionButtons} /> }[this.state.visibleComponent] } </View > diff --git a/components/cycle-day/labels/labels.js b/components/cycle-day/labels/labels.js index 459370b25504e613605520d48b7bb967a1440624..25909dfcd8ecc5d4bccbdb49f6f195006bda38ac 100644 --- a/components/cycle-day/labels/labels.js +++ b/components/cycle-day/labels/labels.js @@ -2,10 +2,16 @@ const bleeding = ['spotting', 'light', 'medium', 'heavy'] const mucusFeeling = ['dry', 'nothing', 'wet', 'slippery'] const mucusTexture = ['nothing', 'creamy', 'egg white'] const mucusNFP = ['t', 'Ø', 'f', 'S', '+S'] +const cervixOpening = ['closed', 'medium', 'open'] +const cervixFirmness = ['hard', 'soft'] +const cervixPosition = ['low', 'medium', 'high'] export { bleeding, mucusFeeling, mucusTexture, - mucusNFP + mucusNFP, + cervixOpening, + cervixFirmness, + cervixPosition } diff --git a/components/cycle-day/symptoms/cervix.js b/components/cycle-day/symptoms/cervix.js new file mode 100644 index 0000000000000000000000000000000000000000..2ba7aa4c66859cca9e3c7d7e6d998d853195c1bc --- /dev/null +++ b/components/cycle-day/symptoms/cervix.js @@ -0,0 +1,125 @@ +import React, { Component } from 'react' +import { + View, + Text, + Switch +} from 'react-native' +import RadioForm from 'react-native-simple-radio-button' +import styles from '../../../styles' +import { saveSymptom } from '../../../db' +import { + cervixOpening as openingLabels, + cervixFirmness as firmnessLabels, + cervixPosition as positionLabels +} from '../labels/labels' + +export default class Cervix extends Component { + constructor(props) { + super(props) + this.cycleDay = props.cycleDay + this.makeActionButtons = props.makeActionButtons + this.state = { + exclude: this.cycleDay.cervix ? this.cycleDay.cervix.exclude : false + } + + this.state.currentOpeningValue = this.cycleDay.cervix && this.cycleDay.cervix.opening + if (typeof this.state.currentOpeningValue !== 'number') { + this.state.currentOpeningValue = -1 + } + this.state.currentFirmnessValue = this.cycleDay.cervix && this.cycleDay.cervix.firmness + if (typeof this.state.currentFirmnessValue !== 'number') { + this.state.currentFirmnessValue = -1 + } + this.state.currentPositionValue = this.cycleDay.cervix && this.cycleDay.cervix.position + if (typeof this.state.currentPositionValue !== 'number') { + this.state.currentPositionValue = -1 + } + } + + render() { + const cervixOpeningRadioProps = [ + {label: openingLabels[0], value: 0}, + {label: openingLabels[1], value: 1}, + {label: openingLabels[2], value: 2} + ] + const cervixFirmnessRadioProps = [ + {label: firmnessLabels[0], value: 0 }, + {label: firmnessLabels[1], value: 1 } + ] + const cervixPositionRadioProps = [ + {label: positionLabels[0], value: 0 }, + {label: positionLabels[1], value: 1 }, + {label: positionLabels[2], value: 2 } + ] + return( + <View style={ styles.symptomEditView }> + <Text style={styles.symptomDayView}>Cervix</Text> + <Text style={styles.symptomDayView}>Opening</Text> + <View style={styles.radioButtonRow}> + <RadioForm + radio_props={cervixOpeningRadioProps} + initial={this.state.currentOpeningValue} + formHorizontal={true} + labelHorizontal={false} + labelStyle={styles.radioButton} + onPress={(itemValue) => { + this.setState({currentOpeningValue: itemValue}) + }} + /> + </View> + <Text style={styles.symptomDayView}>Firmness</Text> + <View style={styles.radioButtonRow}> + <RadioForm + radio_props={cervixFirmnessRadioProps} + initial={this.state.currentFirmnessValue} + formHorizontal={true} + labelHorizontal={false} + labelStyle={styles.radioButton} + onPress={(itemValue) => { + this.setState({currentFirmnessValue: itemValue}) + }} + /> + </View> + <Text style={styles.symptomDayView}>Position</Text> + <View style={styles.radioButtonRow}> + <RadioForm + radio_props={cervixPositionRadioProps} + initial={this.state.currentPositionValue} + formHorizontal={true} + labelHorizontal={false} + labelStyle={styles.radioButton} + onPress={(itemValue) => { + this.setState({currentPositionValue: itemValue}) + }} + /> + </View> + <View style={styles.symptomViewRowInline}> + <Text style={styles.symptomDayView}>Exclude</Text> + <Switch + onValueChange={(val) => { + this.setState({ exclude: val }) + }} + value={this.state.exclude} + /> + </View> + <View style={styles.actionButtonRow}> + {this.makeActionButtons( + { + symptom: 'cervix', + cycleDay: this.cycleDay, + saveAction: () => { + saveSymptom('cervix', this.cycleDay, { + opening: this.state.currentOpeningValue, + firmness: this.state.currentFirmnessValue, + position: this.state.currentPositionValue, + exclude: this.state.exclude + }) + }, + saveDisabled: this.state.currentOpeningValue === -1 || this.state.currentFirmnessValue === -1 + } + )} + </View> + </View> + ) + } +} diff --git a/db.js b/db.js index e2cf94088a12b2db8b8d6167af47f9b5f83b471a..6fb743d0b21038def678efcfb2647f71a4fa229e 100644 --- a/db.js +++ b/db.js @@ -32,6 +32,16 @@ const MucusSchema = { } } +const CervixSchema = { + name: 'Cervix', + properties: { + opening: 'int', + firmness: 'int', + position: {type: 'int', optional: true }, + exclude: 'bool' + } +} + const CycleDaySchema = { name: 'CycleDay', primaryKey: 'date', @@ -48,6 +58,10 @@ const CycleDaySchema = { mucus: { type: 'Mucus', optional: true + }, + cervix: { + type: 'Cervix', + optional: true } } } @@ -57,7 +71,8 @@ const db = new Realm({ CycleDaySchema, TemperatureSchema, BleedingSchema, - MucusSchema + MucusSchema, + CervixSchema ], // we only want this in dev mode deleteRealmIfMigrationNeeded: true