Compare commits

..

1 Commits

Author SHA1 Message Date
wunderfisch efd8ed0e08 unified title to other plattforms, edited screenshots 2024-04-02 16:13:55 +02:00
24 changed files with 58 additions and 367 deletions
+2 -2
View File
@@ -134,8 +134,8 @@ android {
applicationId "com.drip"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 35
versionName "1.2409.26"
versionCode 33
versionName "1.2403.19"
ndk {
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}
+12 -3
View File
@@ -23,14 +23,20 @@ const SymptomBox = ({
const { t } = useTranslation(null, { keyPrefix: 'symptoms' })
const isSymptomEdited = editedSymptom === symptom
const isSymptomDisabled = isDateInFuture(date) && symptom !== 'note'
const isExcluded = symptomData !== null ? symptomData.exclude : false
const iconColor = isSymptomDisabled ? Colors.greyLight : Colors.grey
const iconName = `drip-icon-${symptom}`
const symptomNameStyle = [
styles.symptomName,
isSymptomDisabled && styles.symptomNameDisabled,
isExcluded && styles.symptomNameExcluded,
]
const textStyle = [
styles.text,
isSymptomDisabled && styles.textDisabled,
isExcluded && styles.textExcluded,
]
const textStyle = [styles.text, isSymptomDisabled && styles.textDisabled]
return (
<>
@@ -57,11 +63,11 @@ const SymptomBox = ({
/>
<View style={styles.textContainer}>
<AppText style={symptomNameStyle}>{t(symptom)}</AppText>
{symptomDataToDisplay ? (
{symptomDataToDisplay && (
<AppText style={textStyle} numberOfLines={4}>
{symptomDataToDisplay}
</AppText>
) : null}
)}
</View>
</TouchableOpacity>
</>
@@ -115,6 +121,9 @@ const styles = StyleSheet.create({
textDisabled: {
color: Colors.greyLight,
},
textExcluded: {
color: Colors.grey,
},
})
export default SymptomBox
+18 -37
View File
@@ -12,7 +12,7 @@ import SelectBoxGroup from './select-box-group'
import SelectTabGroup from './select-tab-group'
import Temperature from './temperature'
import { blank, save, shouldShow, symptomPage } from '../helpers/cycle-day'
import { blank, save, shouldShow, symtomPage } from '../helpers/cycle-day'
import { showToast } from '../helpers/general'
import { fertilityTrackingObservable } from '../../local-storage'
@@ -21,10 +21,9 @@ import info from '../../i18n/en/symptom-info'
import { Colors, Containers, Sizes, Spacing } from '../../styles'
const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
const symptomConfig = symptomPage[symptom]
const symptomConfig = symtomPage[symptom]
const [data, setData] = useState(symptomData ? symptomData : blank[symptom])
const [shouldShowInfo, setShouldShowInfo] = useState(false)
const isBleeding = symptom === 'bleeding'
const getParsedData = () => JSON.parse(JSON.stringify(data))
const onPressLearnMore = () => setShouldShowInfo(!shouldShowInfo)
const isFertilityTrackingEnabled = fertilityTrackingObservable.value
@@ -118,23 +117,6 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
textAlignVertical: 'top',
}
{
/* show exclude AppSwitch for bleeding, mucus, cervix, temperature */
}
{
/* but if fertility is off only for bleeding */
}
const excludeToggle = shouldShow(symptomConfig.excludeText) &&
(isBleeding || isFertilityTrackingEnabled) && (
<Segment style={styles.segmentBorder}>
<AppSwitch
onToggle={onExcludeToggle}
text={symptomPage[symptom].excludeText}
value={data.exclude}
/>
</Segment>
)
return (
<AppModal onClose={onSave}>
<ScrollView
@@ -148,16 +130,10 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
save={(value, field) => onSaveTemperature(value, field)}
/>
)}
{/* There should not be a line between the bleeding tab group and the exclude toggle */}
{shouldShow(symptomConfig.selectTabGroups) &&
symptomPage[symptom].selectTabGroups.map((group) => {
symtomPage[symptom].selectTabGroups.map((group) => {
return (
<Segment
key={group.key}
style={styles.segmentBorder}
last={isBleeding}
>
<Segment key={group.key} style={styles.segmentBorder}>
<AppText style={styles.title}>{group.title}</AppText>
<SelectTabGroup
activeButton={data[group.key]}
@@ -167,12 +143,8 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
</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) &&
symptomPage[symptom].selectBoxGroups.map((group) => {
symtomPage[symptom].selectBoxGroups.map((group) => {
const isOtherSelected =
data['other'] !== null &&
data['other'] !== false &&
@@ -197,12 +169,21 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
</Segment>
)
})}
{!isBleeding && excludeToggle}
{/* 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}>
<AppSwitch
onToggle={onExcludeToggle}
text={symtomPage[symptom].excludeText}
value={data.exclude}
/>
</Segment>
)}
{shouldShow(symptomConfig.note) && (
<Segment style={styles.segmentBorder}>
<AppText>{symptomPage[symptom].note}</AppText>
<AppText>{symtomPage[symptom].note}</AppText>
<AppTextInput
{...inputProps}
onChangeText={onEditNote}
+9 -95
View File
@@ -23,7 +23,6 @@ const noteDescription = labels.noteExplainer
const painLabels = labels.pain.categories
const sexLabels = labels.sex.categories
const temperatureLabels = labels.temperature
const productLabels = labels.products.categories
const minutes = ChronoUnit.MINUTES
@@ -61,15 +60,6 @@ export const blank = {
bleeding: {
exclude: false,
value: null,
pad: null,
tampon: null,
underwear: null,
cup: null,
softTampon: null,
disk: null,
none: null,
other: null,
note: null,
},
cervix: {
exclude: false,
@@ -135,10 +125,11 @@ export const blank = {
},
}
export const symptomPage = {
export const symtomPage = {
bleeding: {
excludeText: labels.bleeding.exclude.explainer,
note: null,
selectBoxGroups: null,
selectTabGroups: [
{
key: 'value',
@@ -146,13 +137,6 @@ export const symptomPage = {
title: labels.bleeding.heaviness.explainer,
},
],
selectBoxGroups: [
{
key: 'products',
options: productLabels,
title: labels.products.explainer,
},
],
},
cervix: {
excludeText: cervixLabels.excludeExplainer,
@@ -262,49 +246,10 @@ export const symptomPage = {
export const save = {
bleeding: (data, date, shouldDeleteData) => {
const {
value,
pad,
tampon,
underwear,
cup,
softTampon,
disk,
none,
other,
note,
} = data
let { exclude } = data
const isDataEntered = [
'value',
'pad',
'tampon',
'underwear',
'cup',
'softTampon',
'disk',
'none',
'other',
'note',
].some((value) => typeof data[value] === 'number' || data[value] == true)
// covering the case when a bleeding value was entered, "excluded" and saved. But then the bleeding value was deleted again.
exclude = isNumber(value) ? exclude : false
const { exclude, value } = data
const isDataEntered = isNumber(value)
const valuesToSave =
shouldDeleteData || !isDataEntered
? null
: {
exclude,
value,
pad,
tampon,
underwear,
cup,
softTampon,
disk,
none,
other,
note,
}
shouldDeleteData || !isDataEntered ? null : { value, exclude }
saveSymptom('bleeding', date, valuesToSave)
},
@@ -384,41 +329,10 @@ const saveBoxSymptom = (data, date, shouldDeleteData, symptom) => {
}
const label = {
bleeding: (bleeding) => {
bleeding = mapRealmObjToJsObj(bleeding)
const bleedingLabel = []
if (
bleeding &&
Object.values({ ...bleeding }).some(
(val) => typeof val === 'number' || val == true
)
) {
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(', ')
bleeding: ({ value, exclude }) => {
if (isNumber(value)) {
const bleedingLabel = bleedingLabels[value]
return exclude ? `(${bleedingLabel})` : bleedingLabel
}
},
temperature: ({ value, time, exclude }) => {
+1 -1
View File
@@ -65,7 +65,6 @@ export function getBleedingDaysSortedByDate() {
return db
.objects('CycleDay')
.filtered('bleeding != null')
.filtered('bleeding.value != null')
.sorted('date', true)
}
export function getTemperatureDaysSortedByDate() {
@@ -89,6 +88,7 @@ export function getCycleStartsSortedByDate() {
export function saveSymptom(symptom, date, val) {
let cycleDay = getCycleDay(date)
if (!cycleDay) cycleDay = createCycleDay(date)
db.write(() => {
if (symptom === 'bleeding') {
const mensesDaysAfter = getMensesDaysRightAfter(cycleDay)
-195
View File
@@ -1,195 +0,0 @@
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
}
}
},
}
+1 -2
View File
@@ -3,6 +3,5 @@ import schema1 from './1.js'
import schema2 from './2.js'
import schema3 from './3.js'
import schema4 from './4.js'
import schema5 from './5.js'
export default [schema0, schema1, schema2, schema3, schema4, schema5]
export default [schema0, schema1, schema2, schema3, schema4]
+2 -17
View File
@@ -13,21 +13,6 @@ 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 = {
subcategories: {
opening: 'opening',
@@ -47,7 +32,7 @@ export const cervix = {
explainer: 'How high up in the vagina is the cervix?',
},
excludeExplainer:
"You can exclude these values if you don't want to use them for fertility detection.",
"You can exclude this value if you don't want to use it for fertility detection.",
}
export const mucus = {
@@ -65,7 +50,7 @@ export const mucus = {
'Looking at and touching your cervical mucus, which describes it best?',
},
excludeExplainer:
"You can exclude these values if you don't want to use them for fertility detection",
"You can exclude this value if you don't want to use it for fertility detection",
}
export const desire = {
+1 -1
View File
@@ -19,7 +19,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.2409.26</string>
<string>1.2403.19</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+8 -10
View File
@@ -1,9 +1,7 @@
export default function ({
val,
cycleDay,
mensesDaysAfter,
checkIsMensesStart,
val, cycleDay, mensesDaysAfter, checkIsMensesStart
}) {
cycleDay.bleeding = val
// if a bleeding value is deleted or excluded, we need to check if there are
@@ -22,15 +20,15 @@ export default function ({
}
function bleedingValueDeletedOrExluded(val) {
const bleedingDeleted = !val || !(typeof val?.value === 'number')
const bleedingDeleted = !val
const bleedingExcluded = val && val.exclude
return bleedingDeleted || bleedingExcluded
}
function maybeClearOldCycleStarts() {
// if we have a new bleeding day, we need to clear the
// menses start marker from all following days of this
// menses that may have been marked as start before
mensesDaysAfter.forEach((day) => (day.isCycleStart = false))
// if we have a new bleeding day, we need to clear the
// menses start marker from all following days of this
// menses that may have been marked as start before
mensesDaysAfter.forEach(day => day.isCycleStart = false)
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 152 KiB

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

+1 -1
View File
@@ -1 +1 @@
drip. menstrual cycle and fertility tracking
drip. period & fertility tracker
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "drip.",
"version": "1.2409.26",
"version": "1.2403.19",
"contributors": [
"Julia Friesel <julia.friesel@gmail.com>",
"Marie Kochsiek",
@@ -12,8 +12,8 @@
"scripts": {
"start": "react-native start",
"android": "react-native run-android",
"ios": "react-native run-ios --simulator=\"iPhone 8 Plus\"",
"ios15": "react-native run-ios --simulator=\"iPhone 15 Plus\"",
"ios": "react-native run-ios --simulator=\"iPhone 15\"",
"iosSE": "react-native run-ios --simulator=\"iPhone SE (2nd generation)\"",
"log": "react-native log-android",
"test": "jest test && yarn lint",
"test-watch": "jest --watch test",