Merge branch '273-add-submenu-to-settings' into 'master'

Resolve "add submenu to settings"

Closes #273

See merge request bloodyhealth/drip!139
This commit is contained in:
Julia Friesel
2018-12-19 16:19:34 +00:00
22 changed files with 232 additions and 128 deletions
+6 -2
View File
@@ -7,7 +7,8 @@ import Calendar from './calendar'
import CycleDay from './cycle-day/cycle-day-overview' import CycleDay from './cycle-day/cycle-day-overview'
import symptomViews from './cycle-day/symptoms' import symptomViews from './cycle-day/symptoms'
import Chart from './chart/chart' import Chart from './chart/chart'
import Settings from './settings' import SettingsMenu from './settings/settings-menu'
import settingsViews from './settings'
import Stats from './stats' import Stats from './stats'
import {headerTitles, menuTitles} from '../i18n/en/labels' import {headerTitles, menuTitles} from '../i18n/en/labels'
import setupNotifications from '../lib/notifications' import setupNotifications from '../lib/notifications'
@@ -24,6 +25,7 @@ const menuTitlesLowerCase = Object.keys(menuTitles).reduce((acc, curr) => {
}, {}) }, {})
const isSymptomView = name => Object.keys(symptomViews).includes(name) const isSymptomView = name => Object.keys(symptomViews).includes(name)
const isSettingsView = name => Object.keys(settingsViews).includes(name)
const isMenuItem = name => Object.keys(menuTitles).includes(name) const isMenuItem = name => Object.keys(menuTitles).includes(name)
export default class App extends Component { export default class App extends Component {
@@ -58,6 +60,8 @@ export default class App extends Component {
this.navigate( this.navigate(
this.originForSymptomView, { date: this.state.currentProps.date } this.originForSymptomView, { date: this.state.currentProps.date }
) )
} else if (isSettingsView(this.state.currentPage)) {
this.navigate('SettingsMenu')
} else if(this.state.currentPage === 'CycleDay') { } else if(this.state.currentPage === 'CycleDay') {
this.navigate(this.menuOrigin) this.navigate(this.menuOrigin)
} else { } else {
@@ -68,7 +72,7 @@ export default class App extends Component {
render() { render() {
const page = { const page = {
Home, Calendar, CycleDay, Chart, Settings, Stats, ...symptomViews Home, Calendar, CycleDay, Chart, SettingsMenu, ...settingsViews, Stats, ...symptomViews
}[this.state.currentPage] }[this.state.currentPage]
return ( return (
<View style={{flex: 1}}> <View style={{flex: 1}}>
+1 -1
View File
@@ -38,7 +38,7 @@ export default class Menu extends Component {
{ title: t.Calendar, icon: 'calendar-range', onPress: () => this.goTo('Calendar') }, { title: t.Calendar, icon: 'calendar-range', onPress: () => this.goTo('Calendar') },
{ title: t.Chart, icon: 'chart-line', onPress: () => this.goTo('Chart') }, { title: t.Chart, icon: 'chart-line', onPress: () => this.goTo('Chart') },
{ title: t.Stats, icon: 'chart-pie', onPress: () => this.goTo('Stats') }, { 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)} ].map(this.makeMenuItem)}
</View > </View >
) )
+8 -8
View File
@@ -1,17 +1,17 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { import { View, ScrollView } from 'react-native'
View
} from 'react-native'
import AppText from '../app-text' import AppText from '../app-text'
import styles from '../../styles/index' 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 { export default class AboutSection extends Component {
render() { render() {
return ( return (
<View style={styles.settingsSegment}> <ScrollView>
<AppText style={styles.settingsSegmentTitle}>{`${labels.aboutSection.title} `}</AppText> <View style={styles.settingsSegment}>
<AppText>{`${labels.aboutSection.segmentExplainer} `}</AppText> <AppText style={styles.settingsSegmentTitle}>{`${labels.aboutSection.title} `}</AppText>
</View> <AppText>{`${labels.aboutSection.segmentExplainer} `}</AppText>
</View>
</ScrollView>
) )
} }
} }
@@ -1,9 +1,9 @@
import Share from 'react-native-share' import Share from 'react-native-share'
import { getCycleDaysSortedByDate } from '../../db' import { getCycleDaysSortedByDate } from '../../../db'
import getDataAsCsvDataUri from '../../lib/import-export/export-to-csv' import getDataAsCsvDataUri from '../../../lib/import-export/export-to-csv'
import alertError from './alert-error' import alertError from '../alert-error'
import { settings } from '../../i18n/en/settings' import settings from '../../../i18n/en/settings'
import RNFS from 'react-native-fs' import RNFS from 'react-native-fs'
export default async function exportData() { export default async function exportData() {
@@ -1,10 +1,10 @@
import { Alert } from 'react-native' import { Alert } from 'react-native'
import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker' import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker'
import rnfs from 'react-native-fs' import rnfs from 'react-native-fs'
import importCsv from '../../lib/import-export/import-from-csv' import importCsv from '../../../lib/import-export/import-from-csv'
import { shared as sharedLabels } from '../../i18n/en/labels' 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' import alertError from '../alert-error'
export default function openImportDialogAndImport() { export default function openImportDialogAndImport() {
Alert.alert( Alert.alert(
@@ -0,0 +1,50 @@
import React, { Component } from 'react'
import {
View, ScrollView,
TouchableOpacity,
} from 'react-native'
import styles from '../../../styles/index'
import 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 (
<ScrollView>
<View style={styles.settingsSegment}>
<AppText style={styles.settingsSegmentTitle}>
{labels.export.button}
</AppText>
<AppText>{labels.export.segmentExplainer}</AppText>
<TouchableOpacity
onPress={openShareDialogAndExport}
style={styles.settingsButton}>
<AppText style={styles.settingsButtonText}>
{labels.export.button}
</AppText>
</TouchableOpacity>
</View>
<View style={styles.settingsSegment}>
<AppText style={styles.settingsSegmentTitle}>
{labels.import.button}
</AppText>
<AppText>{labels.import.segmentExplainer}</AppText>
<TouchableOpacity
onPress={openImportDialogAndImport}
style={styles.settingsButton}>
<AppText style={styles.settingsButtonText}>
{labels.import.button}
</AppText>
</TouchableOpacity>
</View>
</ScrollView>
)
}
}
+7 -67
View File
@@ -1,69 +1,9 @@
import React, { Component } from 'react' import Reminders from './reminders'
import { import NfpSettings from './nfp-settings'
View, import ImportExport from './import-export'
TouchableOpacity, import Password from './password'
ScrollView, import About from './about'
} 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'
export default class Settings extends Component { export default {
constructor(props) { Reminders, NfpSettings, ImportExport, Password, About
super(props)
this.state = {}
}
render() {
return (
<ScrollView>
<TempReminderPicker/>
<UseCervixSetting/>
<View style={styles.settingsSegment}>
<AppText style={styles.settingsSegmentTitle}>
{labels.tempScale.segmentTitle}
</AppText>
<AppText>{labels.tempScale.segmentExplainer}</AppText>
<TempSlider/>
</View>
<PeriodReminderPicker/>
<PasswordSetting />
<View style={styles.settingsSegment}>
<AppText style={styles.settingsSegmentTitle}>
{labels.export.button}
</AppText>
<AppText>{labels.export.segmentExplainer}</AppText>
<TouchableOpacity
onPress={openShareDialogAndExport}
style={styles.settingsButton}>
<AppText style={styles.settingsButtonText}>
{labels.export.button}
</AppText>
</TouchableOpacity>
</View>
<View style={styles.settingsSegment}>
<AppText style={styles.settingsSegmentTitle}>
{labels.import.button}
</AppText>
<AppText>{labels.import.segmentExplainer}</AppText>
<TouchableOpacity
onPress={openImportDialogAndImport}
style={styles.settingsButton}>
<AppText style={styles.settingsButtonText}>
{labels.import.button}
</AppText>
</TouchableOpacity>
</View>
<AboutSection/>
</ScrollView>
)
}
} }
+31
View File
@@ -0,0 +1,31 @@
import React, { Component } from 'react'
import {
ScrollView, View
} from 'react-native'
import styles from '../../../styles'
import 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 (
<ScrollView>
<UseCervixSetting/>
<View style={styles.settingsSegment}>
<AppText style={styles.settingsSegmentTitle}>
{labels.tempScale.segmentTitle}
</AppText>
<AppText>{labels.tempScale.segmentExplainer}</AppText>
<TempSlider/>
</View>
</ScrollView>
)
}
}
@@ -1,15 +1,15 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { View } from 'react-native' import { View } from 'react-native'
import Slider from '@ptomasroos/react-native-multi-slider' import Slider from '@ptomasroos/react-native-multi-slider'
import AppText from '../app-text' import AppText from '../../app-text'
import { import {
scaleObservable, scaleObservable,
saveTempScale, saveTempScale,
} from '../../local-storage' } from '../../../local-storage'
import { secondaryColor } from '../../styles/index' import { secondaryColor } from '../../../styles/index'
import { settings as labels } from '../../i18n/en/settings' import labels from '../../../i18n/en/settings'
import config from '../../config' import config from '../../../config'
import alertError from './alert-error' import alertError from '../alert-error'
export default class TempSlider extends Component { export default class TempSlider extends Component {
constructor(props) { constructor(props) {
@@ -4,13 +4,13 @@ import {
TouchableOpacity, TouchableOpacity,
Switch Switch
} from 'react-native' } from 'react-native'
import AppText from '../app-text' import AppText from '../../app-text'
import { import {
useCervixObservable, useCervixObservable,
saveUseCervix saveUseCervix
} from '../../local-storage' } from '../../../local-storage'
import styles from '../../styles/index' 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 { export default class UseCervixSetting extends Component {
constructor() { constructor() {
+1 -1
View File
@@ -1,6 +1,6 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { View } from 'react-native' import { View } from 'react-native'
import { settings } from '../../../i18n/en/settings' import settings from '../../../i18n/en/settings'
import EnterNewPassword from './enter-new-password' import EnterNewPassword from './enter-new-password'
import SettingsButton from './settings-button' import SettingsButton from './settings-button'
import showBackUpReminder from './show-backup-reminder' import showBackUpReminder from './show-backup-reminder'
+1 -1
View File
@@ -6,7 +6,7 @@ import {
import nodejs from 'nodejs-mobile-react-native' import nodejs from 'nodejs-mobile-react-native'
import AppText from '../../app-text' import AppText from '../../app-text'
import styles from '../../../styles' import styles from '../../../styles'
import { settings as labels } from '../../../i18n/en/settings' import labels from '../../../i18n/en/settings'
import { requestHash, changeEncryptionAndRestartApp } from '../../../db' import { requestHash, changeEncryptionAndRestartApp } from '../../../db'
import PasswordField from './password-field' import PasswordField from './password-field'
import showBackUpReminder from './show-backup-reminder' import showBackUpReminder from './show-backup-reminder'
@@ -8,7 +8,7 @@ import PasswordField from './password-field'
import SettingsButton from './settings-button' import SettingsButton from './settings-button'
import styles from '../../../styles' import styles from '../../../styles'
import { settings } from '../../../i18n/en/settings' import settings from '../../../i18n/en/settings'
const LISTENER_TYPE = 'create-or-change-pw' const LISTENER_TYPE = 'create-or-change-pw'
+18 -16
View File
@@ -1,5 +1,5 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { View } from 'react-native' import { View, ScrollView } from 'react-native'
import CreatePassword from './create' import CreatePassword from './create'
import ChangePassword from './update' import ChangePassword from './update'
import DeletePassword from './delete' import DeletePassword from './delete'
@@ -8,7 +8,7 @@ import {
hasEncryptionObservable hasEncryptionObservable
} from '../../../local-storage' } from '../../../local-storage'
import styles from '../../../styles/index' 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 { export default class PasswordSetting extends Component {
constructor(props) { constructor(props) {
@@ -21,30 +21,32 @@ export default class PasswordSetting extends Component {
render() { render() {
return ( return (
<View style={styles.settingsSegment}> <ScrollView>
<View style={styles.settingsSegment}>
<AppText style={styles.settingsSegmentTitle}> <AppText style={styles.settingsSegmentTitle}>
{labels.passwordSettings.title} {labels.passwordSettings.title}
</AppText> </AppText>
{this.state.showUpdateAndDelete ? {this.state.showUpdateAndDelete ?
<AppText>{labels.passwordSettings.explainerEnabled}</AppText> <AppText>{labels.passwordSettings.explainerEnabled}</AppText>
: :
<AppText>{labels.passwordSettings.explainerDisabled}</AppText> <AppText>{labels.passwordSettings.explainerDisabled}</AppText>
} }
{this.state.showUpdateAndDelete && {this.state.showUpdateAndDelete &&
<View> <View>
<ChangePassword/> <ChangePassword/>
<DeletePassword/> <DeletePassword/>
</View> </View>
} }
{this.state.showCreate && {this.state.showCreate &&
<CreatePassword/> <CreatePassword/>
} }
</View> </View>
</ScrollView>
) )
} }
} }
@@ -1,6 +1,6 @@
import { Alert } from 'react-native' import { Alert } from 'react-native'
import { shared } from '../../../i18n/en/labels' 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) { export default function showBackUpReminder(okHandler, isDelete) {
let title, message let title, message
+1 -1
View File
@@ -2,7 +2,7 @@ import React, { Component } from 'react'
import { View } from 'react-native' import { View } from 'react-native'
import nodejs from 'nodejs-mobile-react-native' import nodejs from 'nodejs-mobile-react-native'
import { shared as sharedLabels } from '../../../i18n/en/labels' 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 { requestHash } from '../../../db'
import EnterNewPassword from './enter-new-password' import EnterNewPassword from './enter-new-password'
import PasswordField from './password-field' import PasswordField from './password-field'
+22
View File
@@ -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 (
<ScrollView>
<TempReminderPicker/>
<PeriodReminderPicker/>
</ScrollView>
)
}
}
@@ -3,13 +3,13 @@ import {
View, View,
Switch Switch
} from 'react-native' } from 'react-native'
import AppText from '../app-text' import AppText from '../../app-text'
import { import {
periodReminderObservable, periodReminderObservable,
savePeriodReminder savePeriodReminder
} from '../../local-storage' } from '../../../local-storage'
import styles from '../../styles/index' 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 { export default class PeriodReminderPicker extends Component {
constructor(props) { constructor(props) {
@@ -5,14 +5,14 @@ import {
Switch Switch
} from 'react-native' } from 'react-native'
import DateTimePicker from 'react-native-modal-datetime-picker-nevo' import DateTimePicker from 'react-native-modal-datetime-picker-nevo'
import AppText from '../app-text' import AppText from '../../app-text'
import { import {
tempReminderObservable, tempReminderObservable,
saveTempReminder saveTempReminder
} from '../../local-storage' } from '../../../local-storage'
import styles from '../../styles/index' 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' import padWithZeros from '../../helpers/pad-time-with-zeros'
export default class TempReminderPicker extends Component { export default class TempReminderPicker extends Component {
constructor(props) { constructor(props) {
+40
View File
@@ -0,0 +1,40 @@
import React from 'react'
import {
TouchableOpacity,
ScrollView,
} from 'react-native'
import styles from '../../styles/index'
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'},
{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 (
<ScrollView>
{ menu.map(menuItem)}
</ScrollView>
)
function menuItem(item) {
return (
<TouchableOpacity
style={styles.settingsSegment}
key={item.title}
onPress={() => props.navigate(item.component)}
>
<AppText>{item.title}</AppText>
</TouchableOpacity>
)
}
}
+9 -1
View File
@@ -1,3 +1,6 @@
import labels from './settings'
const settingsTitles = labels.menuTitles
export const shared = { export const shared = {
cancel: 'Cancel', cancel: 'Cancel',
save: 'Save', save: 'Save',
@@ -21,7 +24,12 @@ export const headerTitles = {
Calendar: 'Calendar', Calendar: 'Calendar',
Chart: 'Chart', Chart: 'Chart',
Stats: 'Statistics', Stats: 'Statistics',
Settings: 'Settings', SettingsMenu: 'Settings',
Reminders: settingsTitles.reminders,
NfpSettings: settingsTitles.nfpSettings,
ImportExport: settingsTitles.importExport,
Password: settingsTitles.password,
About: settingsTitles.about,
BleedingEditView: 'Bleeding', BleedingEditView: 'Bleeding',
TemperatureEditView: 'Temperature', TemperatureEditView: 'Temperature',
MucusEditView: 'Mucus', MucusEditView: 'Mucus',
+8 -1
View File
@@ -1,4 +1,11 @@
export const settings = { export default {
menuTitles: {
reminders: 'Reminders',
importExport: 'Import and Export',
nfpSettings: 'NFP settings',
password: 'Password',
about: 'About'
},
export: { export: {
errors: { errors: {
noData: 'There is no data to export', noData: 'There is no data to export',