Compare commits

...

40 Commits

Author SHA1 Message Date
bl00dymarie 3cedcf601e Merge branch 'Release-1.2403.19' into 'main'
Release 1.2403.19 update for Android and iOS

See merge request bloodyhealth/drip!678
2024-03-21 11:56:17 +00:00
bl00dymarie e4d97b362f Release 1.2403.19 update for Android and iOS 2024-03-21 12:53:15 +01:00
bl00dymarie d8cb679d77 Merge branch 'Add-ios-release-notes' into 'main'
Chore: Add release notes for iOS

See merge request bloodyhealth/drip!676
2024-03-19 13:24:13 +00:00
bl00dymarie 839acfa22d Add release notes for iOS 2024-03-19 14:22:08 +01:00
wunderfisch a0482291cf Merge branch '712-chore-testing-feedback-for-v1-2403-11-part-2' into 'main'
Resolve "Chore: Testing Feedback for v1.2403.11 part 2"

Closes #712

See merge request bloodyhealth/drip!675
2024-03-19 11:54:58 +00:00
bl00dymarie 37f718d1b0 Remove info from menu temporarily 2024-03-18 19:03:40 +01:00
bl00dymarie 9b0abd5367 Add one small info text to the bottom of customization index 2024-03-18 19:03:21 +01:00
bl00dymarie c8521cf5ed Merge branch '711-chore-testing-feedback-for-v1-2403-11' into 'main'
Resolve "Chore: Testing Feedback for v1.2403.11"

Closes #711

See merge request bloodyhealth/drip!673
2024-03-18 17:47:49 +00:00
wunderfisch f7c6f4bfd0 replace hard coded label 2024-03-18 18:46:00 +01:00
wunderfisch 15a0b3d270 adapt text according to customization 2024-03-18 18:42:45 +01:00
bl00dymarie 4e37f1b7de Unify spelling starting with capital letter 2024-03-17 17:00:53 +01:00
bl00dymarie 56e90b69e6 Rearrange segments in customization + add subheader 2024-03-16 14:39:38 +01:00
bl00dymarie b481bd8352 Don't show the exclude switch when fertility is off 2024-03-16 14:37:58 +01:00
bl00dymarie e33c13e5e0 Remove idle labels 2024-03-16 14:37:49 +01:00
wunderfisch 693c766da8 fixing cervical mucus button also showing disabled alert 2024-03-14 18:02:15 +01:00
bl00dymarie fc4bc625ce Add some info to home text elements 2024-03-14 14:28:38 +01:00
bl00dymarie 0e7d84874c Add more padding to button if home is almost empty 2024-03-14 14:28:09 +01:00
bl00dymarie a93a338e6e Improve wording for disabled alerts 2024-03-14 14:27:18 +01:00
wunderfisch 003f825ef4 Merge branch '676-feature-customisation-not-display-mucus-cervix' into 'main'
Disable and switch secondary symptom depending on cervical mucus and cervix turned on or off.

Closes #676

See merge request bloodyhealth/drip!656
2024-03-14 11:08:08 +00:00
wunderfisch fc520c4a20 Merge branch 'chore/refactor-customization' into '676-feature-customisation-not-display-mucus-cervix'
Chore/refactor customization

See merge request bloodyhealth/drip!672
2024-03-14 11:04:51 +00:00
bl00dymarie eaf01e98d5 renaming 2024-03-14 10:58:56 +00:00
bl00dymarie f5894c028e renaming 2024-03-14 10:54:18 +00:00
bl00dymarie a29c0e2eec Merge branch '676-feature-customisation-not-display-mucus-cervix' into 'chore/refactor-customization'
# Conflicts:
#   i18n/en/settings.js
2024-03-13 15:19:17 +00:00
bl00dymarie 18466ebcee Merge branch 'feature/Add-symptom-icons-to-customization' into '676-feature-customisation-not-display-mucus-cervix'
Feature: Add symptom icons to customization toggles

See merge request bloodyhealth/drip!666
2024-03-11 11:42:36 +00:00
wunderfisch b65b5f3561 refactoring disable function of temperature slider 2024-03-07 18:58:37 +01:00
wunderfisch 3e8f15e04e disable temperature slider when fertility or temperature turned off 2024-02-29 17:46:56 +01:00
bl00dymarie b17c86ffd6 Merge branch 'Chore/Unify-spelling-of-sympto-thermal' into '676-feature-customisation-not-display-mucus-cervix'
Chore: Unify spelling of sympto-thermal

