On temperature view, replace menu with action buttons
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { View, BackHandler } from 'react-native'
|
import { View, BackHandler, ScrollView } from 'react-native'
|
||||||
import Header from './components/header'
|
import Header from './components/header'
|
||||||
import Menu from './components/menu'
|
import Menu from './components/menu'
|
||||||
import Home from './components/home'
|
import Home from './components/home'
|
||||||
import Calendar from './components/calendar'
|
import Calendar from './components/calendar'
|
||||||
import CycleDay from './components/cycle-day/cycle-day-overview'
|
import CycleDay from './components/cycle-day/cycle-day-overview'
|
||||||
import SymptomView from './components/cycle-day/symptoms'
|
import symptomViews from './components/cycle-day/symptoms'
|
||||||
import Chart from './components/chart/chart'
|
import Chart from './components/chart/chart'
|
||||||
import Settings from './components/settings'
|
import Settings from './components/settings'
|
||||||
import Stats from './components/stats'
|
import Stats from './components/stats'
|
||||||
@@ -13,8 +13,11 @@ import Stats from './components/stats'
|
|||||||
// this is until react native fixes this bugg, see
|
// this is until react native fixes this bugg, see
|
||||||
// https://github.com/facebook/react-native/issues/18868#issuecomment-382671739
|
// https://github.com/facebook/react-native/issues/18868#issuecomment-382671739
|
||||||
import { YellowBox } from 'react-native'
|
import { YellowBox } from 'react-native'
|
||||||
|
import ActionButtonFooter from './components/cycle-day/symptoms/action-button-footer';
|
||||||
YellowBox.ignoreWarnings(['Warning: isMounted(...) is deprecated'])
|
YellowBox.ignoreWarnings(['Warning: isMounted(...) is deprecated'])
|
||||||
|
|
||||||
|
const isSymptomView = name => Object.keys(symptomViews).indexOf(name) > -1
|
||||||
|
|
||||||
export default class App extends Component {
|
export default class App extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
@@ -24,9 +27,11 @@ export default class App extends Component {
|
|||||||
|
|
||||||
const handleBackButtonPress = function() {
|
const handleBackButtonPress = function() {
|
||||||
if (this.state.currentPage === 'Home') return false
|
if (this.state.currentPage === 'Home') return false
|
||||||
// this is handled in the SymptomView
|
if (isSymptomView(this.state.currentPage)) {
|
||||||
if (this.state.currentPage === 'SymptomView') return true
|
this.navigate('CycleDay', {cycleDay: this.state.currentProps.cycleDay})
|
||||||
|
} else {
|
||||||
this.navigate('Home')
|
this.navigate('Home')
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
|
|
||||||
@@ -41,34 +46,40 @@ export default class App extends Component {
|
|||||||
this.setState({currentPage: pageName, currentProps: props})
|
this.setState({currentPage: pageName, currentProps: props})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setActionButtonState(actionButtonInfo) {
|
||||||
|
this.setState({actionButtonInfo})
|
||||||
|
}
|
||||||
|
|
||||||
|
unsetActionButtonState() {
|
||||||
|
this.setState({actionButtonInfo: null})
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const page = {
|
||||||
|
Home, Calendar, CycleDay, Chart, Settings, Stats, ...symptomViews
|
||||||
|
}[this.state.currentPage]
|
||||||
return (
|
return (
|
||||||
<View style={{height: '100%', justifyContent: 'space-between' }}>
|
<View style={{height: '100%', justifyContent: 'space-between' }}>
|
||||||
<View>
|
<View>
|
||||||
{this.state.currentPage != 'CycleDay' && <Header title={this.state.currentPage}/>}
|
{this.state.currentPage != 'CycleDay' && <Header title={this.state.currentPage}/>}
|
||||||
<View>
|
<ScrollView>
|
||||||
<CurrentPage
|
{React.createElement(page, {
|
||||||
page={this.state.currentPage}
|
navigate: this.navigate.bind(this),
|
||||||
|
setActionButtonState: this.setActionButtonState.bind(this),
|
||||||
|
unsetActionButtonState: this.unsetActionButtonState.bind(this),
|
||||||
|
...this.state.currentProps
|
||||||
|
})}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
{isSymptomView(this.state.currentPage) && this.state.actionButtonInfo ?
|
||||||
|
<ActionButtonFooter
|
||||||
|
{...this.state.actionButtonInfo}
|
||||||
navigate={this.navigate.bind(this)}
|
navigate={this.navigate.bind(this)}
|
||||||
props={this.state.currentProps}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
:
|
||||||
</View>
|
<Menu navigate={this.navigate.bind(this)}/>
|
||||||
<Menu navigate={this.navigate.bind(this)} />
|
}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CurrentPage extends Component {
|
|
||||||
render () {
|
|
||||||
const page = {
|
|
||||||
Home, Calendar, CycleDay, SymptomView, Chart, Settings, Stats
|
|
||||||
}[this.props.page]
|
|
||||||
const props = this.props.props || {}
|
|
||||||
return React.createElement(page, {
|
|
||||||
navigate: this.props.navigate,
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {
|
|
||||||
View,
|
|
||||||
Button,
|
|
||||||
} from 'react-native'
|
|
||||||
import { saveSymptom } from '../../db'
|
|
||||||
|
|
||||||
export default function (navigateToOverView) {
|
|
||||||
return function ({ symptom, cycleDay, saveAction, saveDisabled}) {
|
|
||||||
const buttons = [
|
|
||||||
{
|
|
||||||
title: 'Cancel',
|
|
||||||
action: () => navigateToOverView()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Delete',
|
|
||||||
action: () => {
|
|
||||||
saveSymptom(symptom, cycleDay)
|
|
||||||
navigateToOverView()
|
|
||||||
},
|
|
||||||
disabledCondition: !cycleDay[symptom]
|
|
||||||
}, {
|
|
||||||
title: 'Save',
|
|
||||||
action: () => {
|
|
||||||
saveAction()
|
|
||||||
navigateToOverView()
|
|
||||||
},
|
|
||||||
disabledCondition: saveDisabled
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
return buttons.map(({ title, action, disabledCondition }, i) => {
|
|
||||||
const style = { flex: 1, marginHorizontal: 10 }
|
|
||||||
if (i === 0) style.marginLeft = 0
|
|
||||||
if (i === buttons.length - 1) style.marginRight = 0
|
|
||||||
return (
|
|
||||||
<View style={style} key={i}>
|
|
||||||
<Button
|
|
||||||
onPress={action}
|
|
||||||
disabled={disabledCondition}
|
|
||||||
title={title}>
|
|
||||||
</Button>
|
|
||||||
</View >
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -40,9 +40,8 @@ export default class CycleDayOverView extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
navigate(symptom) {
|
navigate(symptom) {
|
||||||
this.props.navigate('SymptomView', {
|
this.props.navigate(symptom, {
|
||||||
symptom,
|
cycleDay: this.state.cycleDay,
|
||||||
cycleDay: this.state.cycleDay
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import {
|
import {
|
||||||
View,
|
View, TouchableOpacity, Text
|
||||||
Button,
|
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
|
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||||
import { saveSymptom } from '../../../db'
|
import { saveSymptom } from '../../../db'
|
||||||
import styles from '../../../styles'
|
import styles, {iconStyles} from '../../../styles'
|
||||||
|
|
||||||
export default class ActionButtonFooter extends Component {
|
export default class ActionButtonFooter extends Component {
|
||||||
render() {
|
render() {
|
||||||
const { symptom, cycleDay, saveAction, saveDisabled, navigate} = this.props
|
const { symptom, cycleDay, saveAction, saveDisabled, navigate} = this.props
|
||||||
const navigateToOverView = () => navigate('CycleDay', cycleDay)
|
const navigateToOverView = () => navigate('CycleDay', {cycleDay})
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
title: 'Cancel',
|
title: 'Cancel',
|
||||||
action: () => navigateToOverView()
|
action: () => navigateToOverView(),
|
||||||
|
icon: 'cancel'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Delete',
|
title: 'Delete',
|
||||||
@@ -21,31 +22,34 @@ export default class ActionButtonFooter extends Component {
|
|||||||
saveSymptom(symptom, cycleDay)
|
saveSymptom(symptom, cycleDay)
|
||||||
navigateToOverView()
|
navigateToOverView()
|
||||||
},
|
},
|
||||||
disabledCondition: !cycleDay[symptom]
|
disabledCondition: !cycleDay[symptom],
|
||||||
|
icon: 'delete-outline'
|
||||||
}, {
|
}, {
|
||||||
title: 'Save',
|
title: 'Save',
|
||||||
action: () => {
|
action: () => {
|
||||||
saveAction()
|
saveAction()
|
||||||
navigateToOverView()
|
navigateToOverView()
|
||||||
},
|
},
|
||||||
disabledCondition: saveDisabled
|
disabledCondition: saveDisabled,
|
||||||
|
icon: 'content-save-outline'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.actionButtonRow}>
|
<View style={styles.menu}>
|
||||||
{buttons.map(({ title, action, disabledCondition }, i) => {
|
{buttons.map(({ title, action, disabledCondition, icon }, i) => {
|
||||||
const style = { flex: 1, marginHorizontal: 10 }
|
|
||||||
if (i === 0) style.marginLeft = 0
|
|
||||||
if (i === buttons.length - 1) style.marginRight = 0
|
|
||||||
return (
|
return (
|
||||||
<View style={style} key={i}>
|
<TouchableOpacity
|
||||||
<Button
|
|
||||||
onPress={action}
|
onPress={action}
|
||||||
|
style={styles.menuItem}
|
||||||
disabled={disabledCondition}
|
disabled={disabledCondition}
|
||||||
title={title}>
|
key={i.toString()}
|
||||||
</Button>
|
>
|
||||||
</View >
|
<Icon name={icon} {...iconStyles.menuIcon} />
|
||||||
|
<Text style={styles.menuText}>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
import React, { Component } from 'react'
|
|
||||||
import { ScrollView, BackHandler } from 'react-native'
|
|
||||||
import Header from '../../header'
|
|
||||||
import actionButtonModule from '../action-buttons'
|
|
||||||
import BleedingEditView from './bleeding'
|
import BleedingEditView from './bleeding'
|
||||||
import TemperatureEditView from './temperature'
|
import TemperatureEditView from './temperature'
|
||||||
import MucusEditView from './mucus'
|
import MucusEditView from './mucus'
|
||||||
@@ -10,7 +6,7 @@ import NoteEditView from './note'
|
|||||||
import DesireEditView from './desire'
|
import DesireEditView from './desire'
|
||||||
import SexEditView from './sex'
|
import SexEditView from './sex'
|
||||||
|
|
||||||
const symptomViews = {
|
export default {
|
||||||
BleedingEditView,
|
BleedingEditView,
|
||||||
TemperatureEditView,
|
TemperatureEditView,
|
||||||
MucusEditView,
|
MucusEditView,
|
||||||
@@ -19,53 +15,3 @@ const symptomViews = {
|
|||||||
DesireEditView,
|
DesireEditView,
|
||||||
SexEditView
|
SexEditView
|
||||||
}
|
}
|
||||||
const titles = {
|
|
||||||
BleedingEditView: 'Bleeding',
|
|
||||||
TemperatureEditView: 'Temperature',
|
|
||||||
MucusEditView: 'Mucus',
|
|
||||||
CervixEditView: 'Cervix',
|
|
||||||
NoteEditView: 'Note',
|
|
||||||
DesireEditView: 'Desire',
|
|
||||||
SexEditView: 'Sex'
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class SymptomView extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props)
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
visibleComponent: props.symptom,
|
|
||||||
cycleDay: props.cycleDay
|
|
||||||
}
|
|
||||||
|
|
||||||
this.makeActionButtons = actionButtonModule(() => {
|
|
||||||
this.props.navigate('CycleDay', {cycleDay: this.state.cycleDay})
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleBackButtonPress = function() {
|
|
||||||
this.props.navigate('CycleDay', {cycleDay: this.state.cycleDay})
|
|
||||||
return true
|
|
||||||
}.bind(this)
|
|
||||||
|
|
||||||
this.backHandler = BackHandler.addEventListener('hardwareBackPress', handleBackButtonPress)
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this.backHandler.remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<ScrollView>
|
|
||||||
<Header title={titles[this.state.visibleComponent]}/>
|
|
||||||
{React.createElement(
|
|
||||||
symptomViews[this.state.visibleComponent],
|
|
||||||
{
|
|
||||||
cycleDay: this.state.cycleDay,
|
|
||||||
makeActionButtons: this.makeActionButtons
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</ScrollView >
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
TextInput,
|
TextInput,
|
||||||
Switch,
|
Switch,
|
||||||
Keyboard
|
Keyboard,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import DateTimePicker from 'react-native-modal-datetime-picker-nevo'
|
import DateTimePicker from 'react-native-modal-datetime-picker-nevo'
|
||||||
|
|
||||||
@@ -37,10 +37,27 @@ export default class Temp extends Component {
|
|||||||
time: this.time || LocalTime.now().truncatedTo(MINUTES).toString(),
|
time: this.time || LocalTime.now().truncatedTo(MINUTES).toString(),
|
||||||
isTimePickerVisible: false
|
isTimePickerVisible: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props.setActionButtonState({
|
||||||
|
symptom : 'temperature',
|
||||||
|
cycleDay: props.cycleDay,
|
||||||
|
saveAction: () => {
|
||||||
|
const dataToSave = {
|
||||||
|
value: Number(this.state.currentValue),
|
||||||
|
exclude: this.state.exclude,
|
||||||
|
time: this.state.time
|
||||||
|
}
|
||||||
|
saveSymptom('temperature', props.cycleDay, dataToSave)
|
||||||
|
},
|
||||||
|
saveDisabled: this.state.currentValue === '' || isInvalidTime(this.state.time)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.props.unsetActionButtonState()
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const cycleDay = this.cycleDay
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.symptomEditView}>
|
<View style={styles.symptomEditView}>
|
||||||
<View style={styles.symptomViewRowInline}>
|
<View style={styles.symptomViewRowInline}>
|
||||||
@@ -61,7 +78,7 @@ export default class Temp extends Component {
|
|||||||
style={styles.temperatureTextInput}
|
style={styles.temperatureTextInput}
|
||||||
onFocus={() => {
|
onFocus={() => {
|
||||||
Keyboard.dismiss()
|
Keyboard.dismiss()
|
||||||
this.setState({isTimePickerVisible: true})
|
this.setState({ isTimePickerVisible: true })
|
||||||
}}
|
}}
|
||||||
value={this.state.time}
|
value={this.state.time}
|
||||||
/>
|
/>
|
||||||
@@ -75,7 +92,7 @@ export default class Temp extends Component {
|
|||||||
isTimePickerVisible: false
|
isTimePickerVisible: false
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
onCancel={() => this.setState({isTimePickerVisible: false})}
|
onCancel={() => this.setState({ isTimePickerVisible: false })}
|
||||||
/>
|
/>
|
||||||
<View style={styles.symptomViewRowInline}>
|
<View style={styles.symptomViewRowInline}>
|
||||||
<Text style={styles.symptomDayView}>Exclude</Text>
|
<Text style={styles.symptomDayView}>Exclude</Text>
|
||||||
@@ -86,21 +103,6 @@ export default class Temp extends Component {
|
|||||||
value={this.state.exclude}
|
value={this.state.exclude}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.actionButtonRow}>
|
|
||||||
{this.makeActionButtons({
|
|
||||||
symptom: 'temperature',
|
|
||||||
cycleDay: this.cycleDay,
|
|
||||||
saveAction: () => {
|
|
||||||
const dataToSave = {
|
|
||||||
value: Number(this.state.currentValue),
|
|
||||||
exclude: this.state.exclude,
|
|
||||||
time: this.state.time
|
|
||||||
}
|
|
||||||
saveSymptom('temperature', cycleDay, dataToSave)
|
|
||||||
},
|
|
||||||
saveDisabled: this.state.currentValue === '' || isInvalidTime(this.state.time)
|
|
||||||
})}
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-10
@@ -8,11 +8,12 @@ import styles, { iconStyles } from '../styles'
|
|||||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
|
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||||
|
|
||||||
export default class Menu extends Component {
|
export default class Menu extends Component {
|
||||||
makeMenuItem({ title, icon, componentName }) {
|
makeMenuItem({ title, icon, onPress}, i) {
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
onPress={() => this.props.navigate(componentName)}
|
onPress={onPress}
|
||||||
style={styles.menuItem}
|
style={styles.menuItem}
|
||||||
|
key={i.toString()}
|
||||||
>
|
>
|
||||||
<Icon name={icon} {...iconStyles.menuIcon} />
|
<Icon name={icon} {...iconStyles.menuIcon} />
|
||||||
<Text style={styles.menuText}>
|
<Text style={styles.menuText}>
|
||||||
@@ -21,18 +22,20 @@ export default class Menu extends Component {
|
|||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goTo(componentName) {
|
||||||
|
this.props.navigate(componentName)
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
this.props.symptomView ?
|
|
||||||
placeActionButtons()
|
|
||||||
:
|
|
||||||
<View style={styles.menu}>
|
<View style={styles.menu}>
|
||||||
{[
|
{[
|
||||||
{title: 'Home', icon: 'home', componentName: 'Home'},
|
{ title: 'Home', icon: 'home', onPress: () => this.goTo('Home') },
|
||||||
{title: 'Calendar', icon: 'calendar-range', componentName: 'Calendar'},
|
{ title: 'Calendar', icon: 'calendar-range', onPress: () => this.goTo('Calendar') },
|
||||||
{title: 'Chart', icon: 'chart-line', componentName: 'Chart'},
|
{ title: 'Chart', icon: 'chart-line', onPress: () => this.goTo('Chart') },
|
||||||
{title: 'Stats', icon: 'chart-pie', componentName: 'Stats'},
|
{ title: 'Stats', icon: 'chart-pie', onPress: () => this.goTo('Stats') },
|
||||||
{title: 'Settings', icon: 'settings', componentName: 'Settings'},
|
{ title: 'Settings', icon: 'settings', onPress: () => this.goTo('Settings') },
|
||||||
].map(this.makeMenuItem.bind(this))}
|
].map(this.makeMenuItem.bind(this))}
|
||||||
</View >
|
</View >
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user