From e16fc392984babd1255d8b8f7e59390230236f25 Mon Sep 17 00:00:00 2001 From: Sofiya Tepikin Date: Wed, 5 Dec 2018 22:20:28 +0100 Subject: [PATCH 01/36] Extracting SettingsButton component --- components/settings/password/create.js | 22 +++--------------- .../settings/password/settings-button.js | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 components/settings/password/settings-button.js diff --git a/components/settings/password/create.js b/components/settings/password/create.js index 68b7b2d..e2e8517 100644 --- a/components/settings/password/create.js +++ b/components/settings/password/create.js @@ -1,8 +1,5 @@ import React, { Component } from 'react' -import { - View, - TouchableOpacity, -} from 'react-native' +import { View } from 'react-native' import nodejs from 'nodejs-mobile-react-native' import AppText from '../../app-text' import styles from '../../../styles' @@ -10,22 +7,9 @@ import { settings } from '../../../i18n/en/settings' import { requestHash, changeEncryptionAndRestartApp } from '../../../db' import PasswordField from './password-field' import showBackUpReminder from './show-backup-reminder' +import SettingsButton from './settings-button' + -const SettingsButton = ({ children, ...props }) => { - return ( - - - {children} - - - ) -} export default class CreatePassword extends Component { constructor() { diff --git a/components/settings/password/settings-button.js b/components/settings/password/settings-button.js new file mode 100644 index 0000000..3b29241 --- /dev/null +++ b/components/settings/password/settings-button.js @@ -0,0 +1,23 @@ +import React from 'react' + +import { TouchableOpacity } from 'react-native' +import AppText from '../../app-text' +import styles from '../../../styles' + +const SettingsButton = ({ children, ...props }) => { + return ( + + + {children} + + + ) +} + +export default SettingsButton \ No newline at end of file From acc7ce13f864d1b9cdc30581b2a1f53f4064c9f6 Mon Sep 17 00:00:00 2001 From: Sofiya Tepikin Date: Wed, 5 Dec 2018 22:38:02 +0100 Subject: [PATCH 02/36] Adds prop types to the project & and uses them in SettingsButton component --- components/settings/password/settings-button.js | 6 ++++++ package.json | 1 + 2 files changed, 7 insertions(+) diff --git a/components/settings/password/settings-button.js b/components/settings/password/settings-button.js index 3b29241..97272bb 100644 --- a/components/settings/password/settings-button.js +++ b/components/settings/password/settings-button.js @@ -1,4 +1,5 @@ import React from 'react' +import PropTypes from 'prop-types' import { TouchableOpacity } from 'react-native' import AppText from '../../app-text' @@ -20,4 +21,9 @@ const SettingsButton = ({ children, ...props }) => { ) } +SettingsButton.propTypes = { + onPress: PropTypes.func.isRequired, + disabled: PropTypes.bool +} + export default SettingsButton \ No newline at end of file diff --git a/package.json b/package.json index e01b525..3cb33ad 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "nodejs-mobile-react-native": "^0.3.0", "object-path": "^0.11.4", "obv": "0.0.1", + "prop-types": "^15.6.2", "react": "16.4.1", "react-native": "~0.56.0", "react-native-calendars": "^1.19.3", From 7ddf9a7002078185bea1f70c3438d7104abea1b6 Mon Sep 17 00:00:00 2001 From: Sofiya Tepikin Date: Wed, 5 Dec 2018 22:41:41 +0100 Subject: [PATCH 03/36] Reuses SettingsButton component --- components/settings/password/update.js | 45 +++++++++++++------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/components/settings/password/update.js b/components/settings/password/update.js index fc10cca..a470e57 100644 --- a/components/settings/password/update.js +++ b/components/settings/password/update.js @@ -10,9 +10,11 @@ import { shared } from '../../../i18n/en/labels' import { settings as labels } from '../../../i18n/en/settings' import { requestHash, changeEncryptionAndRestartApp } from '../../../db' import PasswordField from './password-field' +import SettingsButton from './settings-button' import showBackUpReminder from './show-backup-reminder' import checkCurrentPassword from './check-current-password' + export default class ChangePassword extends Component { constructor() { super() @@ -60,21 +62,23 @@ export default class ChangePassword extends Component { } } + startChangingPassword = () => { + showBackUpReminder(() => { + this.setState({ enteringCurrentPassword: true }) + }) + } + render() { return ( {!this.state.enteringCurrentPassword && !this.state.enteringNewPassword && - showBackUpReminder(() => { - this.setState({ enteringCurrentPassword: true }) - })} - disabled={this.state.currentPassword} - style={styles.settingsButton}> - - {labels.passwordSettings.changePassword} - - + + {labels.passwordSettings.changePassword} + } {this.state.enteringCurrentPassword && @@ -89,14 +93,12 @@ export default class ChangePassword extends Component { value={this.state.currentPassword} placeholder={labels.passwordSettings.enterCurrent} /> - requestHash('pre-change-pw-check', this.state.currentPassword)} disabled={!this.state.currentPassword} - style={styles.settingsButton}> - - {shared.unlock} - - + > + {shared.unlock} + } @@ -112,15 +114,12 @@ export default class ChangePassword extends Component { value={this.state.changedPassword} placeholder={labels.passwordSettings.enterNew} /> - - requestHash('change-pw', this.state.newPassword)} disabled={ !this.state.newPassword } - style={styles.settingsButton}> - - {labels.passwordSettings.changePassword} - - + > + {labels.passwordSettings.changePassword} + } From 857b8fc1f16c462ebbd86b44e6baf5a9b69dce6f Mon Sep 17 00:00:00 2001 From: mashazyu Date: Fri, 7 Dec 2018 23:56:33 +0100 Subject: [PATCH 04/36] Cleanup ChangePassword component --- components/settings/password/create.js | 6 +- components/settings/password/update.js | 126 ++++++++++++++----------- 2 files changed, 70 insertions(+), 62 deletions(-) diff --git a/components/settings/password/create.js b/components/settings/password/create.js index e2e8517..e9603be 100644 --- a/components/settings/password/create.js +++ b/components/settings/password/create.js @@ -59,11 +59,7 @@ export default class CreatePassword extends Component { } handleConfirmationInput = (passwordConfirmation) => { - const { password } = this.state - this.setState({ - passwordConfirmation, - isPasswordsMatch: passwordConfirmation === password - }) + this.setState({ passwordConfirmation }) } render () { diff --git a/components/settings/password/update.js b/components/settings/password/update.js index a470e57..141957b 100644 --- a/components/settings/password/update.js +++ b/components/settings/password/update.js @@ -1,13 +1,8 @@ - import React, { Component } from 'react' -import { - View, - TouchableOpacity} from 'react-native' +import { View } from 'react-native' import nodejs from 'nodejs-mobile-react-native' -import AppText from '../../app-text' -import styles from '../../../styles' -import { shared } from '../../../i18n/en/labels' -import { settings as labels } from '../../../i18n/en/settings' +import { shared as sharedLabels } from '../../../i18n/en/labels' +import { settings } from '../../../i18n/en/settings' import { requestHash, changeEncryptionAndRestartApp } from '../../../db' import PasswordField from './password-field' import SettingsButton from './settings-button' @@ -19,10 +14,11 @@ export default class ChangePassword extends Component { constructor() { super() this.state = { - enteringCurrentPassword: false, currentPassword: null, - enteringNewPassword: false, - newPassword: null + newPassword: null, + newPasswordConfirmation: null, + enteringCurrentPassword: false, + enteringNewPassword: false } nodejs.channel.addListener( @@ -55,9 +51,9 @@ export default class ChangePassword extends Component { if (passwordCorrect) { this.setState({ - enteringCurrentPassword: false, currentPassword: null, - enteringNewPassword: true + enteringNewPassword: true, + enteringCurrentPassword: false }) } } @@ -68,61 +64,77 @@ export default class ChangePassword extends Component { }) } + handleCurrentPasswordInput = (currentPassword) => { + this.setState({ currentPassword }) + } + + checkCurrentPassword = () => { + requestHash('pre-change-pw-check', this.state.currentPassword) + } + + handleNewPasswordInput = (newPassword) => { + this.setState({ newPassword }) + } + + changePassword = () => { + requestHash('change-pw', this.state.newPassword) + } + render() { - return ( - - {!this.state.enteringCurrentPassword && - !this.state.enteringNewPassword && - - {labels.passwordSettings.changePassword} - - } - {this.state.enteringCurrentPassword && - - { - this.setState({ - currentPassword: val, - wrongPassword: false - }) - }} - value={this.state.currentPassword} - placeholder={labels.passwordSettings.enterCurrent} - /> - requestHash('pre-change-pw-check', this.state.currentPassword)} - disabled={!this.state.currentPassword} - > - {shared.unlock} - - - } + const { + enteringCurrentPassword, + enteringNewPassword, + currentPassword, + newPassword + } = this.state - {this.state.enteringNewPassword && + const labels = settings.passwordSettings + + if (enteringCurrentPassword) { + return ( { - this.setState({ - newPassword: val - }) - }} - value={this.state.changedPassword} - placeholder={labels.passwordSettings.enterNew} + placeholder={labels.enterCurrent} + value={currentPassword} + onChangeText={this.handleCurrentPasswordInput} /> requestHash('change-pw', this.state.newPassword)} - disabled={ !this.state.newPassword } + onPress={this.checkCurrentPassword} + disabled={!currentPassword} > - {labels.passwordSettings.changePassword} + {sharedLabels.unlock} - } + ) + } + if (enteringNewPassword) { + return ( + + + + {labels.changePassword} + + + ) + } + + return ( + + + {labels.changePassword} + ) } From 2213872606f59f321cef915b6f847eb2c7029875 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Sat, 8 Dec 2018 10:44:26 +0100 Subject: [PATCH 05/36] Fix non-existent temperature argument --- components/chart/chart.js | 2 +- components/chart/day-column.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/chart/chart.js b/components/chart/chart.js index c11db6b..b8d2142 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -81,7 +81,7 @@ export default class CycleChart extends Component { this.chartSymptoms.push('temperature') } - const columnData = this.makeColumnInfo(nfpLines(), this.chartSymptoms) + const columnData = this.makeColumnInfo() this.setState({ columns: columnData, chartHeight: height diff --git a/components/chart/day-column.js b/components/chart/day-column.js index fe4b82c..e9c6f76 100644 --- a/components/chart/day-column.js +++ b/components/chart/day-column.js @@ -52,7 +52,7 @@ export default class DayColumn extends Component { this.fhmAndLtl = props.getFhmAndLtlInfo( props.dateString, - props.temp, + this.data.temperature, props.columnHeight ) } From d3f9652b9d2592848c2d76a4a5aa5617b7fdc39b Mon Sep 17 00:00:00 2001 From: mashazyu Date: Sun, 9 Dec 2018 12:41:40 +0100 Subject: [PATCH 06/36] Creates reusable password confirmation component --- components/settings/password/create.js | 83 +--------------- .../settings/password/enter-new-password.js | 97 +++++++++++++++++++ components/settings/password/update.js | 39 +------- 3 files changed, 106 insertions(+), 113 deletions(-) create mode 100644 components/settings/password/enter-new-password.js diff --git a/components/settings/password/create.js b/components/settings/password/create.js index e9603be..011bbd7 100644 --- a/components/settings/password/create.js +++ b/components/settings/password/create.js @@ -1,43 +1,15 @@ import React, { Component } from 'react' import { View } from 'react-native' -import nodejs from 'nodejs-mobile-react-native' -import AppText from '../../app-text' -import styles from '../../../styles' import { settings } from '../../../i18n/en/settings' -import { requestHash, changeEncryptionAndRestartApp } from '../../../db' -import PasswordField from './password-field' -import showBackUpReminder from './show-backup-reminder' +import EnterNewPassword from './enter-new-password' import SettingsButton from './settings-button' - - +import showBackUpReminder from './show-backup-reminder' export default class CreatePassword extends Component { constructor() { super() this.state = { - isSettingPassword: false, - password: '', - passwordConfirmation: '', - shouldShowErrorMessage: false, - } - nodejs.channel.addListener( - 'create-pw-hash', - changeEncryptionAndRestartApp, - this - ) - } - - componentWillUnmount() { - nodejs.channel.removeListener('create-pw-hash', changeEncryptionAndRestartApp) - } - - savePassword = () => { - if (this.comparePasswords()) { - requestHash('create-pw-hash', this.state.password) - } else { - this.setState({ - shouldShowErrorMessage: true - }) + isSettingPassword: false } } @@ -50,31 +22,12 @@ export default class CreatePassword extends Component { showBackUpReminder(this.toggleSettingPassword) } - comparePasswords = () => { - return this.state.password === this.state.passwordConfirmation - } - - handlePasswordInput = (password) => { - this.setState({ password }) - } - - handleConfirmationInput = (passwordConfirmation) => { - this.setState({ passwordConfirmation }) - } - render () { const { - isSettingPassword, - password, - passwordConfirmation, - shouldShowErrorMessage, + isSettingPassword } = this.state const labels = settings.passwordSettings - const isSaveButtonDisabled = - !password.length || - !passwordConfirmation.length - if (!isSettingPassword) { return ( @@ -84,33 +37,7 @@ export default class CreatePassword extends Component { ) } else { - return ( - - - - { - shouldShowErrorMessage && - - {labels.passwordsDontMatch} - - } - - {labels.savePassword} - - - ) + return } } diff --git a/components/settings/password/enter-new-password.js b/components/settings/password/enter-new-password.js new file mode 100644 index 0000000..a63556b --- /dev/null +++ b/components/settings/password/enter-new-password.js @@ -0,0 +1,97 @@ +import React, { Component } from 'react' +import { View } from 'react-native' +import nodejs from 'nodejs-mobile-react-native' + +import { requestHash, changeEncryptionAndRestartApp } from '../../../db' +import AppText from '../../app-text' +import PasswordField from './password-field' +import SettingsButton from './settings-button' + +import styles from '../../../styles' +import { settings } from '../../../i18n/en/settings' + +const LISTENER_TYPE = 'create-or-change-pw' + +export default class EnterNewPassword extends Component { + + constructor() { + super() + this.state = { + password: '', + passwordConfirmation: '', + shouldShowErrorMessage: false, + } + nodejs.channel.addListener( + LISTENER_TYPE, + changeEncryptionAndRestartApp, + this + ) + } + + componentWillUnmount() { + nodejs.channel.removeListener(LISTENER_TYPE, changeEncryptionAndRestartApp) + } + + savePassword = () => { + if (this.comparePasswords()) { + requestHash(LISTENER_TYPE, this.state.password) + } else { + this.setState({ + shouldShowErrorMessage: true + }) + } + } + + comparePasswords = () => { + return this.state.password === this.state.passwordConfirmation + } + + handlePasswordInput = (password) => { + this.setState({ password }) + } + + handleConfirmationInput = (passwordConfirmation) => { + this.setState({ passwordConfirmation }) + } + + render () { + const { + password, + passwordConfirmation, + shouldShowErrorMessage, + } = this.state + const labels = settings.passwordSettings + + const isSaveButtonDisabled = + !password.length || + !passwordConfirmation.length + + return ( + + + + { + shouldShowErrorMessage && + + {labels.passwordsDontMatch} + + } + + {labels.savePassword} + + + ) + } +} \ No newline at end of file diff --git a/components/settings/password/update.js b/components/settings/password/update.js index 141957b..33cddbd 100644 --- a/components/settings/password/update.js +++ b/components/settings/password/update.js @@ -3,7 +3,8 @@ import { View } from 'react-native' import nodejs from 'nodejs-mobile-react-native' import { shared as sharedLabels } from '../../../i18n/en/labels' import { settings } from '../../../i18n/en/settings' -import { requestHash, changeEncryptionAndRestartApp } from '../../../db' +import { requestHash } from '../../../db' +import EnterNewPassword from './enter-new-password' import PasswordField from './password-field' import SettingsButton from './settings-button' import showBackUpReminder from './show-backup-reminder' @@ -15,8 +16,6 @@ export default class ChangePassword extends Component { super() this.state = { currentPassword: null, - newPassword: null, - newPasswordConfirmation: null, enteringCurrentPassword: false, enteringNewPassword: false } @@ -26,17 +25,10 @@ export default class ChangePassword extends Component { this.openNewPasswordField, this ) - - nodejs.channel.addListener( - 'change-pw', - changeEncryptionAndRestartApp, - this - ) } componentWillUnmount() { nodejs.channel.removeListener('pre-change-pw-check', this.openNewPasswordField) - nodejs.channel.removeListener('change-pw', changeEncryptionAndRestartApp) } openNewPasswordField = async hash => { @@ -72,21 +64,12 @@ export default class ChangePassword extends Component { requestHash('pre-change-pw-check', this.state.currentPassword) } - handleNewPasswordInput = (newPassword) => { - this.setState({ newPassword }) - } - - changePassword = () => { - requestHash('change-pw', this.state.newPassword) - } - render() { const { enteringCurrentPassword, enteringNewPassword, - currentPassword, - newPassword + currentPassword } = this.state const labels = settings.passwordSettings @@ -110,21 +93,7 @@ export default class ChangePassword extends Component { } if (enteringNewPassword) { - return ( - - - - {labels.changePassword} - - - ) + return } return ( From 5cb4d9f861c2605fadb50460c47a52f84245b56f Mon Sep 17 00:00:00 2001 From: mashazyu Date: Sun, 9 Dec 2018 16:26:37 +0100 Subject: [PATCH 07/36] Fix export of empty database --- components/settings/export-dialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/settings/export-dialog.js b/components/settings/export-dialog.js index e87b9d2..9a8a669 100644 --- a/components/settings/export-dialog.js +++ b/components/settings/export-dialog.js @@ -8,7 +8,7 @@ export default async function openShareDialogAndExport() { try { data = getDataAsCsvDataUri() if (!data) { - return alertError(labels.errors.noData) + return alertError(labels.export.errors.noData) } } catch (err) { console.error(err) From 2bcb1ee08b3405787ab46291d7d9dcb0244599ee Mon Sep 17 00:00:00 2001 From: bl00dymarie Date: Sun, 9 Dec 2018 15:26:52 +0000 Subject: [PATCH 08/36] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 33c2411..092419a 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,8 @@ Unfortunately, the react native version we use doesn't work on Windows 10 it see You can run the tests with `npm test`. ## Debugging -When running into an old version of the app try to run the following command first: -`react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res` +If you want to check what the code is actually doing you can add an extra line to your code to check a specific variable `console.log(someTestVariable)` or a function or just check whether this line gets actually reached. +Save it and run `npm run android` in one window and `rpm run log` in a different window, where it will print out what you speficied in console.log, e.g. `someTestVariable`. ## NFP rules More information about how the app calculates fertility status and bleeding predictions in the [wiki on Gitlab](https://gitlab.com/bloodyhealth/drip/wikis/home) From 1ed771a50c08f3eaee17bbbd5547669e00a64471 Mon Sep 17 00:00:00 2001 From: Anne Menzel Date: Sun, 9 Dec 2018 17:05:08 +0100 Subject: [PATCH 09/36] add date to symptom screen header --- components/app.js | 1 + components/header/cycle-day.js | 14 +++----------- components/header/symptom-view.js | 6 +++++- components/helpers/format-date.js | 9 +++++++++ 4 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 components/helpers/format-date.js diff --git a/components/app.js b/components/app.js index b3218a5..ce0eaf2 100644 --- a/components/app.js +++ b/components/app.js @@ -81,6 +81,7 @@ export default class App extends Component { title={headerTitlesLowerCase[this.state.currentPage]} isSymptomView={true} goBack={this.handleBackButtonPress} + date={this.state.currentProps.date} />} diff --git a/components/header/cycle-day.js b/components/header/cycle-day.js index b5dbbdf..0cb3252 100644 --- a/components/header/cycle-day.js +++ b/components/header/cycle-day.js @@ -2,17 +2,9 @@ import React from 'react' import { View, Text} from 'react-native' -import { LocalDate } from 'js-joda' -import moment from 'moment' import styles from '../../styles' import NavigationArrow from './navigation-arrow' - -const FormattedDate = ({ date }) => { - const today = LocalDate.now() - const dateToDisplay = LocalDate.parse(date) - const formattedDate = today.equals(dateToDisplay) ? 'today' : moment(date).format('MMMM Do YYYY') - return formattedDate.toLowerCase() -} +import formatDate from '../helpers/format-date' export default function CycleDayHeader({ date, ...props }) { return ( @@ -23,7 +15,7 @@ export default function CycleDayHeader({ date, ...props }) { - + {formatDate(date)} {props.cycleDayNumber && @@ -33,4 +25,4 @@ export default function CycleDayHeader({ date, ...props }) { ) -} \ No newline at end of file +} diff --git a/components/header/symptom-view.js b/components/header/symptom-view.js index 3f6a21f..d091a4c 100644 --- a/components/header/symptom-view.js +++ b/components/header/symptom-view.js @@ -5,6 +5,7 @@ import { import styles, { iconStyles } from '../../styles' import FeatherIcon from 'react-native-vector-icons/Feather' import NavigationArrow from './navigation-arrow' +import formatDate from '../helpers/format-date' export default function SymptomViewHeader(props) { return ( @@ -19,6 +20,9 @@ export default function SymptomViewHeader(props) { /> + {formatDate(props.date)} + + {props.title} @@ -29,4 +33,4 @@ export default function SymptomViewHeader(props) { /> ) -} \ No newline at end of file +} diff --git a/components/helpers/format-date.js b/components/helpers/format-date.js new file mode 100644 index 0000000..079ea4d --- /dev/null +++ b/components/helpers/format-date.js @@ -0,0 +1,9 @@ +import { LocalDate } from 'js-joda' +import moment from 'moment' + +export default function (date) { + const today = LocalDate.now() + const dateToDisplay = LocalDate.parse(date) + const formattedDate = today.equals(dateToDisplay) ? 'today' : moment(date).format('MMMM Do YYYY') + return formattedDate.toLowerCase() +} From f222893484eeb61d972b448e273d8fa63ea7876e Mon Sep 17 00:00:00 2001 From: Maike Orlikowski Date: Sun, 9 Dec 2018 17:47:20 +0100 Subject: [PATCH 10/36] added toast button to disabled save button --- .../symptoms/action-button-footer.js | 24 +++++++++++++------ i18n/en/cycle-day.js | 3 ++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/components/cycle-day/symptoms/action-button-footer.js b/components/cycle-day/symptoms/action-button-footer.js index 076b0bb..7f0bb5f 100644 --- a/components/cycle-day/symptoms/action-button-footer.js +++ b/components/cycle-day/symptoms/action-button-footer.js @@ -1,12 +1,13 @@ import React, { Component } from 'react' import { - View, TouchableOpacity, Text, Alert + View, TouchableOpacity, Text, Alert, ToastAndroid } from 'react-native' import Icon from 'react-native-vector-icons/MaterialCommunityIcons' import { saveSymptom } from '../../../db' import styles, {iconStyles} from '../../../styles' import {sharedDialogs as labels} from '../../../i18n/en/cycle-day' + export default class ActionButtonFooter extends Component { render() { const { @@ -43,19 +44,28 @@ export default class ActionButtonFooter extends Component { }, { title: labels.save, action: () => { - saveAction() - if (autoShowDayView) navigateToOverView() + if(saveDisabled) { + //toast + ToastAndroid.show(labels.disabledInfo, ToastAndroid.LONG); + console.log() + } else { + saveAction() + if (autoShowDayView) navigateToOverView() + } + }, disabledCondition: saveDisabled, icon: 'content-save-outline' } ] - + console.log("Hello beautiful people") return ( {buttons.map(({ title, action, disabledCondition, icon }, i) => { const textStyle = [styles.menuText] - if (disabledCondition) textStyle.push(styles.menuTextInActive) + if (disabledCondition) { + textStyle.push(styles.menuTextInActive); + } const iconStyle = disabledCondition ? Object.assign( {}, @@ -68,7 +78,6 @@ export default class ActionButtonFooter extends Component { @@ -76,9 +85,10 @@ export default class ActionButtonFooter extends Component { {title.toLowerCase()} + ) })} ) } -} \ No newline at end of file +} diff --git a/i18n/en/cycle-day.js b/i18n/en/cycle-day.js index ff7ed56..78cd4e2 100644 --- a/i18n/en/cycle-day.js +++ b/i18n/en/cycle-day.js @@ -92,5 +92,6 @@ export const sharedDialogs = { areYouSureToUnset: 'Are you sure you want to unset all entered data?', reallyUnsetData: 'Yes, I am sure', save: 'Save', - unset: 'Unset' + unset: 'Unset', + disabledInfo: 'There is some data missing' } From d8b53da134d2b0cf5fabef292b30c740c2a90aef Mon Sep 17 00:00:00 2001 From: Lisa Hillebrand Date: Sun, 9 Dec 2018 18:10:39 +0100 Subject: [PATCH 11/36] Added about section to settings --- components/settings/about.js | 17 +++++++++++++++++ components/settings/index.js | 2 ++ i18n/en/settings.js | 4 ++++ 3 files changed, 23 insertions(+) create mode 100644 components/settings/about.js diff --git a/components/settings/about.js b/components/settings/about.js new file mode 100644 index 0000000..85a7721 --- /dev/null +++ b/components/settings/about.js @@ -0,0 +1,17 @@ +import React, { Component } from 'react' +import { + View +} from 'react-native' +import AppText from '../app-text' +import styles from '../../styles/index' +import { settings as labels } from '../../i18n/en/settings' +export default class AboutSection extends Component { + render() { + return ( + + {`${labels.aboutSection.title} `} + {`${labels.aboutSection.segmentExplainer} `} + + ) + } +} diff --git a/components/settings/index.js b/components/settings/index.js index b91acbc..8091867 100644 --- a/components/settings/index.js +++ b/components/settings/index.js @@ -10,6 +10,7 @@ import AppText from '../app-text' import TempReminderPicker from './temp-reminder-picker' import PeriodReminderPicker from './period-reminder' import TempSlider from './temp-slider' +import AboutSection from './about' import openImportDialogAndImport from './import-dialog' import openShareDialogAndExport from './export-dialog' import PasswordSetting from './password' @@ -61,6 +62,7 @@ export default class Settings extends Component { + ) } diff --git a/i18n/en/settings.js b/i18n/en/settings.js index eef6615..cc30955 100644 --- a/i18n/en/settings.js +++ b/i18n/en/settings.js @@ -67,5 +67,9 @@ export const settings = { backupReminder: 'Just to be safe, please backup your data using the export function before making changes to your password.\n\nLonger passwords are better! Consider using a passphrase.\n\nPlease also make sure you do not lose your password. There is no way to recover your data if you do.\n\nMaking any changes to your password setting will keep your data as it was before and restart the app.', deleteBackupReminderTitle: 'Read this before deleting your password', deleteBackupReminder: 'Deleting your password means your data will no longer be encrypted.\n\nJust to be safe, please backup your data using the export function before deleting your password.\n\nMaking any changes to your password setting will keep your data as it was before and restart the app.', + }, + aboutSection: { + title: 'About', + segmentExplainer: 'Please note that your data is stored locally on your phone and not on a server. We want to ensure that you stay in control of those sensitive information. If you are planning to switch or reset your phone, please remember to export your data before doing so. You can reinstall the app afterwards and import your data.\n\nIf you encounter any technical issues, don\'t hesitate to contact us via email (bl00dyhealth@mailbox.org). You can also contribute to the code base on GitLab (https://gitlab.com/bloodyhealth/drip/).', } } \ No newline at end of file From d3c605b8cfee06454a28b6ca7f418f2e2450d590 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Sat, 8 Dec 2018 11:33:30 +0100 Subject: [PATCH 12/36] Fix peri phase edge case --- components/home.js | 18 ------------------ lib/sympto-adapter.js | 34 +++++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/components/home.js b/components/home.js index ad4dce1..e57633d 100644 --- a/components/home.js +++ b/components/home.js @@ -9,7 +9,6 @@ import { getCycleDaysSortedByDate } from '../db' import { getFertilityStatusForDay } from '../lib/sympto-adapter' import styles from '../styles' import AppText, { AppTextLight } from './app-text' -import nothingChanged from '../db/db-unchanged' import DripHomeIcon from '../assets/drip-home-icons' const HomeButton = ({ backgroundColor, children }) => { @@ -42,23 +41,6 @@ export default class Home extends Component { } this.cycleDays = getCycleDaysSortedByDate() - this.cycleDays.addListener(this.updateState) - } - - updateState = (_, changes) => { - if (nothingChanged(changes)) return - const prediction = this.getBleedingPrediction() - const fertilityStatus = getFertilityStatusForDay(this.todayDateString) - this.setState({ - cycleDayNumber: this.getCycleDayNumber(this.todayDateString), - predictionText: determinePredictionText(prediction), - bleedingPredictionRange: getBleedingPredictionRange(prediction), - ...fertilityStatus - }) - } - - componentWillUnmount() { - this.cycleDays.removeListener(this.updateState) } passTodayTo(componentName) { diff --git a/lib/sympto-adapter.js b/lib/sympto-adapter.js index 628ea2b..980cbfe 100644 --- a/lib/sympto-adapter.js +++ b/lib/sympto-adapter.js @@ -1,16 +1,17 @@ import getFertilityStatus from './sympto' import cycleModule from './cycle' -import { fertilityStatus } from '../i18n/en/labels' import { useCervixObservable } from '../local-storage' +import { fertilityStatus as labels } from '../i18n/en/labels' export function getFertilityStatusForDay(dateString) { const status = getCycleStatusForDay(dateString) if (!status) return { - status: fertilityStatus.fertile, + status: labels.fertile, phase: null } - const phaseNameForDay = Object.keys(status.phases).find(phaseName => { + const phases = Object.keys(status.phases) + const phaseNameForDay = phases.find(phaseName => { const phase = status.phases[phaseName] const dayIsAfterPhaseStart = dateString >= phase.start.date let dayIsBeforePhaseEnd @@ -22,6 +23,12 @@ export function getFertilityStatusForDay(dateString) { return dayIsAfterPhaseStart && dayIsBeforePhaseEnd }) + // if there's only cycle data for the pre phase and the target day is after its end, + // the day is in the peri phase + if (phases.length === 1 && phases[0] === 'preOvulatory' && !phaseNameForDay) { + return formatStatus('periOvulatory', dateString, {phases: {periOvulatory: {}}}) + } + return formatStatus(phaseNameForDay, dateString, status) } @@ -58,27 +65,32 @@ function formatStatus(phaseNameForDay, dateString, status) { const mapping = { preOvulatory: () => { return { - status: fertilityStatus.infertile, + status: labels.infertile, phase: 1, - statusText: fertilityStatus.preOvuText + statusText: labels.preOvuText } }, periOvulatory: (dateString, status) => { - const phaseEnd = status.phases.periOvulatory.end + //there might not actually be any data for the phase + const peri = status.phases.periOvulatory + const phaseEnd = peri && peri.end + let s if (phaseEnd && phaseEnd.date === dateString) { - return fertilityStatus.fertileUntilEvening + s = labels.fertileUntilEvening + } else { + s = labels.fertile } return { - status: fertilityStatus.fertile, + status: s, phase: 2, - statusText: fertilityStatus.periOvuText + statusText: labels.periOvuText } }, postOvulatory: (dateString, status) => { return { - status: fertilityStatus.infertile, + status: labels.infertile, phase: 3, - statusText: fertilityStatus.postOvuText(status.temperatureShift.rule) + statusText: labels.postOvuText(status.temperatureShift.rule) } } } From a882d6843990720133a0331ab10f29543f27981e Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Sun, 9 Dec 2018 19:04:49 +0000 Subject: [PATCH 13/36] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 092419a..a7b4754 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,7 @@ Unfortunately, the react native version we use doesn't work on Windows 10 it see You can run the tests with `npm test`. ## Debugging -If you want to check what the code is actually doing you can add an extra line to your code to check a specific variable `console.log(someTestVariable)` or a function or just check whether this line gets actually reached. -Save it and run `npm run android` in one window and `rpm run log` in a different window, where it will print out what you speficied in console.log, e.g. `someTestVariable`. +In order to see logging output from the app, run `npm run log` in a separate terminal. ## NFP rules More information about how the app calculates fertility status and bleeding predictions in the [wiki on Gitlab](https://gitlab.com/bloodyhealth/drip/wikis/home) From 420befec36564398be0b72db2f0694e3f374d376 Mon Sep 17 00:00:00 2001 From: mashazyu Date: Sun, 9 Dec 2018 22:30:33 +0100 Subject: [PATCH 14/36] Fixes all export error messages --- components/settings/export-dialog.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/components/settings/export-dialog.js b/components/settings/export-dialog.js index 9a8a669..7104eba 100644 --- a/components/settings/export-dialog.js +++ b/components/settings/export-dialog.js @@ -1,14 +1,15 @@ import Share from 'react-native-share' import getDataAsCsvDataUri from '../../lib/import-export/export-to-csv' import alertError from './alert-error' -import { settings as labels } from '../../i18n/en/settings' +import { settings } from '../../i18n/en/settings' export default async function openShareDialogAndExport() { let data + const labels = settings.export try { data = getDataAsCsvDataUri() if (!data) { - return alertError(labels.export.errors.noData) + return alertError(labels.errors.noData) } } catch (err) { console.error(err) @@ -17,15 +18,15 @@ export default async function openShareDialogAndExport() { try { await Share.open({ - title: labels.export.title, + title: labels.title, url: data, - subject: labels.export.subject, + subject: labels.subject, type: 'text/csv', showAppsToView: true }) } catch (err) { console.error(err) - return alertError(labels.export.errors.problemSharing) + return alertError(labels.errors.problemSharing) } } From 2647512ecc2fffed39e56c8d9394e9481cbd336a Mon Sep 17 00:00:00 2001 From: emelko Date: Mon, 10 Dec 2018 18:01:31 +0100 Subject: [PATCH 15/36] Fix for problem with build gradle 2.3.* repository --- android/build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/android/build.gradle b/android/build.gradle index 3d21e10..12fbc47 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -35,3 +35,11 @@ ext { targetSdkVersion = 26 supportLibVersion = "26.1.0" } + +subprojects {project -> + buildscript { + repositories { + maven { url = 'https://dl.bintray.com/android/android-tools/' } + } + } +} From 9e2fc524a43fac4c27a615324d5e569d0d0a6ad6 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Mon, 10 Dec 2018 18:47:10 +0100 Subject: [PATCH 16/36] Remove unnecessary config files --- .buckconfig | 6 ------ .flowconfig | 54 ----------------------------------------------------- 2 files changed, 60 deletions(-) delete mode 100644 .buckconfig delete mode 100644 .flowconfig diff --git a/.buckconfig b/.buckconfig deleted file mode 100644 index 934256c..0000000 --- a/.buckconfig +++ /dev/null @@ -1,6 +0,0 @@ - -[android] - target = Google Inc.:Google APIs:23 - -[maven_repositories] - central = https://repo1.maven.org/maven2 diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 7d5e2d3..0000000 --- a/.flowconfig +++ /dev/null @@ -1,54 +0,0 @@ -[ignore] -; We fork some components by platform -.*/*[.]android.js - -; Ignore "BUCK" generated dirs -/\.buckd/ - -; Ignore unexpected extra "@providesModule" -.*/node_modules/.*/node_modules/fbjs/.* - -; Ignore duplicate module providers -; For RN Apps installed via npm, "Libraries" folder is inside -; "node_modules/react-native" but in the source repo it is in the root -.*/Libraries/react-native/React.js - -; Ignore polyfills -.*/Libraries/polyfills/.* - -; Ignore metro -.*/node_modules/metro/.* - -[include] - -[libs] -node_modules/react-native/Libraries/react-native/react-native-interface.js -node_modules/react-native/flow/ -node_modules/react-native/flow-github/ - -[options] -emoji=true - -module.system=haste - -munge_underscores=true - -module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' - -module.file_ext=.js -module.file_ext=.jsx -module.file_ext=.json -module.file_ext=.native.js - -suppress_type=$FlowIssue -suppress_type=$FlowFixMe -suppress_type=$FlowFixMeProps -suppress_type=$FlowFixMeState - -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) -suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ -suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy -suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError - -[version] -^0.67.0 From 041885da71faaa1958db97e20e71d667659c7ef1 Mon Sep 17 00:00:00 2001 From: Sofiya Tepikin Date: Tue, 11 Dec 2018 23:23:31 +0100 Subject: [PATCH 17/36] Adds npm script for toggling the develop panel instead of shaking the device --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e01b525..de10609 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "log": "react-native log-android", "test": "mocha --recursive --require @babel/register test && npm run lint", "test-watch": "mocha --recursive --require @babel/register --watch test", - "lint": "eslint components lib test" + "lint": "eslint components lib test", + "devtool": "adb shell input keyevent 82" }, "dependencies": { "@ptomasroos/react-native-multi-slider": "^1.0.0", From ce60588ab2fda0ebd641b903cf1fd945d89887ae Mon Sep 17 00:00:00 2001 From: tina Date: Wed, 12 Dec 2018 16:11:23 +0100 Subject: [PATCH 18/36] only returns cycledaynumber when it is not greater than 99 --- lib/cycle.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/cycle.js b/lib/cycle.js index 0f47690..b675f52 100644 --- a/lib/cycle.js +++ b/lib/cycle.js @@ -39,7 +39,8 @@ export default function config(opts) { const targetDate = LocalDate.parse(targetDateString) const lastMensesLocalDate = LocalDate.parse(lastMensesStart.date) const diffInDays = lastMensesLocalDate.until(targetDate, DAYS) - + // take maxCycleLength into account (we don't display cycle day numbers higher than 99 at the moment) + if (diffInDays >= 99) return null // cycle starts at day 1 return diffInDays + 1 } From f05394acf3ee65f06a25a7662c17231d692f6ba8 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Wed, 12 Dec 2018 19:13:34 +0100 Subject: [PATCH 19/36] Update realm --- package-lock.json | 439 ++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 234 insertions(+), 207 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0964c8a..e7fc36c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -771,12 +771,26 @@ } }, "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz", + "integrity": "sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==", "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "dependencies": { + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + } } }, "ajv-keywords": { @@ -1248,9 +1262,9 @@ } }, "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "assertion-error": { "version": "1.1.0", @@ -1287,9 +1301,9 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.7.0", @@ -2248,34 +2262,18 @@ }, "bl": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" } }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "~2.0.0" - } - }, "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "requires": { - "hoek": "2.x.x" - } - }, "bplist-creator": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz", @@ -2327,7 +2325,7 @@ }, "buffer": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", + "resolved": "http://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", "requires": { "base64-js": "0.0.8", @@ -2721,14 +2719,6 @@ "which": "^1.2.9" } }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "requires": { - "boom": "2.x.x" - } - }, "csvtojson": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/csvtojson/-/csvtojson-2.0.8.tgz", @@ -2804,7 +2794,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } @@ -2861,12 +2851,12 @@ "dependencies": { "file-type": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" }, "get-stream": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "requires": { "object-assign": "^4.0.1", @@ -2875,7 +2865,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } @@ -2902,7 +2892,7 @@ }, "deepmerge": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/deepmerge/-/deepmerge-2.1.0.tgz", "integrity": "sha512-Q89Z26KAfA3lpPGhbF6XMfYAm3jIV3avViy6KOJ2JLzFbeWHOvPQUu5aSJIWXap3gDZC2y1eF5HXEPI2wGqgvw==" }, "define-properties": { @@ -3587,7 +3577,7 @@ "dependencies": { "array-back": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "resolved": "http://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "requires": { "typical": "^2.6.0" @@ -3640,12 +3630,12 @@ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, @@ -3677,6 +3667,14 @@ "klaw": "^1.0.0" } }, + "fs-minipass": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "requires": { + "minipass": "^2.2.1" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4144,27 +4142,6 @@ } } }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", - "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", - "requires": { - "fstream": "^1.0.0", - "inherits": "2", - "minimatch": "^3.0.0" - } - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -4313,17 +4290,17 @@ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" }, "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "requires": { - "ajv": "^4.9.1", - "har-schema": "^1.0.5" + "ajv": "^6.5.5", + "har-schema": "^2.0.0" } }, "has": { @@ -4400,28 +4377,12 @@ } } }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - } - }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" - }, "home-or-tmp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", @@ -4482,11 +4443,11 @@ "integrity": "sha1-p8TnWq6C87tJBOT0P2FWc7TVGMM=" }, "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "^0.2.0", + "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" } @@ -4510,6 +4471,14 @@ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, + "ignore-walk": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "requires": { + "minimatch": "^3.0.4" + } + }, "image-size": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", @@ -5653,8 +5622,7 @@ "nan": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.0.tgz", - "integrity": "sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==", - "optional": true + "integrity": "sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==" }, "nanomatch": { "version": "1.2.13", @@ -5719,6 +5687,23 @@ "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=" }, + "needle": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.4.tgz", + "integrity": "sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA==", + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + } + } + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -5738,6 +5723,11 @@ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" }, + "node-machine-id": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.10.tgz", + "integrity": "sha512-6SVxo3Ic2Qc09z1rCJh3No7ubizPLszImsMQnZZWfzeOC6SYU4orN214++c3ikB8uaP/A6dwSlO88A3ohI5oNA==" + }, "node-modules-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", @@ -5755,21 +5745,20 @@ } }, "node-pre-gyp": { - "version": "0.6.39", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz", - "integrity": "sha512-OsJV74qxnvz/AMGgcfZoDaeDXKD3oY3QVIbBmwszTFkRisTSXbMQyn4UWzUMOtA5SVhrBZOTp0wcoSBgfMfMmQ==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", + "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==", "requires": { "detect-libc": "^1.0.2", - "hawk": "3.1.3", "mkdirp": "^0.5.1", + "needle": "^2.2.1", "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", "npmlog": "^4.0.2", - "rc": "^1.1.7", - "request": "2.81.0", + "rc": "^1.2.7", "rimraf": "^2.6.1", "semver": "^5.3.0", - "tar": "^2.2.1", - "tar-pack": "^3.4.0" + "tar": "^4" }, "dependencies": { "gauge": { @@ -5806,35 +5795,6 @@ "set-blocking": "~2.0.0" } }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.1.1", - "har-validator": "~4.2.1", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "oauth-sign": "~0.8.1", - "performance-now": "^0.2.0", - "qs": "~6.4.0", - "safe-buffer": "^5.0.1", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.0.0" - } - }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -5937,6 +5897,20 @@ "remove-trailing-separator": "^1.0.1" } }, + "npm-bundled": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz", + "integrity": "sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g==" + }, + "npm-packlist": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.12.tgz", + "integrity": "sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -6258,9 +6232,9 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" }, "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { "version": "3.0.0", @@ -6387,20 +6361,25 @@ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" }, "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "querystringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz", - "integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz", + "integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==" }, "randomatic": { "version": "3.1.0", @@ -6746,26 +6725,32 @@ } }, "realm": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/realm/-/realm-2.14.0.tgz", - "integrity": "sha512-HiCj/ZE3iZNOyWexVkhDetNEfcTtSdgsg5lop7g7rcCsE+4NM3hDRxvBjrBSk/mgs6HXBAhHohzGmREbs6piRg==", + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/realm/-/realm-2.21.0.tgz", + "integrity": "sha512-2XxkVogKOObhwBUcP7NPvyA9kU/HIeopVbAGgKanJWYw5z09J+I+q1CN2gCVR5EC4+H55Ht4loEhjDud5+LEYQ==", "requires": { "command-line-args": "^4.0.6", "decompress": "^4.2.0", "deepmerge": "2.1.0", "fs-extra": "^4.0.2", "ini": "^1.3.4", - "nan": "2.8.0", + "nan": "^2.10.0", "node-fetch": "^1.6.3", - "node-pre-gyp": "^0.6.36", + "node-machine-id": "^1.1.10", + "node-pre-gyp": "^0.11.0", "progress": "^2.0.0", "prop-types": "^15.5.10", - "request": "^2.78.0", + "request": "^2.88.0", "stream-counter": "^1.0.0", "sync-request": "^3.0.1", "url-parse": "^1.2.0" }, "dependencies": { + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, "fs-extra": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", @@ -6784,10 +6769,46 @@ "graceful-fs": "^4.1.6" } }, - "nan": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", - "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=" + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } } } }, @@ -7414,7 +7435,7 @@ "dependencies": { "commander": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "requires": { "graceful-readlink": ">= 1.0.0" @@ -7698,14 +7719,6 @@ } } }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "requires": { - "hoek": "2.x.x" - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -7891,11 +7904,6 @@ "safe-buffer": "~5.1.0" } }, - "stringstream": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", - "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==" - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -8000,41 +8008,50 @@ } }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - } - }, - "tar-pack": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz", - "integrity": "sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg==", - "requires": { - "debug": "^2.2.0", - "fstream": "^1.0.10", - "fstream-ignore": "^1.0.5", - "once": "^1.3.3", - "readable-stream": "^2.1.4", - "rimraf": "^2.5.1", - "tar": "^2.2.1", - "uid-number": "^0.0.6" + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + }, + "dependencies": { + "chownr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + }, + "minizlib": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "requires": { + "minipass": "^2.2.1" + } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + } } }, "tar-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", - "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", "requires": { "bl": "^1.0.0", - "buffer-alloc": "^1.1.0", + "buffer-alloc": "^1.2.0", "end-of-stream": "^1.0.0", "fs-constants": "^1.0.0", "readable-stream": "^2.3.0", - "to-buffer": "^1.1.0", + "to-buffer": "^1.1.1", "xtend": "^4.0.0" } }, @@ -8065,7 +8082,7 @@ "dependencies": { "array-back": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "resolved": "http://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "requires": { "typical": "^2.6.0" @@ -8299,20 +8316,15 @@ } } }, - "uid-number": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", - "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=" - }, "ultron": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=" }, "unbzip2-stream": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz", - "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz", + "integrity": "sha512-fIZnvdjblYs7Cru/xC6tCPVhz7JkYcVQQkePwMLyQELzYTds2Xn8QefPVnvdVhhZqubxNA1cASXEH5wcK0Bucw==", "requires": { "buffer": "^3.0.1", "through": "^2.3.6" @@ -8425,15 +8437,30 @@ } } }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + } + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" }, "url-parse": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz", - "integrity": "sha512-rh+KuAW36YKo0vClhQzLLveoj8FwPJNu65xLb7Mrt+eZht0IPT0IXgSv8gcMegZ6NvjJUALf6Mf25POlMwD1Fw==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", + "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", "requires": { "querystringify": "^2.0.0", "requires-port": "^1.0.0" diff --git a/package.json b/package.json index de10609..6b5de6d 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "react-native-restart": "0.0.7", "react-native-share": "^1.1.3", "react-native-vector-icons": "^5.0.0", - "realm": "^2.7.1" + "realm": "^2.21.0" }, "devDependencies": { "@babel/register": "^7.0.0-beta.55", From 5fc90818471243e1107c9f6872388872c98d3811 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Wed, 12 Dec 2018 19:17:35 +0100 Subject: [PATCH 20/36] Fix remaining vulnerabilities --- package-lock.json | 49 ++++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index e7fc36c..9ae02fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2232,18 +2232,11 @@ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" }, "basic-auth": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz", - "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "requires": { - "safe-buffer": "5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - } + "safe-buffer": "5.1.2" } }, "bcrypt-pbkdf": { @@ -2262,7 +2255,7 @@ }, "bl": { "version": "1.2.2", - "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "requires": { "readable-stream": "^2.3.5", @@ -2325,7 +2318,7 @@ }, "buffer": { "version": "3.6.0", - "resolved": "http://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", "requires": { "base64-js": "0.0.8", @@ -2794,7 +2787,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } @@ -2851,12 +2844,12 @@ "dependencies": { "file-type": { "version": "3.9.0", - "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" }, "get-stream": { "version": "2.3.1", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "requires": { "object-assign": "^4.0.1", @@ -2865,7 +2858,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } @@ -2892,7 +2885,7 @@ }, "deepmerge": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/deepmerge/-/deepmerge-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.1.0.tgz", "integrity": "sha512-Q89Z26KAfA3lpPGhbF6XMfYAm3jIV3avViy6KOJ2JLzFbeWHOvPQUu5aSJIWXap3gDZC2y1eF5HXEPI2wGqgvw==" }, "define-properties": { @@ -3577,7 +3570,7 @@ "dependencies": { "array-back": { "version": "1.0.4", - "resolved": "http://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "requires": { "typical": "^2.6.0" @@ -5153,9 +5146,9 @@ } }, "merge": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", - "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==" }, "merge-stream": { "version": "1.0.1", @@ -5598,13 +5591,13 @@ "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" }, "morgan": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz", - "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", "requires": { "basic-auth": "~2.0.0", "debug": "2.6.9", - "depd": "~1.1.1", + "depd": "~1.1.2", "on-finished": "~2.3.0", "on-headers": "~1.0.1" } @@ -7435,7 +7428,7 @@ "dependencies": { "commander": { "version": "2.8.1", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "requires": { "graceful-readlink": ">= 1.0.0" @@ -8082,7 +8075,7 @@ "dependencies": { "array-back": { "version": "1.0.4", - "resolved": "http://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "requires": { "typical": "^2.6.0" From 64f109696006da12ae96f8fe870ec86252fe63f8 Mon Sep 17 00:00:00 2001 From: batabana Date: Sun, 16 Dec 2018 10:41:31 +0100 Subject: [PATCH 21/36] switch date and symptom name in symptom screen header --- components/header/symptom-view.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/header/symptom-view.js b/components/header/symptom-view.js index d091a4c..2081776 100644 --- a/components/header/symptom-view.js +++ b/components/header/symptom-view.js @@ -20,10 +20,10 @@ export default function SymptomViewHeader(props) { /> - {formatDate(props.date)} + {props.title} - {props.title} + {formatDate(props.date)} Date: Tue, 11 Dec 2018 23:06:10 +0100 Subject: [PATCH 22/36] Fixes the 2 csv files being created on export, in Downloads --- android/app/src/main/AndroidManifest.xml | 9 +++++++-- android/app/src/main/res/xml/filepaths.xml | 4 ++++ components/settings/export-dialog.js | 17 ++++++++++++++--- lib/import-export/export-to-csv.js | 14 +------------- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 207d90a..5c5243a 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,8 @@ - + @@ -36,9 +39,11 @@ android:grantUriPermissions="true" android:exported="false"> + + + \ No newline at end of file diff --git a/components/settings/export-dialog.js b/components/settings/export-dialog.js index 7104eba..97db9d3 100644 --- a/components/settings/export-dialog.js +++ b/components/settings/export-dialog.js @@ -1,13 +1,20 @@ import Share from 'react-native-share' + +import { getCycleDaysSortedByDate } from '../../db' import getDataAsCsvDataUri from '../../lib/import-export/export-to-csv' import alertError from './alert-error' import { settings } from '../../i18n/en/settings' +import RNFS from 'react-native-fs' -export default async function openShareDialogAndExport() { +export default async function exportData() { let data const labels = settings.export + const cycleDaysByDate = getCycleDaysSortedByDate() + + if (!cycleDaysByDate.length) return alertError(labels.errors.noData) + try { - data = getDataAsCsvDataUri() + data = getDataAsCsvDataUri(cycleDaysByDate) if (!data) { return alertError(labels.errors.noData) } @@ -17,13 +24,17 @@ export default async function openShareDialogAndExport() { } try { + const path = RNFS.DocumentDirectoryPath + '/data.csv' + await RNFS.writeFile(path, data) + await Share.open({ title: labels.title, - url: data, + url: `file://${path}`, subject: labels.subject, type: 'text/csv', showAppsToView: true }) + } catch (err) { console.error(err) return alertError(labels.errors.problemSharing) diff --git a/lib/import-export/export-to-csv.js b/lib/import-export/export-to-csv.js index 619c5e2..cb73126 100644 --- a/lib/import-export/export-to-csv.js +++ b/lib/import-export/export-to-csv.js @@ -1,19 +1,8 @@ import objectPath from 'object-path' -import { Base64 } from 'js-base64' -import { getCycleDaysSortedByDate } from '../../db' import getColumnNamesForCsv from './get-csv-column-names' -export default function makeDataURI() { - const cycleDaysSortedByDate = getCycleDaysSortedByDate() - if (!cycleDaysSortedByDate.length) return null - const csv = transformToCsv(cycleDaysSortedByDate) - const encoded = Base64.encodeURI(csv) - // this is the MIME type android/libcore/MimeUtils expects, so we oblige - return `data:text/comma-separated-values;base64,${encoded}` -} - -function transformToCsv(cycleDays) { +export default function transformToCsv(cycleDays) { const columnNames = getColumnNamesForCsv() const rows = cycleDays .map(day => { @@ -23,7 +12,6 @@ function transformToCsv(cycleDays) { }) }) .map(row => row.join(',')) - rows.unshift(columnNames.join(',')) return rows.join('\n') } From 79ff978a8214421d7d5b584b5183acf118335b77 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Mon, 17 Dec 2018 19:35:36 +0100 Subject: [PATCH 23/36] Fix float imprecision --- lib/sympto/temperature.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/sympto/temperature.js b/lib/sympto/temperature.js index d738ba3..1e8c87e 100644 --- a/lib/sympto/temperature.js +++ b/lib/sympto/temperature.js @@ -51,7 +51,7 @@ function checkIfFirstHighMeasurement(temp, i, temperatureDays, ltl) { function getResultForRegularRule(nextDaysAfterPotentialFhm, ltl) { if (!nextDaysAfterPotentialFhm.every(day => day.temp > ltl)) return false const thirdDay = nextDaysAfterPotentialFhm[1] - if (rounded(thirdDay.temp - ltl, 0.1) < 0.2) return false + if (isLessThan0Point2(thirdDay.temp - ltl)) return false return { detected: true, rule: 0, @@ -77,7 +77,7 @@ function getResultForSecondExceptionRule(nextDaysAfterPotentialFhm, ltl) { if (nextDaysAfterPotentialFhm.length < 3) return false if (secondOrThirdTempIsAtOrBelowLtl(nextDaysAfterPotentialFhm, ltl)) { const fourthDay = nextDaysAfterPotentialFhm[2] - if (rounded(fourthDay.temp - ltl, 0.1) >= 0.2) { + if (isBiggerOrEqual0Point2(fourthDay.temp - ltl)) { return { detected: true, rule: 2, @@ -104,3 +104,19 @@ function rounded(val, step) { // we round the difference because of JS decimal weirdness return Math.round(val * inverted) / inverted } + + +// since we're dealing with floats, there is some imprecision in comparisons, +// so we add an error margin that is definitely much smaller than any possible +// actual difference between values +// see https://floating-point-gui.de/errors/comparison/ for background + +const errorMargin = 0.0001 + +function isLessThan0Point2(val) { + return val < (0.2 - errorMargin) +} + +function isBiggerOrEqual0Point2(val) { + return val >= (0.2 - errorMargin) +} \ No newline at end of file From d342a5c27e0bc4fb8507f9f0ae10d4cd0b674b12 Mon Sep 17 00:00:00 2001 From: Maike Orlikowski Date: Tue, 18 Dec 2018 12:13:56 +0100 Subject: [PATCH 24/36] deleted console log in render function --- components/cycle-day/symptoms/action-button-footer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/components/cycle-day/symptoms/action-button-footer.js b/components/cycle-day/symptoms/action-button-footer.js index 7f0bb5f..bfd9857 100644 --- a/components/cycle-day/symptoms/action-button-footer.js +++ b/components/cycle-day/symptoms/action-button-footer.js @@ -58,7 +58,6 @@ export default class ActionButtonFooter extends Component { icon: 'content-save-outline' } ] - console.log("Hello beautiful people") return ( {buttons.map(({ title, action, disabledCondition, icon }, i) => { From 683d90b2f8e3b906d5f337ede6d4477299ba41ad Mon Sep 17 00:00:00 2001 From: Maike Orlikowski Date: Tue, 18 Dec 2018 12:43:24 +0100 Subject: [PATCH 25/36] deleted debug comment no longer needed --- components/cycle-day/symptoms/action-button-footer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/components/cycle-day/symptoms/action-button-footer.js b/components/cycle-day/symptoms/action-button-footer.js index bfd9857..9da25e2 100644 --- a/components/cycle-day/symptoms/action-button-footer.js +++ b/components/cycle-day/symptoms/action-button-footer.js @@ -45,7 +45,6 @@ export default class ActionButtonFooter extends Component { title: labels.save, action: () => { if(saveDisabled) { - //toast ToastAndroid.show(labels.disabledInfo, ToastAndroid.LONG); console.log() } else { From 1c9eea3aa0b7159725ddad9ef7c4e535c81bbca6 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Wed, 19 Dec 2018 09:53:37 +0100 Subject: [PATCH 26/36] Split settings view up --- components/app.js | 4 +- components/menu.js | 2 +- components/settings/about.js | 14 ++-- .../{ => import-export}/export-dialog.js | 8 +- .../{ => import-export}/import-dialog.js | 8 +- components/settings/import-export/index.js | 50 +++++++++++++ components/settings/index.js | 75 ++----------------- components/settings/nfp-settings/index.js | 31 ++++++++ .../{ => nfp-settings}/temp-slider.js | 12 +-- .../settings/{ => nfp-settings}/use-cervix.js | 8 +- components/settings/password/index.js | 32 ++++---- components/settings/reminders/index.js | 22 ++++++ .../{ => reminders}/period-reminder.js | 8 +- .../{ => reminders}/temp-reminder-picker.js | 10 +-- components/settings/settings-menu.js | 38 ++++++++++ i18n/en/settings.js | 7 ++ 16 files changed, 210 insertions(+), 119 deletions(-) rename components/settings/{ => import-export}/export-dialog.js (79%) rename components/settings/{ => import-export}/import-dialog.js (86%) create mode 100644 components/settings/import-export/index.js create mode 100644 components/settings/nfp-settings/index.js rename components/settings/{ => nfp-settings}/temp-slider.js (86%) rename components/settings/{ => nfp-settings}/use-cervix.js (86%) create mode 100644 components/settings/reminders/index.js rename components/settings/{ => reminders}/period-reminder.js (84%) rename components/settings/{ => reminders}/temp-reminder-picker.js (89%) create mode 100644 components/settings/settings-menu.js diff --git a/components/app.js b/components/app.js index ce0eaf2..93a7428 100644 --- a/components/app.js +++ b/components/app.js @@ -7,7 +7,7 @@ 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 settingsViews from './settings' import Stats from './stats' import {headerTitles, menuTitles} from '../i18n/en/labels' import setupNotifications from '../lib/notifications' @@ -68,7 +68,7 @@ export default class App extends Component { render() { const page = { - Home, Calendar, CycleDay, Chart, Settings, Stats, ...symptomViews + Home, Calendar, CycleDay, Chart, ...settingsViews, Stats, ...symptomViews }[this.state.currentPage] return ( diff --git a/components/menu.js b/components/menu.js index 4e80cbb..7a692e0 100644 --- a/components/menu.js +++ b/components/menu.js @@ -38,7 +38,7 @@ export default class Menu extends Component { { title: t.Calendar, icon: 'calendar-range', onPress: () => this.goTo('Calendar') }, { title: t.Chart, icon: 'chart-line', onPress: () => this.goTo('Chart') }, { title: t.Stats, icon: 'chart-pie', onPress: () => this.goTo('Stats') }, - { title: t.Settings, icon: 'settings', onPress: () => this.goTo('Settings') }, + { title: t.Settings, icon: 'settings', onPress: () => this.goTo('SettingsMenu') }, ].map(this.makeMenuItem)} ) diff --git a/components/settings/about.js b/components/settings/about.js index 85a7721..fbeb32e 100644 --- a/components/settings/about.js +++ b/components/settings/about.js @@ -1,17 +1,17 @@ import React, { Component } from 'react' -import { - View -} from 'react-native' +import { View, ScrollView } from 'react-native' import AppText from '../app-text' import styles from '../../styles/index' import { settings as labels } from '../../i18n/en/settings' export default class AboutSection extends Component { render() { return ( - - {`${labels.aboutSection.title} `} - {`${labels.aboutSection.segmentExplainer} `} - + + + {`${labels.aboutSection.title} `} + {`${labels.aboutSection.segmentExplainer} `} + + ) } } diff --git a/components/settings/export-dialog.js b/components/settings/import-export/export-dialog.js similarity index 79% rename from components/settings/export-dialog.js rename to components/settings/import-export/export-dialog.js index 97db9d3..e568a19 100644 --- a/components/settings/export-dialog.js +++ b/components/settings/import-export/export-dialog.js @@ -1,9 +1,9 @@ import Share from 'react-native-share' -import { getCycleDaysSortedByDate } from '../../db' -import getDataAsCsvDataUri from '../../lib/import-export/export-to-csv' -import alertError from './alert-error' -import { settings } from '../../i18n/en/settings' +import { getCycleDaysSortedByDate } from '../../../db' +import getDataAsCsvDataUri from '../../../lib/import-export/export-to-csv' +import alertError from '../alert-error' +import { settings } from '../../../i18n/en/settings' import RNFS from 'react-native-fs' export default async function exportData() { diff --git a/components/settings/import-dialog.js b/components/settings/import-export/import-dialog.js similarity index 86% rename from components/settings/import-dialog.js rename to components/settings/import-export/import-dialog.js index 5701b08..fe374c8 100644 --- a/components/settings/import-dialog.js +++ b/components/settings/import-export/import-dialog.js @@ -1,10 +1,10 @@ import { Alert } from 'react-native' import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker' import rnfs from 'react-native-fs' -import importCsv from '../../lib/import-export/import-from-csv' -import { shared as sharedLabels } from '../../i18n/en/labels' -import { settings as labels } from '../../i18n/en/settings' -import alertError from './alert-error' +import importCsv from '../../../lib/import-export/import-from-csv' +import { shared as sharedLabels } from '../../../i18n/en/labels' +import { settings as labels } from '../../../i18n/en/settings' +import alertError from '../alert-error' export default function openImportDialogAndImport() { Alert.alert( diff --git a/components/settings/import-export/index.js b/components/settings/import-export/index.js new file mode 100644 index 0000000..4ea77dd --- /dev/null +++ b/components/settings/import-export/index.js @@ -0,0 +1,50 @@ +import React, { Component } from 'react' +import { + View, ScrollView, + TouchableOpacity, +} from 'react-native' +import styles from '../../../styles/index' +import { settings as labels } from '../../../i18n/en/settings' +import AppText from '../../app-text' +import openImportDialogAndImport from './import-dialog' +import openShareDialogAndExport from './export-dialog' + +export default class Settings extends Component { + constructor(props) { + super(props) + this.state = {} + } + + render() { + return ( + + + + {labels.export.button} + + {labels.export.segmentExplainer} + + + {labels.export.button} + + + + + + {labels.import.button} + + {labels.import.segmentExplainer} + + + {labels.import.button} + + + + + ) + } +} diff --git a/components/settings/index.js b/components/settings/index.js index 8091867..3bc35c0 100644 --- a/components/settings/index.js +++ b/components/settings/index.js @@ -1,69 +1,10 @@ -import React, { Component } from 'react' -import { - View, - TouchableOpacity, - ScrollView, -} from 'react-native' -import styles from '../../styles/index' -import { settings as labels } from '../../i18n/en/settings' -import AppText from '../app-text' -import TempReminderPicker from './temp-reminder-picker' -import PeriodReminderPicker from './period-reminder' -import TempSlider from './temp-slider' -import AboutSection from './about' -import openImportDialogAndImport from './import-dialog' -import openShareDialogAndExport from './export-dialog' -import PasswordSetting from './password' -import UseCervixSetting from './use-cervix' +import SettingsMenu from './settings-menu' +import Reminders from './reminders' +import NfpSettings from './nfp-settings' +import ImportExport from './import-export' +import Password from './password' +import About from './about' -export default class Settings extends Component { - constructor(props) { - super(props) - this.state = {} - } - - render() { - return ( - - - - - - {labels.tempScale.segmentTitle} - - {labels.tempScale.segmentExplainer} - - - - - - - {labels.export.button} - - {labels.export.segmentExplainer} - - - {labels.export.button} - - - - - - {labels.import.button} - - {labels.import.segmentExplainer} - - - {labels.import.button} - - - - - - ) - } +export default { + SettingsMenu, Reminders, NfpSettings, ImportExport, Password, About } diff --git a/components/settings/nfp-settings/index.js b/components/settings/nfp-settings/index.js new file mode 100644 index 0000000..ceb48a8 --- /dev/null +++ b/components/settings/nfp-settings/index.js @@ -0,0 +1,31 @@ +import React, { Component } from 'react' +import { + ScrollView, View +} from 'react-native' +import styles from '../../../styles' +import { settings as labels } from '../../../i18n/en/settings' +import AppText from '../../app-text' +import TempSlider from './temp-slider' +import UseCervixSetting from './use-cervix' + +export default class Settings extends Component { + constructor(props) { + super(props) + this.state = {} + } + + render() { + return ( + + + + + {labels.tempScale.segmentTitle} + + {labels.tempScale.segmentExplainer} + + + + ) + } +} diff --git a/components/settings/temp-slider.js b/components/settings/nfp-settings/temp-slider.js similarity index 86% rename from components/settings/temp-slider.js rename to components/settings/nfp-settings/temp-slider.js index 7052299..c4e2988 100644 --- a/components/settings/temp-slider.js +++ b/components/settings/nfp-settings/temp-slider.js @@ -1,15 +1,15 @@ import React, { Component } from 'react' import { View } from 'react-native' import Slider from '@ptomasroos/react-native-multi-slider' -import AppText from '../app-text' +import AppText from '../../app-text' import { scaleObservable, saveTempScale, -} from '../../local-storage' -import { secondaryColor } from '../../styles/index' -import { settings as labels } from '../../i18n/en/settings' -import config from '../../config' -import alertError from './alert-error' +} from '../../../local-storage' +import { secondaryColor } from '../../../styles/index' +import { settings as labels } from '../../../i18n/en/settings' +import config from '../../../config' +import alertError from '../alert-error' export default class TempSlider extends Component { constructor(props) { diff --git a/components/settings/use-cervix.js b/components/settings/nfp-settings/use-cervix.js similarity index 86% rename from components/settings/use-cervix.js rename to components/settings/nfp-settings/use-cervix.js index 668a0e8..2c7f868 100644 --- a/components/settings/use-cervix.js +++ b/components/settings/nfp-settings/use-cervix.js @@ -4,13 +4,13 @@ import { TouchableOpacity, Switch } from 'react-native' -import AppText from '../app-text' +import AppText from '../../app-text' import { useCervixObservable, saveUseCervix -} from '../../local-storage' -import styles from '../../styles/index' -import { settings as labels } from '../../i18n/en/settings' +} from '../../../local-storage' +import styles from '../../../styles/index' +import { settings as labels } from '../../../i18n/en/settings' export default class UseCervixSetting extends Component { constructor() { diff --git a/components/settings/password/index.js b/components/settings/password/index.js index 47e4848..22b48c7 100644 --- a/components/settings/password/index.js +++ b/components/settings/password/index.js @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { View } from 'react-native' +import { View, ScrollView } from 'react-native' import CreatePassword from './create' import ChangePassword from './update' import DeletePassword from './delete' @@ -21,30 +21,32 @@ export default class PasswordSetting extends Component { render() { return ( - + + - - {labels.passwordSettings.title} - + + {labels.passwordSettings.title} + - {this.state.showUpdateAndDelete ? - {labels.passwordSettings.explainerEnabled} - : - {labels.passwordSettings.explainerDisabled} - } + {this.state.showUpdateAndDelete ? + {labels.passwordSettings.explainerEnabled} + : + {labels.passwordSettings.explainerDisabled} + } - {this.state.showUpdateAndDelete && + {this.state.showUpdateAndDelete && - } + } - {this.state.showCreate && + {this.state.showCreate && - } + } - + + ) } } \ No newline at end of file diff --git a/components/settings/reminders/index.js b/components/settings/reminders/index.js new file mode 100644 index 0000000..ca234d1 --- /dev/null +++ b/components/settings/reminders/index.js @@ -0,0 +1,22 @@ +import React, { Component } from 'react' +import { + ScrollView, +} from 'react-native' +import TempReminderPicker from './temp-reminder-picker' +import PeriodReminderPicker from './period-reminder' + +export default class Settings extends Component { + constructor(props) { + super(props) + this.state = {} + } + + render() { + return ( + + + + + ) + } +} diff --git a/components/settings/period-reminder.js b/components/settings/reminders/period-reminder.js similarity index 84% rename from components/settings/period-reminder.js rename to components/settings/reminders/period-reminder.js index 1bc41cb..b091741 100644 --- a/components/settings/period-reminder.js +++ b/components/settings/reminders/period-reminder.js @@ -3,13 +3,13 @@ import { View, Switch } from 'react-native' -import AppText from '../app-text' +import AppText from '../../app-text' import { periodReminderObservable, savePeriodReminder -} from '../../local-storage' -import styles from '../../styles/index' -import { settings as labels } from '../../i18n/en/settings' +} from '../../../local-storage' +import styles from '../../../styles/index' +import { settings as labels } from '../../../i18n/en/settings' export default class PeriodReminderPicker extends Component { constructor(props) { diff --git a/components/settings/temp-reminder-picker.js b/components/settings/reminders/temp-reminder-picker.js similarity index 89% rename from components/settings/temp-reminder-picker.js rename to components/settings/reminders/temp-reminder-picker.js index 48a7611..1a37d41 100644 --- a/components/settings/temp-reminder-picker.js +++ b/components/settings/reminders/temp-reminder-picker.js @@ -5,14 +5,14 @@ import { Switch } from 'react-native' import DateTimePicker from 'react-native-modal-datetime-picker-nevo' -import AppText from '../app-text' +import AppText from '../../app-text' import { tempReminderObservable, saveTempReminder -} from '../../local-storage' -import styles from '../../styles/index' -import { settings as labels } from '../../i18n/en/settings' -import padWithZeros from '../helpers/pad-time-with-zeros' +} from '../../../local-storage' +import styles from '../../../styles/index' +import { settings as labels } from '../../../i18n/en/settings' +import padWithZeros from '../../helpers/pad-time-with-zeros' export default class TempReminderPicker extends Component { constructor(props) { diff --git a/components/settings/settings-menu.js b/components/settings/settings-menu.js new file mode 100644 index 0000000..502759a --- /dev/null +++ b/components/settings/settings-menu.js @@ -0,0 +1,38 @@ +import React from 'react' +import { + TouchableOpacity, + ScrollView, +} from 'react-native' +import styles from '../../styles/index' +import { settings as settingsLabels } from '../../i18n/en/settings' +import AppText from '../app-text' + +const labels = settingsLabels.menuTitles + +const menu = [ + {title: labels.reminders, component: 'Reminders'}, + {title: labels.nfpSettings, component: 'NfpSettings'}, + {title: labels.importExport, component: 'ImportExport'}, + {title: labels.password, component: 'Password'}, + {title: labels.about, component: 'About'} +] + +export default function SettingsMenu(props) { + return ( + + { menu.map(menuItem)} + + ) + + function menuItem(item) { + return ( + props.navigate(item.component)} + > + {item.title} + + ) + } +} \ No newline at end of file diff --git a/i18n/en/settings.js b/i18n/en/settings.js index cc30955..24d9ef7 100644 --- a/i18n/en/settings.js +++ b/i18n/en/settings.js @@ -1,4 +1,11 @@ export const settings = { + menuTitles: { + reminders: 'Reminders', + importExport: 'Import and Export', + nfpSettings: 'NFP settings', + password: 'Password', + about: 'About' + }, export: { errors: { noData: 'There is no data to export', From 73e21772780e21ac326f43b9cd915dd3016b8049 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Wed, 19 Dec 2018 10:00:47 +0100 Subject: [PATCH 27/36] Fix back behavior --- components/app.js | 6 +++++- components/settings/index.js | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/components/app.js b/components/app.js index 93a7428..39318f3 100644 --- a/components/app.js +++ b/components/app.js @@ -7,6 +7,7 @@ import Calendar from './calendar' import CycleDay from './cycle-day/cycle-day-overview' import symptomViews from './cycle-day/symptoms' import Chart from './chart/chart' +import SettingsMenu from './settings/settings-menu' import settingsViews from './settings' import Stats from './stats' import {headerTitles, menuTitles} from '../i18n/en/labels' @@ -24,6 +25,7 @@ const menuTitlesLowerCase = Object.keys(menuTitles).reduce((acc, curr) => { }, {}) const isSymptomView = name => Object.keys(symptomViews).includes(name) +const isSettingsView = name => Object.keys(settingsViews).includes(name) const isMenuItem = name => Object.keys(menuTitles).includes(name) export default class App extends Component { @@ -58,6 +60,8 @@ export default class App extends Component { this.navigate( this.originForSymptomView, { date: this.state.currentProps.date } ) + } else if (isSettingsView(this.state.currentPage)) { + this.navigate('SettingsMenu') } else if(this.state.currentPage === 'CycleDay') { this.navigate(this.menuOrigin) } else { @@ -68,7 +72,7 @@ export default class App extends Component { render() { const page = { - Home, Calendar, CycleDay, Chart, ...settingsViews, Stats, ...symptomViews + Home, Calendar, CycleDay, Chart, SettingsMenu, ...settingsViews, Stats, ...symptomViews }[this.state.currentPage] return ( diff --git a/components/settings/index.js b/components/settings/index.js index 3bc35c0..a1eaa03 100644 --- a/components/settings/index.js +++ b/components/settings/index.js @@ -1,4 +1,3 @@ -import SettingsMenu from './settings-menu' import Reminders from './reminders' import NfpSettings from './nfp-settings' import ImportExport from './import-export' @@ -6,5 +5,5 @@ import Password from './password' import About from './about' export default { - SettingsMenu, Reminders, NfpSettings, ImportExport, Password, About + Reminders, NfpSettings, ImportExport, Password, About } From 59dff5066ed301c556c337e41b46b6da36f0c15d Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Wed, 19 Dec 2018 10:25:18 +0100 Subject: [PATCH 28/36] Add header titles --- components/settings/about.js | 2 +- components/settings/import-export/import-dialog.js | 2 +- components/settings/import-export/index.js | 2 +- components/settings/nfp-settings/index.js | 2 +- components/settings/nfp-settings/temp-slider.js | 2 +- components/settings/nfp-settings/use-cervix.js | 2 +- components/settings/password/delete.js | 2 +- components/settings/password/index.js | 2 +- components/settings/password/show-backup-reminder.js | 2 +- components/settings/reminders/period-reminder.js | 2 +- components/settings/reminders/temp-reminder-picker.js | 2 +- components/settings/settings-menu.js | 4 +++- i18n/en/labels.js | 10 +++++++++- i18n/en/settings.js | 2 +- 14 files changed, 24 insertions(+), 14 deletions(-) diff --git a/components/settings/about.js b/components/settings/about.js index fbeb32e..96d0b96 100644 --- a/components/settings/about.js +++ b/components/settings/about.js @@ -2,7 +2,7 @@ import React, { Component } from 'react' import { View, ScrollView } from 'react-native' import AppText from '../app-text' import styles from '../../styles/index' -import { settings as labels } from '../../i18n/en/settings' +import labels from '../../i18n/en/settings' export default class AboutSection extends Component { render() { return ( diff --git a/components/settings/import-export/import-dialog.js b/components/settings/import-export/import-dialog.js index fe374c8..2ff977e 100644 --- a/components/settings/import-export/import-dialog.js +++ b/components/settings/import-export/import-dialog.js @@ -3,7 +3,7 @@ import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker import rnfs from 'react-native-fs' import importCsv from '../../../lib/import-export/import-from-csv' import { shared as sharedLabels } from '../../../i18n/en/labels' -import { settings as labels } from '../../../i18n/en/settings' +import labels from '../../../i18n/en/settings' import alertError from '../alert-error' export default function openImportDialogAndImport() { diff --git a/components/settings/import-export/index.js b/components/settings/import-export/index.js index 4ea77dd..430f29b 100644 --- a/components/settings/import-export/index.js +++ b/components/settings/import-export/index.js @@ -4,7 +4,7 @@ import { TouchableOpacity, } from 'react-native' import styles from '../../../styles/index' -import { settings as labels } from '../../../i18n/en/settings' +import labels from '../../../i18n/en/settings' import AppText from '../../app-text' import openImportDialogAndImport from './import-dialog' import openShareDialogAndExport from './export-dialog' diff --git a/components/settings/nfp-settings/index.js b/components/settings/nfp-settings/index.js index ceb48a8..bac516c 100644 --- a/components/settings/nfp-settings/index.js +++ b/components/settings/nfp-settings/index.js @@ -3,7 +3,7 @@ import { ScrollView, View } from 'react-native' import styles from '../../../styles' -import { settings as labels } from '../../../i18n/en/settings' +import labels from '../../../i18n/en/settings' import AppText from '../../app-text' import TempSlider from './temp-slider' import UseCervixSetting from './use-cervix' diff --git a/components/settings/nfp-settings/temp-slider.js b/components/settings/nfp-settings/temp-slider.js index c4e2988..9dcdfb9 100644 --- a/components/settings/nfp-settings/temp-slider.js +++ b/components/settings/nfp-settings/temp-slider.js @@ -7,7 +7,7 @@ import { saveTempScale, } from '../../../local-storage' import { secondaryColor } from '../../../styles/index' -import { settings as labels } from '../../../i18n/en/settings' +import labels from '../../../i18n/en/settings' import config from '../../../config' import alertError from '../alert-error' diff --git a/components/settings/nfp-settings/use-cervix.js b/components/settings/nfp-settings/use-cervix.js index 2c7f868..ecfe5d3 100644 --- a/components/settings/nfp-settings/use-cervix.js +++ b/components/settings/nfp-settings/use-cervix.js @@ -10,7 +10,7 @@ import { saveUseCervix } from '../../../local-storage' import styles from '../../../styles/index' -import { settings as labels } from '../../../i18n/en/settings' +import labels from '../../../i18n/en/settings' export default class UseCervixSetting extends Component { constructor() { diff --git a/components/settings/password/delete.js b/components/settings/password/delete.js index d75f2de..6cef844 100644 --- a/components/settings/password/delete.js +++ b/components/settings/password/delete.js @@ -6,7 +6,7 @@ import { import nodejs from 'nodejs-mobile-react-native' import AppText from '../../app-text' import styles from '../../../styles' -import { settings as labels } from '../../../i18n/en/settings' +import labels from '../../../i18n/en/settings' import { requestHash, changeEncryptionAndRestartApp } from '../../../db' import PasswordField from './password-field' import showBackUpReminder from './show-backup-reminder' diff --git a/components/settings/password/index.js b/components/settings/password/index.js index 22b48c7..f5741e3 100644 --- a/components/settings/password/index.js +++ b/components/settings/password/index.js @@ -8,7 +8,7 @@ import { hasEncryptionObservable } from '../../../local-storage' import styles from '../../../styles/index' -import { settings as labels } from '../../../i18n/en/settings' +import labels from '../../../i18n/en/settings' export default class PasswordSetting extends Component { constructor(props) { diff --git a/components/settings/password/show-backup-reminder.js b/components/settings/password/show-backup-reminder.js index 708b81c..f61e5a4 100644 --- a/components/settings/password/show-backup-reminder.js +++ b/components/settings/password/show-backup-reminder.js @@ -1,6 +1,6 @@ import { Alert } from 'react-native' import { shared } from '../../../i18n/en/labels' -import { settings as labels } from '../../../i18n/en/settings' +import labels from '../../../i18n/en/settings' export default function showBackUpReminder(okHandler, isDelete) { let title, message diff --git a/components/settings/reminders/period-reminder.js b/components/settings/reminders/period-reminder.js index b091741..3c07c10 100644 --- a/components/settings/reminders/period-reminder.js +++ b/components/settings/reminders/period-reminder.js @@ -9,7 +9,7 @@ import { savePeriodReminder } from '../../../local-storage' import styles from '../../../styles/index' -import { settings as labels } from '../../../i18n/en/settings' +import labels from '../../../i18n/en/settings' export default class PeriodReminderPicker extends Component { constructor(props) { diff --git a/components/settings/reminders/temp-reminder-picker.js b/components/settings/reminders/temp-reminder-picker.js index 1a37d41..09dda42 100644 --- a/components/settings/reminders/temp-reminder-picker.js +++ b/components/settings/reminders/temp-reminder-picker.js @@ -11,7 +11,7 @@ import { saveTempReminder } from '../../../local-storage' import styles from '../../../styles/index' -import { settings as labels } from '../../../i18n/en/settings' +import labels from '../../../i18n/en/settings' import padWithZeros from '../../helpers/pad-time-with-zeros' export default class TempReminderPicker extends Component { diff --git a/components/settings/settings-menu.js b/components/settings/settings-menu.js index 502759a..4152c11 100644 --- a/components/settings/settings-menu.js +++ b/components/settings/settings-menu.js @@ -4,10 +4,12 @@ import { ScrollView, } from 'react-native' import styles from '../../styles/index' -import { settings as settingsLabels } from '../../i18n/en/settings' +import settingsLabels from '../../i18n/en/settings' import AppText from '../app-text' +console.log(settingsLabels.menuTitles) const labels = settingsLabels.menuTitles +console.log(settingsLabels.menuTitles) const menu = [ {title: labels.reminders, component: 'Reminders'}, diff --git a/i18n/en/labels.js b/i18n/en/labels.js index 059e2c0..743f4c1 100644 --- a/i18n/en/labels.js +++ b/i18n/en/labels.js @@ -1,3 +1,6 @@ +import labels from './settings' +const settingsTitles = labels.menuTitles + export const shared = { cancel: 'Cancel', save: 'Save', @@ -21,7 +24,12 @@ export const headerTitles = { Calendar: 'Calendar', Chart: 'Chart', Stats: 'Statistics', - Settings: 'Settings', + SettingsMenu: 'Settings', + Reminders: settingsTitles.reminders, + NfpSettings: settingsTitles.nfpSettings, + ImportExport: settingsTitles.importExport, + Password: settingsTitles.password, + About: settingsTitles.about, BleedingEditView: 'Bleeding', TemperatureEditView: 'Temperature', MucusEditView: 'Mucus', diff --git a/i18n/en/settings.js b/i18n/en/settings.js index 24d9ef7..d230cf0 100644 --- a/i18n/en/settings.js +++ b/i18n/en/settings.js @@ -1,4 +1,4 @@ -export const settings = { +export default { menuTitles: { reminders: 'Reminders', importExport: 'Import and Export', From b8914b53396d346a28a005abdf69b642dee3a371 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Wed, 19 Dec 2018 10:31:42 +0100 Subject: [PATCH 29/36] Fix imports --- components/settings/import-export/export-dialog.js | 2 +- components/settings/password/create.js | 2 +- components/settings/password/enter-new-password.js | 2 +- components/settings/password/update.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/settings/import-export/export-dialog.js b/components/settings/import-export/export-dialog.js index e568a19..58301cf 100644 --- a/components/settings/import-export/export-dialog.js +++ b/components/settings/import-export/export-dialog.js @@ -3,7 +3,7 @@ import Share from 'react-native-share' import { getCycleDaysSortedByDate } from '../../../db' import getDataAsCsvDataUri from '../../../lib/import-export/export-to-csv' import alertError from '../alert-error' -import { settings } from '../../../i18n/en/settings' +import settings from '../../../i18n/en/settings' import RNFS from 'react-native-fs' export default async function exportData() { diff --git a/components/settings/password/create.js b/components/settings/password/create.js index 011bbd7..bda688f 100644 --- a/components/settings/password/create.js +++ b/components/settings/password/create.js @@ -1,6 +1,6 @@ import React, { Component } from 'react' import { View } from 'react-native' -import { settings } from '../../../i18n/en/settings' +import settings from '../../../i18n/en/settings' import EnterNewPassword from './enter-new-password' import SettingsButton from './settings-button' import showBackUpReminder from './show-backup-reminder' diff --git a/components/settings/password/enter-new-password.js b/components/settings/password/enter-new-password.js index a63556b..ed09ead 100644 --- a/components/settings/password/enter-new-password.js +++ b/components/settings/password/enter-new-password.js @@ -8,7 +8,7 @@ import PasswordField from './password-field' import SettingsButton from './settings-button' import styles from '../../../styles' -import { settings } from '../../../i18n/en/settings' +import settings from '../../../i18n/en/settings' const LISTENER_TYPE = 'create-or-change-pw' diff --git a/components/settings/password/update.js b/components/settings/password/update.js index 33cddbd..a246c0e 100644 --- a/components/settings/password/update.js +++ b/components/settings/password/update.js @@ -2,7 +2,7 @@ import React, { Component } from 'react' import { View } from 'react-native' import nodejs from 'nodejs-mobile-react-native' import { shared as sharedLabels } from '../../../i18n/en/labels' -import { settings } from '../../../i18n/en/settings' +import settings from '../../../i18n/en/settings' import { requestHash } from '../../../db' import EnterNewPassword from './enter-new-password' import PasswordField from './password-field' From 8696a6d7eaf56bfa9286132376f48067fe31740f Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Thu, 20 Dec 2018 14:52:00 +0100 Subject: [PATCH 30/36] Add info text --- components/settings/nfp-settings/index.js | 4 ++++ i18n/en/settings.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/components/settings/nfp-settings/index.js b/components/settings/nfp-settings/index.js index bac516c..35d9a25 100644 --- a/components/settings/nfp-settings/index.js +++ b/components/settings/nfp-settings/index.js @@ -25,6 +25,10 @@ export default class Settings extends Component { {labels.tempScale.segmentExplainer} + + {`${labels.preOvu.title} `} + {`${labels.preOvu.note} `} + ) } diff --git a/i18n/en/settings.js b/i18n/en/settings.js index d230cf0..3351ffa 100644 --- a/i18n/en/settings.js +++ b/i18n/en/settings.js @@ -78,5 +78,9 @@ export default { aboutSection: { title: 'About', segmentExplainer: 'Please note that your data is stored locally on your phone and not on a server. We want to ensure that you stay in control of those sensitive information. If you are planning to switch or reset your phone, please remember to export your data before doing so. You can reinstall the app afterwards and import your data.\n\nIf you encounter any technical issues, don\'t hesitate to contact us via email (bl00dyhealth@mailbox.org). You can also contribute to the code base on GitLab (https://gitlab.com/bloodyhealth/drip/).', + }, + preOvu: { + title: 'Infertile days at cycle start', + note: "drip applies NFP's rules for calculating infertile days at the start of the cycle (see the wiki for more info). However, drip does not currently apply the so called 20-day-rule, which determines infertile days at the cycle start from past cycle lengths, in case no past symptothermal info is available." } } \ No newline at end of file From f1b152bb5aaacbb0961ec6546675af95f3b50414 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Thu, 20 Dec 2018 14:59:49 +0100 Subject: [PATCH 31/36] Add icon --- components/settings/nfp-settings/index.js | 8 ++++++-- i18n/en/settings.js | 2 +- styles/index.js | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/components/settings/nfp-settings/index.js b/components/settings/nfp-settings/index.js index 35d9a25..8375350 100644 --- a/components/settings/nfp-settings/index.js +++ b/components/settings/nfp-settings/index.js @@ -2,11 +2,12 @@ import React, { Component } from 'react' import { ScrollView, View } from 'react-native' -import styles from '../../../styles' +import styles, { iconStyles } from '../../../styles' import labels from '../../../i18n/en/settings' import AppText from '../../app-text' import TempSlider from './temp-slider' import UseCervixSetting from './use-cervix' +import Icon from 'react-native-vector-icons/Entypo' export default class Settings extends Component { constructor(props) { @@ -26,7 +27,10 @@ export default class Settings extends Component { - {`${labels.preOvu.title} `} + + + {`${labels.preOvu.title} `} + {`${labels.preOvu.note} `} diff --git a/i18n/en/settings.js b/i18n/en/settings.js index 3351ffa..a37ca75 100644 --- a/i18n/en/settings.js +++ b/i18n/en/settings.js @@ -81,6 +81,6 @@ export default { }, preOvu: { title: 'Infertile days at cycle start', - note: "drip applies NFP's rules for calculating infertile days at the start of the cycle (see the wiki for more info). However, drip does not currently apply the so called 20-day-rule, which determines infertile days at the cycle start from past cycle lengths, in case no past symptothermal info is available." + note: "drip applies NFP's rules for calculating infertile days at the start of the cycle (see the wiki for more info). However, drip does not currently apply the so called 20-day-rule, which determines infertile days at the cycle start from past cycle lengths in case no past symptothermal info is available." } } \ No newline at end of file diff --git a/styles/index.js b/styles/index.js index 852b6fb..d61b3b7 100644 --- a/styles/index.js +++ b/styles/index.js @@ -409,4 +409,8 @@ export const iconStyles = { menuIconInactive: { color: colorInActive, }, + infoInHeading: { + marginRight: 5, + color: 'black' + } } \ No newline at end of file From 77363511adc93322f19b6ae40da170b0248c2e0e Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Thu, 20 Dec 2018 15:05:25 +0100 Subject: [PATCH 32/36] Add bottom margin --- components/settings/nfp-settings/index.js | 2 +- styles/index.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/components/settings/nfp-settings/index.js b/components/settings/nfp-settings/index.js index 8375350..a83405e 100644 --- a/components/settings/nfp-settings/index.js +++ b/components/settings/nfp-settings/index.js @@ -26,7 +26,7 @@ export default class Settings extends Component { {labels.tempScale.segmentExplainer} - + {`${labels.preOvu.title} `} diff --git a/styles/index.js b/styles/index.js index d61b3b7..f4558e4 100644 --- a/styles/index.js +++ b/styles/index.js @@ -259,6 +259,9 @@ export default StyleSheet.create({ marginHorizontal: defaultIndentation, padding: 7, }, + settingsSegmentLast: { + marginBottom: defaultTopMargin, + }, settingsSegmentTitle: { fontWeight: 'bold' }, From 0aa817957052c320a0cfd75b12e7459b470a912a Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Thu, 20 Dec 2018 15:45:13 +0100 Subject: [PATCH 33/36] Add link --- components/app-text.js | 47 +++++++++++------------ components/link.js | 13 +++++++ components/settings/nfp-settings/index.js | 7 +++- i18n/en/settings.js | 5 ++- styles/index.js | 4 ++ 5 files changed, 49 insertions(+), 27 deletions(-) create mode 100644 components/link.js diff --git a/components/app-text.js b/components/app-text.js index eabab32..6e996da 100644 --- a/components/app-text.js +++ b/components/app-text.js @@ -1,33 +1,30 @@ -import React, { Component } from 'react' +import React from 'react' import { Text } from 'react-native' import styles from "../styles" -export default class AppText extends Component { - render() { - return ( - - {this.props.children} - - ) - } +export default function AppText(props) { + return ( + + {props.children} + + ) } -export class AppTextLight extends Component { - render() { - return ( - - {this.props.children} - - ) - } +export function AppTextLight(props) { + return ( + + {props.children} + + ) } -export class SymptomSectionHeader extends Component { - render() { - return ( - - {this.props.children} - - ) - } +export function SymptomSectionHeader(props) { + return ( + + {props.children} + + ) } \ No newline at end of file diff --git a/components/link.js b/components/link.js new file mode 100644 index 0000000..f5d2c10 --- /dev/null +++ b/components/link.js @@ -0,0 +1,13 @@ +import React from 'react' +import { Linking } from 'react-native' +import AppText from "./app-text" +import styles from '../styles'; + +export default function Link(props) { + return ( + Linking.openURL(props.href)} + >{props.text} + ) +} \ No newline at end of file diff --git a/components/settings/nfp-settings/index.js b/components/settings/nfp-settings/index.js index a83405e..e975dc7 100644 --- a/components/settings/nfp-settings/index.js +++ b/components/settings/nfp-settings/index.js @@ -8,6 +8,7 @@ import AppText from '../../app-text' import TempSlider from './temp-slider' import UseCervixSetting from './use-cervix' import Icon from 'react-native-vector-icons/Entypo' +import Link from '../../link' export default class Settings extends Component { constructor(props) { @@ -31,7 +32,11 @@ export default class Settings extends Component { {`${labels.preOvu.title} `} - {`${labels.preOvu.note} `} + + {labels.preOvu.note1} + + {labels.preOvu.note2} + ) diff --git a/i18n/en/settings.js b/i18n/en/settings.js index a37ca75..b703703 100644 --- a/i18n/en/settings.js +++ b/i18n/en/settings.js @@ -1,3 +1,4 @@ + export default { menuTitles: { reminders: 'Reminders', @@ -81,6 +82,8 @@ export default { }, preOvu: { title: 'Infertile days at cycle start', - note: "drip applies NFP's rules for calculating infertile days at the start of the cycle (see the wiki for more info). However, drip does not currently apply the so called 20-day-rule, which determines infertile days at the cycle start from past cycle lengths in case no past symptothermal info is available." + note1: "drip applies NFP's rules for calculating infertile days at the start of the cycle (see the ", + link: 'wiki', + note2: " for more info). However, drip does not currently apply the so called 20-day-rule, which determines infertile days at the cycle start from past cycle lengths in case no past symptothermal info is available." } } \ No newline at end of file diff --git a/styles/index.js b/styles/index.js index f4558e4..1c6cf62 100644 --- a/styles/index.js +++ b/styles/index.js @@ -40,6 +40,10 @@ export default StyleSheet.create({ emphasis: { fontWeight: 'bold', }, + link: { + color: cycleDayColor, + textDecorationLine: 'underline' + }, title: { fontSize: 18, color: 'black', From 2c48d59f547d2265d5a52c923361a59201dd473a Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 21 Dec 2018 08:43:52 +0100 Subject: [PATCH 34/36] Rename module --- components/cycle-day/symptoms/mucus.js | 4 ++-- lib/{sensiplan-mucus.js => nfp-mucus.js} | 0 test/sensiplan-mucus.spec.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename lib/{sensiplan-mucus.js => nfp-mucus.js} (100%) diff --git a/components/cycle-day/symptoms/mucus.js b/components/cycle-day/symptoms/mucus.js index f2c268d..7de9896 100644 --- a/components/cycle-day/symptoms/mucus.js +++ b/components/cycle-day/symptoms/mucus.js @@ -7,7 +7,7 @@ import { import styles from '../../../styles' import { saveSymptom } from '../../../db' import { mucus as labels } from '../../../i18n/en/cycle-day' -import computeSensiplanValue from '../../../lib/sensiplan-mucus' +import computeNfpValue from '../../../lib/nfp-mucus' import ActionButtonFooter from './action-button-footer' import SelectTabGroup from '../select-tab-group' import SymptomSection from './symptom-section' @@ -80,7 +80,7 @@ export default class Mucus extends Component { saveSymptom('mucus', this.props.date, { feeling, texture, - value: computeSensiplanValue(feeling, texture), + value: computeNfpValue(feeling, texture), exclude: Boolean(this.state.exclude) }) }} diff --git a/lib/sensiplan-mucus.js b/lib/nfp-mucus.js similarity index 100% rename from lib/sensiplan-mucus.js rename to lib/nfp-mucus.js diff --git a/test/sensiplan-mucus.spec.js b/test/sensiplan-mucus.spec.js index df1c461..accbfe3 100644 --- a/test/sensiplan-mucus.spec.js +++ b/test/sensiplan-mucus.spec.js @@ -4,7 +4,7 @@ import dirtyChai from 'dirty-chai' const expect = chai.expect chai.use(dirtyChai) -import getSensiplanMucus from '../lib/sensiplan-mucus' +import getSensiplanMucus from '../lib/nfp-mucus' describe('getSensiplanMucus', () => { From db68df9cfd355db0de5577ed8d48c6736b4ba090 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 21 Dec 2018 15:58:27 +0100 Subject: [PATCH 35/36] Add credits to about section --- components/settings/about.js | 4 ++++ i18n/en/settings.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/components/settings/about.js b/components/settings/about.js index 96d0b96..ab63482 100644 --- a/components/settings/about.js +++ b/components/settings/about.js @@ -11,6 +11,10 @@ export default class AboutSection extends Component { {`${labels.aboutSection.title} `} {`${labels.aboutSection.segmentExplainer} `} + + {`${labels.credits.title} `} + {`${labels.credits.note}`} + ) } diff --git a/i18n/en/settings.js b/i18n/en/settings.js index b703703..9d46eb4 100644 --- a/i18n/en/settings.js +++ b/i18n/en/settings.js @@ -85,5 +85,9 @@ export default { note1: "drip applies NFP's rules for calculating infertile days at the start of the cycle (see the ", link: 'wiki', note2: " for more info). However, drip does not currently apply the so called 20-day-rule, which determines infertile days at the cycle start from past cycle lengths in case no past symptothermal info is available." + }, + credits: { + title: 'Credits', + note: 'Thanks and lots of <3 to all of our contributors, as well as, and especially, Susanne Umscheid for the wonderful visual and logo design, and Paula Härtel for the symptom icons' } } \ No newline at end of file From a0ef9fbe8e709ab746e09893abc222ba8213ede5 Mon Sep 17 00:00:00 2001 From: Julia Friesel Date: Fri, 21 Dec 2018 16:02:18 +0100 Subject: [PATCH 36/36] Add margin --- components/settings/about.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/settings/about.js b/components/settings/about.js index ab63482..5d7cba1 100644 --- a/components/settings/about.js +++ b/components/settings/about.js @@ -11,7 +11,7 @@ export default class AboutSection extends Component { {`${labels.aboutSection.title} `} {`${labels.aboutSection.segmentExplainer} `} - + {`${labels.credits.title} `} {`${labels.credits.note}`}