See merge request bloodyhealth/drip!667
2024-02-29 10:37:05 +00:00
bl00dymarie 24df5cea31 Spell "science-based" 2024-02-29 10:35:22 +00:00
bl00dymarie 610383a103 Unify the spelling of "sympto-thermal" 2024-02-28 13:06:32 +01:00
wunderfisch ad47b4bee0 enabling alert for disabled button in tab group 2024-02-28 13:06:25 +01:00
bl00dymarie ffe8fab822 Add colored tracking icons to customization toggles 2024-02-28 12:27:59 +01:00
wunderfisch 661abc8aee revision of customization texts and refactoring behavior when disabled 2024-02-27 18:10:11 +01:00
bl00dymarie 46a02560e8 Add title labels to customization 2024-02-26 18:23:04 +01:00
bl00dymarie 9ec52b78cf Add comment for future TODO linking gitlab issue 2024-02-26 16:51:29 +00:00
bl00dymarie 8a65c081a8 Use translation for customization tracking categories 2024-02-26 17:24:44 +01:00
bl00dymarie 72823ef95c Generalize title of symptom labels 2024-02-26 17:24:44 +01:00
bl00dymarie 27776f93cc 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
2024-02-26 15:48:27 +00:00
wunderfisch ef4095d61c fixing issue import and empty statement 2024-02-26 16:32:08 +01:00
wunderfisch 4fc11d2f7e changes in customization texts and small changes to styling 2024-02-26 16:31:53 +01:00
wunderfisch 37152b3fec small changes in styling. more space beween switch lines, smaller switches in iOS (testing please), less bottom margin for segments 2024-02-26 16:31:29 +01:00
21 changed files with 399 additions and 180 deletions
+2 -2
View File
@@ -33,9 +33,10 @@ We are an open source project and we highly appreciate contributions. At the sam
- 🔮 open source - 🔮 open source
- 🩸 feminist and gender inclusive - 🩸 feminist and gender inclusive
- 🔒 secure: data entered stays with that person/on their device - 🔒 secure: data entered stays with that person/on their device
- 🔬 science based: we implemented the symptothermal method - 🔬 science-based: we implemented the sympto-thermal method
This means that we will never implement anything that contradicts these core values. Some examples: We will never build a cloud integration, we will never make an ovulation prediction. This means that we will never implement anything that contradicts these core values. Some examples: We will never build a cloud integration, we will never make an ovulation prediction.
- If you would like to make a sustainable contribution to the project, we would be happy to join the game. - If you would like to make a sustainable contribution to the project, we would be happy to join the game.
### Reporting Bugs or Making Suggestions ### Reporting Bugs or Making Suggestions
@@ -48,7 +49,6 @@ If you found a bug or have suggestions, please :one: first review the [list of e
- If you want to open a merge request, yeah :tada: exciting! We are using a template for merge requests to make sure we explain what we have done and why. - If you want to open a merge request, yeah :tada: exciting! We are using a template for merge requests to make sure we explain what we have done and why.
- Keep in mind that people who will review your merge request are more motivated to do so when the merge request is well explained and ideally not too big. - Keep in mind that people who will review your merge request are more motivated to do so when the merge request is well explained and ideally not too big.
### Thank you ### Thank you
![](https://media.giphy.com/media/kPA88elN9kYco/giphy.gif) ![](https://media.giphy.com/media/kPA88elN9kYco/giphy.gif)
+20
View File
@@ -25,6 +25,15 @@ yarn release
The versionName and versionCode [are defined here](https://gitlab.com/bloodyhealth/drip/-/blob/5401789c46f4a02915ab900ef284581be420451c/android/app/build.gradle#L137-138) and in [package.json](https://gitlab.com/bloodyhealth/drip/-/blob/5401789c46f4a02915ab900ef284581be420451c/package.json#L3). The versionName and versionCode [are defined here](https://gitlab.com/bloodyhealth/drip/-/blob/5401789c46f4a02915ab900ef284581be420451c/android/app/build.gradle#L137-138) and in [package.json](https://gitlab.com/bloodyhealth/drip/-/blob/5401789c46f4a02915ab900ef284581be420451c/package.json#L3).
**Note for iOS**
Update the version number for iOS in `ios/drip/Info.plist` under:
```
<key>CFBundleShortVersionString</key>
<string>1.2403.19</string>
```
## Building in Android ## Building in Android
APK versus AAB APK versus AAB
@@ -75,6 +84,17 @@ yarn sign-android-aab-release
_which is a shortcut for:_ `jarsigner -keystore ./android/app/drip-release-key.keystore ./android/app/build/outputs/bundle/release/app-release.aab drip-release-key` _which is a shortcut for:_ `jarsigner -keystore ./android/app/drip-release-key.keystore ./android/app/build/outputs/bundle/release/app-release.aab drip-release-key`
## Building in iOS
To build an .ipa archive file for an upload to the AppStore you need to go to xCode and select Build -> "Any iOS Device" and under "Product" -> "Archive".
Once the archiving process has completed you can chose to do the following:
"Distribute the app"
- TestFlight & App Store for when you want to upload it for external testing and/or production release
- TestFlight Internal Only for when you want to upload it for internal testing
## Share the release ## Share the release
### Gitlab repository ### Gitlab repository
+2 -2
View File
@@ -134,8 +134,8 @@ android {
applicationId "com.drip" applicationId "com.drip"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 27 versionCode 33
versionName "1.2402.15" versionName "1.2403.19"
ndk { ndk {
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64" abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
} }
+9
View File
@@ -51,6 +51,7 @@ const Home = ({ navigate, setDate }) => {
> >
<AppText style={styles.title}>{moment().format('MMM Do YYYY')}</AppText> <AppText style={styles.title}>{moment().format('MMM Do YYYY')}</AppText>
{/* display if at least 1 bleeding day has been entered */}
{cycleDayNumber && ( {cycleDayNumber && (
<View style={styles.line}> <View style={styles.line}>
<AppText style={styles.whiteSubtitle}>{cycleDayText}</AppText> <AppText style={styles.whiteSubtitle}>{cycleDayText}</AppText>
@@ -59,6 +60,8 @@ const Home = ({ navigate, setDate }) => {
</AppText> </AppText>
</View> </View>
)} )}
{/* display if fertility tracking enabled and if phase 1, 2 or 3 has been identified */}
{isFertilityTrackingEnabled && phase && ( {isFertilityTrackingEnabled && phase && (
<View style={styles.line}> <View style={styles.line}>
<AppText style={styles.whiteSubtitle}> <AppText style={styles.whiteSubtitle}>
@@ -71,11 +74,14 @@ const Home = ({ navigate, setDate }) => {
<Asterisk /> <Asterisk />
</View> </View>
)} )}
{isPeriodPredictionEnabled && ( {isPeriodPredictionEnabled && (
<View style={styles.line}> <View style={styles.line}>
<AppText style={styles.turquoiseText}>{prediction}</AppText> <AppText style={styles.turquoiseText}>{prediction}</AppText>
</View> </View>
)} )}
{!isFertilityTrackingEnabled && <View style={styles.largePadding}></View>}
<Button isCTA isSmall={false} onPress={navigateToCycleDayView}> <Button isCTA isSmall={false} onPress={navigateToCycleDayView}>
{t('labels.home.addDataForToday')} {t('labels.home.addDataForToday')}
</Button> </Button>
@@ -114,6 +120,9 @@ const styles = StyleSheet.create({
color: 'white', color: 'white',
fontSize: Sizes.subtitle, fontSize: Sizes.subtitle,
}, },
largePadding: {
padding: Spacing.large,
},
}) })
Home.propTypes = { Home.propTypes = {
+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,
+8 -1
View File
@@ -6,13 +6,14 @@ import AppText from './app-text'
import { Colors, Containers, Spacing, Typography } from '../../styles' import { Colors, Containers, Spacing, Typography } from '../../styles'
const Segment = ({ children, last, title }) => { const Segment = ({ children, last, title, subheader }) => {
const containerStyle = last ? styles.containerLast : styles.container const containerStyle = last ? styles.containerLast : styles.container
const commonStyle = Object.assign({}, containerStyle) const commonStyle = Object.assign({}, containerStyle)
return ( return (
<View style={commonStyle}> <View style={commonStyle}>
{title && <AppText style={styles.title}>{title}</AppText>} {title && <AppText style={styles.title}>{title}</AppText>}
{subheader && <AppText style={styles.subheader}>{subheader}</AppText>}
{children} {children}
</View> </View>
) )
@@ -23,6 +24,7 @@ Segment.propTypes = {
last: PropTypes.bool, last: PropTypes.bool,
style: PropTypes.object, style: PropTypes.object,
title: PropTypes.string, title: PropTypes.string,
subheader: PropTypes.string,
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@@ -39,6 +41,11 @@ const styles = StyleSheet.create({
title: { title: {
...Typography.subtitle, ...Typography.subtitle,
}, },
subheader: {
...Typography.subtitle,
fontWeight: 'bold',
marginBottom: Spacing.zero,
},
}) })
export default Segment export default Segment
@@ -0,0 +1,63 @@
import React from 'react'
import { Platform, StyleSheet, Switch, View } from 'react-native'
import PropTypes from 'prop-types'
import AppText from './app-text'
import DripIcon from '../../assets/drip-icons'
import { Colors, Containers, Sizes, Spacing } from '../../styles'
const TrackingCategorySwitch = ({ onToggle, symptom, text, value }) => {
const trackColor = { true: Colors.turquoiseDark }
const iconColor = value ? Colors.iconColors[symptom].color : Colors.grey
return (
<View style={styles.container}>
<View style={styles.iconContainer}>
<DripIcon
color={iconColor}
name={`drip-icon-${symptom}`}
size={Sizes.title}
/>
</View>
<View style={styles.textContainer}>
<AppText>{text}</AppText>
</View>
<Switch
onValueChange={onToggle}
style={styles.appSwitch}
value={value}
trackColor={trackColor}
/>
</View>
)
}
TrackingCategorySwitch.propTypes = {
onToggle: PropTypes.func.isRequired,
symptom: PropTypes.string,
text: PropTypes.string,
value: PropTypes.bool,
}
const styles = StyleSheet.create({
container: {
...Containers.rowContainer,
marginVertical: Spacing.tiny,
},
iconContainer: {
marginRight: Spacing.tiny,
flex: 1,
},
textContainer: {
flex: 5,
},
appSwitch: {
flex: 2,
transform:
Platform.OS === 'ios'
? [{ scaleX: 0.8 }, { scaleY: 0.8 }]
: [{ scaleX: 1 }, { scaleY: 1 }],
},
})
export default TrackingCategorySwitch
+35 -3
View File
@@ -1,17 +1,37 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { StyleSheet, TouchableOpacity, View } from 'react-native' import { Alert, StyleSheet, TouchableOpacity, View } from 'react-native'
import AppText from '../common/app-text' import AppText from '../common/app-text'
import { Colors, Containers } from '../../styles' import { Colors, Containers } from '../../styles'
import labels from '../../i18n/en/settings' import labels from '../../i18n/en/settings'
export default function SelectTabGroup({ activeButton, buttons, onSelect }) { export default function SelectTabGroup({
activeButton,
buttons,
onSelect,
disabled,
}) {
// TODO https://gitlab.com/bloodyhealth/drip/-/issues/707
const oneTimeTransformIntoNumber = const oneTimeTransformIntoNumber =
typeof activeButton === 'boolean' && Number(activeButton) typeof activeButton === 'boolean' && Number(activeButton)
const isSecondarySymptomSwitch = const isSecondarySymptomSwitch =
buttons[0]['label'] === labels.secondarySymptom.mucus buttons[0]['label'] === labels.secondarySymptom.mucus
// Disable is only used for secondarySymptom in customization, if more come up maybe consider more tidy solution
const showDisabledAlert = (label) => {
if (
label === labels.secondarySymptom.cervix ||
label === labels.secondarySymptom.mucus
) {
Alert.alert(
labels.secondarySymptom.disabled.title,
labels.secondarySymptom.disabled.message
)
}
}
return ( return (
<View style={styles.container}> <View style={styles.container}>
{buttons.map(({ label, value }, i) => { {buttons.map(({ label, value }, i) => {
@@ -22,16 +42,20 @@ export default function SelectTabGroup({ activeButton, buttons, onSelect }) {
isActive && styles.boxActive, isActive && styles.boxActive,
isSecondarySymptomSwitch && styles.purpleBox, isSecondarySymptomSwitch && styles.purpleBox,
isSecondarySymptomSwitch && isActive && styles.activePurpleBox, isSecondarySymptomSwitch && isActive && styles.activePurpleBox,
disabled && styles.disabledBox,
] ]
const textStyle = [ const textStyle = [
styles.text, styles.text,
isSecondarySymptomSwitch && styles.purpleText, isSecondarySymptomSwitch && styles.purpleText,
isActive && styles.textActive, isActive && styles.textActive,
disabled && styles.greyText,
] ]
return ( return (
<TouchableOpacity <TouchableOpacity
onPress={() => onSelect(value)} onPress={() =>
!disabled ? onSelect(value) : showDisabledAlert(label)
}
key={i} key={i}
style={boxStyle} style={boxStyle}
> >
@@ -47,6 +71,7 @@ SelectTabGroup.propTypes = {
activeButton: PropTypes.number, activeButton: PropTypes.number,
buttons: PropTypes.array.isRequired, buttons: PropTypes.array.isRequired,
onSelect: PropTypes.func.isRequired, onSelect: PropTypes.func.isRequired,
disabled: PropTypes.bool,
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@@ -74,4 +99,11 @@ const styles = StyleSheet.create({
purpleText: { purpleText: {
color: Colors.purple, color: Colors.purple,
}, },
greyText: {
color: Colors.grey,
},
disabledBox: {
borderColor: Colors.grey,
backgroundColor: Colors.turquoiseLight,
},
}) })
+1 -1
View File
@@ -20,7 +20,7 @@ const SymptomBox = ({
editedSymptom, editedSymptom,
setEditedSymptom, setEditedSymptom,
}) => { }) => {
const { t } = useTranslation(null, { keyPrefix: 'cycleDay.symptomBox' }) const { t } = useTranslation(null, { keyPrefix: 'symptoms' })
const isSymptomEdited = editedSymptom === symptom const isSymptomEdited = editedSymptom === symptom
const isSymptomDisabled = isDateInFuture(date) && symptom !== 'note' const isSymptomDisabled = isDateInFuture(date) && symptom !== 'note'
const isExcluded = symptomData !== null ? symptomData.exclude : false const isExcluded = symptomData !== null ? symptomData.exclude : false
+6 -1
View File
@@ -15,6 +15,7 @@ import Temperature from './temperature'
import { blank, save, shouldShow, symtomPage } from '../helpers/cycle-day' import { blank, save, shouldShow, symtomPage } from '../helpers/cycle-day'
import { showToast } from '../helpers/general' import { showToast } from '../helpers/general'
import { fertilityTrackingObservable } from '../../local-storage'
import { shared as sharedLabels } from '../../i18n/en/labels' import { shared as sharedLabels } from '../../i18n/en/labels'
import info from '../../i18n/en/symptom-info' import info from '../../i18n/en/symptom-info'
import { Colors, Containers, Sizes, Spacing } from '../../styles' import { Colors, Containers, Sizes, Spacing } from '../../styles'
@@ -25,6 +26,7 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
const [shouldShowInfo, setShouldShowInfo] = useState(false) const [shouldShowInfo, setShouldShowInfo] = useState(false)
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 onEditNote = (note) => { const onEditNote = (note) => {
const parsedData = getParsedData() const parsedData = getParsedData()
@@ -167,7 +169,10 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
</Segment> </Segment>
) )
})} })}
{shouldShow(symptomConfig.excludeText) && ( {/* show exclude AppSwitch for bleeding, mucus, cervix, temperature */}
{/* but if fertility is off only for bleeding */}
{shouldShow(symptomConfig.excludeText) &&
(symptom === 'bleeding' || isFertilityTrackingEnabled) && (
<Segment style={styles.segmentBorder}> <Segment style={styles.segmentBorder}>
<AppSwitch <AppSwitch
onToggle={onExcludeToggle} onToggle={onExcludeToggle}
+110 -71
View File
@@ -1,11 +1,15 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { Alert, Pressable } from 'react-native' import { Alert, Pressable, StyleSheet, View } from 'react-native'
import { useTranslation } from 'react-i18next'
import AppIcon from '../../common/app-icon'
import AppPage from '../../common/app-page' import AppPage from '../../common/app-page'
import AppSwitch from '../../common/app-switch' import AppSwitch from '../../common/app-switch'
import AppText from '../../common/app-text' import AppText from '../../common/app-text'
import { Colors, Spacing, Typography } from '../../../styles'
import TemperatureSlider from './temperature-slider' import TemperatureSlider from './temperature-slider'
import Segment from '../../common/segment' import Segment from '../../common/segment'
import TrackingCategorySwitch from '../../common/tracking-category-switch'
import SelectTabGroup from '../../cycle-day/select-tab-group' import SelectTabGroup from '../../cycle-day/select-tab-group'
import { import {
@@ -18,6 +22,8 @@ import {
temperatureTrackingCategoryObservable, temperatureTrackingCategoryObservable,
mucusTrackingCategoryObservable, mucusTrackingCategoryObservable,
cervixTrackingCategoryObservable, cervixTrackingCategoryObservable,
periodPredictionObservable,
useCervixAsSecondarySymptomObservable,
saveDesireTrackingCategory, saveDesireTrackingCategory,
saveFertilityTrackingEnabled, saveFertilityTrackingEnabled,
saveMoodTrackingCategory, saveMoodTrackingCategory,
@@ -29,13 +35,13 @@ import {
saveSexTrackingCategory, saveSexTrackingCategory,
saveTemperatureTrackingCategory, saveTemperatureTrackingCategory,
saveUseCervixAsSecondarySymptom, saveUseCervixAsSecondarySymptom,
periodPredictionObservable,
useCervixAsSecondarySymptomObservable,
} from '../../../local-storage' } from '../../../local-storage'
import labels from '../../../i18n/en/settings' import labels from '../../../i18n/en/settings'
import { SYMPTOMS } from '../../../config' import { SYMPTOMS } from '../../../config'
const Settings = () => { const Settings = () => {
const { t } = useTranslation(null, { keyPrefix: 'symptoms' })
const [useCervixAsSecondarySymptom, setUseCervixAsSecondarySymptom] = const [useCervixAsSecondarySymptom, setUseCervixAsSecondarySymptom] =
useState(useCervixAsSecondarySymptomObservable.value) useState(useCervixAsSecondarySymptomObservable.value)
@@ -77,6 +83,7 @@ const Settings = () => {
const [isFertilityTrackingEnabled, setFertilityTrackingEnabled] = useState( const [isFertilityTrackingEnabled, setFertilityTrackingEnabled] = useState(
fertilityTrackingObservable.value fertilityTrackingObservable.value
) )
const fertilityTrackingToggle = (value) => { const fertilityTrackingToggle = (value) => {
setFertilityTrackingEnabled(value) setFertilityTrackingEnabled(value)
saveFertilityTrackingEnabled(value) saveFertilityTrackingEnabled(value)
@@ -161,7 +168,6 @@ const Settings = () => {
if (!cervix && mucus) { if (!cervix && mucus) {
setUseCervixAsSecondarySymptom(0) setUseCervixAsSecondarySymptom(0)
saveUseCervixAsSecondarySymptom(0) saveUseCervixAsSecondarySymptom(0)
} else if (cervix && mucus) {
} else if (cervix && !mucus) { } else if (cervix && !mucus) {
setUseCervixAsSecondarySymptom(1) setUseCervixAsSecondarySymptom(1)
saveUseCervixAsSecondarySymptom(1) saveUseCervixAsSecondarySymptom(1)
@@ -176,7 +182,14 @@ const Settings = () => {
} }
const secondarySymptomDisabledPrompt = () => { const secondarySymptomDisabledPrompt = () => {
if (!isMucusTrackingCategoryEnabled == isCervixTrackingCategoryEnabled) { if (!isFertilityTrackingEnabled) {
Alert.alert(
labels.secondarySymptom.disabled.title,
labels.secondarySymptom.disabled.message
)
} else if (
!isMucusTrackingCategoryEnabled == isCervixTrackingCategoryEnabled
) {
Alert.alert( Alert.alert(
labels.secondarySymptom.disabled.title, labels.secondarySymptom.disabled.title,
labels.secondarySymptom.disabled.noSecondaryEnabled labels.secondarySymptom.disabled.noSecondaryEnabled
@@ -184,129 +197,155 @@ const Settings = () => {
} }
} }
const manageFertilityFeature =
isTemperatureTrackingCategoryEnabled &&
(isMucusTrackingCategoryEnabled || isCervixTrackingCategoryEnabled)
const cervixText = useCervixAsSecondarySymptom const cervixText = useCervixAsSecondarySymptom
? labels.secondarySymptom.cervixModeOn ? labels.secondarySymptom.cervixModeOn
: labels.secondarySymptom.cervixModeOff : labels.secondarySymptom.cervixModeOff
const sliderDisabledPrompt = () => { const sliderDisabledPrompt = () => {
if (!isTemperatureTrackingCategoryEnabled) { if (!isTemperatureTrackingCategoryEnabled) {
Alert.alert(labels.disabled.title, labels.disabled.message) Alert.alert(labels.tempScale.disabled, labels.tempScale.disabledMessage)
}
}
const fertilityDisabledPrompt = () => {
if (!manageFertilityFeature) {
Alert.alert(
labels.fertilityTracking.disabledTitle,
labels.fertilityTracking.disabled
)
} }
} }
return ( return (
<AppPage title={'Customization'}> <AppPage title={labels.customization.title}>
<Segment title={'Tracking categories'}> <Segment title={labels.customization.trackingCategories}>
<AppSwitch <TrackingCategorySwitch
onToggle={temperatureTrackingCategoryToggle} onToggle={temperatureTrackingCategoryToggle}
text={SYMPTOMS[1]} text={t(SYMPTOMS[1])}
value={isTemperatureTrackingCategoryEnabled} value={isTemperatureTrackingCategoryEnabled}
symptom={SYMPTOMS[1]}
/> />
<TrackingCategorySwitch
<AppSwitch
onToggle={(enabled) => { onToggle={(enabled) => {
mucusTrackingCategoryToggle(enabled) mucusTrackingCategoryToggle(enabled)
}} }}
text={SYMPTOMS[2]} text={t(SYMPTOMS[2])}
value={isMucusTrackingCategoryEnabled} value={isMucusTrackingCategoryEnabled}
symptom={SYMPTOMS[2]}
/> />
<TrackingCategorySwitch
<AppSwitch
onToggle={(enabled) => { onToggle={(enabled) => {
cervixTrackingCategoryToggle(enabled) cervixTrackingCategoryToggle(enabled)
}} }}
text={SYMPTOMS[3]} text={t(SYMPTOMS[3])}
value={isCervixTrackingCategoryEnabled} value={isCervixTrackingCategoryEnabled}
symptom={SYMPTOMS[3]}
/> />
<TrackingCategorySwitch
<AppSwitch
onToggle={sexTrackingCategoryToggle} onToggle={sexTrackingCategoryToggle}
text={SYMPTOMS[4]} text={t(SYMPTOMS[4])}
value={isSexTrackingCategoryEnabled} value={isSexTrackingCategoryEnabled}
symptom={SYMPTOMS[4]}
/> />
<AppSwitch <TrackingCategorySwitch
onToggle={desireTrackingCategoryToggle} onToggle={desireTrackingCategoryToggle}
text={SYMPTOMS[5]} text={t(SYMPTOMS[5])}
value={isDesireTrackingCategoryEnabled} value={isDesireTrackingCategoryEnabled}
symptom={SYMPTOMS[5]}
/> />
<AppSwitch <TrackingCategorySwitch
onToggle={painTrackingCategoryToggle} onToggle={painTrackingCategoryToggle}
text={SYMPTOMS[6]} text={t(SYMPTOMS[6])}
value={isPainTrackingCategoryEnabled} value={isPainTrackingCategoryEnabled}
symptom={SYMPTOMS[6]}
/> />
<AppSwitch <TrackingCategorySwitch
onToggle={moodTrackingCategoryToggle} onToggle={moodTrackingCategoryToggle}
text={SYMPTOMS[7]} text={t(SYMPTOMS[7])}
value={isMoodTrackingCategoryEnabled} value={isMoodTrackingCategoryEnabled}
symptom={SYMPTOMS[7]}
/> />
<AppSwitch <TrackingCategorySwitch
onToggle={noteTrackingCategoryToggle} onToggle={noteTrackingCategoryToggle}
text={SYMPTOMS[8]} text={t(SYMPTOMS[8])}
value={isNoteTrackingCategoryEnabled} value={isNoteTrackingCategoryEnabled}
symptom={SYMPTOMS[8]}
/> />
</Segment> </Segment>
<Pressable onPress={sliderDisabledPrompt}>
<Pressable onPress={fertilityDisabledPrompt}>
<Segment title={labels.fertilityTracking.title}> <Segment title={labels.fertilityTracking.title}>
{isTemperatureTrackingCategoryEnabled && <AppText>{labels.fertilityTracking.message}</AppText>
isMucusTrackingCategoryEnabled ||
isCervixTrackingCategoryEnabled ?
(
<>
<AppSwitch <AppSwitch
onToggle={fertilityTrackingToggle} onToggle={fertilityTrackingToggle}
text={fertilityTrackingText} text={fertilityTrackingText}
value={isFertilityTrackingEnabled} value={isFertilityTrackingEnabled}
disabled={!manageFertilityFeature}
/> />
</>
) :
(
<AppText>{labels.disabled.message}</AppText>
)}
</Segment> </Segment>
</Pressable> </Pressable>
<Pressable onPress={sliderDisabledPrompt}> <Segment title={labels.periodPrediction.title}>
<Segment title={labels.tempScale.segmentTitle}>
{isTemperatureTrackingCategoryEnabled && (
<>
<AppText>{labels.tempScale.segmentExplainer}</AppText>
<TemperatureSlider />
</>
)}
{!isTemperatureTrackingCategoryEnabled && (
<AppText>{labels.disabled.message}</AppText>
)}
</Segment>
</Pressable>
{/* used to be switch for onCervixToggle */}
<Pressable onPress={secondarySymptomDisabledPrompt}>
<Segment title={labels.secondarySymptom.title}>
{!isFertilityTrackingEnabled ? (
<AppText>{labels.secondarySymptom.disabled.message}</AppText>
) : (
<>
<AppText>{cervixText}</AppText>
<SelectTabGroup
activeButton={useCervixAsSecondarySymptom}
buttons={secondarySymptomButtons}
onSelect={(value) => onSelectTab(value)}
/>
</>
)}
</Segment>
</Pressable>
<Segment title={labels.periodPrediction.title} last>
<AppSwitch <AppSwitch
onToggle={onPeriodPredictionToggle} onToggle={onPeriodPredictionToggle}
text={periodPredictionText} text={periodPredictionText}
value={isPeriodPredictionEnabled} value={isPeriodPredictionEnabled}
/> />
</Segment> </Segment>
<Segment
subheader={labels.customization.subheaderSymptoThermalMethod}
last
></Segment>
<Pressable onPress={sliderDisabledPrompt}>
<Segment title={labels.tempScale.segmentTitle}>
<AppText>{labels.tempScale.segmentExplainer}</AppText>
<TemperatureSlider disabled={!isTemperatureTrackingCategoryEnabled} />
</Segment>
</Pressable>
<Pressable onPress={secondarySymptomDisabledPrompt}>
<Segment title={labels.secondarySymptom.title}>
<AppText>{cervixText}</AppText>
<SelectTabGroup
activeButton={useCervixAsSecondarySymptom}
buttons={secondarySymptomButtons}
onSelect={(value) => onSelectTab(value)}
disabled={!isFertilityTrackingEnabled}
/>
</Segment>
</Pressable>
<Segment last>
<View style={styles.line}>
<AppIcon
color={Colors.purple}
name="info-with-circle"
style={styles.icon}
/>
<AppText style={styles.title}>{labels.preOvu.title}</AppText>
</View>
<AppText>{labels.preOvu.note}</AppText>
</Segment>
</AppPage> </AppPage>
) )
} }
export default Settings export default Settings
const styles = StyleSheet.create({
icon: {
marginRight: Spacing.base,
},
line: {
flexDirection: 'row',
alignItems: 'center',
},
title: {
...Typography.subtitle,
},
})
@@ -1,5 +1,6 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import { StyleSheet, View } from 'react-native' import { StyleSheet, View } from 'react-native'
import PropTypes from 'prop-types'
import Slider from '@ptomasroos/react-native-multi-slider' import Slider from '@ptomasroos/react-native-multi-slider'
import alertError from '../common/alert-error' import alertError from '../common/alert-error'
@@ -10,7 +11,7 @@ import { Colors, Sizes } from '../../../styles'
import labels from '../../../i18n/en/settings' import labels from '../../../i18n/en/settings'
import { TEMP_MIN, TEMP_MAX, TEMP_SLIDER_STEP } from '../../../config' import { TEMP_MIN, TEMP_MAX, TEMP_SLIDER_STEP } from '../../../config'
const TemperatureSlider = () => { const TemperatureSlider = ({ disabled }) => {
const savedValue = scaleObservable.value const savedValue = scaleObservable.value
const [minTemperature, setMinTemperature] = useState(savedValue.min) const [minTemperature, setMinTemperature] = useState(savedValue.min)
const [maxTemperature, setMaxTemperature] = useState(savedValue.max) const [maxTemperature, setMaxTemperature] = useState(savedValue.max)
@@ -25,6 +26,14 @@ const TemperatureSlider = () => {
} }
} }
const sliderAccentBackground = disabled
? styles.disabledSliderAccentBackground
: styles.sliderAccentBackground
const sliderBackground = disabled
? styles.disabledSliderBackground
: styles.sliderBackground
return ( return (
<View style={styles.container}> <View style={styles.container}>
<Slider <Slider
@@ -35,11 +44,13 @@ const TemperatureSlider = () => {
max={TEMP_MAX} max={TEMP_MAX}
min={TEMP_MIN} min={TEMP_MIN}
onValuesChange={onTemperatureSliderChange} onValuesChange={onTemperatureSliderChange}
selectedStyle={styles.sliderAccentBackground}
step={TEMP_SLIDER_STEP} step={TEMP_SLIDER_STEP}
trackStyle={styles.slider} trackStyle={styles.slider}
unselectedStyle={styles.sliderBackground}
values={[minTemperature, maxTemperature]} values={[minTemperature, maxTemperature]}
enabledOne={!disabled}
enabledTwo={!disabled}
selectedStyle={sliderAccentBackground}
unselectedStyle={sliderBackground}
/> />
</View> </View>
) )
@@ -47,6 +58,10 @@ const TemperatureSlider = () => {
export default TemperatureSlider export default TemperatureSlider
TemperatureSlider.propTypes = {
disabled: PropTypes.bool,
}
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
alignItems: 'center', alignItems: 'center',
@@ -54,6 +69,7 @@ const styles = StyleSheet.create({
}, },
marker: { marker: {
backgroundColor: Colors.turquoiseDark, backgroundColor: Colors.turquoiseDark,
borderRadius: 50, borderRadius: 50,
elevation: 4, elevation: 4,
height: Sizes.subtitle, height: Sizes.subtitle,
@@ -66,7 +82,13 @@ const styles = StyleSheet.create({
sliderAccentBackground: { sliderAccentBackground: {
backgroundColor: Colors.turquoiseDark, backgroundColor: Colors.turquoiseDark,
}, },
disabledSliderAccentBackground: {
backgroundColor: Colors.grey,
},
sliderBackground: { sliderBackground: {
backgroundColor: Colors.turquoise, backgroundColor: Colors.turquoise,
}, },
disabledSliderBackground: {
backgroundColor: Colors.greyLight,
},
}) })
-1
View File
@@ -11,7 +11,6 @@ const menuItems = [
{ label: 'reminders', componentName: 'Reminders' }, { label: 'reminders', componentName: 'Reminders' },
{ label: 'dataManagement', componentName: 'DataManagement' }, { label: 'dataManagement', componentName: 'DataManagement' },
{ label: 'password', componentName: 'Password' }, { label: 'password', componentName: 'Password' },
{ label: 'info', componentName: 'Info' },
] ]
const SettingsMenu = ({ navigate }) => { const SettingsMenu = ({ navigate }) => {
+5 -7
View File
@@ -7,8 +7,7 @@
"chart": { "chart": {
"tutorial": "You can swipe the chart to view more dates." "tutorial": "You can swipe the chart to view more dates."
}, },
"cycleDay": { "symptoms": {
"symptomBox": {
"bleeding": "bleeding", "bleeding": "bleeding",
"temperature": "temperature", "temperature": "temperature",
"mucus": "cervical mucus", "mucus": "cervical mucus",
@@ -18,7 +17,6 @@
"sex": "sex", "sex": "sex",
"pain": "pain", "pain": "pain",
"mood": "mood" "mood": "mood"
}
}, },
"labels": { "labels": {
"bleedingPrediction": { "bleedingPrediction": {
@@ -114,19 +112,19 @@
"menuItem": { "menuItem": {
"dataManagement": { "dataManagement": {
"name": "Data", "name": "Data",
"text": "import, export or delete your data" "text": "Import, export or delete your data"
}, },
"customization": { "customization": {
"name": "Customization", "name": "Customization",
"text": "define how you want to use drip" "text": "Define how you want to use drip"
}, },
"password": { "password": {
"name": "Password", "name": "Password",
"text": "set or edit your password" "text": "Set, edit or delete your password"
}, },
"reminders": { "reminders": {
"name": "Reminders", "name": "Reminders",
"text": "turn on/off reminders" "text": "Turn on/off reminders"
}, },
"info": { "info": {
"name": "Info", "name": "Info",
+46 -40
View File
@@ -4,70 +4,71 @@ export const intensity = ['low', 'medium', 'high']
export const bleeding = { export const bleeding = {
labels: ['spotting', 'light', 'medium', 'heavy'], labels: ['spotting', 'light', 'medium', 'heavy'],
heaviness: { heaviness: {
header: "Heaviness", header: 'Heaviness',
explainer: "How heavy is the bleeding?", explainer: 'How heavy is the bleeding?',
}, },
exclude: { exclude: {
header: "Exclude", header: 'Exclude',
explainer: "You can exclude this value if it's not menstrual bleeding" explainer: "You can exclude this value if it's not menstrual bleeding",
} },
} }
export const cervix = { export const cervix = {
subcategories: { subcategories: {
opening: 'opening', opening: 'opening',
firmness: 'firmness', firmness: 'firmness',
position: 'position' position: 'position',
}, },
opening: { opening: {
categories: ['closed', 'medium', 'open'], categories: ['closed', 'medium', 'open'],
explainer: 'Is your cervix open or closed?' explainer: 'Is your cervix open or closed?',
}, },
firmness: { firmness: {
categories: ['hard', 'soft'], categories: ['hard', 'soft'],
explainer: "When it's hard, it might feel like the tip of your nose" explainer: "When it's hard, it might feel like the tip of your nose",
}, },
position: { position: {
categories: ['low', 'medium', 'high'], categories: ['low', 'medium', 'high'],
explainer: 'How high up in the vagina is the cervix?' explainer: 'How high up in the vagina is the cervix?',
}, },
excludeExplainer: "You can exclude this value if you don't want to use it for fertility detection.", excludeExplainer:
actionHint: 'Choose values for at least "Opening" and "Firmness" to save.' "You can exclude this value if you don't want to use it for fertility detection.",
} }
export const mucus = { export const mucus = {
subcategories: { subcategories: {
feeling: 'feeling', feeling: 'feeling',
texture: 'texture' texture: 'texture',
}, },
feeling: { feeling: {
categories: ['dry', 'nothing', 'wet', 'slippery'], categories: ['dry', 'nothing', 'wet', 'slippery'],
explainer: 'What does your vaginal entrance feel like?' explainer: 'What does your vaginal entrance feel like?',
}, },
texture: { texture: {
categories: ['nothing', 'creamy', 'egg white'], categories: ['nothing', 'creamy', 'egg white'],
explainer: "Looking at and touching your cervical mucus, which describes it best?" explainer:
'Looking at and touching your cervical mucus, which describes it best?',
}, },
excludeExplainer: "You can exclude this value if you don't want to use it for fertility detection", excludeExplainer:
actionHint: 'Choose values for both "Feeling" and "Texture" to save.' "You can exclude this value if you don't want to use it for fertility detection",
} }
export const desire = { export const desire = {
header: 'Intensity', header: 'Intensity',
explainer: 'How would you rate your sexual desire?' explainer: 'How would you rate your sexual desire?',
} }
export const sex = { export const sex = {
categories:{ categories: {
solo: 'solo', solo: 'solo',
partner: 'partner', partner: 'partner',
}, },
header: "Activity", header: 'Activity',
explainer: 'Were you sexually active today?', explainer: 'Were you sexually active today?',
} }
export const contraceptives = { export const contraceptives = {
categories:{ categories: {
condom: 'condom', condom: 'condom',
pill: 'pill', pill: 'pill',
iud: 'iud', iud: 'iud',
@@ -78,8 +79,8 @@ export const contraceptives = {
none: 'none', none: 'none',
other: 'other', other: 'other',
}, },
header: "Contraceptives", header: 'Contraceptives',
explainer: 'Did you use contraceptives?' explainer: 'Did you use contraceptives?',
} }
export const pain = { export const pain = {
@@ -91,9 +92,9 @@ export const pain = {
nausea: 'nausea', nausea: 'nausea',
tenderBreasts: 'tender breasts', tenderBreasts: 'tender breasts',
migraine: 'migraine', migraine: 'migraine',
other: 'other' other: 'other',
}, },
explainer: 'How did your body feel today?' explainer: 'How did your body feel today?',
} }
export const mood = { export const mood = {
@@ -107,34 +108,39 @@ export const mood = {
energetic: 'energetic', energetic: 'energetic',
fatigue: 'fatigue', fatigue: 'fatigue',
angry: 'angry', angry: 'angry',
other: 'other' other: 'other',
}, },
explainer: 'How did you feel today?' explainer: 'How did you feel today?',
} }
export const temperature = { 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.', outOfRangeWarning:
outOfAbsoluteRangeWarning: 'This temperature value is too high or low to be shown on the temperature chart.', '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.',
temperature: { temperature: {
header: "Temperature", header: 'Temperature',
explainer: 'Take your temperature right after waking up, before getting out of bed' explainer:
'Take your temperature right after waking up, before getting out of bed',
}, },
time: "Time", time: 'Time',
note: { note: {
header: "Note", header: 'Note',
explainer: 'Is there anything that could have influenced this value, such as bad sleep or alcohol consumption?' explainer:
'Is there anything that could have influenced this value, such as bad sleep or alcohol consumption?',
}, },
exclude: { exclude: {
header: "Exclude", header: 'Exclude',
explainer: "You can exclude this value if you don't want to use it for fertility detection" explainer:
} "You can exclude this value if you don't want to use it for fertility detection",
},
} }
export const noteExplainer = "Anything you want to add for the day?" export const noteExplainer = 'Anything you want to add for the day?'
export const general = { export const general = {
cycleDayNumber: "Cycle day ", cycleDayNumber: 'Cycle day ',
today: "Today" today: 'Today',
} }
export const sharedDialogs = { export const sharedDialogs = {
@@ -144,5 +150,5 @@ export const sharedDialogs = {
reallyDeleteData: 'Yes, I am sure', reallyDeleteData: 'Yes, I am sure',
save: 'Save', save: 'Save',
delete: 'Delete', delete: 'Delete',
disabledInfo: 'There is some data missing' disabledInfo: 'There is some data missing',
} }
+24 -15
View File
@@ -1,6 +1,11 @@
import links from './links' import links from './links'
export default { export default {
customization: {
title: 'Customization',
trackingCategories: 'Tracking categories',
subheaderSymptoThermalMethod: 'Sympto-thermal method settings',
},
export: { export: {
errors: { errors: {
noData: 'There is no data to export', noData: 'There is no data to export',
@@ -32,17 +37,16 @@ export default {
tempScale: { tempScale: {
segmentTitle: 'Temperature scale', segmentTitle: 'Temperature scale',
segmentExplainer: segmentExplainer:
'Change the minimum and maximum value for the temperature chart', 'Change the minimum and maximum value for the temperature chart.',
min: 'Min', min: 'Min',
max: 'Max', max: 'Max',
loadError: 'Could not load saved temperature scale settings', loadError: 'Could not load saved temperature scale settings',
saveError: 'Could not save temperature scale settings', saveError: 'Could not save temperature scale settings',
disabled: 'Disabled',
disabledMessage:
'To use the temperature scale please first enable temperature tracking above.',
}, },
disabled: {
title: 'This feature is turned off',
message:
'Please first enable the temperature tracking category in the customization settings.',
},
tempReminder: { tempReminder: {
title: 'Temperature reminder', title: 'Temperature reminder',
noTimeSet: 'Set a time for a daily reminder to take your temperature', noTimeSet: 'Set a time for a daily reminder to take your temperature',
@@ -68,29 +72,34 @@ export default {
}, },
fertilityTracking: { fertilityTracking: {
title: 'Fertility phases calculation', title: 'Fertility phases calculation',
on: 'The quick brown fox jumps over the lazy dog', disabledTitle: 'Disabled',
off: 'No no', disabled:
'To use fertility phases calculation please enable both temperature tracking and either cervical mucus or cervix tracking above.',
message:
'If you enter menstrual bleeding, temperature and cervical mucus or cervix data according to the sympto-thermal method, 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:
'Cervix values are being used for symptothermal fertility detection. You can switch here to use cervical mucus values for symptothermal fertility detection', 'Cervix values are being used for fertility detection according to the sympto-thermal method.',
cervixModeOff: cervixModeOff:
'By default, cervical mucus values are being used for symptothermal fertility detection. You can switch here to use cervix values for symptothermal fertility detection', 'Cervical mucus values are being used for fertility detection according to the sympto-thermal method.',
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 cervical mucus or cervix tracking category as well as temperature and fertility phases calculation 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: {
title: 'App password', title: 'App password',
@@ -133,6 +142,6 @@ Making any changes to your password setting will keep your data as it was before
}, },
preOvu: { preOvu: {
title: 'Infertile days at cycle start', title: 'Infertile days at cycle start',
note: `drip. applies the sympto-thermal method for calculating infertile days at the start of the cycle (see ${links.wiki.url} for more info). However, drip. does not currently apply the so called 20-day-rule, which determines infertile days at the cycle start from past cycle lengths in case no past symptothermal info is available.`, note: `drip. applies the sympto-thermal method for calculating infertile days at the start of the cycle (see ${links.wiki.url} for more info). However, drip. does not currently apply the so called 20-day-rule, which determines infertile days at the cycle start from past cycle lengths in case no past sympto-thermal info is available.`,
}, },
} }
+2 -2
View File
@@ -25,7 +25,7 @@ export default {
After tracking at least 3 menstrual cycles, drip. will give you an overview of After tracking at least 3 menstrual cycles, drip. will give you an overview of
· how long your cycles last on average (in "stats"), · how long your cycles last on average (in "stats"),
· whether the length of your cycles varied significantly (in "stats" and in bleeding predictions) · whether the length of your cycles varied significantly (in "stats" and in bleeding predictions)
· and predict your next 3 cycles with a range of 3 or 5 days (on home screen and "calendar"). · and predict your next 3 cycles with a range of 3 or 5 days (on home screen and "calendar") if this functionality is enabled in the customization settings.
The app allows you to track different intensities of bleeding. On the chart and on the calendar, bleeding values are colored in different shades of red. The darker, the more intense your bleeding. Every bleeding value that is not excluded is taken into account for fertility calculation and period predictions. The app allows you to track different intensities of bleeding. On the chart and on the calendar, bleeding values are colored in different shades of red. The darker, the more intense your bleeding. Every bleeding value that is not excluded is taken into account for fertility calculation and period predictions.
@@ -74,7 +74,7 @@ ${generalInfo.curiousNfp}`,
title: 'Tracking cervical mucus', title: 'Tracking cervical mucus',
text: `Cervical mucus can help determine in which phase of the menstrual cycle you are. text: `Cervical mucus can help determine in which phase of the menstrual cycle you are.
By default the secondary symptom the app uses for the sympto-thermal method is cervical mucus. By default the secondary symptom the app uses for the sympto-thermal method is cervical mucus. You can change this in the customization settings.
· How to identify fertile cervical mucus? · How to identify fertile cervical mucus?
Tracking the feeling and the texture of your cervical mucus on a daily basis helps you identify changes of the quality of the cervical mucus. The values you enter for both feeling and texture of your cervical mucus are combined by drip. into one of five values following the sympto-thermal method. Tracking the feeling and the texture of your cervical mucus on a daily basis helps you identify changes of the quality of the cervical mucus. The values you enter for both feeling and texture of your cervical mucus are combined by drip. into one of five values following the sympto-thermal method.
+1 -1
View File
@@ -19,7 +19,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.2401.17</string> <string>1.2403.19</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "drip.", "name": "drip.",
"version": "1.2402.15", "version": "1.2403.19",
"contributors": [ "contributors": [
"Julia Friesel <julia.friesel@gmail.com>", "Julia Friesel <julia.friesel@gmail.com>",
"Marie Kochsiek", "Marie Kochsiek",
+5 -1
View File
@@ -18,6 +18,7 @@ const shadesOfPink = ['#c485a6', '#b15c89', pinkColor] // light to dark
const lightGreenColor = '#bccd67' const lightGreenColor = '#bccd67'
const orangeColor = '#bc6642' const orangeColor = '#bc6642'
const mintColor = '#6ca299' const mintColor = '#6ca299'
const turquoiseDark = '#69CBC1'
export default { export default {
greyDark: '#555', greyDark: '#555',
@@ -27,7 +28,7 @@ export default {
orange: '#F38337', orange: '#F38337',
purple: '#3A2671', purple: '#3A2671',
purpleLight: '#938EB2', purpleLight: '#938EB2',
turquoiseDark: '#69CBC1', turquoiseDark: turquoiseDark,
turquoise: '#CFECEA', turquoise: '#CFECEA',
turquoiseLight: '#E9F2ED', turquoiseLight: '#E9F2ED',
iconColors: { iconColors: {
@@ -35,6 +36,9 @@ export default {
color: redColor, color: redColor,
shades: shadesOfRed, shades: shadesOfRed,
}, },
temperature: {
color: turquoiseDark,
},
mucus: { mucus: {
color: violetColor, color: violetColor,
shades: shadesOfViolet, shades: shadesOfViolet,
+2 -1
View File
@@ -1,10 +1,11 @@
import { scale } from 'react-native-size-matters' import { scale } from 'react-native-size-matters'
export default { export default {
zero: '0%',
tiny: scale(4), tiny: scale(4),
small: scale(10), small: scale(10),
base: scale(16), base: scale(16),
large: scale(20), large: scale(20),
symptomTileWidth: '48%', symptomTileWidth: '48%',
textWidth: '70%' textWidth: '70%',
} }