Merge branch '675-feature-customisation-not-display-fertility-phases' into '676-feature-customisation-not-display-mucus-cervix'

Resolve "feature: customisation (not) display fertility phases"

See merge request bloodyhealth/drip!659
This commit is contained in:
bl00dymarie
2024-02-26 15:48:27 +00:00
7 changed files with 93 additions and 38 deletions
+7 -3
View File
@@ -14,7 +14,10 @@ import {
determinePredictionText, determinePredictionText,
formatWithOrdinalSuffix, formatWithOrdinalSuffix,
} from './helpers/home' } from './helpers/home'
import { periodPredictionObservable } from '../local-storage' import {
fertilityTrackingObservable,
periodPredictionObservable,
} from '../local-storage'
import { Colors, Fonts, Sizes, Spacing } from '../styles' import { Colors, Fonts, Sizes, Spacing } from '../styles'
import { LocalDate } from '@js-joda/core' import { LocalDate } from '@js-joda/core'
@@ -28,11 +31,12 @@ const Home = ({ navigate, setDate }) => {
navigate('CycleDay') navigate('CycleDay')
} }
const isFertilityTrackingEnabled = fertilityTrackingObservable.value
const todayDateString = LocalDate.now().toString() const todayDateString = LocalDate.now().toString()
const { getCycleDayNumber, getPredictedMenses } = cycleModule() const { getCycleDayNumber, getPredictedMenses } = cycleModule()
const cycleDayNumber = getCycleDayNumber(todayDateString) const cycleDayNumber = getCycleDayNumber(todayDateString)
const { status, phase, statusText } = const { status, phase, statusText } =
getFertilityStatusForDay(todayDateString) isFertilityTrackingEnabled && getFertilityStatusForDay(todayDateString)
const isPeriodPredictionEnabled = periodPredictionObservable.value const isPeriodPredictionEnabled = periodPredictionObservable.value
const prediction = determinePredictionText(getPredictedMenses(), t) const prediction = determinePredictionText(getPredictedMenses(), t)
@@ -55,7 +59,7 @@ const Home = ({ navigate, setDate }) => {
</AppText> </AppText>
</View> </View>
)} )}
{phase && ( {isFertilityTrackingEnabled && phase && (
<View style={styles.line}> <View style={styles.line}>
<AppText style={styles.whiteSubtitle}> <AppText style={styles.whiteSubtitle}>
{formatWithOrdinalSuffix(phase)} {formatWithOrdinalSuffix(phase)}
+7 -2
View File
@@ -1,10 +1,10 @@
import React from 'react' import React from 'react'
import { StyleSheet, Switch, View } from 'react-native' import { Platform, StyleSheet, Switch, View } from 'react-native'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import AppText from './app-text' import AppText from './app-text'
import { Colors, Containers } from '../../styles' import { Colors, Containers, Spacing } from '../../styles'
const AppSwitch = ({ onToggle, text, value, disabled }) => { const AppSwitch = ({ onToggle, text, value, disabled }) => {
const trackColor = { true: Colors.turquoiseDark } const trackColor = { true: Colors.turquoiseDark }
@@ -34,9 +34,14 @@ AppSwitch.propTypes = {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
...Containers.rowContainer, ...Containers.rowContainer,
marginTop: Spacing.tiny,
}, },
switch: { switch: {
flex: 1, flex: 1,
transform:
Platform.OS === 'ios'
? [{ scaleX: 0.8 }, { scaleY: 0.8 }]
: [{ scaleX: 1 }, { scaleY: 1 }],
}, },
textContainer: { textContainer: {
flex: 4, flex: 4,
+7 -2
View File
@@ -1,6 +1,10 @@
import { LocalDate } from '@js-joda/core' import { LocalDate } from '@js-joda/core'
import { scaleObservable, unitObservable } from '../../local-storage' import {
fertilityTrackingObservable,
scaleObservable,
unitObservable,
} from '../../local-storage'
import { getCycleStatusForDay } from '../../lib/sympto-adapter' import { getCycleStatusForDay } from '../../lib/sympto-adapter'
import { getCycleDay, getAmountOfCycleDays } from '../../db' import { getCycleDay, getAmountOfCycleDays } from '../../db'
@@ -270,7 +274,8 @@ export function nfpLines() {
if (dateString < cycle.startDate) updateCurrentCycle(dateString) if (dateString < cycle.startDate) updateCurrentCycle(dateString)
if (cycle.noMoreCycles) return ret if (cycle.noMoreCycles) return ret
const tempShift = cycle.status.temperatureShift const tempShift =
fertilityTrackingObservable.value && cycle.status.temperatureShift
if (tempShift) { if (tempShift) {
if (tempShift.firstHighMeasurementDay.date === dateString) { if (tempShift.firstHighMeasurementDay.date === dateString) {
+36 -21
View File
@@ -10,6 +10,7 @@ import SelectTabGroup from '../../cycle-day/select-tab-group'
import { import {
desireTrackingCategoryObservable, desireTrackingCategoryObservable,
fertilityTrackingObservable,
moodTrackingCategoryObservable, moodTrackingCategoryObservable,
noteTrackingCategoryObservable, noteTrackingCategoryObservable,
painTrackingCategoryObservable, painTrackingCategoryObservable,
@@ -18,6 +19,7 @@ import {
mucusTrackingCategoryObservable, mucusTrackingCategoryObservable,
cervixTrackingCategoryObservable, cervixTrackingCategoryObservable,
saveDesireTrackingCategory, saveDesireTrackingCategory,
saveFertilityTrackingEnabled,
saveMoodTrackingCategory, saveMoodTrackingCategory,
saveNoteTrackingCategory, saveNoteTrackingCategory,
savePainTrackingCategory, savePainTrackingCategory,
@@ -72,15 +74,21 @@ const Settings = () => {
noteTrackingCategoryObservable.value noteTrackingCategoryObservable.value
) )
const [isSecondarySymptomDisabled, setIsSecondarySymptomDisabled] = const [isFertilityTrackingEnabled, setFertilityTrackingEnabled] = useState(
useState(false) fertilityTrackingObservable.value
)
const [isEnabled, setIsEnabled] = useState(false) const fertilityTrackingToggle = (value) => {
const toggleSwitch = () => setIsEnabled((previousState) => !previousState) setFertilityTrackingEnabled(value)
saveFertilityTrackingEnabled(value)
}
const temperatureTrackingCategoryToggle = (value) => { const temperatureTrackingCategoryToggle = (value) => {
setTemperatureTrackingCategory(value) setTemperatureTrackingCategory(value)
saveTemperatureTrackingCategory(value) saveTemperatureTrackingCategory(value)
if (!value) {
setFertilityTrackingEnabled(false)
saveFertilityTrackingEnabled(false)
}
} }
const mucusTrackingCategoryToggle = (value) => { const mucusTrackingCategoryToggle = (value) => {
manageSecondarySymptom(cervixTrackingCategoryObservable.value, value) manageSecondarySymptom(cervixTrackingCategoryObservable.value, value)
@@ -112,6 +120,11 @@ const Settings = () => {
setPeriodPrediction(value) setPeriodPrediction(value)
savePeriodPrediction(value) savePeriodPrediction(value)
} }
const fertilityTrackingText = isFertilityTrackingEnabled
? labels.fertilityTracking.on
: labels.fertilityTracking.off
const periodPredictionText = isPeriodPredictionEnabled const periodPredictionText = isPeriodPredictionEnabled
? labels.periodPrediction.on ? labels.periodPrediction.on
: labels.periodPrediction.off : labels.periodPrediction.off
@@ -148,15 +161,12 @@ const Settings = () => {
if (!cervix && mucus) { if (!cervix && mucus) {
setUseCervixAsSecondarySymptom(0) setUseCervixAsSecondarySymptom(0)
saveUseCervixAsSecondarySymptom(0) saveUseCervixAsSecondarySymptom(0)
setIsSecondarySymptomDisabled(false)
} else if (cervix && mucus) {
setIsSecondarySymptomDisabled(false)
} else if (cervix && !mucus) { } else if (cervix && !mucus) {
setUseCervixAsSecondarySymptom(1) setUseCervixAsSecondarySymptom(1)
saveUseCervixAsSecondarySymptom(1) saveUseCervixAsSecondarySymptom(1)
setIsSecondarySymptomDisabled(false)
} else if (!cervix && !mucus) { } else if (!cervix && !mucus) {
setIsSecondarySymptomDisabled(true) setFertilityTrackingEnabled(false)
saveFertilityTrackingEnabled(false)
} }
setMucusTrackingCategory(mucus) setMucusTrackingCategory(mucus)
saveMucusTrackingCategory(mucus) saveMucusTrackingCategory(mucus)
@@ -191,7 +201,6 @@ const Settings = () => {
text={SYMPTOMS[1]} text={SYMPTOMS[1]}
value={isTemperatureTrackingCategoryEnabled} value={isTemperatureTrackingCategoryEnabled}
/> />
<AppSwitch <AppSwitch
onToggle={(enabled) => { onToggle={(enabled) => {
mucusTrackingCategoryToggle(enabled) mucusTrackingCategoryToggle(enabled)
@@ -199,7 +208,6 @@ const Settings = () => {
text={SYMPTOMS[2]} text={SYMPTOMS[2]}
value={isMucusTrackingCategoryEnabled} value={isMucusTrackingCategoryEnabled}
/> />
<AppSwitch <AppSwitch
onToggle={(enabled) => { onToggle={(enabled) => {
cervixTrackingCategoryToggle(enabled) cervixTrackingCategoryToggle(enabled)
@@ -207,7 +215,6 @@ const Settings = () => {
text={SYMPTOMS[3]} text={SYMPTOMS[3]}
value={isCervixTrackingCategoryEnabled} value={isCervixTrackingCategoryEnabled}
/> />
<AppSwitch <AppSwitch
onToggle={sexTrackingCategoryToggle} onToggle={sexTrackingCategoryToggle}
text={SYMPTOMS[4]} text={SYMPTOMS[4]}
@@ -234,14 +241,24 @@ const Settings = () => {
value={isNoteTrackingCategoryEnabled} value={isNoteTrackingCategoryEnabled}
/> />
</Segment> </Segment>
<Pressable onPress={sliderDisabledPrompt}>
<Segment title={'Fertility feature'}> <Segment title={labels.fertilityTracking.title}>
{isTemperatureTrackingCategoryEnabled &&
(isMucusTrackingCategoryEnabled ||
isCervixTrackingCategoryEnabled) ? (
<>
<AppText>{labels.fertilityTracking.message}</AppText>
<AppSwitch <AppSwitch
onToggle={toggleSwitch} onToggle={fertilityTrackingToggle}
text={'If turned on ...'} text={fertilityTrackingText}
value={isEnabled} value={isFertilityTrackingEnabled}
/> />
</>
) : (
<AppText>{labels.disabled.message}</AppText>
)}
</Segment> </Segment>
</Pressable>
<Pressable onPress={sliderDisabledPrompt}> <Pressable onPress={sliderDisabledPrompt}>
<Segment title={labels.tempScale.segmentTitle}> <Segment title={labels.tempScale.segmentTitle}>
@@ -257,11 +274,9 @@ const Settings = () => {
</Segment> </Segment>
</Pressable> </Pressable>
{/* used to be switch for onCervixToggle */}
<Pressable onPress={secondarySymptomDisabledPrompt}> <Pressable onPress={secondarySymptomDisabledPrompt}>
<Segment title={labels.secondarySymptom.title}> <Segment title={labels.secondarySymptom.title}>
{!isTemperatureTrackingCategoryEnabled || {!isFertilityTrackingEnabled ? (
isSecondarySymptomDisabled ? (
<AppText>{labels.secondarySymptom.disabled.message}</AppText> <AppText>{labels.secondarySymptom.disabled.message}</AppText>
) : ( ) : (
<> <>
+11 -4
View File
@@ -41,7 +41,7 @@ export default {
disabled: { disabled: {
title: 'This feature is turned off', title: 'This feature is turned off',
message: message:
'Please first enable the temperature tracking category in the customization settings.', 'To use the temperature scale please first enable the temperature tracking category above.',
}, },
tempReminder: { tempReminder: {
title: 'Temperature reminder', title: 'Temperature reminder',
@@ -66,6 +66,13 @@ export default {
'To use the period reminder please first enable period predictions in the customization settings.', 'To use the period reminder please first enable period predictions in the customization settings.',
}, },
}, },
fertilityTracking: {
title: 'Fertility phases calculation',
message:
'If you enter menstrual bleeding, temperature and cervical mucus or cervix data according to the sympto-thermal rules, drip will calculate cycle phases with the provided data.',
on: 'If you switch this off, drip will not show fertility related information.',
off: 'If you switch this on, drip will show fertility related information.',
},
secondarySymptom: { secondarySymptom: {
title: 'Secondary symptom', title: 'Secondary symptom',
cervixModeOn: cervixModeOn:
@@ -75,16 +82,16 @@ export default {
disabled: { disabled: {
title: 'Disabled', title: 'Disabled',
message: message:
'To set a secondary symptom please first enable the temperature, cervical mucus or cervix tracking category as well as the fertility feature in the customization settings.', 'To set a secondary symptom please first enable the temperature, cervical mucus or cervix tracking category as well as the fertility feature above.',
noSecondaryEnabled: noSecondaryEnabled:
'To switch the secondary symptom both cervical mucus an cervix need to be enabled in the customization settings.', 'To switch the secondary symptom both cervical mucus and cervix need to be enabled above.',
}, },
mucus: 'cervical mucus', mucus: 'cervical mucus',
cervix: 'cervix', cervix: 'cervix',
}, },
periodPrediction: { periodPrediction: {
title: 'Period predictions', title: 'Period predictions',
on: 'drip predicts your 3 next menstrual bleedings based on the statistics of your previously tracked cycles, min 3 complete cycles.', on: 'drip predicts your 3 next menstrual bleedings based on statistics if you previously tracked at least 3 complete cycles.',
off: 'There are no predictions for menstrual cycles displayed. If turned on the calendar and the home screen will display period predictions.', off: 'There are no predictions for menstrual cycles displayed. If turned on the calendar and the home screen will display period predictions.',
}, },
passwordSettings: { passwordSettings: {
+11 -1
View File
@@ -1,9 +1,15 @@
import getFertilityStatus from 'sympto' import getFertilityStatus from 'sympto'
import cycleModule from './cycle' import cycleModule from './cycle'
import { useCervixAsSecondarySymptomObservable } from '../local-storage' import { fertilityTrackingObservable, useCervixAsSecondarySymptomObservable } from '../local-storage'
import { fertilityStatus as labels } from '../i18n/en/labels' import { fertilityStatus as labels } from '../i18n/en/labels'
const isFertilityTrackingEnabled = fertilityTrackingObservable.value
export function getFertilityStatusForDay(dateString) { export function getFertilityStatusForDay(dateString) {
if (!isFertilityTrackingEnabled) {
return
}
const status = getCycleStatusForDay(dateString) const status = getCycleStatusForDay(dateString)
if (!status) return { if (!status) return {
status: labels.fertile, status: labels.fertile,
@@ -34,6 +40,10 @@ export function getFertilityStatusForDay(dateString) {
} }
export function getCycleStatusForDay(dateString, opts = {}) { export function getCycleStatusForDay(dateString, opts = {}) {
if (!isFertilityTrackingEnabled) {
return
}
const { const {
getCycleForDay, getCycleForDay,
getCyclesBefore, getCyclesBefore,
+11 -2
View File
@@ -107,8 +107,9 @@ export async function saveTemperatureTrackingCategory(bool) {
temperatureTrackingCategoryObservable.set(bool) temperatureTrackingCategoryObservable.set(bool)
if (!temperatureTrackingCategoryObservable.value) { if (!temperatureTrackingCategoryObservable.value) {
const result = await AsyncStorage.getItem('tempReminder') // if temperature tracking is turned off, the temperature reminder gets disabled
if (JSON.parse(result).enabled) { const tempReminderResult = await AsyncStorage.getItem('tempReminder')
if (tempReminderResult && JSON.parse(tempReminderResult).enabled) {
tempReminderObservable.set(false) tempReminderObservable.set(false)
} }
} }
@@ -170,6 +171,14 @@ export async function saveNoteTrackingCategory(bool) {
noteTrackingCategoryObservable.set(bool) noteTrackingCategoryObservable.set(bool)
} }
export const fertilityTrackingObservable = Observable()
setObvWithInitValue('fertilityTracking', fertilityTrackingObservable, true)
export async function saveFertilityTrackingEnabled(bool) {
await AsyncStorage.setItem('fertilityTracking', JSON.stringify(bool))
fertilityTrackingObservable.set(bool)
}
async function setObvWithInitValue(key, obv, defaultValue) { async function setObvWithInitValue(key, obv, defaultValue) {
const result = await AsyncStorage.getItem(key) const result = await AsyncStorage.getItem(key)
let value let value