Compare commits

...

6 Commits

Author SHA1 Message Date
bl00dymarie 960a411794 Merge branch 'main' into 'feature/prods'
# Conflicts:
#   components/cycle-day/symptom-edit-view.js
#   i18n/en/cycle-day.js
2024-04-03 19:56:12 +00:00
Liv eda7d9c7f3 Remove line in bleeding and change wording 2024-01-17 15:45:10 +01:00
Liv 8db4424df5 Added disk as option and moved toggle 2024-01-12 21:27:20 +01:00
Liv d822d057a3 Fix spelling symtom -> symptom 2023-11-20 12:14:25 +01:00
Liv 3b797b8500 Fix labels and clean up code 2023-11-20 12:14:14 +01:00
Liv 503ce6e82d Basic working version that includes period products 2023-11-20 12:13:42 +01:00
7 changed files with 291 additions and 23 deletions
+2 -2
View File
@@ -63,11 +63,11 @@ const SymptomBox = ({
/> />
<View style={styles.textContainer}> <View style={styles.textContainer}>
<AppText style={symptomNameStyle}>{t(symptom)}</AppText> <AppText style={symptomNameStyle}>{t(symptom)}</AppText>
{symptomDataToDisplay && ( {symptomDataToDisplay ? (
<AppText style={textStyle} numberOfLines={4}> <AppText style={textStyle} numberOfLines={4}>
{symptomDataToDisplay} {symptomDataToDisplay}
</AppText> </AppText>
)} ) : null}
</View> </View>
</TouchableOpacity> </TouchableOpacity>
</> </>
+26 -6
View File
@@ -12,7 +12,7 @@ import SelectBoxGroup from './select-box-group'
import SelectTabGroup from './select-tab-group' import SelectTabGroup from './select-tab-group'
import Temperature from './temperature' import Temperature from './temperature'
import { blank, save, shouldShow, symtomPage } from '../helpers/cycle-day' import { blank, save, shouldShow, symptomPage } from '../helpers/cycle-day'
import { showToast } from '../helpers/general' import { showToast } from '../helpers/general'
import { fertilityTrackingObservable } from '../../local-storage' import { fertilityTrackingObservable } from '../../local-storage'
@@ -21,9 +21,10 @@ import info from '../../i18n/en/symptom-info'
import { Colors, Containers, Sizes, Spacing } from '../../styles' import { Colors, Containers, Sizes, Spacing } from '../../styles'
const SymptomEditView = ({ date, onClose, symptom, symptomData }) => { const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
const symptomConfig = symtomPage[symptom] const symptomConfig = symptomPage[symptom]
const [data, setData] = useState(symptomData ? symptomData : blank[symptom]) const [data, setData] = useState(symptomData ? symptomData : blank[symptom])
const [shouldShowInfo, setShouldShowInfo] = useState(false) const [shouldShowInfo, setShouldShowInfo] = useState(false)
const isBleeding = symptom === 'bleeding'
const getParsedData = () => JSON.parse(JSON.stringify(data)) const getParsedData = () => JSON.parse(JSON.stringify(data))
const onPressLearnMore = () => setShouldShowInfo(!shouldShowInfo) const onPressLearnMore = () => setShouldShowInfo(!shouldShowInfo)
const isFertilityTrackingEnabled = fertilityTrackingObservable.value const isFertilityTrackingEnabled = fertilityTrackingObservable.value
@@ -116,6 +117,15 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
style: styles.input, style: styles.input,
textAlignVertical: 'top', textAlignVertical: 'top',
} }
const excludeToggle = shouldShow(symptomConfig.excludeText) && (
<Segment style={styles.segmentBorder}>
<AppSwitch
onToggle={onExcludeToggle}
text={symptomPage[symptom].excludeText}
value={data.exclude}
/>
</Segment>
)
return ( return (
<AppModal onClose={onSave}> <AppModal onClose={onSave}>
@@ -130,10 +140,16 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
save={(value, field) => onSaveTemperature(value, field)} save={(value, field) => onSaveTemperature(value, field)}
/> />
)} )}
{/* There should not be a line between the bleeding tab group and the exclude toggle */}
{shouldShow(symptomConfig.selectTabGroups) && {shouldShow(symptomConfig.selectTabGroups) &&
symtomPage[symptom].selectTabGroups.map((group) => { symptomPage[symptom].selectTabGroups.map((group) => {
return ( return (
<Segment key={group.key} style={styles.segmentBorder}> <Segment
key={group.key}
style={styles.segmentBorder}
last={isBleeding}
>
<AppText style={styles.title}>{group.title}</AppText> <AppText style={styles.title}>{group.title}</AppText>
<SelectTabGroup <SelectTabGroup
activeButton={data[group.key]} activeButton={data[group.key]}
@@ -143,8 +159,12 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
</Segment> </Segment>
) )
})} })}
{/*for bleeding, we want to move the "exclude" toggle up between the tab and box groups, all other symptoms should still have it at the bottom*/}
{isBleeding && excludeToggle}
{shouldShow(symptomConfig.selectBoxGroups) && {shouldShow(symptomConfig.selectBoxGroups) &&
symtomPage[symptom].selectBoxGroups.map((group) => { symptomPage[symptom].selectBoxGroups.map((group) => {
const isOtherSelected = const isOtherSelected =
data['other'] !== null && data['other'] !== null &&
data['other'] !== false && data['other'] !== false &&
@@ -183,7 +203,7 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
)} )}
{shouldShow(symptomConfig.note) && ( {shouldShow(symptomConfig.note) && (
<Segment style={styles.segmentBorder}> <Segment style={styles.segmentBorder}>
<AppText>{symtomPage[symptom].note}</AppText> <AppText>{symptomPage[symptom].note}</AppText>
<AppTextInput <AppTextInput
{...inputProps} {...inputProps}
onChangeText={onEditNote} onChangeText={onEditNote}
+49 -12
View File
@@ -23,6 +23,7 @@ const noteDescription = labels.noteExplainer
const painLabels = labels.pain.categories const painLabels = labels.pain.categories
const sexLabels = labels.sex.categories const sexLabels = labels.sex.categories
const temperatureLabels = labels.temperature const temperatureLabels = labels.temperature
const productLabels = labels.products.categories
const minutes = ChronoUnit.MINUTES const minutes = ChronoUnit.MINUTES
@@ -60,6 +61,15 @@ export const blank = {
bleeding: { bleeding: {
exclude: false, exclude: false,
value: null, value: null,
pad: null,
tampon: null,
underwear: null,
cup: null,
softTampon: null,
disk: null,
none: null,
other: null,
note: null,
}, },
cervix: { cervix: {
exclude: false, exclude: false,
@@ -125,11 +135,10 @@ export const blank = {
}, },
} }
export const symtomPage = { export const symptomPage = {
bleeding: { bleeding: {
excludeText: labels.bleeding.exclude.explainer, excludeText: labels.bleeding.exclude.explainer,
note: null, note: null,
selectBoxGroups: null,
selectTabGroups: [ selectTabGroups: [
{ {
key: 'value', key: 'value',
@@ -137,6 +146,13 @@ export const symtomPage = {
title: labels.bleeding.heaviness.explainer, title: labels.bleeding.heaviness.explainer,
}, },
], ],
selectBoxGroups: [
{
key: 'products',
options: productLabels,
title: labels.products.explainer,
},
],
}, },
cervix: { cervix: {
excludeText: cervixLabels.excludeExplainer, excludeText: cervixLabels.excludeExplainer,
@@ -246,12 +262,7 @@ export const symtomPage = {
export const save = { export const save = {
bleeding: (data, date, shouldDeleteData) => { bleeding: (data, date, shouldDeleteData) => {
const { exclude, value } = data saveBoxSymptom(data, date, shouldDeleteData, 'bleeding')
const isDataEntered = isNumber(value)
const valuesToSave =
shouldDeleteData || !isDataEntered ? null : { value, exclude }
saveSymptom('bleeding', date, valuesToSave)
}, },
cervix: (data, date, shouldDeleteData) => { cervix: (data, date, shouldDeleteData) => {
const { opening, firmness, position, exclude } = data const { opening, firmness, position, exclude } = data
@@ -329,10 +340,36 @@ const saveBoxSymptom = (data, date, shouldDeleteData, symptom) => {
} }
const label = { const label = {
bleeding: ({ value, exclude }) => { bleeding: (bleeding) => {
if (isNumber(value)) { bleeding = mapRealmObjToJsObj(bleeding)
const bleedingLabel = bleedingLabels[value] const bleedingLabel = []
return exclude ? `(${bleedingLabel})` : bleedingLabel if (bleeding && Object.values({ ...bleeding }).some((val) => val)) {
Object.keys(bleeding).forEach((key) => {
if (bleeding[key] != null && key === 'value') {
bleedingLabel.push(
bleeding.exclude
? `(${bleedingLabels[bleeding[key]]})`
: bleedingLabels[bleeding[key]]
)
}
if (
bleeding[key] &&
key !== 'other' &&
key !== 'note' &&
key !== 'value' &&
key !== 'exclude'
) {
bleedingLabel.push(bleedingLabels[key] || productLabels[key])
}
if (key === 'other' && bleeding.other) {
let label = productLabels[key]
if (bleeding.note) {
label = `${label} (${bleeding.note})`
}
bleedingLabel.push(label)
}
})
return bleedingLabel.join(', ')
} }
}, },
temperature: ({ value, time, exclude }) => { temperature: ({ value, time, exclude }) => {
+2 -2
View File
@@ -65,6 +65,7 @@ export function getBleedingDaysSortedByDate() {
return db return db
.objects('CycleDay') .objects('CycleDay')
.filtered('bleeding != null') .filtered('bleeding != null')
.filtered('bleeding.value != null')
.sorted('date', true) .sorted('date', true)
} }
export function getTemperatureDaysSortedByDate() { export function getTemperatureDaysSortedByDate() {
@@ -88,9 +89,8 @@ export function getCycleStartsSortedByDate() {
export function saveSymptom(symptom, date, val) { export function saveSymptom(symptom, date, val) {
let cycleDay = getCycleDay(date) let cycleDay = getCycleDay(date)
if (!cycleDay) cycleDay = createCycleDay(date) if (!cycleDay) cycleDay = createCycleDay(date)
db.write(() => { db.write(() => {
if (symptom === 'bleeding') { if (symptom === 'bleeding' && val != null && val.value != null) {
const mensesDaysAfter = getMensesDaysRightAfter(cycleDay) const mensesDaysAfter = getMensesDaysRightAfter(cycleDay)
maybeSetNewCycleStart({ maybeSetNewCycleStart({
val, val,
+195
View File
@@ -0,0 +1,195 @@
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: { type: 'int', optional: true },
exclude: 'bool',
pad: { type: 'bool', optional: true },
tampon: { type: 'bool', optional: true },
underwear: { type: 'bool', optional: true },
cup: { type: 'bool', optional: true },
softTampon: { type: 'bool', optional: true },
disk: { type: 'bool', optional: true },
none: { type: 'bool', optional: true },
other: { type: 'bool', optional: true },
note: { type: 'string', optional: true },
},
}
const MucusSchema = {
name: 'Mucus',
properties: {
feeling: { type: 'int', optional: true },
texture: { type: 'int', optional: true },
value: { type: 'int', optional: true },
exclude: 'bool',
},
}
const CervixSchema = {
name: 'Cervix',
properties: {
opening: { type: 'int', optional: true },
firmness: { type: 'int', optional: true },
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: 5,
migration: (oldRealm, newRealm) => {
if (oldRealm.schemaVersion < 5) {
const newObjects = newRealm.objects('Bleeding')
// loop through all objects and assign a default value for new properties
for (let i = 0; i < newObjects.length; i++) {
newObjects[i].pad = false
newObjects[i].tampon = false
newObjects[i].underwear = false
newObjects[i].cup = false
newObjects[i].softTampon = false
newObjects[i].disk = false
newObjects[i].none = false
newObjects[i].other = false
newObjects[i].note = null
}
}
},
}
+2 -1
View File
@@ -3,5 +3,6 @@ import schema1 from './1.js'
import schema2 from './2.js' import schema2 from './2.js'
import schema3 from './3.js' import schema3 from './3.js'
import schema4 from './4.js' import schema4 from './4.js'
import schema5 from './5.js'
export default [schema0, schema1, schema2, schema3, schema4] export default [schema0, schema1, schema2, schema3, schema4, schema5]
+15
View File
@@ -13,6 +13,21 @@ export const bleeding = {
}, },
} }
export const products = {
categories: {
pad: 'pad',
tampon: 'tampon',
underwear: 'underwear',
cup: 'cup',
softTampon: 'soft tampon',
disk: 'disk',
none: 'none',
other: 'other',
},
header: 'period products',
explainer: 'Did you use period products?',
}
export const cervix = { export const cervix = {
subcategories: { subcategories: {
opening: 'opening', opening: 'opening',