Warn when user enters an out-of-range temperature
This commit is contained in:
@@ -22,8 +22,8 @@ export default function (showView) {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
title: 'Save',
|
title: 'Save',
|
||||||
action: () => {
|
action: async () => {
|
||||||
saveAction()
|
await saveAction()
|
||||||
showView(dayView)
|
showView(dayView)
|
||||||
},
|
},
|
||||||
disabledCondition: saveDisabled
|
disabledCondition: saveDisabled
|
||||||
|
|||||||
@@ -26,3 +26,8 @@ export const fertilityStatus = {
|
|||||||
fertileUntilEvening: 'Fertile phase ends in the evening',
|
fertileUntilEvening: 'Fertile phase ends in the evening',
|
||||||
unknown: 'We cannot show any cycle information because no menses has been entered'
|
unknown: 'We cannot show any cycle information because no menses has been entered'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.',
|
||||||
|
saveAnyway: 'Save anyway'
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,56 +4,89 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
TextInput,
|
TextInput,
|
||||||
Switch,
|
Switch,
|
||||||
Keyboard
|
Keyboard,
|
||||||
|
Alert
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import DateTimePicker from 'react-native-modal-datetime-picker-nevo'
|
import DateTimePicker from 'react-native-modal-datetime-picker-nevo'
|
||||||
|
|
||||||
import { getPreviousTemperature, saveSymptom } from '../../../db'
|
import { getPreviousTemperature, saveSymptom } from '../../../db'
|
||||||
import styles from '../../../styles'
|
import styles from '../../../styles'
|
||||||
import { LocalTime, ChronoUnit } from 'js-joda'
|
import { LocalTime, ChronoUnit } from 'js-joda'
|
||||||
|
import { temperature as tempLabels } from '../labels/labels'
|
||||||
|
import { scaleObservable } from '../../../local-storage'
|
||||||
|
import { shared } from '../../labels'
|
||||||
|
|
||||||
const MINUTES = ChronoUnit.MINUTES
|
const minutes = ChronoUnit.MINUTES
|
||||||
|
|
||||||
export default class Temp extends Component {
|
export default class Temp extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
this.cycleDay = props.cycleDay
|
this.cycleDay = props.cycleDay
|
||||||
this.makeActionButtons = props.makeActionButtons
|
this.makeActionButtons = props.makeActionButtons
|
||||||
let initialValue
|
|
||||||
|
|
||||||
const temp = this.cycleDay.temperature
|
const temp = this.cycleDay.temperature
|
||||||
|
|
||||||
if (temp) {
|
this.state = {
|
||||||
initialValue = temp.value.toString()
|
exclude: temp ? temp.exclude : false,
|
||||||
this.time = temp.time
|
time: temp ? temp.time : LocalTime.now().truncatedTo(minutes).toString(),
|
||||||
} else {
|
isTimePickerVisible: false,
|
||||||
const prevTemp = getPreviousTemperature(this.cycleDay)
|
integer: '',
|
||||||
initialValue = prevTemp ? prevTemp.toString() : ''
|
fractional: '',
|
||||||
|
outOfRange: null
|
||||||
}
|
}
|
||||||
|
|
||||||
this.state = {
|
if (temp) {
|
||||||
currentValue: initialValue,
|
const [integer, fractional] = temp.value.toString().split('.')
|
||||||
exclude: temp ? temp.exclude : false,
|
this.state.integer = integer
|
||||||
time: this.time || LocalTime.now().truncatedTo(MINUTES).toString(),
|
this.state.fractional = fractional
|
||||||
isTimePickerVisible: false
|
} else {
|
||||||
|
const prevTemp = getPreviousTemperature(this.cycleDay)
|
||||||
|
if (prevTemp) {
|
||||||
|
const [integer, fractional] = prevTemp.toString().split('.')
|
||||||
|
this.state.integer = integer
|
||||||
|
this.state.fractional = fractional
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkRange = () => {
|
||||||
|
const value = Number(`${this.state.integer}.${this.state.fractional}`)
|
||||||
|
if (isNaN(value)) return
|
||||||
|
const scale = scaleObservable.value
|
||||||
|
if (value < scale.min || value > scale.max) {
|
||||||
|
Alert.alert(
|
||||||
|
shared.warning,
|
||||||
|
tempLabels.outOfRangeWarning,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const cycleDay = this.cycleDay
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.symptomEditView}>
|
<View style={styles.symptomEditView}>
|
||||||
<View style={styles.symptomViewRowInline}>
|
<View style={styles.symptomViewRowInline}>
|
||||||
<Text style={styles.symptomDayView}>Temperature (°C)</Text>
|
<Text style={styles.symptomDayView}>Temperature (°C)</Text>
|
||||||
|
<View style={{flexDirection: 'row', alignItems: 'center'}}>
|
||||||
<TextInput
|
<TextInput
|
||||||
style={styles.temperatureTextInput}
|
style={styles.temperatureTextInput}
|
||||||
placeholder="Enter"
|
|
||||||
onChangeText={(val) => {
|
onChangeText={(val) => {
|
||||||
this.setState({ currentValue: val })
|
this.setState({ integer: val })
|
||||||
}}
|
}}
|
||||||
keyboardType='numeric'
|
keyboardType='numeric'
|
||||||
value={this.state.currentValue}
|
value={this.state.integer}
|
||||||
|
onBlur={this.checkRange}
|
||||||
/>
|
/>
|
||||||
|
<Text style={styles.temperatureTextInput}>.</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.temperatureTextInput}
|
||||||
|
onChangeText={(val) => {
|
||||||
|
this.setState({ fractional: val })
|
||||||
|
}}
|
||||||
|
keyboardType='numeric'
|
||||||
|
value={this.state.fractional}
|
||||||
|
onBlur={this.checkRange}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.symptomViewRowInline}>
|
<View style={styles.symptomViewRowInline}>
|
||||||
<Text style={styles.symptomDayView}>Time</Text>
|
<Text style={styles.symptomDayView}>Time</Text>
|
||||||
@@ -71,7 +104,7 @@ export default class Temp extends Component {
|
|||||||
isVisible={this.state.isTimePickerVisible}
|
isVisible={this.state.isTimePickerVisible}
|
||||||
onConfirm={jsDate => {
|
onConfirm={jsDate => {
|
||||||
this.setState({
|
this.setState({
|
||||||
time: `${jsDate.getHours()}:${jsDate.getMinutes()}`,
|
time: `${jsDate.getinteger()}:${jsDate.getfractional()}`,
|
||||||
isTimePickerVisible: false
|
isTimePickerVisible: false
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
@@ -90,15 +123,20 @@ export default class Temp extends Component {
|
|||||||
{this.makeActionButtons({
|
{this.makeActionButtons({
|
||||||
symptom: 'temperature',
|
symptom: 'temperature',
|
||||||
cycleDay: this.cycleDay,
|
cycleDay: this.cycleDay,
|
||||||
saveAction: () => {
|
saveAction: async () => {
|
||||||
|
const v = Number(`${this.state.integer}.${this.state.fractional}`)
|
||||||
const dataToSave = {
|
const dataToSave = {
|
||||||
value: Number(this.state.currentValue),
|
value: v,
|
||||||
exclude: this.state.exclude,
|
exclude: this.state.exclude,
|
||||||
time: this.state.time
|
time: this.state.time
|
||||||
}
|
}
|
||||||
saveSymptom('temperature', cycleDay, dataToSave)
|
saveSymptom('temperature', this.cycleDay, dataToSave)
|
||||||
},
|
},
|
||||||
saveDisabled: this.state.currentValue === '' || isInvalidTime(this.state.time)
|
saveDisabled:
|
||||||
|
this.state.integer === '' ||
|
||||||
|
isNaN(Number(this.state.integer)) ||
|
||||||
|
isNaN(Number(this.state.fractional)) ||
|
||||||
|
isInvalidTime(this.state.time)
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
export const settings = {
|
export const shared = {
|
||||||
shared: {
|
|
||||||
cancel: 'Cancel',
|
cancel: 'Cancel',
|
||||||
errorTitle: 'Error',
|
errorTitle: 'Error',
|
||||||
successTitle: 'Success'
|
successTitle: 'Success',
|
||||||
},
|
warning: 'Warning'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const settings = {
|
||||||
export: {
|
export: {
|
||||||
errors: {
|
errors: {
|
||||||
noData: 'There is no data to export',
|
noData: 'There is no data to export',
|
||||||
|
|||||||
+3
-2
@@ -66,8 +66,6 @@ export default StyleSheet.create({
|
|||||||
marginBottom: 15
|
marginBottom: 15
|
||||||
},
|
},
|
||||||
temperatureTextInput: {
|
temperatureTextInput: {
|
||||||
width: 80,
|
|
||||||
textAlign: 'center',
|
|
||||||
fontSize: 20
|
fontSize: 20
|
||||||
},
|
},
|
||||||
actionButtonRow: {
|
actionButtonRow: {
|
||||||
@@ -105,5 +103,8 @@ export default StyleSheet.create({
|
|||||||
},
|
},
|
||||||
settingsButtonText: {
|
settingsButtonText: {
|
||||||
color: 'white'
|
color: 'white'
|
||||||
|
},
|
||||||
|
warning: {
|
||||||
|
color: 'red'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user