diff --git a/components/settings/about.js b/components/settings/about.js index 6ee54511ac57c9dd59838972cd5011e6bc419e48..9e334026151a296873c4e98a08001cac8d434be5 100644 --- a/components/settings/about.js +++ b/components/settings/about.js @@ -2,7 +2,7 @@ import React, { Component } from 'react' import { ScrollView } from 'react-native' import Hyperlink from 'react-native-hyperlink' import AppText from '../app-text' -import SettingsSegment from './settings-segment' +import SettingsSegment from './shared/settings-segment' import styles from '../../styles/index' import labels, { links } from '../../i18n/en/settings' import replace from '../helpers/replace-url-with-text' @@ -13,21 +13,21 @@ export default class AboutSection extends Component { <ScrollView> <SettingsSegment title={labels.aboutSection.title}> <Hyperlink linkStyle={styles.link} linkText={replace}> - <AppText>{`${labels.aboutSection.text} `}</AppText> + <AppText>{labels.aboutSection.text}</AppText> </Hyperlink> </SettingsSegment> <SettingsSegment title={labels.philosophy.title}> <AppText>{labels.philosophy.text}</AppText> </SettingsSegment> <SettingsSegment title={labels.credits.title}> - <AppText>{`${labels.credits.note}`}</AppText> + <AppText>{labels.credits.note}</AppText> </SettingsSegment> <SettingsSegment title={labels.website.title}> <Hyperlink linkStyle={styles.link}> <AppText>{links.website.url}</AppText> </Hyperlink> </SettingsSegment> - <SettingsSegment title={labels.version.title} last={true}> + <SettingsSegment title={labels.version.title} last> <AppText>{require('../../package.json').version}</AppText> </SettingsSegment> </ScrollView> diff --git a/components/settings/data-management/delete-data.js b/components/settings/data-management/delete-data.js index dd09c4a149a9d4b4dc64b95e636f00aac919b574..581c881f7408bf797e302697a2f299e4ac6d4008 100644 --- a/components/settings/data-management/delete-data.js +++ b/components/settings/data-management/delete-data.js @@ -4,9 +4,9 @@ import { Alert, ToastAndroid } from 'react-native' import { clearDb, isDbEmpty } from '../../../db' import { hasEncryptionObservable } from '../../../local-storage' -import SettingsButton from '../settings-button' -import ConfirmWithPassword from './confirm-with-password' -import alertError from '../alert-error' +import SettingsButton from '../shared/settings-button' +import ConfirmWithPassword from '../shared/confirm-with-password' +import alertError from '../shared/alert-error' import settings from '../../../i18n/en/settings' import { shared as sharedLabels } from '../../../i18n/en/labels' diff --git a/components/settings/data-management/export-dialog.js b/components/settings/data-management/export-dialog.js index cfc5f5d5d3e5e0580e6833298ffc310a12801f86..4b47c2c52106053ac1eab911678c0d01ca8b0f9d 100644 --- a/components/settings/data-management/export-dialog.js +++ b/components/settings/data-management/export-dialog.js @@ -2,7 +2,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 alertError from '../shared/alert-error' import settings from '../../../i18n/en/settings' import { EXPORT_FILE_NAME } from './constants' import RNFS from 'react-native-fs' diff --git a/components/settings/data-management/import-dialog.js b/components/settings/data-management/import-dialog.js index 2ff977e27e44fc71c9b696fd72e037971b98e92f..5971c4bb1e4837ed8b5c35b3ce74aa0afe253678 100644 --- a/components/settings/data-management/import-dialog.js +++ b/components/settings/data-management/import-dialog.js @@ -4,7 +4,7 @@ import rnfs from 'react-native-fs' import importCsv from '../../../lib/import-export/import-from-csv' import { shared as sharedLabels } from '../../../i18n/en/labels' import labels from '../../../i18n/en/settings' -import alertError from '../alert-error' +import alertError from '../shared/alert-error' export default function openImportDialogAndImport() { Alert.alert( diff --git a/components/settings/data-management/index.js b/components/settings/data-management/index.js index 93887b8cef1f62ae147f4d10536a57b8c332c19f..43b4f48a22248e86805d385414e836f4575221d7 100644 --- a/components/settings/data-management/index.js +++ b/components/settings/data-management/index.js @@ -1,8 +1,8 @@ import React from 'react' import { ScrollView } from 'react-native' import AppText from '../../app-text' -import SettingsSegment from '../settings-segment' -import SettingsButton from '../settings-button' +import SettingsSegment from '../shared/settings-segment' +import SettingsButton from '../shared/settings-button' import openImportDialogAndImport from './import-dialog' import openShareDialogAndExport from './export-dialog' import DeleteData from './delete-data' @@ -25,7 +25,7 @@ const DataManagement = () => { </SettingsSegment> <SettingsSegment title={labels.deleteSegment.title} - last={true} + last > <AppText>{labels.deleteSegment.explainer}</AppText> <DeleteData /> diff --git a/components/settings/nfp-settings/index.js b/components/settings/nfp-settings/index.js index c4810bcc92c0b56ea904dc34e476981509b87f99..a95c5def03dbb375a048c1ed02d53fdb19ae3139 100644 --- a/components/settings/nfp-settings/index.js +++ b/components/settings/nfp-settings/index.js @@ -6,6 +6,7 @@ import Hyperlink from 'react-native-hyperlink' import styles, { iconStyles } from '../../../styles' import labels from '../../../i18n/en/settings' import AppText from '../../app-text' +import SettingsSegment from '../shared/settings-segment' import TempSlider from './temp-slider' import UseCervixSetting from './use-cervix' import Icon from 'react-native-vector-icons/Entypo' @@ -20,15 +21,14 @@ export default class Settings extends Component { render() { return ( <ScrollView> - <UseCervixSetting/> - <View style={styles.settingsSegment}> - <AppText style={styles.settingsSegmentTitle}> - {labels.tempScale.segmentTitle} - </AppText> + <SettingsSegment title={labels.useCervix.title}> + <UseCervixSetting/> + </SettingsSegment> + <SettingsSegment title={labels.tempScale.segmentTitle}> <AppText>{labels.tempScale.segmentExplainer}</AppText> <TempSlider/> - </View> - <View style={[styles.settingsSegment, styles.settingsSegmentLast]}> + </SettingsSegment> + <SettingsSegment style={styles.settingsSegmentLast} > <View style={{flexDirection: 'row', alignItems: 'center'}}> <Icon name="info-with-circle" style={iconStyles.infoInHeading}/> <AppText style={styles.settingsSegmentTitle}>{`${labels.preOvu.title} `}</AppText> @@ -36,8 +36,8 @@ export default class Settings extends Component { <Hyperlink linkStyle={styles.link} linkText={replaceUrlWithText}> <AppText>{labels.preOvu.note}</AppText> </Hyperlink> - </View> + </SettingsSegment> </ScrollView> ) } -} +} \ No newline at end of file diff --git a/components/settings/nfp-settings/temp-slider.js b/components/settings/nfp-settings/temp-slider.js index 9dcdfb9824722bd0511e7a9453f3e79e737520c5..ecccaf472fe21a5b5b34e1440289b8af46672841 100644 --- a/components/settings/nfp-settings/temp-slider.js +++ b/components/settings/nfp-settings/temp-slider.js @@ -9,7 +9,7 @@ import { import { secondaryColor } from '../../../styles/index' import labels from '../../../i18n/en/settings' import config from '../../../config' -import alertError from '../alert-error' +import alertError from '../shared/alert-error' export default class TempSlider extends Component { constructor(props) { diff --git a/components/settings/nfp-settings/use-cervix.js b/components/settings/nfp-settings/use-cervix.js index ecfe5d3825786a0c4803ff58a91f9b8201ac3bf2..2bb9ff985168d382b72b7b35e2a861e2a92672bb 100644 --- a/components/settings/nfp-settings/use-cervix.js +++ b/components/settings/nfp-settings/use-cervix.js @@ -1,7 +1,6 @@ import React, { Component } from 'react' import { View, - TouchableOpacity, Switch } from 'react-native' import AppText from '../../app-text' @@ -9,7 +8,6 @@ import { useCervixObservable, saveUseCervix } from '../../../local-storage' -import styles from '../../../styles/index' import labels from '../../../i18n/en/settings' export default class UseCervixSetting extends Component { @@ -20,29 +18,22 @@ export default class UseCervixSetting extends Component { render() { return ( - <TouchableOpacity - style={styles.settingsSegment} - > - <AppText style={styles.settingsSegmentTitle}> - {labels.useCervix.title} - </AppText> - <View style={{ flexDirection: 'row', alignItems: 'center' }}> - <View style={{ flex: 1 }}> - {this.state.useCervix ? - <AppText>{labels.useCervix.cervixModeOn}</AppText> - : - <AppText>{labels.useCervix.cervixModeOff}</AppText> - } - </View> - <Switch - value={this.state.useCervix} - onValueChange={bool => { - this.setState({ useCervix: bool }) - saveUseCervix(bool) - }} - /> + <View style={{ flexDirection: 'row', alignItems: 'center' }}> + <View style={{ flex: 1 }}> + {this.state.useCervix ? + <AppText>{labels.useCervix.cervixModeOn}</AppText> + : + <AppText>{labels.useCervix.cervixModeOff}</AppText> + } </View> - </TouchableOpacity> + <Switch + value={this.state.useCervix} + onValueChange={bool => { + this.setState({ useCervix: bool }) + saveUseCervix(bool) + }} + /> + </View> ) } } diff --git a/components/settings/password/check-current-password.js b/components/settings/password/check-current-password.js deleted file mode 100644 index 92d78bf99effcfc56cfb4afd758bbc7e16371ab3..0000000000000000000000000000000000000000 --- a/components/settings/password/check-current-password.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Alert } from 'react-native' -import { openDb } from '../../../db' -import { shared } from '../../../i18n/en/labels' - -export default async function checkPassword({hash, onCancel, onTryAgain }) { - try { - await openDb(hash) - return true - } catch (err) { - Alert.alert( - shared.incorrectPassword, - shared.incorrectPasswordMessage, - [{ - text: shared.cancel, - onPress: onCancel - }, { - text: shared.tryAgain, - onPress: onTryAgain - }] - ) - return false - } -} \ No newline at end of file diff --git a/components/settings/password/create.js b/components/settings/password/create.js index cdc9b69c3a9e85cfe9925cf10ecd73c04fc76247..aaa021dcb905756c15a5be1f6a85c1064661fea2 100644 --- a/components/settings/password/create.js +++ b/components/settings/password/create.js @@ -2,7 +2,7 @@ import React, { Component } from 'react' import { View } from 'react-native' import settings from '../../../i18n/en/settings' import EnterNewPassword from './enter-new-password' -import SettingsButton from '../settings-button' +import SettingsButton from '../shared/settings-button' import showBackUpReminder from './show-backup-reminder' export default class CreatePassword extends Component { diff --git a/components/settings/password/delete.js b/components/settings/password/delete.js index 6cef844e5c3896e85c46017ebd0a36e8e7893fe8..b6435a09d38448cdd552d8c10ad8d723c8465213 100644 --- a/components/settings/password/delete.js +++ b/components/settings/password/delete.js @@ -1,80 +1,47 @@ import React, { Component } from 'react' -import { - View, - TouchableOpacity -} from 'react-native' -import nodejs from 'nodejs-mobile-react-native' -import AppText from '../../app-text' -import styles from '../../../styles' import labels from '../../../i18n/en/settings' -import { requestHash, changeEncryptionAndRestartApp } from '../../../db' -import PasswordField from './password-field' -import showBackUpReminder from './show-backup-reminder' -import checkCurrentPassword from './check-current-password' +import { changeEncryptionAndRestartApp } from '../../../db' +import ConfirmWithPassword from '../shared/confirm-with-password' +import SettingsButton from '../shared/settings-button' export default class DeletePassword extends Component { constructor() { super() this.state = { - enteringCurrentPassword: false, - currentPassword: null + enteringCurrentPassword: false } - - nodejs.channel.addListener( - 'pre-delete-pw-check', - this.removeEncryption, - this - ) } - componentWillUnmount() { - nodejs.channel.removeListener('pre-delete-pw-check', this.removeEncryption) + startConfirmWithPassword = () => { + this.setState({ enteringCurrentPassword: true }) + this.props.onStartDeletingPassword() } - removeEncryption = async hash => { - const passwordIsCorrect = await checkCurrentPassword({ - hash, - onTryAgain: () => this.setState({currentPassword: null}), - onCancel: () => this.setState({ - enteringCurrentPassword: false, - currentPassword: null - }) - }) + startDeletePassword = async () => { + await changeEncryptionAndRestartApp() + } - if (passwordIsCorrect) await changeEncryptionAndRestartApp() + cancelConfirmationWithPassword = () => { + this.setState({ enteringCurrentPassword: false }) } render() { + + const { enteringCurrentPassword } = this.state + + if (enteringCurrentPassword) { + return ( + <ConfirmWithPassword + onSuccess={this.startDeletePassword} + onCancel={this.cancelConfirmationWithPassword} + /> + ) + } + return ( - <View> - {this.state.enteringCurrentPassword && - <PasswordField - onChangeText={val => this.setState({ currentPassword: val })} - value={this.state.currentPassword} - placeholder={labels.passwordSettings.enterCurrent} - /> - } - <TouchableOpacity - onPress={() => { - if (!this.state.enteringCurrentPassword) { - showBackUpReminder(() => { - this.setState({ enteringCurrentPassword: true }) - }, true) - } else { - requestHash('pre-delete-pw-check', this.state.currentPassword) - } - }} - disabled={ - this.state.enteringCurrentPassword && - !this.state.currentPassword - } - style={styles.settingsButton} - > - <AppText style={styles.settingsButtonText}> - {labels.passwordSettings.deletePassword} - </AppText> - </TouchableOpacity> - </View> + <SettingsButton onPress={this.startConfirmWithPassword} > + {labels.passwordSettings.deletePassword} + </SettingsButton> ) } } \ No newline at end of file diff --git a/components/settings/password/enter-new-password.js b/components/settings/password/enter-new-password.js index 084a6bc671f6f11f765520228f794a75d45dd757..cba3a11c731c232a756fa02c4d8f6b8b9442ed12 100644 --- a/components/settings/password/enter-new-password.js +++ b/components/settings/password/enter-new-password.js @@ -4,8 +4,8 @@ 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 PasswordField from '../shared/password-field' +import SettingsButton from '../shared/settings-button' import styles from '../../../styles' import settings from '../../../i18n/en/settings' diff --git a/components/settings/password/index.js b/components/settings/password/index.js index fca09664f5cd06f6dce2ac4e61430fd9ce3e4def..d9caf4b1659773ab9d13933260a9e20903c17bc0 100644 --- a/components/settings/password/index.js +++ b/components/settings/password/index.js @@ -1,9 +1,9 @@ import React, { Component } from 'react' -import { View, ScrollView } from 'react-native' +import { ScrollView } from 'react-native' import CreatePassword from './create' import ChangePassword from './update' import DeletePassword from './delete' -import SettingsSegment from '../settings-segment' +import SettingsSegment from '../shared/settings-segment' import AppText from '../../app-text' import { hasEncryptionObservable @@ -14,33 +14,54 @@ export default class PasswordSetting extends Component { constructor(props) { super(props) this.state = { - showUpdateAndDelete: hasEncryptionObservable.value, - showCreate: !hasEncryptionObservable.value + isPasswordSet: hasEncryptionObservable.value, + isChangingPassword: false, + isDeletingPassword: false } } + onChangingPassword = () => { + this.setState({ isChangingPassword: true }) + } + + onDeletingPassword = () => { + this.setState({ isDeletingPassword: true }) + } + render() { + + const { + isPasswordSet, + isChangingPassword, + isDeletingPassword, + } = this.state + + const { + title, + explainerEnabled, + explainerDisabled + } = labels.passwordSettings + return ( <ScrollView> - <SettingsSegment title={labels.passwordSettings.title}> - - {this.state.showUpdateAndDelete ? - <AppText>{labels.passwordSettings.explainerEnabled}</AppText> - : - <AppText>{labels.passwordSettings.explainerDisabled}</AppText> - } + <SettingsSegment title={title}> + <AppText> + { isPasswordSet ? explainerEnabled : explainerDisabled } + </AppText> - {this.state.showUpdateAndDelete && - <View> - <ChangePassword/> - <DeletePassword/> - </View> - } + { !isPasswordSet && <CreatePassword/> } - {this.state.showCreate && - <CreatePassword/> - } + { (isPasswordSet && !isDeletingPassword) && ( + <ChangePassword + onStartChangingPassword = {this.onChangingPassword} + /> + )} + { (isPasswordSet && !isChangingPassword) && ( + <DeletePassword + onStartDeletingPassword = {this.onDeletingPassword} + /> + )} </SettingsSegment> </ScrollView> ) diff --git a/components/settings/password/update.js b/components/settings/password/update.js index bac6d2bcf2d41e51c1d1f4aa6cb58fcad638de54..e09433ae7525cd5084bdc94b63809f2ba5513327 100644 --- a/components/settings/password/update.js +++ b/components/settings/password/update.js @@ -1,14 +1,9 @@ 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 { requestHash } from '../../../db' import EnterNewPassword from './enter-new-password' -import PasswordField from './password-field' -import SettingsButton from '../settings-button' +import SettingsButton from '../shared/settings-button' import showBackUpReminder from './show-backup-reminder' -import checkCurrentPassword from './check-current-password' +import ConfirmWithPassword from '../shared/confirm-with-password' export default class ChangePassword extends Component { @@ -19,49 +14,29 @@ export default class ChangePassword extends Component { enteringCurrentPassword: false, enteringNewPassword: false } - - nodejs.channel.addListener( - 'pre-change-pw-check', - this.openNewPasswordField, - this - ) - } - - componentWillUnmount() { - nodejs.channel.removeListener('pre-change-pw-check', this.openNewPasswordField) - } - - openNewPasswordField = async hash => { - const passwordCorrect = await checkCurrentPassword({ - hash, - onTryAgain: () => this.setState({ currentPassword: null }), - onCancel: () => this.setState({ - enteringCurrentPassword: false, - currentPassword: null - }) - }) - - if (passwordCorrect) { - this.setState({ - currentPassword: null, - enteringNewPassword: true, - enteringCurrentPassword: false - }) - } } startChangingPassword = () => { showBackUpReminder(() => { this.setState({ enteringCurrentPassword: true }) }) + this.props.onStartChangingPassword() } - handleCurrentPasswordInput = (currentPassword) => { - this.setState({ currentPassword }) + startEnteringNewPassword = () => { + this.setState({ + currentPassword: null, + enteringNewPassword: true, + enteringCurrentPassword: false + }) } - checkCurrentPassword = () => { - requestHash('pre-change-pw-check', this.state.currentPassword) + cancelConfirmationWithPassword = () => { + this.setState({ + currentPassword: null, + enteringNewPassword: false, + enteringCurrentPassword: false + }) } render() { @@ -76,19 +51,10 @@ export default class ChangePassword extends Component { if (enteringCurrentPassword) { return ( - <View> - <PasswordField - placeholder={labels.enterCurrent} - value={currentPassword} - onChangeText={this.handleCurrentPasswordInput} - /> - <SettingsButton - onPress={this.checkCurrentPassword} - disabled={!currentPassword} - > - {sharedLabels.unlock} - </SettingsButton> - </View> + <ConfirmWithPassword + onSuccess={this.startEnteringNewPassword} + onCancel={this.cancelConfirmationWithPassword} + /> ) } @@ -97,14 +63,12 @@ export default class ChangePassword extends Component { } return ( - <View> - <SettingsButton - onPress={this.startChangingPassword} - disabled={currentPassword} - > - {labels.changePassword} - </SettingsButton> - </View> + <SettingsButton + onPress={this.startChangingPassword} + disabled={currentPassword} + > + {labels.changePassword} + </SettingsButton> ) } } \ No newline at end of file diff --git a/components/settings/reminders/index.js b/components/settings/reminders/index.js index ca234d1345afa26d25118453d0510da75cf4e3e1..92fc461d5027eeb4e2d91446279178104c2929f0 100644 --- a/components/settings/reminders/index.js +++ b/components/settings/reminders/index.js @@ -2,9 +2,12 @@ import React, { Component } from 'react' import { ScrollView, } from 'react-native' +import SettingsSegment from '../shared/settings-segment' import TempReminderPicker from './temp-reminder-picker' import PeriodReminderPicker from './period-reminder' +import labels from '../../../i18n/en/settings' + export default class Settings extends Component { constructor(props) { super(props) @@ -14,8 +17,12 @@ export default class Settings extends Component { render() { return ( <ScrollView> - <TempReminderPicker/> - <PeriodReminderPicker/> + <SettingsSegment title={labels.tempReminder.title}> + <TempReminderPicker/> + </SettingsSegment> + <SettingsSegment title={labels.periodReminder.title}> + <PeriodReminderPicker/> + </SettingsSegment> </ScrollView> ) } diff --git a/components/settings/reminders/period-reminder.js b/components/settings/reminders/period-reminder.js index 3c07c1028634ba27146ea2a3964a88d01135e1bc..f7e177c654864ad0247706c59fe029976b9673fe 100644 --- a/components/settings/reminders/period-reminder.js +++ b/components/settings/reminders/period-reminder.js @@ -8,7 +8,6 @@ import { periodReminderObservable, savePeriodReminder } from '../../../local-storage' -import styles from '../../../styles/index' import labels from '../../../i18n/en/settings' export default class PeriodReminderPicker extends Component { @@ -19,22 +18,17 @@ export default class PeriodReminderPicker extends Component { render() { return ( - <View style={styles.settingsSegment}> - <AppText style={styles.settingsSegmentTitle}> - {labels.periodReminder.title} - </AppText> - <View style={{ flexDirection: 'row', alignItems: 'center' }}> - <View style={{ flex: 1 }}> - <AppText>{labels.periodReminder.reminderText}</AppText> - </View> - <Switch - value={this.state.enabled} - onValueChange={switchOn => { - this.setState({ enabled: switchOn }) - savePeriodReminder({enabled: switchOn}) - }} - /> + <View style={{ flexDirection: 'row', alignItems: 'center' }}> + <View style={{ flex: 1 }}> + <AppText>{labels.periodReminder.reminderText}</AppText> </View> + <Switch + value={this.state.enabled} + onValueChange={switchOn => { + this.setState({ enabled: switchOn }) + savePeriodReminder({enabled: switchOn}) + }} + /> </View> ) } diff --git a/components/settings/reminders/temp-reminder-picker.js b/components/settings/reminders/temp-reminder-picker.js index 09dda4255458150b300530f713f4a6dc28405cee..a481d61f392093b333bae0e4b3bb70a69ad0c9b2 100644 --- a/components/settings/reminders/temp-reminder-picker.js +++ b/components/settings/reminders/temp-reminder-picker.js @@ -10,64 +10,63 @@ import { tempReminderObservable, saveTempReminder } from '../../../local-storage' -import styles from '../../../styles/index' import labels from '../../../i18n/en/settings' import padWithZeros from '../../helpers/pad-time-with-zeros' export default class TempReminderPicker extends Component { constructor(props) { super(props) - this.state = Object.assign({}, tempReminderObservable.value) + const { time, enabled } = tempReminderObservable.value + this.state = { + time, + enabled, + isTimePickerVisible: false + } } render() { return ( <TouchableOpacity - style={styles.settingsSegment} + style={{ flexDirection: 'row', alignItems: 'center' }} onPress={() => this.setState({ isTimePickerVisible: true })} > - <AppText style={styles.settingsSegmentTitle}> - {labels.tempReminder.title} - </AppText> - <View style={{ flexDirection: 'row', alignItems: 'center' }}> - <View style={{ flex: 1 }}> - {this.state.time && this.state.enabled ? - <AppText>{labels.tempReminder.timeSet(this.state.time)}</AppText> - : - <AppText>{labels.tempReminder.noTimeSet}</AppText> - } - </View> - <Switch - value={this.state.enabled} - onValueChange={switchOn => { - this.setState({ enabled: switchOn }) - if (switchOn && !this.state.time) { - this.setState({ isTimePickerVisible: true }) - } - if (!switchOn) saveTempReminder({ enabled: false }) - }} - /> - <DateTimePicker - mode="time" - isVisible={this.state.isTimePickerVisible} - onConfirm={jsDate => { - const time = padWithZeros(jsDate) - this.setState({ - time, - isTimePickerVisible: false, - enabled: true - }) - saveTempReminder({ - time, - enabled: true - }) - }} - onCancel={() => { - this.setState({ isTimePickerVisible: false }) - if (!this.state.time) this.setState({enabled: false}) - }} - /> + <View style={{ flex: 1 }}> + {this.state.time && this.state.enabled ? + <AppText>{labels.tempReminder.timeSet(this.state.time)}</AppText> + : + <AppText>{labels.tempReminder.noTimeSet}</AppText> + } </View> + <Switch + value={this.state.enabled} + onValueChange={switchOn => { + this.setState({ enabled: switchOn }) + if (switchOn && !this.state.time) { + this.setState({ isTimePickerVisible: true }) + } + if (!switchOn) saveTempReminder({ enabled: false }) + }} + /> + <DateTimePicker + mode="time" + isVisible={this.state.isTimePickerVisible} + onConfirm={jsDate => { + const time = padWithZeros(jsDate) + this.setState({ + time, + isTimePickerVisible: false, + enabled: true + }) + saveTempReminder({ + time, + enabled: true + }) + }} + onCancel={() => { + this.setState({ isTimePickerVisible: false }) + if (!this.state.time) this.setState({enabled: false}) + }} + /> </TouchableOpacity> ) } diff --git a/components/settings/alert-error.js b/components/settings/shared/alert-error.js similarity index 65% rename from components/settings/alert-error.js rename to components/settings/shared/alert-error.js index b4d447d25742ed21e46e24e07e053e529962c766..6d08d91c317eb041bf1f7d80b53c5b3fb6777300 100644 --- a/components/settings/alert-error.js +++ b/components/settings/shared/alert-error.js @@ -1,5 +1,5 @@ import { Alert } from 'react-native' -import { shared as sharedLabels } from '../../i18n/en/labels' +import { shared as sharedLabels } from '../../../i18n/en/labels' export default function alertError(msg) { Alert.alert(sharedLabels.errorTitle, msg) diff --git a/components/settings/data-management/confirm-with-password.js b/components/settings/shared/confirm-with-password.js similarity index 92% rename from components/settings/data-management/confirm-with-password.js rename to components/settings/shared/confirm-with-password.js index fee296af379aa093dc32335962560a161da1a228..bacef7c57ef2f401760222d41822761213a9ae3f 100644 --- a/components/settings/data-management/confirm-with-password.js +++ b/components/settings/shared/confirm-with-password.js @@ -4,8 +4,8 @@ import { View, Alert } from 'react-native' import nodejs from 'nodejs-mobile-react-native' import { requestHash, openDb } from '../../../db' -import PasswordField from '../password/password-field' -import SettingsButton from '../settings-button' +import PasswordField from './password-field' +import SettingsButton from '../shared/settings-button' import settings from '../../../i18n/en/settings' import { shared } from '../../../i18n/en/labels' @@ -79,7 +79,7 @@ export default class ConfirmWithPassword extends Component { onPress={this.initPasswordCheck} disabled={!password} > - {settings.deleteSegment.title} + {shared.confirmToProceed} </SettingsButton> </View> ) diff --git a/components/settings/password/password-field.js b/components/settings/shared/password-field.js similarity index 100% rename from components/settings/password/password-field.js rename to components/settings/shared/password-field.js diff --git a/components/settings/settings-button.js b/components/settings/shared/settings-button.js similarity index 88% rename from components/settings/settings-button.js rename to components/settings/shared/settings-button.js index bfa89832f2919ac86e4c88f559851c4aecb3f042..97272bb2bb6cb603d97fcd37b97408d808ca7582 100644 --- a/components/settings/settings-button.js +++ b/components/settings/shared/settings-button.js @@ -2,8 +2,8 @@ import React from 'react' import PropTypes from 'prop-types' import { TouchableOpacity } from 'react-native' -import AppText from '../app-text' -import styles from '../../styles' +import AppText from '../../app-text' +import styles from '../../../styles' const SettingsButton = ({ children, ...props }) => { return ( diff --git a/components/settings/settings-segment.js b/components/settings/shared/settings-segment.js similarity index 57% rename from components/settings/settings-segment.js rename to components/settings/shared/settings-segment.js index f29f7c58135ae93359aba77755cf641416fb5ead..8d73a77aa58dc6324509fb72c5beb59479046b8d 100644 --- a/components/settings/settings-segment.js +++ b/components/settings/shared/settings-segment.js @@ -2,22 +2,25 @@ import React from 'react' import PropTypes from 'prop-types' import { View } from 'react-native' -import AppText from '../app-text' -import styles from '../../styles' +import AppText from '../../app-text' +import styles from '../../../styles' const SettingsSegment = ({ children, ...props }) => { const style = [styles.settingsSegment, props.style] if (props.last) style.push(styles.settingsSegmentLast) return ( - <View style={style}> - <AppText style={styles.settingsSegmentTitle}>{props.title}</AppText> + <View style={[styles.settingsSegment, props.style]}> + { + props.title + && <AppText style={styles.settingsSegmentTitle}>{props.title}</AppText> + } {children} </View> ) } SettingsSegment.propTypes = { - title: PropTypes.string.isRequired + title: PropTypes.string } export default SettingsSegment \ No newline at end of file diff --git a/i18n/en/labels.js b/i18n/en/labels.js index 0f569aab450d236f5447f52ca0451905c744c10e..c4b952af2e4aa316c936b73953e0ecd3de223385 100644 --- a/i18n/en/labels.js +++ b/i18n/en/labels.js @@ -11,7 +11,7 @@ export const shared = { incorrectPasswordMessage: 'That password is incorrect.', tryAgain: 'Try again', ok: 'OK', - unlock: 'Unlock', + confirmToProceed: 'Confirm to proceed', date: 'Date', cycleDayWithLinebreak: 'Cycle\nday', loading: 'Loading ...', diff --git a/lib/notifications.js b/lib/notifications.js index ded27c3419038a9284b48d446993a625ae0e978e..9836a379e32b8e603cbc9b89d04946408825f93b 100644 --- a/lib/notifications.js +++ b/lib/notifications.js @@ -2,7 +2,7 @@ import {tempReminderObservable, periodReminderObservable} from '../local-storage import Notification from 'react-native-push-notification' import { LocalDate } from 'js-joda' import Moment from 'moment' -import { settings as labels } from '../i18n/en/settings' +import labels from '../i18n/en/settings' import { getBleedingDaysSortedByDate } from '../db' import cycleModule from './cycle' import nothingChanged from '../db/db-unchanged'