From 4a2b99f9d53d38e1f34139ecb6917ee9ad6a597a Mon Sep 17 00:00:00 2001 From: emelko Date: Fri, 20 Jul 2018 12:25:17 +0200 Subject: [PATCH 1/4] Adds cervix to symptoms: has 3 properties: opening, firmness and position (which is optional); --- components/cervix.js | 155 +++++++++++++++++++++ components/cycle-day/cycle-day-overview.js | 26 ++++ components/cycle-day/index.js | 4 +- components/cycle-day/labels/labels.js | 8 +- components/cycle-day/symptoms/cervix.js | 125 +++++++++++++++++ db.js | 17 ++- 6 files changed, 332 insertions(+), 3 deletions(-) create mode 100644 components/cervix.js create mode 100644 components/cycle-day/symptoms/cervix.js diff --git a/components/cervix.js b/components/cervix.js new file mode 100644 index 0000000..0d9eb36 --- /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( + + + + + + Cervix + + + + Position + + + + { + this.setState({currentPositionValue: itemValue}) + }} + /> + + + + Consistency + + + + { + this.setState({currentConsistencyValue: itemValue}) + }} + /> + + + + + + + + Exclude + + + + { + this.setState({exclude: val}) + }} + value={this.state.exclude} + /> + + + + + + + + + + + + + + + + + + + + + + + + ) + } +} diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 13d43a4..82a2d42 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 ( @@ -100,6 +115,17 @@ export default class DayView extends Component { + + + Cervix + + + + + ) } diff --git a/components/cycle-day/index.js b/components/cycle-day/index.js index 758fa1d..3d2ffde 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: , bleedingEditView: , temperatureEditView: , - mucusEditView: + mucusEditView: , + cervixEditView: }[this.state.visibleComponent] } diff --git a/components/cycle-day/labels/labels.js b/components/cycle-day/labels/labels.js index 459370b..25909df 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 0000000..2ba7aa4 --- /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( + + Cervix + Opening + + { + this.setState({currentOpeningValue: itemValue}) + }} + /> + + Firmness + + { + this.setState({currentFirmnessValue: itemValue}) + }} + /> + + Position + + { + this.setState({currentPositionValue: itemValue}) + }} + /> + + + Exclude + { + this.setState({ exclude: val }) + }} + value={this.state.exclude} + /> + + + {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 + } + )} + + + ) + } +} diff --git a/db.js b/db.js index e2cf940..6fb743d 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 From b8e99194d9bed8f81241b8173136facce15c9f71 Mon Sep 17 00:00:00 2001 From: emelko Date: Fri, 20 Jul 2018 12:25:59 +0200 Subject: [PATCH 2/4] Reorganise labels for cylce day overview --- components/cycle-day/cycle-day-overview.js | 47 ++++++++++++---------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 82a2d42..eeef9f2 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -44,44 +44,49 @@ export default class DayView extends Component { } render() { - const bleedingValue = this.cycleDay.bleeding && this.cycleDay.bleeding.value let bleedingLabel - if (typeof bleedingValue === 'number') { - bleedingLabel = `${bleedingLabels[bleedingValue]}` - if (this.cycleDay.bleeding.exclude) bleedingLabel = "( " + bleedingLabel + " )" + if (this.cycleDay.bleeding) { + const bleeding = this.cycleDay.bleeding + if (typeof bleeding === 'number') { + bleedingLabel = `${bleedingLabels[bleeding]}` + if (bleeding.exclude) bleedingLabel = "( " + bleedingLabel + " )" + } } else { bleedingLabel = 'edit' } - const temperatureValue = this.cycleDay.temperature && this.cycleDay.temperature.value let temperatureLabel - if (typeof temperatureValue === 'number') { - temperatureLabel = `${temperatureValue} °C - ${this.cycleDay.temperature.time}` - if (this.cycleDay.temperature.exclude) { - temperatureLabel = "( " + temperatureLabel + " )" + if (this.cycleDay.temperature) { + const temperature = this.cycleDay.temperature + if (typeof temperature === 'number') { + temperatureLabel = `${temperature} °C - ${temperature.time}` + if (temperature.exclude) { + temperatureLabel = "( " + temperatureLabel + " )" + } } } else { temperatureLabel = 'edit' } - const mucusFeelingValue = this.cycleDay.mucus && this.cycleDay.mucus.feeling - const mucusTextureValue = this.cycleDay.mucus && this.cycleDay.mucus.texture - const mucusComputedValue = this.cycleDay.mucus && this.cycleDay.mucus.computedNfp let mucusLabel - if (typeof mucusFeelingValue === 'number' && typeof mucusTextureValue === 'number') { - mucusLabel = `${feelingLabels[mucusFeelingValue]} + ${textureLabels[mucusTextureValue]} ( ${computeSensiplanMucusLabels[mucusComputedValue]} )` - if (this.cycleDay.mucus.exclude) mucusLabel = "( " + mucusLabel + " )" + if (this.cycleDay.mucus) { + const mucus = this.cycleDay.mucus + if (typeof mucus.feeling === 'number' && typeof mucus.texture === 'number') { + mucusLabel = `${feelingLabels[mucus.feeling]} + ${textureLabels[mucus.texture]} ( ${computeSensiplanMucusLabels[mucus.computedNfp]} )` + if (mucus.exclude) mucusLabel = "( " + mucusLabel + " )" + } } else { 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 + " )" + if (this.cycleDay.cervix) { + const cervix = this.cycleDay.cervix + if (cervix.opening > -1 && cervix.firmness > -1) { + cervixLabel = `${openingLabels[cervix.opening]} + ${firmnessLabels[cervix.firmness]}` + if (cervix.position > -1) cervixLabel += `+ ${positionLabels[cervix.position]}` + if (cervix.exclude) cervixLabel = "( " + cervixLabel + " )" + } } else { cervixLabel = 'edit' } From 32c08c8df71d81d2695d81a958e659ba6d539118 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 20 Jul 2018 13:33:15 +0200 Subject: [PATCH 3/4] Fix cycle day overview categories inline --- components/cycle-day/cycle-day-overview.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index eeef9f2..839de29 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -120,11 +120,9 @@ export default class DayView extends Component { - - - Cervix - - + + Cervix + - - - - - - - - - - - - - - ) - } -} diff --git a/components/cycle-day/symptoms/cervix.js b/components/cycle-day/symptoms/cervix.js index 2ba7aa4..59d9d8b 100644 --- a/components/cycle-day/symptoms/cervix.js +++ b/components/cycle-day/symptoms/cervix.js @@ -20,20 +20,16 @@ export default class Cervix extends Component { 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 - } + /* eslint-disable react/no-direct-mutation-state */ + ['opening', 'firmness', 'position'].forEach(label => { + this.state[label] = this.cycleDay.cervix && this.cycleDay.cervix[label] + if (typeof this.state[label] !== 'number') { + this.state[label] = -1 + } + }) + /* eslint-enable react/no-direct-mutation-state */ } render() { @@ -58,12 +54,12 @@ export default class Cervix extends Component { { - this.setState({currentOpeningValue: itemValue}) + this.setState({opening: itemValue}) }} /> @@ -71,12 +67,12 @@ export default class Cervix extends Component { { - this.setState({currentFirmnessValue: itemValue}) + this.setState({firmness: itemValue}) }} /> @@ -84,12 +80,12 @@ export default class Cervix extends Component { { - this.setState({currentPositionValue: itemValue}) + this.setState({position: itemValue}) }} /> @@ -109,13 +105,13 @@ export default class Cervix extends Component { cycleDay: this.cycleDay, saveAction: () => { saveSymptom('cervix', this.cycleDay, { - opening: this.state.currentOpeningValue, - firmness: this.state.currentFirmnessValue, - position: this.state.currentPositionValue, + opening: this.state.opening, + firmness: this.state.firmness, + position: this.state.position, exclude: this.state.exclude }) }, - saveDisabled: this.state.currentOpeningValue === -1 || this.state.currentFirmnessValue === -1 + saveDisabled: this.state.opening === -1 || this.state.firmness === -1 } )} diff --git a/components/cycle-day/symptoms/mucus.js b/components/cycle-day/symptoms/mucus.js index f94a656..4a090d2 100644 --- a/components/cycle-day/symptoms/mucus.js +++ b/components/cycle-day/symptoms/mucus.js @@ -21,17 +21,17 @@ export default class Mucus extends Component { this.makeActionButtons = props.makeActionButtons this.state = { exclude: this.cycleDay.mucus ? this.cycleDay.mucus.exclude : false - } + }; - this.state.currentFeelingValue = this.cycleDay.mucus && this.cycleDay.mucus.feeling - if (typeof this.state.currentFeelingValue !== 'number') { - this.state.currentFeelingValue = -1 - } + /* eslint-disable react/no-direct-mutation-state */ + ['feeling', 'texture'].forEach(label => { + this.state[label] = this.cycleDay.mucus && this.cycleDay.mucus[label] + if (typeof this.state[label] !== 'number') { + this.state[label] = -1 + } + }) + /* eslint-enable react/no-direct-mutation-state */ - this.state.currentTextureValue = this.cycleDay.mucus && this.cycleDay.mucus.texture - if (typeof this.state.currentTextureValue !== 'number') { - this.state.currentTextureValue = -1 - } } render() { @@ -53,12 +53,12 @@ export default class Mucus extends Component { { - this.setState({ currentFeelingValue: itemValue }) + this.setState({feeling: itemValue }) }} /> @@ -66,12 +66,12 @@ export default class Mucus extends Component { { - this.setState({ currentTextureValue: itemValue }) + this.setState({texture: itemValue }) }} /> @@ -92,13 +92,13 @@ export default class Mucus extends Component { cycleDay: this.cycleDay, saveAction: () => { saveSymptom('mucus', this.cycleDay, { - feeling: this.state.currentFeelingValue, - texture: this.state.currentTextureValue, - computedNfp: computeSensiplanValue(this.state.currentFeelingValue, this.state.currentTextureValue), + feeling: this.state.feeling, + texture: this.state.texture, + computedNfp: computeSensiplanValue(this.state.feeling, this.state.texture), exclude: this.state.exclude }) }, - saveDisabled: this.state.currentFeelingValue === -1 || this.state.currentTextureValue === -1 + saveDisabled: this.state.feeling === -1 || this.state.texture === -1 } )}