From 29a82fca9f3e71e279a05e4670aa9bd1c4e658e9 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Thu, 16 Aug 2018 19:40:57 +0200 Subject: [PATCH 01/28] Start styling the day overview --- app.js | 8 +- components/cycle-day/assets/placeholder.png | Bin 0 -> 4782 bytes components/cycle-day/cycle-day-overview.js | 130 ++++++++++---------- components/cycle-day/index.js | 8 -- components/cycle-day/symptoms/bleeding.js | 46 +++---- styles/index.js | 51 +++++--- 6 files changed, 127 insertions(+), 116 deletions(-) create mode 100644 components/cycle-day/assets/placeholder.png diff --git a/app.js b/app.js index 7735256..0c951c8 100644 --- a/app.js +++ b/app.js @@ -7,7 +7,7 @@ import Chart from './components/chart/chart' import Settings from './components/settings' import Stats from './components/stats' -import styles from './styles' +import styles, { primaryColor } from './styles' // this is until react native fixes this bugg, see // https://github.com/facebook/react-native/issues/18868#issuecomment-382671739 @@ -26,9 +26,9 @@ const config = { labeled: true, shifting: false, tabBarOptions: { - style: {backgroundColor: '#ff7e5f'}, - labelStyle: {fontSize: 15, color: 'white'} - }, + style: {backgroundColor: primaryColor }, + labelStyle: styles.menuLabel + } } export default createBottomTabNavigator(routes, config) \ No newline at end of file diff --git a/components/cycle-day/assets/placeholder.png b/components/cycle-day/assets/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..fb6a6c98deedf368459cf4c5d5af315f3ab5f739 GIT binary patch literal 4782 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 - - Bleeding - - - - - - Temperature - - - - - - Mucus - - - - - - Cervix - - - - - - Note - - - - - - Desire - - - - - - Sex - - - - + + this.showView('BleedingEditView')} + data={getLabel('bleeding', cycleDay.bleeding)} + /> + this.showView('TemperatureEditView')} + data={getLabel('temperature', cycleDay.temperature)} + /> + this.showView('MucusEditView')} + data={getLabel('mucus', cycleDay.mucus)} + /> + this.showView('CervixEditView')} + data={getLabel('cervix', cycleDay.cervix)} + /> + this.showView('NoteEditView')} + data={getLabel('note', cycleDay.note)} + /> + this.showView('DesireEditView')} + data={getLabel('desire', cycleDay.desire)} + /> + this.showView('SexEditView')} + data={getLabel('sex', cycleDay.sex)} + /> + ) } @@ -186,3 +167,20 @@ function getLabel(symptomName, symptom) { if (!symptom) return 'edit' return labels[symptomName](symptom) || 'edit' } + +class SymptomBox extends Component { + render() { + return ( + + + + {this.props.title} + {this.props.data} + + + ) + } +} \ No newline at end of file diff --git a/components/cycle-day/index.js b/components/cycle-day/index.js index 94bb51e..fab2b2e 100644 --- a/components/cycle-day/index.js +++ b/components/cycle-day/index.js @@ -5,7 +5,6 @@ import { ScrollView } from 'react-native' import cycleModule from '../../lib/cycle' -import { getFertilityStatusStringForDay } from '../../lib/sympto-adapter' import { formatDateForViewHeader } from './labels/format' import styles from '../../styles' import actionButtonModule from './action-buttons' @@ -50,23 +49,16 @@ export default class Day extends Component { render() { const cycleDayNumber = getCycleDayNumber(this.cycleDay.date) - const fertilityStatus = getFertilityStatusStringForDay(this.cycleDay.date) return ( {formatDateForViewHeader(this.cycleDay.date)} - - { cycleDayNumber && Cycle day {cycleDayNumber} } - - - {fertilityStatus} - { this.cycleDayViews[this.state.visibleComponent] } diff --git a/components/cycle-day/symptoms/bleeding.js b/components/cycle-day/symptoms/bleeding.js index 7ec0574..ffd1836 100644 --- a/components/cycle-day/symptoms/bleeding.js +++ b/components/cycle-day/symptoms/bleeding.js @@ -32,28 +32,30 @@ export default class Bleeding extends Component { { label: labels[3], value: 3 }, ] return ( - - Bleeding - - { - this.setState({ currentValue: itemValue }) - }} - /> - - - Exclude - { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> + + + Bleeding + + { + this.setState({ currentValue: itemValue }) + }} + /> + + + Exclude + { + this.setState({ exclude: val }) + }} + value={this.state.exclude} + /> + {this.makeActionButtons( diff --git a/styles/index.js b/styles/index.js index fde1700..9197f31 100644 --- a/styles/index.js +++ b/styles/index.js @@ -1,5 +1,8 @@ import { StyleSheet } from 'react-native' +export const primaryColor = '#ff7e5f' +export const secondaryColor = '#351c4d' + export default StyleSheet.create({ container: { justifyContent: 'center', @@ -12,31 +15,46 @@ export default StyleSheet.create({ textAlignVertical: 'center' }, dateHeader: { - fontSize: 20, + fontSize: 18, fontWeight: 'bold', - margin: 15, color: 'white', textAlign: 'center', - textAlignVertical: 'center' }, cycleDayNumber: { - fontSize: 18, + fontSize: 15, + color: 'white', textAlign: 'center', - textAlignVertical: 'center' + marginLeft: 15 }, symptomDayView: { fontSize: 20, textAlignVertical: 'center' }, + symptomBoxImage: { + width: 50, + height: 50 + }, radioButton: { fontSize: 18, margin: 8, textAlign: 'center', textAlignVertical: 'center' }, - symptomEditView: { - justifyContent: 'space-between', - marginHorizontal: 15 + symptomBoxesView: { + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'space-evenly' + }, + symptomBox: { + borderColor: secondaryColor, + borderStyle: 'solid', + borderWidth: 1, + borderRadius: 10, + justifyContent: 'center', + alignItems: 'center', + marginTop: '20%', + minWidth: 100, + minHeight: 100 }, symptomEditRow: { justifyContent: 'space-between', @@ -50,14 +68,11 @@ export default StyleSheet.create({ height: 50 }, cycleDayDateView: { + backgroundColor: primaryColor, + padding: 10, + flexDirection: 'row', justifyContent: 'center', - backgroundColor: 'steelblue' - }, - cycleDayNumberView: { - justifyContent: 'center', - backgroundColor: 'skyblue', - marginBottom: 15, - paddingVertical: 15 + alignItems: 'center' }, homeButtons: { marginHorizontal: 15 @@ -88,5 +103,9 @@ export default StyleSheet.create({ margin: 30, textAlign: 'left', textAlignVertical: 'center' - } + }, + menuLabel: { + fontSize: 15, + color: 'white' + }, }) \ No newline at end of file From ff60db089cbe0fbda13e1cbc6b9644699467760f Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Thu, 16 Aug 2018 21:32:55 +0200 Subject: [PATCH 02/28] Align grid --- components/cycle-day/cycle-day-overview.js | 113 ++++++++++++--------- styles/index.js | 3 +- 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index dee8a9e..31e54d5 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -3,7 +3,8 @@ import { View, Text, Image, - TouchableOpacity + TouchableOpacity, + Dimensions } from 'react-native' import styles from '../../styles' import { @@ -48,51 +49,52 @@ export default class DayView extends Component { render() { const cycleDay = this.cycleDay return ( - - - this.showView('BleedingEditView')} - data={getLabel('bleeding', cycleDay.bleeding)} - /> - this.showView('TemperatureEditView')} - data={getLabel('temperature', cycleDay.temperature)} - /> - this.showView('MucusEditView')} - data={getLabel('mucus', cycleDay.mucus)} - /> - this.showView('CervixEditView')} - data={getLabel('cervix', cycleDay.cervix)} - /> - this.showView('NoteEditView')} - data={getLabel('note', cycleDay.note)} - /> - this.showView('DesireEditView')} - data={getLabel('desire', cycleDay.desire)} - /> - this.showView('SexEditView')} - data={getLabel('sex', cycleDay.sex)} - /> - + + this.showView('BleedingEditView')} + data={getLabel('bleeding', cycleDay.bleeding)} + /> + this.showView('TemperatureEditView')} + data={getLabel('temperature', cycleDay.temperature)} + /> + this.showView('MucusEditView')} + data={getLabel('mucus', cycleDay.mucus)} + /> + this.showView('CervixEditView')} + data={getLabel('cervix', cycleDay.cervix)} + /> + this.showView('NoteEditView')} + data={getLabel('note', cycleDay.note)} + /> + this.showView('DesireEditView')} + data={getLabel('desire', cycleDay.desire)} + /> + this.showView('SexEditView')} + data={getLabel('sex', cycleDay.sex)} + /> + {/* this is just to make the last row adhere to the grid + (and) because there are no pseudo properties in RN */} + ) } @@ -160,12 +162,12 @@ function getLabel(symptomName, symptom) { sex.patch || sex.ring || sex.implant || sex.other) { sexLabel += 'Contraceptive' } - return sexLabel ? sexLabel : 'edit' + return sexLabel ? sexLabel : undefined } } - if (!symptom) return 'edit' - return labels[symptomName](symptom) || 'edit' + if (!symptom) return + return labels[symptomName](symptom) } class SymptomBox extends Component { @@ -183,4 +185,17 @@ class SymptomBox extends Component { ) } +} + +class FillerBoxes extends Component { + render() { + const n = Dimensions.get('window').width / styles.symptomBox.minHeight + return Array(Math.ceil(n)).fill( + + ) + } } \ No newline at end of file diff --git a/styles/index.js b/styles/index.js index 9197f31..88b76cb 100644 --- a/styles/index.js +++ b/styles/index.js @@ -53,8 +53,9 @@ export default StyleSheet.create({ justifyContent: 'center', alignItems: 'center', marginTop: '20%', + marginHorizontal: 1, minWidth: 100, - minHeight: 100 + minHeight: 100, }, symptomEditRow: { justifyContent: 'space-between', From a59aa86dbfbac8b76c7aa0926dc38f544a0c2cde Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Thu, 16 Aug 2018 21:45:17 +0200 Subject: [PATCH 03/28] Fix key --- components/cycle-day/cycle-day-overview.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 31e54d5..3578682 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -190,12 +190,16 @@ class SymptomBox extends Component { class FillerBoxes extends Component { render() { const n = Dimensions.get('window').width / styles.symptomBox.minHeight - return Array(Math.ceil(n)).fill( - - ) + const fillerBoxes = [] + for (let i = 0; i < Math.ceil(n); i++) { + fillerBoxes.push( + + ) + } + return fillerBoxes } } \ No newline at end of file From fae278435aaa1448d2d04cb64c4f947a2ca18d94 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 17 Aug 2018 08:05:15 +0200 Subject: [PATCH 04/28] Add navigation arrows --- components/cycle-day/cycle-day-overview.js | 29 +-------- components/cycle-day/index.js | 70 ++++++++++++++-------- styles/index.js | 27 ++++++--- 3 files changed, 67 insertions(+), 59 deletions(-) diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 3578682..4b75224 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -17,37 +17,10 @@ import { cervixPosition as positionLabels, intensity as intensityLabels } from './labels/labels' -import cycleDayModule from '../../lib/cycle' -import { bleedingDaysSortedByDate } from '../../db' - -const getCycleDayNumber = cycleDayModule().getCycleDayNumber export default class DayView extends Component { - constructor(props) { - super(props) - this.cycleDay = props.cycleDay - this.showView = props.showView - this.state = { - cycleDayNumber: getCycleDayNumber(this.cycleDay.date), - } - - this.setStateWithCycleDayNumber = (function (DayViewComponent) { - return function () { - DayViewComponent.setState({ - cycleDayNumber: getCycleDayNumber(DayViewComponent.cycleDay.date) - }) - } - })(this) - - bleedingDaysSortedByDate.addListener(this.setStateWithCycleDayNumber) - } - - componentWillUnmount() { - bleedingDaysSortedByDate.removeListener(this.setStateWithCycleDayNumber) - } - render() { - const cycleDay = this.cycleDay + const cycleDay = this.props.cycleDay return ( { + this.showView = view => { this.setState({visibleComponent: view}) } + this.makeActionButtons = actionButtonModule(this.showView) + } - const makeActionButtons = actionButtonModule(showView) + goToCycleDay(target) { + const localDate = LocalDate.parse(this.state.cycleDay.date) + const targetDate = target === 'before' ? + localDate.minusDays(1).toString() : + localDate.plusDays(1).toString() + this.setState({cycleDay: getOrCreateCycleDay(targetDate)}) + } - const symptomComponentNames = Object.keys(symptomComponents) - this.cycleDayViews = symptomComponentNames.reduce((acc, curr) => { + render() { + const cycleDayNumber = getCycleDayNumber(this.state.cycleDay.date) + const cycleDayViews = symptomComponentNames.reduce((acc, curr) => { acc[curr] = React.createElement( symptomComponents[curr], { - cycleDay: this.cycleDay, - makeActionButtons + cycleDay: this.state.cycleDay, + makeActionButtons: this.makeActionButtons } ) return acc }, {}) - // DayView needs showView instead of makeActionButtons - this.cycleDayViews.DayView = React.createElement(DayView, { - cycleDay: this.cycleDay, - showView + cycleDayViews.DayView = React.createElement(DayView, { + dateString: this.state.cycleDay.date, + cycleDay: this.state.cycleDay, + showView: this.showView }) - } - render() { - const cycleDayNumber = getCycleDayNumber(this.cycleDay.date) return ( - - {formatDateForViewHeader(this.cycleDay.date)} - - { cycleDayNumber && - - Cycle day {cycleDayNumber} - } + this.goToCycleDay('before')} + /> + + + {formatDateForViewHeader(this.state.cycleDay.date)} + + {cycleDayNumber && + + Cycle day {cycleDayNumber} + } + + this.goToCycleDay('after')} + /> - { this.cycleDayViews[this.state.visibleComponent] } + { cycleDayViews[this.state.visibleComponent] } ) } -} +} \ No newline at end of file diff --git a/styles/index.js b/styles/index.js index 88b76cb..8896f03 100644 --- a/styles/index.js +++ b/styles/index.js @@ -2,6 +2,7 @@ import { StyleSheet } from 'react-native' export const primaryColor = '#ff7e5f' export const secondaryColor = '#351c4d' +export const fontOnPrimaryColor = 'white' export default StyleSheet.create({ container: { @@ -17,12 +18,12 @@ export default StyleSheet.create({ dateHeader: { fontSize: 18, fontWeight: 'bold', - color: 'white', + color: fontOnPrimaryColor, textAlign: 'center', }, cycleDayNumber: { fontSize: 15, - color: 'white', + color: fontOnPrimaryColor, textAlign: 'center', marginLeft: 15 }, @@ -70,10 +71,15 @@ export default StyleSheet.create({ }, cycleDayDateView: { backgroundColor: primaryColor, - padding: 10, + paddingVertical: 18, + paddingHorizontal: 15, + alignItems: 'center', flexDirection: 'row', - justifyContent: 'center', - alignItems: 'center' + justifyContent: 'space-between' + }, + navigationArrow: { + fontSize: 60, + color: fontOnPrimaryColor }, homeButtons: { marginHorizontal: 15 @@ -107,6 +113,13 @@ export default StyleSheet.create({ }, menuLabel: { fontSize: 15, - color: 'white' + color: fontOnPrimaryColor }, -}) \ No newline at end of file +}) + +export const iconStyles = { + navigationArrow: { + size: 45, + color: fontOnPrimaryColor + } +} \ No newline at end of file From 1c390f784cc2028b547acbab197bf8a516a577f4 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 17 Aug 2018 08:59:44 +0200 Subject: [PATCH 05/28] Use realistic icon and set active state --- components/cycle-day/assets/placeholder.png | Bin 4782 -> 0 bytes components/cycle-day/cycle-day-overview.js | 45 ++++++++++---------- styles/index.js | 12 ++++++ 3 files changed, 35 insertions(+), 22 deletions(-) delete mode 100644 components/cycle-day/assets/placeholder.png diff --git a/components/cycle-day/assets/placeholder.png b/components/cycle-day/assets/placeholder.png deleted file mode 100644 index fb6a6c98deedf368459cf4c5d5af315f3ab5f739..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4782 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 this.showView('BleedingEditView')} + onPress={() => this.props.showView('BleedingEditView')} data={getLabel('bleeding', cycleDay.bleeding)} /> this.showView('TemperatureEditView')} + onPress={() => this.props.showView('TemperatureEditView')} data={getLabel('temperature', cycleDay.temperature)} /> this.showView('MucusEditView')} + onPress={() => this.props.showView('MucusEditView')} data={getLabel('mucus', cycleDay.mucus)} /> this.showView('CervixEditView')} + onPress={() => this.props.showView('CervixEditView')} data={getLabel('cervix', cycleDay.cervix)} /> this.showView('NoteEditView')} + onPress={() => this.props.showView('NoteEditView')} data={getLabel('note', cycleDay.note)} /> this.showView('DesireEditView')} + onPress={() => this.props.showView('DesireEditView')} data={getLabel('desire', cycleDay.desire)} /> this.showView('SexEditView')} + onPress={() => this.props.showView('SexEditView')} data={getLabel('sex', cycleDay.sex)} /> {/* this is just to make the last row adhere to the grid @@ -145,15 +138,23 @@ function getLabel(symptomName, symptom) { class SymptomBox extends Component { render() { + const d = this.props.data + const boxActive = d ? styles.symptomBoxActive : {} + const iconActive = d ? iconStyles.symptomBoxActive : {} + const textStyle = d ? styles.symptomTextActive : {} + + const symptomBoxStyle = Object.assign({}, styles.symptomBox, boxActive) + const iconStyle = Object.assign({}, iconStyles.symptomBox, iconActive) + return ( - - + - {this.props.title} - {this.props.data} + {this.props.title} + {this.props.data} ) diff --git a/styles/index.js b/styles/index.js index 8896f03..087d20d 100644 --- a/styles/index.js +++ b/styles/index.js @@ -58,6 +58,12 @@ export default StyleSheet.create({ minWidth: 100, minHeight: 100, }, + symptomBoxActive: { + backgroundColor: secondaryColor, + }, + symptomTextActive: { + color: fontOnPrimaryColor + }, symptomEditRow: { justifyContent: 'space-between', marginBottom: 10, @@ -121,5 +127,11 @@ export const iconStyles = { navigationArrow: { size: 45, color: fontOnPrimaryColor + }, + symptomBox: { + size: 40 + }, + symptomBoxActive: { + color: fontOnPrimaryColor } } \ No newline at end of file From 636e5e2f9d8e1ae072b1f37a9af9c99d5fe8f389 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 17 Aug 2018 10:17:17 +0200 Subject: [PATCH 06/28] Use navigator for symptom views also --- app.js | 9 +- components/cycle-day/cycle-day-overview.js | 136 ++++++++++++++------- components/cycle-day/index.js | 91 -------------- components/cycle-day/symptoms/index.js | 56 ++++++++- 4 files changed, 156 insertions(+), 136 deletions(-) delete mode 100644 components/cycle-day/index.js diff --git a/app.js b/app.js index 0c951c8..0baccba 100644 --- a/app.js +++ b/app.js @@ -2,7 +2,8 @@ import { createStackNavigator, createBottomTabNavigator } from 'react-navigation import Home from './components/home' import Calendar from './components/calendar' -import CycleDay from './components/cycle-day' +import CycleDay from './components/cycle-day/cycle-day-overview' +import SymptomView from './components/cycle-day/symptoms' import Chart from './components/chart/chart' import Settings from './components/settings' import Stats from './components/stats' @@ -14,9 +15,11 @@ import styles, { primaryColor } from './styles' import { YellowBox } from 'react-native' YellowBox.ignoreWarnings(['Warning: isMounted(...) is deprecated']) +const CycleDayStack = createStackNavigator({CycleDay, SymptomView}, {headerMode: 'none'}) + const routes = { - Home: createStackNavigator({Home, CycleDay}, {headerMode: 'none'}), - Calendar: createStackNavigator({Calendar, CycleDay}, {headerMode: 'none'}), + Home: createStackNavigator({Home, CycleDayStack}, {headerMode: 'none'}), + Calendar: createStackNavigator({Calendar, CycleDayStack}, {headerMode: 'none'}), Chart: createStackNavigator({Chart, CycleDay}, {headerMode: 'none'}), Settings: { screen: Settings }, Stats: { screen: Stats} diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 19e0084..35e1e3f 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -1,11 +1,17 @@ import React, { Component } from 'react' import { + ScrollView, View, Text, TouchableOpacity, Dimensions } from 'react-native' +import { LocalDate } from 'js-joda' +import { getOrCreateCycleDay } from '../../db' +import cycleModule from '../../lib/cycle' import Icon from 'react-native-vector-icons/FontAwesome' +import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons' +import { formatDateForViewHeader } from './labels/format' import styles, { iconStyles } from '../../styles' import { bleeding as bleedingLabels, @@ -18,50 +24,98 @@ import { intensity as intensityLabels } from './labels/labels' -export default class DayView extends Component { +const getCycleDayNumber = cycleModule().getCycleDayNumber + +export default class CycleDayOverView extends Component { + constructor(props) { + super(props) + this.state = { + cycleDay: props.navigation.state.params.cycleDay + } + } + + goToCycleDay(target) { + const localDate = LocalDate.parse(this.state.cycleDay.date) + const targetDate = target === 'before' ? + localDate.minusDays(1).toString() : + localDate.plusDays(1).toString() + this.setState({cycleDay: getOrCreateCycleDay(targetDate)}) + } + + navigate(symptom) { + this.props.navigation.navigate('SymptomView', { + symptom, + cycleDay: this.state.cycleDay + }) + } + render() { - const cycleDay = this.props.cycleDay + const cycleDay = this.state.cycleDay + const cycleDayNumber = getCycleDayNumber(cycleDay.date) return ( - - this.props.showView('BleedingEditView')} - data={getLabel('bleeding', cycleDay.bleeding)} - /> - this.props.showView('TemperatureEditView')} - data={getLabel('temperature', cycleDay.temperature)} - /> - this.props.showView('MucusEditView')} - data={getLabel('mucus', cycleDay.mucus)} - /> - this.props.showView('CervixEditView')} - data={getLabel('cervix', cycleDay.cervix)} - /> - this.props.showView('NoteEditView')} - data={getLabel('note', cycleDay.note)} - /> - this.props.showView('DesireEditView')} - data={getLabel('desire', cycleDay.desire)} - /> - this.props.showView('SexEditView')} - data={getLabel('sex', cycleDay.sex)} - /> - {/* this is just to make the last row adhere to the grid + + + this.goToCycleDay('before')} + /> + + + {formatDateForViewHeader(cycleDay.date)} + + {cycleDayNumber && + + Cycle day {cycleDayNumber} + } + + this.goToCycleDay('after')} + /> + + + this.navigate('BleedingEditView')} + data={getLabel('bleeding', cycleDay.bleeding)} + /> + this.navigate('TemperatureEditView')} + data={getLabel('temperature', cycleDay.temperature)} + /> + this.navigate('MucusEditView')} + data={getLabel('mucus', cycleDay.mucus)} + /> + this.navigate('CervixEditView')} + data={getLabel('cervix', cycleDay.cervix)} + /> + this.navigate('NoteEditView')} + data={getLabel('note', cycleDay.note)} + /> + this.navigate('DesireEditView')} + data={getLabel('desire', cycleDay.desire)} + /> + this.navigate('SexEditView')} + data={getLabel('sex', cycleDay.sex)} + /> + {/* this is just to make the last row adhere to the grid (and) because there are no pseudo properties in RN */} - - + + + ) } } diff --git a/components/cycle-day/index.js b/components/cycle-day/index.js deleted file mode 100644 index d162a26..0000000 --- a/components/cycle-day/index.js +++ /dev/null @@ -1,91 +0,0 @@ -import React, { Component } from 'react' -import { - View, - Text, - ScrollView -} from 'react-native' -import Icon from 'react-native-vector-icons/MaterialCommunityIcons' -import cycleModule from '../../lib/cycle' -import { formatDateForViewHeader } from './labels/format' -import styles, { iconStyles } from '../../styles' -import actionButtonModule from './action-buttons' -import symptomComponents from './symptoms' -import DayView from './cycle-day-overview' -import { LocalDate } from 'js-joda' -import { getOrCreateCycleDay } from '../../db' - -const getCycleDayNumber = cycleModule().getCycleDayNumber -const symptomComponentNames = Object.keys(symptomComponents) - -export default class Day extends Component { - constructor(props) { - super(props) - - this.state = { - visibleComponent: 'DayView', - cycleDay: props.navigation.state.params.cycleDay - } - - this.showView = view => { - this.setState({visibleComponent: view}) - } - this.makeActionButtons = actionButtonModule(this.showView) - } - - goToCycleDay(target) { - const localDate = LocalDate.parse(this.state.cycleDay.date) - const targetDate = target === 'before' ? - localDate.minusDays(1).toString() : - localDate.plusDays(1).toString() - this.setState({cycleDay: getOrCreateCycleDay(targetDate)}) - } - - render() { - const cycleDayNumber = getCycleDayNumber(this.state.cycleDay.date) - const cycleDayViews = symptomComponentNames.reduce((acc, curr) => { - acc[curr] = React.createElement( - symptomComponents[curr], - { - cycleDay: this.state.cycleDay, - makeActionButtons: this.makeActionButtons - } - ) - return acc - }, {}) - // DayView needs showView instead of makeActionButtons - cycleDayViews.DayView = React.createElement(DayView, { - dateString: this.state.cycleDay.date, - cycleDay: this.state.cycleDay, - showView: this.showView - }) - - return ( - - - this.goToCycleDay('before')} - /> - - - {formatDateForViewHeader(this.state.cycleDay.date)} - - {cycleDayNumber && - - Cycle day {cycleDayNumber} - } - - this.goToCycleDay('after')} - /> - - - { cycleDayViews[this.state.visibleComponent] } - - - ) - } -} \ No newline at end of file diff --git a/components/cycle-day/symptoms/index.js b/components/cycle-day/symptoms/index.js index c3583df..3c0f834 100644 --- a/components/cycle-day/symptoms/index.js +++ b/components/cycle-day/symptoms/index.js @@ -1,3 +1,11 @@ +import React, { Component } from 'react' +import { + View, + Text, + ScrollView +} from 'react-native' +import styles from '../../../styles' +import actionButtonModule from '../action-buttons' import BleedingEditView from './bleeding' import TemperatureEditView from './temperature' import MucusEditView from './mucus' @@ -6,7 +14,7 @@ import NoteEditView from './note' import DesireEditView from './desire' import SexEditView from './sex' -export default { +const symptomViews = { BleedingEditView, TemperatureEditView, MucusEditView, @@ -15,3 +23,49 @@ export default { DesireEditView, 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.navigation.state.params.symptom, + cycleDay: props.navigation.state.params.cycleDay + } + + this.showView = view => { + this.setState({visibleComponent: view}) + } + this.makeActionButtons = actionButtonModule(this.showView) + } + + render() { + return ( + + + + + {titles[this.state.visibleComponent]} + + + + {React.createElement( + symptomViews[this.state.visibleComponent], + { + cycleDay: this.state.cycleDay, + makeActionButtons: this.makeActionButtons + } + )} + + ) + } +} From 51629f67e2d7a6d823be611fff6a3a6e998ab461 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 17 Aug 2018 16:26:00 +0200 Subject: [PATCH 07/28] Place header as component --- components/calendar.js | 16 +++++--- components/cycle-day/cycle-day-overview.js | 32 ++++------------ components/cycle-day/symptoms/index.js | 16 ++------ components/header.js | 43 ++++++++++++++++++++++ components/home.js | 2 + components/settings.js | 2 + components/stats.js | 2 + styles/index.js | 5 ++- 8 files changed, 73 insertions(+), 45 deletions(-) create mode 100644 components/header.js diff --git a/components/calendar.js b/components/calendar.js index 4aa7f13..dbff83c 100644 --- a/components/calendar.js +++ b/components/calendar.js @@ -1,6 +1,7 @@ import React, { Component } from 'react' import { View } from 'react-native' import { CalendarList } from 'react-native-calendars' +import Header from './header' import * as styles from '../styles' import { getOrCreateCycleDay, bleedingDaysSortedByDate } from '../db' @@ -34,12 +35,15 @@ export default class CalendarView extends Component { render() { return ( - - + +
+ + + ) } diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 35e1e3f..78178fe 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -7,11 +7,10 @@ import { Dimensions } from 'react-native' import { LocalDate } from 'js-joda' +import Header from '../header' import { getOrCreateCycleDay } from '../../db' import cycleModule from '../../lib/cycle' import Icon from 'react-native-vector-icons/FontAwesome' -import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons' -import { formatDateForViewHeader } from './labels/format' import styles, { iconStyles } from '../../styles' import { bleeding as bleedingLabels, @@ -24,8 +23,6 @@ import { intensity as intensityLabels } from './labels/labels' -const getCycleDayNumber = cycleModule().getCycleDayNumber - export default class CycleDayOverView extends Component { constructor(props) { super(props) @@ -51,30 +48,15 @@ export default class CycleDayOverView extends Component { render() { const cycleDay = this.state.cycleDay + const getCycleDayNumber = cycleModule().getCycleDayNumber const cycleDayNumber = getCycleDayNumber(cycleDay.date) return ( - - this.goToCycleDay('before')} - /> - - - {formatDateForViewHeader(cycleDay.date)} - - {cycleDayNumber && - - Cycle day {cycleDayNumber} - } - - this.goToCycleDay('after')} - /> - +
- - - - {titles[this.state.visibleComponent]} - - - +
{React.createElement( symptomViews[this.state.visibleComponent], { diff --git a/components/header.js b/components/header.js new file mode 100644 index 0000000..1fd285e --- /dev/null +++ b/components/header.js @@ -0,0 +1,43 @@ +import React, { Component } from 'react' +import { + View, + Text +} from 'react-native' +import styles, { iconStyles } from '../styles' +import Icon from 'react-native-vector-icons/MaterialCommunityIcons' +import { formatDateForViewHeader } from '../components/cycle-day/labels/format' + +export default class Header extends Component { + render() { + return ( + this.props.cycleDayOverView ? + + this.goToCycleDay('before')} + /> + + + {formatDateForViewHeader(this.props.date)} + + {this.props.cycleDayNumber && + + Cycle day {this.props.cycleDayNumber} + } + + this.goToCycleDay('after')} + /> + + : + + + {this.props.title} + + + ) + } +} \ No newline at end of file diff --git a/components/home.js b/components/home.js index 5381e3b..9c8d14f 100644 --- a/components/home.js +++ b/components/home.js @@ -6,6 +6,7 @@ import { ScrollView } from 'react-native' import { LocalDate } from 'js-joda' +import Header from './header' import styles from '../styles/index' import cycleModule from '../lib/cycle' import { getOrCreateCycleDay, bleedingDaysSortedByDate, fillWithDummyData, deleteAll } from '../db' @@ -48,6 +49,7 @@ export default class Home extends Component { render() { return ( +
{this.state.welcomeText} diff --git a/components/settings.js b/components/settings.js index 97907b1..3552872 100644 --- a/components/settings.js +++ b/components/settings.js @@ -9,6 +9,7 @@ import { import Share from 'react-native-share' import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker' import rnfs from 'react-native-fs' +import Header from './header' import styles from '../styles/index' import { settings as labels } from './labels' import getDataAsCsvDataUri from '../lib/import-export/export-to-csv' @@ -18,6 +19,7 @@ export default class Settings extends Component { render() { return ( +
+ + ) + })} + + ) + } +} \ No newline at end of file From 86f26e3814041b0036e24997fa3ff1b87136de13 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Sun, 19 Aug 2018 15:02:01 +0200 Subject: [PATCH 13/28] Position footer and fix navigating to cycle day view --- app.js | 27 +++++++++++++++------- components/cycle-day/cycle-day-overview.js | 6 ++--- components/header.js | 2 +- components/home.js | 3 +-- components/menu.js | 6 +++++ styles/index.js | 3 ++- 6 files changed, 32 insertions(+), 15 deletions(-) diff --git a/app.js b/app.js index 58b22ae..ec6f308 100644 --- a/app.js +++ b/app.js @@ -23,16 +23,24 @@ export default class App extends Component { } } - navigate(pageName) { - this.setState({currentPage: pageName}) + navigate(pageName, props) { + this.setState({currentPage: pageName, currentProps: props}) } render() { return ( - -
- - + + + {this.state.currentPage != 'CycleDay' &&
} + + + + + ) } @@ -40,10 +48,13 @@ export default class App extends Component { class CurrentPage extends Component { render () { - console.log('urrentpage render') const page = { Home, Calendar, CycleDay, SymptomView, Chart, Settings, Stats }[this.props.page] - return React.createElement(page) + const props = this.props.props || {} + return React.createElement(page, { + navigate: this.props.navigate, + ...props + }) } } \ No newline at end of file diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 0dfa769..0076aa2 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -27,7 +27,7 @@ export default class CycleDayOverView extends Component { constructor(props) { super(props) this.state = { - cycleDay: props.navigation.state.params.cycleDay + cycleDay: props.cycleDay } } @@ -40,7 +40,7 @@ export default class CycleDayOverView extends Component { } navigate(symptom) { - this.props.navigation.navigate('SymptomView', { + this.props.navigate('SymptomView', { symptom, cycleDay: this.state.cycleDay }) @@ -53,7 +53,7 @@ export default class CycleDayOverView extends Component { return (
diff --git a/components/header.js b/components/header.js index 1fd285e..5863e43 100644 --- a/components/header.js +++ b/components/header.js @@ -10,7 +10,7 @@ import { formatDateForViewHeader } from '../components/cycle-day/labels/format' export default class Header extends Component { render() { return ( - this.props.cycleDayOverView ? + this.props.isCycleDayOverView ? + this.props.navigate('Home')} + > + {'Home'} + this.props.navigate('Calendar')} diff --git a/styles/index.js b/styles/index.js index 5fb3d5d..8943efa 100644 --- a/styles/index.js +++ b/styles/index.js @@ -106,7 +106,8 @@ export default StyleSheet.create({ paddingVertical: 18, paddingHorizontal: 15, alignItems: 'center', - justifyContent: 'center' + justifyContent: 'space-evenly', + flexDirection: 'row', }, headerCycleDay: { flexDirection: 'row', From a67bfda43f65d5745bb19f32a6f9e8a078cc49eb Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Sun, 19 Aug 2018 16:11:01 +0200 Subject: [PATCH 14/28] Handle back button presses --- app.js | 16 +++++++++++++++- components/calendar.js | 2 -- components/cycle-day/symptoms/index.js | 19 +++++++++++++++---- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/app.js b/app.js index ec6f308..2cfc07e 100644 --- a/app.js +++ b/app.js @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { View } from 'react-native' +import { View, BackHandler } from 'react-native' import Header from './components/header' import Menu from './components/menu' import Home from './components/home' @@ -21,6 +21,20 @@ export default class App extends Component { this.state = { currentPage: 'Home' } + + const handleBackButtonPress = function() { + if (this.state.currentPage === 'Home') return false + // this is handled in the SymptomView + if (this.state.currentPage === 'SymptomView') return true + this.navigate('Home') + return true + }.bind(this) + + this.backHandler = BackHandler.addEventListener('hardwareBackPress', handleBackButtonPress) + } + + componentWillUnmount() { + this.backHandler.remove() } navigate(pageName, props) { diff --git a/components/calendar.js b/components/calendar.js index 3159b0c..0744872 100644 --- a/components/calendar.js +++ b/components/calendar.js @@ -10,7 +10,6 @@ export default class CalendarView extends Component { this.state = { bleedingDaysInCalFormat: toCalFormat(bleedingDaysSortedByDate) } - console.log(Object.keys(this.state.bleedingDaysInCalFormat)) this.setStateWithCalFormattedDays = (function (CalendarComponent) { return function(_, changes) { @@ -35,7 +34,6 @@ export default class CalendarView extends Component { } render() { - console.log('cal render') return ( diff --git a/components/cycle-day/symptoms/index.js b/components/cycle-day/symptoms/index.js index 5b73d85..4ce4010 100644 --- a/components/cycle-day/symptoms/index.js +++ b/components/cycle-day/symptoms/index.js @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { ScrollView } from 'react-native' +import { ScrollView, BackHandler } from 'react-native' import Header from '../../header' import actionButtonModule from '../action-buttons' import BleedingEditView from './bleeding' @@ -34,13 +34,24 @@ export default class SymptomView extends Component { super(props) this.state = { - visibleComponent: props.navigation.state.params.symptom, - cycleDay: props.navigation.state.params.cycleDay + visibleComponent: props.symptom, + cycleDay: props.cycleDay } this.makeActionButtons = actionButtonModule(() => { - this.props.navigation.navigate('CycleDay', {cycleDay: this.state.cycleDay}) + 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() { From d731bbbec4a38484371810d87c1a747cfffd8db1 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Sun, 19 Aug 2018 16:31:23 +0200 Subject: [PATCH 15/28] Add remaining menu items and icons --- components/menu.js | 39 ++++++++++++++++++++------------------- styles/index.js | 11 +++++++++-- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/components/menu.js b/components/menu.js index 9631c02..d7cb1d4 100644 --- a/components/menu.js +++ b/components/menu.js @@ -13,27 +13,28 @@ export default class Menu extends Component { placeActionButtons() : - this.props.navigate('Home')} - > - {'Home'} - - this.props.navigate('Calendar')} - > - {'Calendar'} - - this.props.navigate('Settings')} - > - {'Settings'} - + {[ + {title: 'Home', icon: 'home', componentName: 'Home'}, + {title: 'Calendar', icon: 'calendar-range', componentName: 'Calendar'}, + {title: 'Chart', icon: 'chart-line', componentName: 'Chart'}, + {title: 'Stats', icon: 'chart-pie', componentName: 'Stats'}, + {title: 'Settings', icon: 'settings', componentName: 'Settings'}, + ].map(makeMenuItem)} ) } } -function placeActionButtons() {} \ No newline at end of file +function makeMenuItem({title, icon, componentName}) { + return ( + + + this.props.navigate(componentName)} + > + {title} + + + ) +} \ No newline at end of file diff --git a/styles/index.js b/styles/index.js index 8943efa..42784d9 100644 --- a/styles/index.js +++ b/styles/index.js @@ -104,11 +104,14 @@ export default StyleSheet.create({ menu: { backgroundColor: primaryColor, paddingVertical: 18, - paddingHorizontal: 15, + paddingHorizontal: 10, alignItems: 'center', - justifyContent: 'space-evenly', + justifyContent: 'space-between', flexDirection: 'row', }, + menuText: { + color: fontOnPrimaryColor + }, headerCycleDay: { flexDirection: 'row', justifyContent: 'space-between' @@ -163,5 +166,9 @@ export const iconStyles = { }, symptomBoxActive: { color: fontOnPrimaryColor + }, + menuIcon: { + size: 20, + color: fontOnPrimaryColor } } \ No newline at end of file From c744520bd95d938c35b7121a000e50a7694d1fe5 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Sun, 19 Aug 2018 16:37:37 +0200 Subject: [PATCH 16/28] Fix menu bug --- components/menu.js | 32 ++++++++++++++++---------------- components/settings.js | 2 -- components/stats.js | 1 - 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/components/menu.js b/components/menu.js index d7cb1d4..3cf8b10 100644 --- a/components/menu.js +++ b/components/menu.js @@ -1,12 +1,26 @@ import React, { Component } from 'react' import { View, - Text + Text, + TouchableOpacity } from 'react-native' import styles, { iconStyles } from '../styles' import Icon from 'react-native-vector-icons/MaterialCommunityIcons' export default class Menu extends Component { + makeMenuItem({ title, icon, componentName }) { + return ( + this.props.navigate(componentName)} + style={{ alignItems: 'center' }} + > + + + {title} + + + ) + } render() { return ( this.props.symptomView ? @@ -19,22 +33,8 @@ export default class Menu extends Component { {title: 'Chart', icon: 'chart-line', componentName: 'Chart'}, {title: 'Stats', icon: 'chart-pie', componentName: 'Stats'}, {title: 'Settings', icon: 'settings', componentName: 'Settings'}, - ].map(makeMenuItem)} + ].map(this.makeMenuItem.bind(this))} ) } } - -function makeMenuItem({title, icon, componentName}) { - return ( - - - this.props.navigate(componentName)} - > - {title} - - - ) -} \ No newline at end of file diff --git a/components/settings.js b/components/settings.js index 3552872..97907b1 100644 --- a/components/settings.js +++ b/components/settings.js @@ -9,7 +9,6 @@ import { import Share from 'react-native-share' import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker' import rnfs from 'react-native-fs' -import Header from './header' import styles from '../styles/index' import { settings as labels } from './labels' import getDataAsCsvDataUri from '../lib/import-export/export-to-csv' @@ -19,7 +18,6 @@ export default class Settings extends Component { render() { return ( -
- - ) - }) - } -} \ No newline at end of file diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 0076aa2..9ab3225 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -40,9 +40,8 @@ export default class CycleDayOverView extends Component { } navigate(symptom) { - this.props.navigate('SymptomView', { - symptom, - cycleDay: this.state.cycleDay + this.props.navigate(symptom, { + cycleDay: this.state.cycleDay, }) } diff --git a/components/cycle-day/symptoms/action-button-footer.js b/components/cycle-day/symptoms/action-button-footer.js index 0f05a7b..be0cd6a 100644 --- a/components/cycle-day/symptoms/action-button-footer.js +++ b/components/cycle-day/symptoms/action-button-footer.js @@ -1,19 +1,20 @@ import React, { Component } from 'react' import { - View, - Button, + View, TouchableOpacity, Text } from 'react-native' +import Icon from 'react-native-vector-icons/MaterialCommunityIcons' import { saveSymptom } from '../../../db' -import styles from '../../../styles' +import styles, {iconStyles} from '../../../styles' export default class ActionButtonFooter extends Component { render() { const { symptom, cycleDay, saveAction, saveDisabled, navigate} = this.props - const navigateToOverView = () => navigate('CycleDay', cycleDay) + const navigateToOverView = () => navigate('CycleDay', {cycleDay}) const buttons = [ { title: 'Cancel', - action: () => navigateToOverView() + action: () => navigateToOverView(), + icon: 'cancel' }, { title: 'Delete', @@ -21,31 +22,34 @@ export default class ActionButtonFooter extends Component { saveSymptom(symptom, cycleDay) navigateToOverView() }, - disabledCondition: !cycleDay[symptom] + disabledCondition: !cycleDay[symptom], + icon: 'delete-outline' }, { title: 'Save', action: () => { saveAction() navigateToOverView() }, - disabledCondition: saveDisabled + disabledCondition: saveDisabled, + icon: 'content-save-outline' } ] 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 + + {buttons.map(({ title, action, disabledCondition, icon }, i) => { return ( - - - + + + + {title} + + ) })} diff --git a/components/cycle-day/symptoms/index.js b/components/cycle-day/symptoms/index.js index 4ce4010..12622b7 100644 --- a/components/cycle-day/symptoms/index.js +++ b/components/cycle-day/symptoms/index.js @@ -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 TemperatureEditView from './temperature' import MucusEditView from './mucus' @@ -10,7 +6,7 @@ import NoteEditView from './note' import DesireEditView from './desire' import SexEditView from './sex' -const symptomViews = { +export default { BleedingEditView, TemperatureEditView, MucusEditView, @@ -18,54 +14,4 @@ const symptomViews = { NoteEditView, DesireEditView, 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 ( - -
- {React.createElement( - symptomViews[this.state.visibleComponent], - { - cycleDay: this.state.cycleDay, - makeActionButtons: this.makeActionButtons - } - )} - - ) - } -} +} \ No newline at end of file diff --git a/components/cycle-day/symptoms/temperature.js b/components/cycle-day/symptoms/temperature.js index 7296883..a7bd55e 100644 --- a/components/cycle-day/symptoms/temperature.js +++ b/components/cycle-day/symptoms/temperature.js @@ -4,7 +4,7 @@ import { Text, TextInput, Switch, - Keyboard + Keyboard, } from 'react-native' 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(), 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() { - const cycleDay = this.cycleDay return ( @@ -61,7 +78,7 @@ export default class Temp extends Component { style={styles.temperatureTextInput} onFocus={() => { Keyboard.dismiss() - this.setState({isTimePickerVisible: true}) + this.setState({ isTimePickerVisible: true }) }} value={this.state.time} /> @@ -75,7 +92,7 @@ export default class Temp extends Component { isTimePickerVisible: false }) }} - onCancel={() => this.setState({isTimePickerVisible: false})} + onCancel={() => this.setState({ isTimePickerVisible: false })} /> Exclude @@ -86,21 +103,6 @@ export default class Temp extends Component { value={this.state.exclude} /> - - {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) - })} - ) } diff --git a/components/menu.js b/components/menu.js index 1a8bed7..8a55187 100644 --- a/components/menu.js +++ b/components/menu.js @@ -8,11 +8,12 @@ import styles, { iconStyles } from '../styles' import Icon from 'react-native-vector-icons/MaterialCommunityIcons' export default class Menu extends Component { - makeMenuItem({ title, icon, componentName }) { + makeMenuItem({ title, icon, onPress}, i) { return ( this.props.navigate(componentName)} + onPress={onPress} style={styles.menuItem} + key={i.toString()} > @@ -21,20 +22,22 @@ export default class Menu extends Component { ) } + + goTo(componentName) { + this.props.navigate(componentName) + } + render() { return ( - this.props.symptomView ? - placeActionButtons() - : - - {[ - {title: 'Home', icon: 'home', componentName: 'Home'}, - {title: 'Calendar', icon: 'calendar-range', componentName: 'Calendar'}, - {title: 'Chart', icon: 'chart-line', componentName: 'Chart'}, - {title: 'Stats', icon: 'chart-pie', componentName: 'Stats'}, - {title: 'Settings', icon: 'settings', componentName: 'Settings'}, - ].map(this.makeMenuItem.bind(this))} - + + {[ + { title: 'Home', icon: 'home', onPress: () => this.goTo('Home') }, + { title: 'Calendar', icon: 'calendar-range', onPress: () => this.goTo('Calendar') }, + { title: 'Chart', icon: 'chart-line', onPress: () => this.goTo('Chart') }, + { title: 'Stats', icon: 'chart-pie', onPress: () => this.goTo('Stats') }, + { title: 'Settings', icon: 'settings', onPress: () => this.goTo('Settings') }, + ].map(this.makeMenuItem.bind(this))} + ) } } From 8629fd53691184c2b3a962d3bcc83f9268a40aa0 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Mon, 20 Aug 2018 13:44:05 +0200 Subject: [PATCH 19/28] Replace action button footer in remaining symptom views --- app.js | 42 +--- components/cycle-day/symptoms/bleeding.js | 32 ++- components/cycle-day/symptoms/cervix.js | 136 +++++------ components/cycle-day/symptoms/desire.js | 50 ++-- components/cycle-day/symptoms/mucus.js | 125 +++++----- components/cycle-day/symptoms/note.js | 28 +-- components/cycle-day/symptoms/sex.js | 238 +++++++++---------- components/cycle-day/symptoms/temperature.js | 113 +++++---- components/stats.js | 1 - styles/index.js | 4 + 10 files changed, 375 insertions(+), 394 deletions(-) diff --git a/app.js b/app.js index b6e9ff5..fe0f57c 100644 --- a/app.js +++ b/app.js @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { View, BackHandler, ScrollView } from 'react-native' +import { View, BackHandler } from 'react-native' import Header from './components/header' import Menu from './components/menu' import Home from './components/home' @@ -9,11 +9,11 @@ import symptomViews from './components/cycle-day/symptoms' import Chart from './components/chart/chart' import Settings from './components/settings' import Stats from './components/stats' +import styles from './styles' // this is until react native fixes this bugg, see // https://github.com/facebook/react-native/issues/18868#issuecomment-382671739 import { YellowBox } from 'react-native' -import ActionButtonFooter from './components/cycle-day/symptoms/action-button-footer'; YellowBox.ignoreWarnings(['Warning: isMounted(...) is deprecated']) const isSymptomView = name => Object.keys(symptomViews).indexOf(name) > -1 @@ -46,38 +46,22 @@ export default class App extends Component { this.setState({currentPage: pageName, currentProps: props}) } - setActionButtonState(actionButtonInfo) { - this.setState({actionButtonInfo}) - } - - unsetActionButtonState() { - this.setState({actionButtonInfo: null}) - } - render() { const page = { Home, Calendar, CycleDay, Chart, Settings, Stats, ...symptomViews }[this.state.currentPage] return ( - - - {this.state.currentPage != 'CycleDay' &&
} - - {React.createElement(page, { - navigate: this.navigate.bind(this), - setActionButtonState: this.setActionButtonState.bind(this), - unsetActionButtonState: this.unsetActionButtonState.bind(this), - ...this.state.currentProps - })} - - - {isSymptomView(this.state.currentPage) && this.state.actionButtonInfo ? - - : - + + + {this.state.currentPage != 'CycleDay' &&
} + + {React.createElement(page, { + navigate: this.navigate.bind(this), + ...this.state.currentProps + })} + + {!isSymptomView(this.state.currentPage) && + } ) diff --git a/components/cycle-day/symptoms/bleeding.js b/components/cycle-day/symptoms/bleeding.js index ffd1836..ce27ba1 100644 --- a/components/cycle-day/symptoms/bleeding.js +++ b/components/cycle-day/symptoms/bleeding.js @@ -8,6 +8,7 @@ import RadioForm from 'react-native-simple-radio-button' import styles from '../../../styles' import { saveSymptom } from '../../../db' import { bleeding as labels } from '../labels/labels' +import ActionButtonFooter from './action-button-footer' export default class Bleeding extends Component { constructor(props) { @@ -32,8 +33,8 @@ export default class Bleeding extends Component { { label: labels[3], value: 3 }, ] return ( - - + + Bleeding - - {this.makeActionButtons( - { - symptom: 'bleeding', - cycleDay: this.cycleDay, - saveAction: () => { - saveSymptom('bleeding', this.cycleDay, { - value: this.state.currentValue, - exclude: this.state.exclude - }) - }, - saveDisabled: this.state.currentValue === -1 - } - )} - + { + saveSymptom('bleeding', this.props.cycleDay, { + value: this.state.currentValue, + exclude: this.state.exclude + }) + }} + saveDisabled={this.state.currentValue === -1} + navigate={this.props.navigate} + /> ) } diff --git a/components/cycle-day/symptoms/cervix.js b/components/cycle-day/symptoms/cervix.js index 59d9d8b..2de5582 100644 --- a/components/cycle-day/symptoms/cervix.js +++ b/components/cycle-day/symptoms/cervix.js @@ -12,6 +12,7 @@ import { cervixFirmness as firmnessLabels, cervixPosition as positionLabels } from '../labels/labels' +import ActionButtonFooter from './action-button-footer' export default class Cervix extends Component { constructor(props) { @@ -45,76 +46,75 @@ export default class Cervix extends Component { const cervixPositionRadioProps = [ {label: positionLabels[0], value: 0 }, {label: positionLabels[1], value: 1 }, - {label: positionLabels[2], value: 2 } + { label: positionLabels[2], value: 2 } ] - return( - - Cervix - Opening - - { - this.setState({opening: itemValue}) - }} - /> - - Firmness - - { - this.setState({firmness: itemValue}) - }} - /> - - Position - - { - this.setState({position: itemValue}) - }} - /> - - - Exclude - { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> - - - {this.makeActionButtons( - { - symptom: 'cervix', - cycleDay: this.cycleDay, - saveAction: () => { - saveSymptom('cervix', this.cycleDay, { - opening: this.state.opening, - firmness: this.state.firmness, - position: this.state.position, - exclude: this.state.exclude - }) - }, - saveDisabled: this.state.opening === -1 || this.state.firmness === -1 - } - )} + return ( + + + Cervix + Opening + + { + this.setState({ opening: itemValue }) + }} + /> + + Firmness + + { + this.setState({ firmness: itemValue }) + }} + /> + + Position + + { + this.setState({ position: itemValue }) + }} + /> + + + Exclude + { + this.setState({ exclude: val }) + }} + value={this.state.exclude} + /> + + { + saveSymptom('cervix', this.cycleDay, { + opening: this.state.opening, + firmness: this.state.firmness, + position: this.state.position, + exclude: this.state.exclude + }) + }} + saveDisabled={this.state.opening === -1 || this.state.firmness === -1} + navigate={this.props.navigate} + /> ) } diff --git a/components/cycle-day/symptoms/desire.js b/components/cycle-day/symptoms/desire.js index 58a7ceb..351dc97 100644 --- a/components/cycle-day/symptoms/desire.js +++ b/components/cycle-day/symptoms/desire.js @@ -7,6 +7,7 @@ import RadioForm from 'react-native-simple-radio-button' import styles from '../../../styles' import { saveSymptom } from '../../../db' import { intensity as labels } from '../labels/labels' +import ActionButtonFooter from './action-button-footer' export default class Desire extends Component { constructor(props) { @@ -27,32 +28,31 @@ export default class Desire extends Component { { label: labels[2], value: 2 } ] return ( - - Desire - - { - this.setState({ currentValue: itemValue }) - }} - /> - - - {this.makeActionButtons( - { - symptom: 'desire', - cycleDay: this.cycleDay, - saveAction: () => { - saveSymptom('desire', this.cycleDay, { value: this.state.currentValue }) - }, - saveDisabled: this.state.currentValue === -1 - } - )} + + + Desire + + { + this.setState({ currentValue: itemValue }) + }} + /> + + { + saveSymptom('desire', this.cycleDay, { value: this.state.currentValue }) + }} + saveDisabled={this.state.currentValue === -1} + navigate={this.props.navigate} + /> ) } diff --git a/components/cycle-day/symptoms/mucus.js b/components/cycle-day/symptoms/mucus.js index abafe56..2df033d 100644 --- a/components/cycle-day/symptoms/mucus.js +++ b/components/cycle-day/symptoms/mucus.js @@ -12,6 +12,7 @@ import { mucusTexture as textureLabels } from '../labels/labels' import computeSensiplanValue from '../../../lib/sensiplan-mucus' +import ActionButtonFooter from './action-button-footer' export default class Mucus extends Component { @@ -31,78 +32,74 @@ export default class Mucus extends Component { } }) /* eslint-enable react/no-direct-mutation-state */ - } render() { const mucusFeelingRadioProps = [ - {label: feelingLabels[0], value: 0 }, - {label: feelingLabels[1], value: 1 }, - {label: feelingLabels[2], value: 2 }, - {label: feelingLabels[3], value: 3 } + { label: feelingLabels[0], value: 0 }, + { label: feelingLabels[1], value: 1 }, + { label: feelingLabels[2], value: 2 }, + { label: feelingLabels[3], value: 3 } ] const mucusTextureRadioProps = [ - {label: textureLabels[0], value: 0 }, - {label: textureLabels[1], value: 1 }, - {label: textureLabels[2], value: 2 } + { label: textureLabels[0], value: 0 }, + { label: textureLabels[1], value: 1 }, + { label: textureLabels[2], value: 2 } ] - return( - - Mucus - Feeling - - { - this.setState({feeling: itemValue }) - }} - /> + return ( + + + Mucus + Feeling + + { + this.setState({ feeling: itemValue }) + }} + /> + + Texture + + { + this.setState({ texture: itemValue }) + }} + /> + + + Exclude + { + this.setState({ exclude: val }) + }} + value={this.state.exclude} + /> + - Texture - - { - this.setState({texture: itemValue }) - }} - /> - - - Exclude - { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> - - - - {this.makeActionButtons( - { - symptom: 'mucus', - cycleDay: this.cycleDay, - saveAction: () => { - saveSymptom('mucus', this.cycleDay, { - feeling: this.state.feeling, - texture: this.state.texture, - value: computeSensiplanValue(this.state.feeling, this.state.texture), - exclude: this.state.exclude - }) - }, - saveDisabled: this.state.feeling === -1 || this.state.texture === -1 - } - )} - - + { + saveSymptom('mucus', this.cycleDay, { + feeling: this.state.feeling, + texture: this.state.texture, + value: computeSensiplanValue(this.state.feeling, this.state.texture), + exclude: this.state.exclude + }) + }} + saveDisabled={this.state.feeling === -1 || this.state.texture === -1} + navigate={this.props.navigate} + /> ) } diff --git a/components/cycle-day/symptoms/note.js b/components/cycle-day/symptoms/note.js index 1796600..6100a7a 100644 --- a/components/cycle-day/symptoms/note.js +++ b/components/cycle-day/symptoms/note.js @@ -7,6 +7,7 @@ import { import styles from '../../../styles' import { saveSymptom } from '../../../db' +import ActionButtonFooter from './action-button-footer' export default class Temp extends Component { constructor(props) { @@ -22,7 +23,7 @@ export default class Temp extends Component { render() { return ( - + Note - - {this.makeActionButtons({ - symptom: 'note', - cycleDay: this.cycleDay, - saveAction: () => { - saveSymptom('note', this.cycleDay, { - value: this.state.currentValue - }) - }, - saveDisabled: !this.state.currentValue - })} - + { + saveSymptom('note', this.cycleDay, { + value: this.state.currentValue + }) + }} + saveDisabled={!this.state.currentValue} + navigate={this.props.navigate} + /> ) } -} +} \ No newline at end of file diff --git a/components/cycle-day/symptoms/sex.js b/components/cycle-day/symptoms/sex.js index d9ec336..9adb224 100644 --- a/components/cycle-day/symptoms/sex.js +++ b/components/cycle-day/symptoms/sex.js @@ -11,6 +11,7 @@ import { sexActivity as activityLabels, contraceptives as contraceptiveLabels } from '../labels/labels' +import ActionButtonFooter from './action-button-footer' export default class Sex extends Component { constructor(props) { @@ -30,127 +31,126 @@ export default class Sex extends Component { render() { return ( - - SEX - - {activityLabels.solo} - { - this.setState({solo: val}) - }} - /> - {activityLabels.partner} - { - this.setState({partner: val}) - }} - /> + + + SEX + + {activityLabels.solo} + { + this.setState({ solo: val }) + }} + /> + {activityLabels.partner} + { + this.setState({ partner: val }) + }} + /> + + CONTRACEPTIVES + + + {contraceptiveLabels.condom} + + { + this.setState({ condom: val }) + }} + /> + + {contraceptiveLabels.pill} + + { + this.setState({ pill: val }) + }} + /> + + + + {contraceptiveLabels.iud} + + { + this.setState({ iud: val }) + }} + /> + + {contraceptiveLabels.patch} + + { + this.setState({ patch: val }) + }} + /> + + + + {contraceptiveLabels.ring} + + { + this.setState({ ring: val }) + }} + /> + + {contraceptiveLabels.implant} + + { + this.setState({ implant: val }) + }} + /> + + + + {contraceptiveLabels.other} + + { + this.setState({ + other: val, + focusTextArea: true + }) + }} + /> + + {this.state.other && + { + this.setState({ note: val }) + }} + /> + } - CONTRACEPTIVES - - - {contraceptiveLabels.condom} - - { - this.setState({condom: val}) - }} - /> - - {contraceptiveLabels.pill} - - { - this.setState({pill: val}) - }} - /> - - - - {contraceptiveLabels.iud} - - { - this.setState({iud: val}) - }} - /> - - {contraceptiveLabels.patch} - - { - this.setState({patch: val}) - }} - /> - - - - {contraceptiveLabels.ring} - - { - this.setState({ring: val}) - }} - /> - - {contraceptiveLabels.implant} - - { - this.setState({implant: val}) - }} - /> - - - - {contraceptiveLabels.other} - - { - this.setState({ - other: val, - focusTextArea: true - }) - }} - /> - - { this.state.other && - { - this.setState({note: val}) - }} - /> - } - - {this.props.makeActionButtons( - { - symptom: 'sex', - cycleDay: this.cycleDay, - saveAction: () => { - const copyOfState = Object.assign({}, this.state) - if (!copyOfState.other) { - copyOfState.note = null - } - saveSymptom('sex', this.cycleDay, copyOfState) - }, - saveDisabled: Object.values(this.state).every(value => !value) + { + const copyOfState = Object.assign({}, this.state) + if (!copyOfState.other) { + copyOfState.note = null } - )} - + saveSymptom('sex', this.cycleDay, copyOfState) + }} + saveDisabled={Object.values(this.state).every(value => !value)} + navigate={this.props.navigate} + /> ) } -} +} \ No newline at end of file diff --git a/components/cycle-day/symptoms/temperature.js b/components/cycle-day/symptoms/temperature.js index a7bd55e..4c2d97e 100644 --- a/components/cycle-day/symptoms/temperature.js +++ b/components/cycle-day/symptoms/temperature.js @@ -11,6 +11,7 @@ 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 ActionButtonFooter from './action-button-footer' const MINUTES = ChronoUnit.MINUTES @@ -37,72 +38,70 @@ export default class Temp extends Component { time: this.time || LocalTime.now().truncatedTo(MINUTES).toString(), 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() { return ( - - - Temperature (°C) - { - this.setState({ currentValue: val }) + + + + Temperature (°C) + { + this.setState({ currentValue: val }) + }} + keyboardType='numeric' + value={this.state.currentValue} + /> + + + Time + { + Keyboard.dismiss() + this.setState({ isTimePickerVisible: true }) + }} + value={this.state.time} + /> + + { + this.setState({ + time: `${jsDate.getHours()}:${jsDate.getMinutes()}`, + isTimePickerVisible: false + }) }} - keyboardType='numeric' - value={this.state.currentValue} + onCancel={() => this.setState({ isTimePickerVisible: false })} /> + + Exclude + { + this.setState({ exclude: val }) + }} + value={this.state.exclude} + /> + - - Time - { - Keyboard.dismiss() - this.setState({ isTimePickerVisible: true }) - }} - value={this.state.time} - /> - - { - this.setState({ - time: `${jsDate.getHours()}:${jsDate.getMinutes()}`, - isTimePickerVisible: false - }) + { + const dataToSave = { + value: Number(this.state.currentValue), + exclude: this.state.exclude, + time: this.state.time + } + saveSymptom('temperature', this.props.cycleDay, dataToSave) }} - onCancel={() => this.setState({ isTimePickerVisible: false })} + saveDisabled={this.state.currentValue === '' || isInvalidTime(this.state.time)} + navigate={this.props.navigate} /> - - Exclude - { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> - ) } diff --git a/components/stats.js b/components/stats.js index 864c139..4021fde 100644 --- a/components/stats.js +++ b/components/stats.js @@ -5,7 +5,6 @@ import { ScrollView } from 'react-native' import { LocalDate, ChronoUnit } from 'js-joda' -import Header from './header' import styles from '../styles/index' import cycleModule from '../lib/cycle' import getCycleInfo from '../lib/cycle-length' diff --git a/styles/index.js b/styles/index.js index 6cf269e..b1476b0 100644 --- a/styles/index.js +++ b/styles/index.js @@ -83,6 +83,10 @@ export default StyleSheet.create({ symptomDataText: { fontSize: 12 }, + menuOnBottom: { + flex: 1, + justifyContent: 'space-between' + }, symptomEditRow: { justifyContent: 'space-between', marginBottom: 10, From 559aa684dc5aa4579263b8716e9840f672bc803d Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Mon, 20 Aug 2018 15:06:50 +0200 Subject: [PATCH 20/28] Visualize disabled action buttons --- components/cycle-day/symptoms/action-button-footer.js | 9 +++++++-- styles/index.js | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/components/cycle-day/symptoms/action-button-footer.js b/components/cycle-day/symptoms/action-button-footer.js index be0cd6a..a153496 100644 --- a/components/cycle-day/symptoms/action-button-footer.js +++ b/components/cycle-day/symptoms/action-button-footer.js @@ -38,6 +38,11 @@ export default class ActionButtonFooter extends Component { return ( {buttons.map(({ title, action, disabledCondition, icon }, i) => { + const textStyle = disabledCondition ? styles.menuTextInActive : styles.menuText + const iconStyle = disabledCondition ? + Object.assign({}, iconStyles.menuIcon, iconStyles.menuIconInactive) : + iconStyles.menuIcon + return ( - - + + {title} diff --git a/styles/index.js b/styles/index.js index b1476b0..c5605a1 100644 --- a/styles/index.js +++ b/styles/index.js @@ -119,6 +119,9 @@ export default StyleSheet.create({ menuText: { color: fontOnPrimaryColor }, + menuTextInActive: { + color: 'lightgrey' + }, headerCycleDay: { flexDirection: 'row', justifyContent: 'space-between' @@ -177,5 +180,8 @@ export const iconStyles = { menuIcon: { size: 20, color: fontOnPrimaryColor + }, + menuIconInactive: { + color: 'lightgrey' } } \ No newline at end of file From e2b9d4b4a1d9b954ec46174ab7c2a88ce1caf2f1 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Mon, 20 Aug 2018 15:14:17 +0200 Subject: [PATCH 21/28] Fix symptom headers --- app.js | 3 ++- components/cycle-day/symptoms/bleeding.js | 1 - components/cycle-day/symptoms/cervix.js | 1 - components/cycle-day/symptoms/desire.js | 1 - components/cycle-day/symptoms/mucus.js | 1 - components/cycle-day/symptoms/note.js | 1 - components/cycle-day/symptoms/sex.js | 1 - components/labels.js | 15 +++++++++++++++ 8 files changed, 17 insertions(+), 7 deletions(-) diff --git a/app.js b/app.js index fe0f57c..5e4b9ba 100644 --- a/app.js +++ b/app.js @@ -10,6 +10,7 @@ import Chart from './components/chart/chart' import Settings from './components/settings' import Stats from './components/stats' import styles from './styles' +import {headerTitles as titles} from './components/labels' // this is until react native fixes this bugg, see // https://github.com/facebook/react-native/issues/18868#issuecomment-382671739 @@ -53,7 +54,7 @@ export default class App extends Component { return ( - {this.state.currentPage != 'CycleDay' &&
} + {this.state.currentPage != 'CycleDay' &&
} {React.createElement(page, { navigate: this.navigate.bind(this), diff --git a/components/cycle-day/symptoms/bleeding.js b/components/cycle-day/symptoms/bleeding.js index ce27ba1..277c400 100644 --- a/components/cycle-day/symptoms/bleeding.js +++ b/components/cycle-day/symptoms/bleeding.js @@ -35,7 +35,6 @@ export default class Bleeding extends Component { return ( - Bleeding - Cervix Opening - Desire - Mucus Feeling - Note - SEX {activityLabels.solo} Date: Mon, 20 Aug 2018 15:30:14 +0200 Subject: [PATCH 22/28] Fix menu on calendar view --- components/calendar.js | 14 +++++--------- styles/index.js | 4 ---- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/components/calendar.js b/components/calendar.js index cb10817..635a9a2 100644 --- a/components/calendar.js +++ b/components/calendar.js @@ -35,15 +35,11 @@ export default class CalendarView extends Component { render() { return ( - - - - - + ) } } diff --git a/styles/index.js b/styles/index.js index c5605a1..89c1f63 100644 --- a/styles/index.js +++ b/styles/index.js @@ -5,10 +5,6 @@ export const secondaryColor = '#351c4d' export const fontOnPrimaryColor = 'white' export default StyleSheet.create({ - container: { - justifyContent: 'center', - alignItems: 'center' - }, welcome: { fontSize: 20, margin: 30, From d53b8029dc38379e74ffcc97785d74d6b4a33198 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Mon, 20 Aug 2018 16:46:42 +0200 Subject: [PATCH 23/28] Make scrolling work again --- app.js | 2 +- components/cycle-day/cycle-day-overview.js | 86 ++++---- components/cycle-day/symptoms/bleeding.js | 51 ++--- components/cycle-day/symptoms/cervix.js | 105 ++++----- components/cycle-day/symptoms/desire.js | 32 +-- components/cycle-day/symptoms/mucus.js | 79 +++---- components/cycle-day/symptoms/note.js | 26 +-- components/cycle-day/symptoms/sex.js | 215 ++++++++++--------- components/cycle-day/symptoms/temperature.js | 89 ++++---- styles/index.js | 6 +- 10 files changed, 354 insertions(+), 337 deletions(-) diff --git a/app.js b/app.js index 5e4b9ba..7c2a14b 100644 --- a/app.js +++ b/app.js @@ -52,7 +52,7 @@ export default class App extends Component { Home, Calendar, CycleDay, Chart, Settings, Stats, ...symptomViews }[this.state.currentPage] return ( - + {this.state.currentPage != 'CycleDay' &&
} diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 9ab3225..c165633 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -36,7 +36,7 @@ export default class CycleDayOverView extends Component { const targetDate = target === 'before' ? localDate.minusDays(1).toString() : localDate.plusDays(1).toString() - this.setState({cycleDay: getOrCreateCycleDay(targetDate)}) + this.setState({ cycleDay: getOrCreateCycleDay(targetDate) }) } navigate(symptom) { @@ -50,53 +50,55 @@ export default class CycleDayOverView extends Component { const getCycleDayNumber = cycleModule().getCycleDayNumber const cycleDayNumber = getCycleDayNumber(cycleDay.date) return ( - +
- - this.navigate('BleedingEditView')} - data={getLabel('bleeding', cycleDay.bleeding)} - /> - this.navigate('TemperatureEditView')} - data={getLabel('temperature', cycleDay.temperature)} - /> - this.navigate('MucusEditView')} - data={getLabel('mucus', cycleDay.mucus)} - /> - this.navigate('CervixEditView')} - data={getLabel('cervix', cycleDay.cervix)} - /> - this.navigate('NoteEditView')} - data={getLabel('note', cycleDay.note)} - /> - this.navigate('DesireEditView')} - data={getLabel('desire', cycleDay.desire)} - /> - this.navigate('SexEditView')} - data={getLabel('sex', cycleDay.sex)} - /> - {/* this is just to make the last row adhere to the grid + + + this.navigate('BleedingEditView')} + data={getLabel('bleeding', cycleDay.bleeding)} + /> + this.navigate('TemperatureEditView')} + data={getLabel('temperature', cycleDay.temperature)} + /> + this.navigate('MucusEditView')} + data={getLabel('mucus', cycleDay.mucus)} + /> + this.navigate('CervixEditView')} + data={getLabel('cervix', cycleDay.cervix)} + /> + this.navigate('NoteEditView')} + data={getLabel('note', cycleDay.note)} + /> + this.navigate('DesireEditView')} + data={getLabel('desire', cycleDay.desire)} + /> + this.navigate('SexEditView')} + data={getLabel('sex', cycleDay.sex)} + /> + {/* this is just to make the last row adhere to the grid (and) because there are no pseudo properties in RN */} - - - + + + + ) } } diff --git a/components/cycle-day/symptoms/bleeding.js b/components/cycle-day/symptoms/bleeding.js index 277c400..bd24b9e 100644 --- a/components/cycle-day/symptoms/bleeding.js +++ b/components/cycle-day/symptoms/bleeding.js @@ -2,7 +2,8 @@ import React, { Component } from 'react' import { View, Text, - Switch + Switch, + ScrollView } from 'react-native' import RadioForm from 'react-native-simple-radio-button' import styles from '../../../styles' @@ -33,30 +34,32 @@ export default class Bleeding extends Component { { label: labels[3], value: 3 }, ] return ( - - - - { - this.setState({ currentValue: itemValue }) - }} - /> + + + + + { + this.setState({ currentValue: itemValue }) + }} + /> + + + Exclude + { + this.setState({ exclude: val }) + }} + value={this.state.exclude} + /> + - - Exclude - { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> - - + - - Opening - - { - this.setState({ opening: itemValue }) - }} - /> + + + + Opening + + { + this.setState({ opening: itemValue }) + }} + /> + + Firmness + + { + this.setState({ firmness: itemValue }) + }} + /> + + Position + + { + this.setState({ position: itemValue }) + }} + /> + + + Exclude + { + this.setState({ exclude: val }) + }} + value={this.state.exclude} + /> + - Firmness - - { - this.setState({ firmness: itemValue }) - }} - /> - - Position - - { - this.setState({ position: itemValue }) - }} - /> - - - Exclude - { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> - - + - - - { - this.setState({ currentValue: itemValue }) - }} - /> + + + + + { + this.setState({ currentValue: itemValue }) + }} + /> + - + - - Feeling - - { - this.setState({ feeling: itemValue }) - }} - /> + + + + Feeling + + { + this.setState({ feeling: itemValue }) + }} + /> + + Texture + + { + this.setState({ texture: itemValue }) + }} + /> + + + Exclude + { + this.setState({ exclude: val }) + }} + value={this.state.exclude} + /> + - Texture - - { - this.setState({ texture: itemValue }) - }} - /> - - - Exclude - { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> - - + - - { - this.setState({ currentValue: val }) - }} - value={this.state.currentValue} - /> - + + + + { + this.setState({ currentValue: val }) + }} + value={this.state.currentValue} + /> + + - - - {activityLabels.solo} - { - this.setState({ solo: val }) - }} - /> - {activityLabels.partner} - { - this.setState({ partner: val }) - }} - /> + + + + + {activityLabels.solo} + { + this.setState({ solo: val }) + }} + /> + {activityLabels.partner} + { + this.setState({ partner: val }) + }} + /> + + CONTRACEPTIVES + + + {contraceptiveLabels.condom} + + { + this.setState({ condom: val }) + }} + /> + + {contraceptiveLabels.pill} + + { + this.setState({ pill: val }) + }} + /> + + + + {contraceptiveLabels.iud} + + { + this.setState({ iud: val }) + }} + /> + + {contraceptiveLabels.patch} + + { + this.setState({ patch: val }) + }} + /> + + + + {contraceptiveLabels.ring} + + { + this.setState({ ring: val }) + }} + /> + + {contraceptiveLabels.implant} + + { + this.setState({ implant: val }) + }} + /> + + + + {contraceptiveLabels.other} + + { + this.setState({ + other: val, + focusTextArea: true + }) + }} + /> + + {this.state.other && + { + this.setState({ note: val }) + }} + /> + } - CONTRACEPTIVES - - - {contraceptiveLabels.condom} - - { - this.setState({ condom: val }) - }} - /> - - {contraceptiveLabels.pill} - - { - this.setState({ pill: val }) - }} - /> - - - - {contraceptiveLabels.iud} - - { - this.setState({ iud: val }) - }} - /> - - {contraceptiveLabels.patch} - - { - this.setState({ patch: val }) - }} - /> - - - - {contraceptiveLabels.ring} - - { - this.setState({ ring: val }) - }} - /> - - {contraceptiveLabels.implant} - - { - this.setState({ implant: val }) - }} - /> - - - - {contraceptiveLabels.other} - - { - this.setState({ - other: val, - focusTextArea: true - }) - }} - /> - - {this.state.other && - { - this.setState({ note: val }) - }} - /> - } - + - - - Temperature (°C) - { - this.setState({ currentValue: val }) + + + + + Temperature (°C) + { + this.setState({ currentValue: val }) + }} + keyboardType='numeric' + value={this.state.currentValue} + /> + + + Time + { + Keyboard.dismiss() + this.setState({ isTimePickerVisible: true }) + }} + value={this.state.time} + /> + + { + this.setState({ + time: `${jsDate.getHours()}:${jsDate.getMinutes()}`, + isTimePickerVisible: false + }) }} - keyboardType='numeric' - value={this.state.currentValue} + onCancel={() => this.setState({ isTimePickerVisible: false })} /> + + Exclude + { + this.setState({ exclude: val }) + }} + value={this.state.exclude} + /> + - - Time - { - Keyboard.dismiss() - this.setState({ isTimePickerVisible: true }) - }} - value={this.state.time} - /> - - { - this.setState({ - time: `${jsDate.getHours()}:${jsDate.getMinutes()}`, - isTimePickerVisible: false - }) - }} - onCancel={() => this.setState({ isTimePickerVisible: false })} - /> - - Exclude - { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> - - + Date: Mon, 20 Aug 2018 16:54:02 +0200 Subject: [PATCH 24/28] Move app component to components --- app.js => components/app.js | 26 ++++++++++---------------- index.js | 2 +- 2 files changed, 11 insertions(+), 17 deletions(-) rename app.js => components/app.js (65%) diff --git a/app.js b/components/app.js similarity index 65% rename from app.js rename to components/app.js index 7c2a14b..b0924aa 100644 --- a/app.js +++ b/components/app.js @@ -1,21 +1,15 @@ import React, { Component } from 'react' import { View, BackHandler } from 'react-native' -import Header from './components/header' -import Menu from './components/menu' -import Home from './components/home' -import Calendar from './components/calendar' -import CycleDay from './components/cycle-day/cycle-day-overview' -import symptomViews from './components/cycle-day/symptoms' -import Chart from './components/chart/chart' -import Settings from './components/settings' -import Stats from './components/stats' -import styles from './styles' -import {headerTitles as titles} from './components/labels' - -// this is until react native fixes this bugg, see -// https://github.com/facebook/react-native/issues/18868#issuecomment-382671739 -import { YellowBox } from 'react-native' -YellowBox.ignoreWarnings(['Warning: isMounted(...) is deprecated']) +import Header from './header' +import Menu from './menu' +import Home from './home' +import Calendar from './calendar' +import CycleDay from './cycle-day/cycle-day-overview' +import symptomViews from './cycle-day/symptoms' +import Chart from './chart/chart' +import Settings from './settings' +import Stats from './stats' +import {headerTitles as titles} from './labels' const isSymptomView = name => Object.keys(symptomViews).indexOf(name) > -1 diff --git a/index.js b/index.js index 408a2f0..25e2616 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ import { AppRegistry } from 'react-native' -import App from './app' +import App from './components/app' AppRegistry.registerComponent('home', () => App) \ No newline at end of file From 90e0cdffeadd352cc30379277336319d1c49ef48 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Mon, 20 Aug 2018 17:00:44 +0200 Subject: [PATCH 25/28] Fix go to next cycle day --- components/cycle-day/cycle-day-overview.js | 1 + components/header.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index c165633..37b34b2 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -55,6 +55,7 @@ export default class CycleDayOverView extends Component { isCycleDayOverView={true} cycleDayNumber={cycleDayNumber} date={cycleDay.date} + goToCycleDay={this.goToCycleDay.bind(this)} /> diff --git a/components/header.js b/components/header.js index 5863e43..a4d3414 100644 --- a/components/header.js +++ b/components/header.js @@ -15,7 +15,7 @@ export default class Header extends Component { this.goToCycleDay('before')} + onPress={() => this.props.goToCycleDay('before')} /> @@ -29,7 +29,7 @@ export default class Header extends Component { this.goToCycleDay('after')} + onPress={() => this.props.goToCycleDay('after')} /> : From fde9a6cbc31de7d1e25204d8e94fc1d5c06a2951 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Mon, 20 Aug 2018 17:13:03 +0200 Subject: [PATCH 26/28] Remove unneeded imports --- components/calendar.js | 2 -- components/cycle-day/cycle-day-overview.js | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/components/calendar.js b/components/calendar.js index 635a9a2..72fb1ba 100644 --- a/components/calendar.js +++ b/components/calendar.js @@ -1,7 +1,5 @@ import React, { Component } from 'react' -import { View } from 'react-native' import { CalendarList } from 'react-native-calendars' -import * as styles from '../styles' import { getOrCreateCycleDay, bleedingDaysSortedByDate } from '../db' export default class CalendarView extends Component { diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index 37b34b2..168954f 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -167,8 +167,8 @@ function getLabel(symptomName, symptom) { if (!symptom) return const label = labels[symptomName](symptom) - if (label.length < 50) return label - return label.slice(0, 47) + '...' + if (label.length < 45) return label + return label.slice(0, 42) + '...' } class SymptomBox extends Component { From db4d82e945aabc778a093697cc8854a16c687875 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Wed, 22 Aug 2018 13:05:28 +0200 Subject: [PATCH 27/28] Fix layout on chart view --- components/chart/chart.js | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/components/chart/chart.js b/components/chart/chart.js index d31b128..c9c2b1d 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { View, FlatList } from 'react-native' +import { View, FlatList, ScrollView } from 'react-native' import range from 'date-range' import { LocalDate } from 'js-joda' import { yAxis, normalizeToScale, horizontalGrid } from './y-axis' @@ -41,21 +41,23 @@ export default class CycleChart extends Component { render() { return ( - - {yAxisView} - {horizontalGrid} - { item.dateString} - initialNumToRender={15} - maxToRenderPerBatch={5} - > - } - + + + {yAxisView} + {horizontalGrid} + { item.dateString} + initialNumToRender={15} + maxToRenderPerBatch={5} + > + } + + ) } } From 74041f7e3261fd3d62fa177a1ebcac43258ef583 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Wed, 22 Aug 2018 13:20:07 +0200 Subject: [PATCH 28/28] Fix typo --- components/chart/day-column.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/chart/day-column.js b/components/chart/day-column.js index 88eb44e..a7ccfb1 100644 --- a/components/chart/day-column.js +++ b/components/chart/day-column.js @@ -15,7 +15,7 @@ const label = styles.column.label export default class DayColumn extends Component { passDateToDayView(dateString) { const cycleDay = getOrCreateCycleDay(dateString) - this.props.navigate('cycleDay', { cycleDay }) + this.props.navigate('CycleDay', { cycleDay }) } shouldComponentUpdate(newProps) {