From 0878135aed7b827fda126520470f345ece61fc9f Mon Sep 17 00:00:00 2001 From: Julia Friesel <julia.friesel@gmail.com> Date: Wed, 22 Aug 2018 13:17:12 +0200 Subject: [PATCH] Warn when user enters an out-of-range temperature --- components/cycle-day/action-buttons.js | 4 +- components/cycle-day/labels/labels.js | 5 ++ components/cycle-day/symptoms/temperature.js | 90 ++++++++++++++------ components/labels.js | 12 +-- styles/index.js | 5 +- 5 files changed, 81 insertions(+), 35 deletions(-) diff --git a/components/cycle-day/action-buttons.js b/components/cycle-day/action-buttons.js index 78e24793..9ddb036e 100644 --- a/components/cycle-day/action-buttons.js +++ b/components/cycle-day/action-buttons.js @@ -22,8 +22,8 @@ export default function (showView) { } }, { title: 'Save', - action: () => { - saveAction() + action: async () => { + await saveAction() showView(dayView) }, disabledCondition: saveDisabled diff --git a/components/cycle-day/labels/labels.js b/components/cycle-day/labels/labels.js index ee88428f..c2e185bd 100644 --- a/components/cycle-day/labels/labels.js +++ b/components/cycle-day/labels/labels.js @@ -26,3 +26,8 @@ export const fertilityStatus = { fertileUntilEvening: 'Fertile phase ends in the evening', 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' +} diff --git a/components/cycle-day/symptoms/temperature.js b/components/cycle-day/symptoms/temperature.js index 72968832..6d3a3727 100644 --- a/components/cycle-day/symptoms/temperature.js +++ b/components/cycle-day/symptoms/temperature.js @@ -4,56 +4,89 @@ import { Text, TextInput, Switch, - Keyboard + Keyboard, + Alert } from 'react-native' import DateTimePicker from 'react-native-modal-datetime-picker-nevo' import { getPreviousTemperature, saveSymptom } from '../../../db' import styles from '../../../styles' 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 { constructor(props) { super(props) this.cycleDay = props.cycleDay this.makeActionButtons = props.makeActionButtons - let initialValue const temp = this.cycleDay.temperature + this.state = { + exclude: temp ? temp.exclude : false, + time: temp ? temp.time : LocalTime.now().truncatedTo(minutes).toString(), + isTimePickerVisible: false, + integer: '', + fractional: '', + outOfRange: null + } + if (temp) { - initialValue = temp.value.toString() - this.time = temp.time + const [integer, fractional] = temp.value.toString().split('.') + this.state.integer = integer + this.state.fractional = fractional } else { const prevTemp = getPreviousTemperature(this.cycleDay) - initialValue = prevTemp ? prevTemp.toString() : '' + if (prevTemp) { + const [integer, fractional] = prevTemp.toString().split('.') + this.state.integer = integer + this.state.fractional = fractional + } } + } - this.state = { - currentValue: initialValue, - exclude: temp ? temp.exclude : false, - time: this.time || LocalTime.now().truncatedTo(MINUTES).toString(), - isTimePickerVisible: false + 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() { - const cycleDay = this.cycleDay return ( <View style={styles.symptomEditView}> <View style={styles.symptomViewRowInline}> <Text style={styles.symptomDayView}>Temperature (°C)</Text> - <TextInput - style={styles.temperatureTextInput} - placeholder="Enter" - onChangeText={(val) => { - this.setState({ currentValue: val }) - }} - keyboardType='numeric' - value={this.state.currentValue} - /> + <View style={{flexDirection: 'row', alignItems: 'center'}}> + <TextInput + style={styles.temperatureTextInput} + onChangeText={(val) => { + this.setState({ integer: val }) + }} + keyboardType='numeric' + 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 style={styles.symptomViewRowInline}> <Text style={styles.symptomDayView}>Time</Text> @@ -71,7 +104,7 @@ export default class Temp extends Component { isVisible={this.state.isTimePickerVisible} onConfirm={jsDate => { this.setState({ - time: `${jsDate.getHours()}:${jsDate.getMinutes()}`, + time: `${jsDate.getinteger()}:${jsDate.getfractional()}`, isTimePickerVisible: false }) }} @@ -90,15 +123,20 @@ export default class Temp extends Component { {this.makeActionButtons({ symptom: 'temperature', cycleDay: this.cycleDay, - saveAction: () => { + saveAction: async () => { + const v = Number(`${this.state.integer}.${this.state.fractional}`) const dataToSave = { - value: Number(this.state.currentValue), + value: v, exclude: this.state.exclude, 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> diff --git a/components/labels.js b/components/labels.js index 893062b2..27cef636 100644 --- a/components/labels.js +++ b/components/labels.js @@ -1,9 +1,11 @@ +export const shared = { + cancel: 'Cancel', + errorTitle: 'Error', + successTitle: 'Success', + warning: 'Warning' +} + export const settings = { - shared: { - cancel: 'Cancel', - errorTitle: 'Error', - successTitle: 'Success' - }, export: { errors: { noData: 'There is no data to export', diff --git a/styles/index.js b/styles/index.js index 44ea90d3..69ef0c2c 100644 --- a/styles/index.js +++ b/styles/index.js @@ -66,8 +66,6 @@ export default StyleSheet.create({ marginBottom: 15 }, temperatureTextInput: { - width: 80, - textAlign: 'center', fontSize: 20 }, actionButtonRow: { @@ -105,5 +103,8 @@ export default StyleSheet.create({ }, settingsButtonText: { color: 'white' + }, + warning: { + color: 'red' } }) \ No newline at end of file -- GitLab