From 56f5c92f879cb45799dd3c381e728efb064cd3b8 Mon Sep 17 00:00:00 2001 From: mashazyu Date: Wed, 9 Jan 2019 08:53:30 +0100 Subject: [PATCH 1/4] Add mood component, add mood as tracking category to db schemas, add mood category description, add mood to the cycle-day-overview --- components/cycle-day/cycle-day-overview.js | 34 +++- components/cycle-day/symptoms/index.js | 4 +- components/cycle-day/symptoms/mood.js | 78 +++++++++ db/schemas/3.js | 188 +++++++++++++++++++++ db/schemas/index.js | 3 +- i18n/en/cycle-day.js | 16 ++ 6 files changed, 318 insertions(+), 5 deletions(-) create mode 100644 components/cycle-day/symptoms/mood.js create mode 100644 db/schemas/3.js diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 09e9ef9..a1b869e 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -24,6 +24,7 @@ const intensityLabels = labels.intensity const sexLabels = labels.sex.categories const contraceptiveLabels = labels.contraceptives.categories const painLabels = labels.pain.categories +const moodLabels = labels.mood.categories export default class CycleDayOverView extends Component { constructor(props) { @@ -143,6 +144,25 @@ export default class CycleDayOverView extends Component { painLabel = painLabel.join(', ') return painLabel } + }, + mood: mood => { + let moodLabel = [] + if (mood && Object.values(mood).some(val => val)){ + Object.keys(mood).forEach(key => { + if(mood[key] && key !== 'other' && key !== 'note') { + moodLabel.push(moodLabels[key]) + } + if(key === 'other' && mood.other) { + let label = moodLabels[key] + if(mood.note) { + label = `${label} (${mood.note})` + } + moodLabel.push(label) + } + }) + moodLabel = moodLabel.join(', ') + return moodLabel + } } } @@ -226,6 +246,14 @@ export default class CycleDayOverView extends Component { iconName='drip-icon-pain' > + this.navigate('MoodEditView')} + data={this.getLabel('mood')} + disabled={dateInFuture} + iconName='drip-icon-pain' + > + this.navigate('NoteEditView')} @@ -236,9 +264,9 @@ export default class CycleDayOverView extends Component { {/* this is just to make the last row adhere to the grid (and) because there are no pseudo properties in RN */} - - - + + + ) } } diff --git a/components/cycle-day/symptoms/index.js b/components/cycle-day/symptoms/index.js index 014e9fe..aa84321 100644 --- a/components/cycle-day/symptoms/index.js +++ b/components/cycle-day/symptoms/index.js @@ -6,6 +6,7 @@ import NoteEditView from './note' import DesireEditView from './desire' import SexEditView from './sex' import PainEditView from './pain' +import MoodEditView from './mood' export default { BleedingEditView, @@ -15,5 +16,6 @@ export default { NoteEditView, DesireEditView, SexEditView, - PainEditView + PainEditView, + MoodEditView } diff --git a/components/cycle-day/symptoms/mood.js b/components/cycle-day/symptoms/mood.js new file mode 100644 index 0000000..37b40a0 --- /dev/null +++ b/components/cycle-day/symptoms/mood.js @@ -0,0 +1,78 @@ +import React, { Component } from 'react' +import { + ScrollView, + TextInput, + View +} from 'react-native' +import { saveSymptom } from '../../../db' +import { mood as labels } from '../../../i18n/en/cycle-day' +import ActionButtonFooter from './action-button-footer' +import SelectBoxGroup from '../select-box-group' +import SymptomSection from './symptom-section' +import styles from '../../../styles' + +export default class Mood extends Component { + constructor(props) { + super(props) + const cycleDay = props.cycleDay + if (cycleDay && cycleDay.pain) { + this.state = Object.assign({}, cycleDay.pain) + } else { + this.state = {} + } + if (this.state.note) { + this.state.other = true + } + } + + toggleState = (key) => { + const curr = this.state[key] + this.setState({[key]: !curr}) + if (key === 'other' && !curr) { + this.setState({focusTextArea: true}) + } + } + + render() { + return ( + + + + + { this.state.other && + { + this.setState({note: val}) + }} + /> + } + + + { + const copyOfState = Object.assign({}, this.state) + if (!copyOfState.other) { + copyOfState.note = null + } + saveSymptom('mood', this.props.date, copyOfState) + }} + saveDisabled={Object.values(this.state).every(value => !value)} + navigate={this.props.navigate} + /> + + ) + } +} diff --git a/db/schemas/3.js b/db/schemas/3.js new file mode 100644 index 0000000..1edc4aa --- /dev/null +++ b/db/schemas/3.js @@ -0,0 +1,188 @@ +import cycleModule from '../../lib/cycle' + +const TemperatureSchema = { + name: 'Temperature', + properties: { + value: 'double', + exclude: 'bool', + time: { + type: 'string', + optional: true + }, + note: { + type: 'string', + optional: true + } + } +} + +const BleedingSchema = { + name: 'Bleeding', + properties: { + value: 'int', + exclude: 'bool' + } +} + +const MucusSchema = { + name: 'Mucus', + properties: { + feeling: 'int', + texture: 'int', + value: 'int', + exclude: 'bool' + } +} + +const CervixSchema = { + name: 'Cervix', + properties: { + opening: 'int', + firmness: 'int', + position: {type: 'int', optional: true }, + exclude: 'bool' + } +} + +const NoteSchema = { + name: 'Note', + properties: { + value: 'string' + } +} + +const DesireSchema = { + name: 'Desire', + properties: { + value: 'int' + } +} + +const SexSchema = { + name: 'Sex', + properties: { + solo: { type: 'bool', optional: true }, + partner: { type: 'bool', optional: true }, + condom: { type: 'bool', optional: true }, + pill: { type: 'bool', optional: true }, + iud: { type: 'bool', optional: true }, + patch: { type: 'bool', optional: true }, + ring: { type: 'bool', optional: true }, + implant: { type: 'bool', optional: true }, + diaphragm: { type: 'bool', optional: true }, + none: { type: 'bool', optional: true }, + other: { type: 'bool', optional: true }, + note: { type: 'string', optional: true } + } +} + +const PainSchema = { + name: 'Pain', + properties: { + cramps: { type: 'bool', optional: true }, + ovulationPain: { type: 'bool', optional: true }, + headache: { type: 'bool', optional: true }, + backache: { type: 'bool', optional: true }, + nausea: { type: 'bool', optional: true }, + tenderBreasts: { type: 'bool', optional: true }, + migraine: { type: 'bool', optional: true }, + other: { type: 'bool', optional: true }, + note: { type: 'string', optional: true } + } +} + +const MoodSchema = { + name: 'Mood', + properties: { + happy: { type: 'bool', optional: true }, + sad: { type: 'bool', optional: true }, + stressed: { type: 'bool', optional: true }, + balanced: { type: 'bool', optional: true }, + fine: { type: 'bool', optional: true }, + anxious: { type: 'bool', optional: true }, + energetic: { type: 'bool', optional: true }, + fatigue: { type: 'bool', optional: true }, + angry: { type: 'bool', optional: true }, + other: { type: 'bool', optional: true }, + note: { type: 'string', optional: true } + } +} + +const CycleDaySchema = { + name: 'CycleDay', + primaryKey: 'date', + properties: { + date: 'string', + temperature: { + type: 'Temperature', + optional: true + }, + isCycleStart: 'bool', + bleeding: { + type: 'Bleeding', + optional: true + }, + mucus: { + type: 'Mucus', + optional: true + }, + cervix: { + type: 'Cervix', + optional: true + }, + note: { + type: 'Note', + optional: true + }, + desire: { + type: 'Desire', + optional: true + }, + sex: { + type: 'Sex', + optional: true + }, + pain: { + type: 'Pain', + optional: true + }, + mood: { + type: 'Mood', + optional: true + } + } +} + +export default { + schema: [ + CycleDaySchema, + TemperatureSchema, + BleedingSchema, + MucusSchema, + CervixSchema, + NoteSchema, + DesireSchema, + SexSchema, + PainSchema, + MoodSchema + ], + schemaVersion: 3, + migration: (oldRealm, newRealm) => { + if (oldRealm.schemaVersion >= 3) return + const oldBleedingDays = oldRealm.objects('CycleDay') + .filtered('bleeding != null') + .sorted('date', true) + + const { isMensesStart } = cycleModule({ + bleedingDaysSortedByDate: oldBleedingDays + }) + + const newBleedingDays = newRealm.objects('CycleDay') + .filtered('bleeding != null') + .sorted('date', true) + + oldBleedingDays.forEach((day, i) => { + newBleedingDays[i].isCycleStart = isMensesStart(day) + }) + } +} diff --git a/db/schemas/index.js b/db/schemas/index.js index 5b80738..ed14e67 100644 --- a/db/schemas/index.js +++ b/db/schemas/index.js @@ -1,5 +1,6 @@ import schema0 from './0.js' import schema1 from './1.js' import schema2 from './2.js' +import schema3 from './3.js' -export default [schema0, schema1, schema2] \ No newline at end of file +export default [schema0, schema1, schema2, schema3] \ No newline at end of file diff --git a/i18n/en/cycle-day.js b/i18n/en/cycle-day.js index b3c783f..886e6aa 100644 --- a/i18n/en/cycle-day.js +++ b/i18n/en/cycle-day.js @@ -86,6 +86,22 @@ export const pain = { explainer: 'How did your body feel today?' } +export const mood = { + categories: { + happy: 'Happy', + sad: 'Sad', + stressed: 'Stressed', + balanced: 'Balanced', + fine: 'Fine', + anxious: 'Anxious', + energetic: 'Energetic', + fatigue: 'Fatigue', + angry: 'Angry', + other: 'Other' + }, + explainer: 'How did you feel today?' +} + export const temperature = { outOfRangeWarning: 'This temperature value is out of the current range for the temperature chart. You can change the range in the settings.', outOfAbsoluteRangeWarning: 'This temperature value is too high or low to be shown on the temperature chart.', From 570d0dc608b2ea7c606bf215565f33cedcf2ec40 Mon Sep 17 00:00:00 2001 From: mashazyu Date: Wed, 16 Jan 2019 08:48:36 +0100 Subject: [PATCH 2/4] Add mood category to chart --- components/chart/chart.js | 2 ++ components/chart/day-column.js | 16 ++++++++++++++++ components/chart/styles.js | 1 + components/cycle-day/cycle-day-overview.js | 8 ++++++-- components/cycle-day/symptoms/mood.js | 4 ++-- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/components/chart/chart.js b/components/chart/chart.js index b8d2142..eb32e74 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -23,6 +23,7 @@ const symptomIcons = { desire: , sex: , pain: , + mood: , note: } @@ -62,6 +63,7 @@ export default class CycleChart extends Component { 'sex', 'desire', 'pain', + 'mood', 'note' ].filter((symptomName) => { return this.cycleDaysSortedByDate.some(cycleDay => { diff --git a/components/chart/day-column.js b/components/chart/day-column.js index e9c6f76..4c2244d 100644 --- a/components/chart/day-column.js +++ b/components/chart/day-column.js @@ -44,6 +44,10 @@ export default class DayColumn extends Component { // is any pain documented? acc.pain = cycleDay.pain && Object.values(cycleDay.pain).some(x => x === true) + } else if (symptom === 'mood') { + // is mood documented? + acc.mood = cycleDay.mood && + Object.values(cycleDay.mood).some(x => x === true) } acc[`${symptom}Exclude`] = cycleDay[symptom] && cycleDay[symptom].exclude return acc @@ -214,6 +218,18 @@ export default class DayColumn extends Component { /> ), + mood: ( + + + + ), note: ( this.navigate('MoodEditView')} data={this.getLabel('mood')} disabled={dateInFuture} - iconName='drip-icon-pain' + iconName='circle' > - + {this.props.iconName == 'circle' + ? + : + } {this.props.title.toLowerCase()} diff --git a/components/cycle-day/symptoms/mood.js b/components/cycle-day/symptoms/mood.js index 37b40a0..903d5d9 100644 --- a/components/cycle-day/symptoms/mood.js +++ b/components/cycle-day/symptoms/mood.js @@ -15,8 +15,8 @@ export default class Mood extends Component { constructor(props) { super(props) const cycleDay = props.cycleDay - if (cycleDay && cycleDay.pain) { - this.state = Object.assign({}, cycleDay.pain) + if (cycleDay && cycleDay.mood) { + this.state = Object.assign({}, cycleDay.mood) } else { this.state = {} } From fee13da2dc4fd78657658c67fe1914b6e31fb074 Mon Sep 17 00:00:00 2001 From: Sofiya Tepikin Date: Wed, 30 Jan 2019 13:15:12 +0300 Subject: [PATCH 3/4] Changing the mood icon --- components/chart/chart.js | 2 +- components/chart/styles.js | 4 ++-- components/cycle-day/cycle-day-overview.js | 14 +++++--------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/components/chart/chart.js b/components/chart/chart.js index eb32e74..f986524 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -23,7 +23,7 @@ const symptomIcons = { desire: , sex: , pain: , - mood: , + mood: , note: } diff --git a/components/chart/styles.js b/components/chart/styles.js index 58c751c..4da89b2 100644 --- a/components/chart/styles.js +++ b/components/chart/styles.js @@ -77,8 +77,8 @@ const styles = { '#9e346c', ], 'pain': ['#bccd67'], - 'mood': ['#BC6642'], - 'note': ['#6CA299'] + 'mood': ['#bc6642'], + 'note': ['#6ca299'] }, yAxis: { width: 27, diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 28303e7..dd5dd10 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -13,7 +13,6 @@ import styles from '../../styles' import * as labels from '../../i18n/en/cycle-day' import AppText from '../app-text' import DripIcon from '../../assets/drip-icons' -import DripHomeIcon from '../../assets/drip-home-icons' const bleedingLabels = labels.bleeding.labels const feelingLabels = labels.mucus.feeling.categories @@ -252,7 +251,7 @@ export default class CycleDayOverView extends Component { onPress={() => this.navigate('MoodEditView')} data={this.getLabel('mood')} disabled={dateInFuture} - iconName='circle' + iconName='drip-icon-mood' > - {this.props.iconName == 'circle' - ? - : - } + {this.props.title.toLowerCase()} From 78869f99b87ea102f044c5fe630ade6c19e03e52 Mon Sep 17 00:00:00 2001 From: Sofiya Tepikin Date: Wed, 30 Jan 2019 14:05:22 +0300 Subject: [PATCH 4/4] Adds the missing mood title on mood edit view --- i18n/en/labels.js | 1 + 1 file changed, 1 insertion(+) diff --git a/i18n/en/labels.js b/i18n/en/labels.js index 9f06412..ebd768a 100644 --- a/i18n/en/labels.js +++ b/i18n/en/labels.js @@ -40,6 +40,7 @@ export const headerTitles = { DesireEditView: 'Desire', SexEditView: 'Sex', PainEditView: 'Pain', + MoodEditView: 'Mood', InfoSymptom: 'Info' }