Merge branch 'mood-category' into 'master'

Add mood component, add mood as tracking category to db schemas, add mood...

See merge request bloodyhealth/drip!156
This commit is contained in:
bl00dymarie
2019-01-30 11:18:10 +00:00
10 changed files with 343 additions and 10 deletions
+2
View File
@@ -23,6 +23,7 @@ const symptomIcons = {
desire: <DripIcon size={16} name='drip-icon-desire' color={styles.iconShades.desire[2]}/>,
sex: <DripIcon size={16} name='drip-icon-sex' color={styles.iconShades.sex[2]}/>,
pain: <DripIcon size={16} name='drip-icon-pain' color={styles.iconShades.pain[0]}/>,
mood: <DripIcon size={16} name='drip-icon-mood' color={styles.iconShades.mood[0]}/>,
note: <DripIcon size={16} name='drip-icon-note' color={styles.iconShades.note[0]}/>
}
@@ -62,6 +63,7 @@ export default class CycleChart extends Component {
'sex',
'desire',
'pain',
'mood',
'note'
].filter((symptomName) => {
return this.cycleDaysSortedByDate.some(cycleDay => {
+16
View File
@@ -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 {
/>
</SymptomIconView>
),
mood: (
<SymptomIconView
value={this.data.mood}
symptomHeight={symptomHeight}
key='mood'
>
<View
{...styles.symptomIcon}
backgroundColor={styles.iconShades.mood}
/>
</SymptomIconView>
),
note: (
<SymptomIconView
value={this.data.note}
+2 -1
View File
@@ -77,7 +77,8 @@ const styles = {
'#9e346c',
],
'pain': ['#bccd67'],
'note': ['#6CA299']
'mood': ['#bc6642'],
'note': ['#6ca299']
},
yAxis: {
width: 27,
+35 -7
View File
@@ -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'
>
</SymptomBox>
<SymptomBox
title='Mood'
onPress={() => this.navigate('MoodEditView')}
data={this.getLabel('mood')}
disabled={dateInFuture}
iconName='drip-icon-mood'
>
</SymptomBox>
<SymptomBox
title='Note'
onPress={() => 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 */}
<FillerBoxes />
</View >
</ScrollView >
</View >
</View>
</ScrollView>
</View>
)
}
}
@@ -248,9 +276,9 @@ export default class CycleDayOverView extends Component {
class SymptomBox extends Component {
render() {
const d = this.props.data
const boxActive = d ? styles.symptomBoxActive : {}
const textActive = d ? styles.symptomTextActive : {}
const hasData = this.props.data
const boxActive = hasData ? styles.symptomBoxActive : {}
const textActive = hasData ? styles.symptomTextActive : {}
const disabledStyle = this.props.disabled ? styles.symptomInFuture : {}
return (
@@ -259,7 +287,7 @@ class SymptomBox extends Component {
disabled={this.props.disabled}
>
<View style={[styles.symptomBox, boxActive, disabledStyle]}>
<DripIcon name={this.props.iconName} size={50} color={d ? 'white' : 'black'}/>
<DripIcon name={this.props.iconName} size={50} color={hasData ? 'white' : 'black'}/>
<AppText style={[textActive, disabledStyle]}>
{this.props.title.toLowerCase()}
</AppText>
+3 -1
View File
@@ -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
}
+78
View File
@@ -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.mood) {
this.state = Object.assign({}, cycleDay.mood)
} 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 (
<View style={{ flex: 1 }}>
<ScrollView style={styles.page}>
<SymptomSection
explainer={labels.explainer}
>
<SelectBoxGroup
labels={labels.categories}
onSelect={this.toggleState}
optionsState={this.state}
/>
{ this.state.other &&
<TextInput
autoFocus={this.state.focusTextArea}
multiline={true}
placeholder="Enter"
value={this.state.note}
onChangeText={(val) => {
this.setState({note: val})
}}
/>
}
</SymptomSection>
</ScrollView>
<ActionButtonFooter
symptom='mood'
date={this.props.date}
currentSymptomValue={this.state}
saveAction={() => {
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}
/>
</View>
)
}
}
+188
View File
@@ -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)
})
}
}
+2 -1
View File
@@ -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]
export default [schema0, schema1, schema2, schema3]
+16
View File
@@ -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.',
+1
View File
@@ -40,6 +40,7 @@ export const headerTitles = {
DesireEditView: 'Desire',
SexEditView: 'Sex',
PainEditView: 'Pain',
MoodEditView: 'Mood',
InfoSymptom: 'Info'
}