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.',