From ce5a8ce5a12f0ac2d18c376899a29f57fb4eac1b Mon Sep 17 00:00:00 2001 From: tina Date: Tue, 25 Sep 2018 13:00:55 +0200 Subject: [PATCH 1/4] set up period reminder in settings --- components/labels.js | 5 ++++ components/settings/index.js | 2 ++ components/settings/period-reminder.js | 41 ++++++++++++++++++++++++++ local-storage/index.js | 10 +++++++ 4 files changed, 58 insertions(+) create mode 100644 components/settings/period-reminder.js diff --git a/components/labels.js b/components/labels.js index 7fde2b8..60b53fc 100644 --- a/components/labels.js +++ b/components/labels.js @@ -54,6 +54,11 @@ export const settings = { timeSet: time => `Daily reminder set for ${time}`, notification: 'Record your morning temperature' }, + periodReminder: { + title: 'Next period reminder', + reminderText: 'Get a notification 3 days before your next period is likely to start.', + notification: 'your next period is likely to start in x days.' + }, passwordSettings: { title: 'App password', explainerDisabled: "Encrypt the app's database with a password. You need to enter the password every time the app is started.", diff --git a/components/settings/index.js b/components/settings/index.js index e0828d8..1180f24 100644 --- a/components/settings/index.js +++ b/components/settings/index.js @@ -8,6 +8,7 @@ import styles from '../../styles/index' import { settings as labels } from '../labels' import { AppText } from '../app-text' import TempReminderPicker from './temp-reminder-picker' +import PeriodReminderPicker from './period-reminder' import TempSlider from './temp-slider' import openImportDialogAndImport from './import-dialog' import openShareDialogAndExport from './export-dialog' @@ -30,6 +31,7 @@ export default class Settings extends Component { {labels.tempScale.segmentExplainer} + diff --git a/components/settings/period-reminder.js b/components/settings/period-reminder.js new file mode 100644 index 0000000..212c39d --- /dev/null +++ b/components/settings/period-reminder.js @@ -0,0 +1,41 @@ +import React, { Component } from 'react' +import { + View, + Switch +} from 'react-native' +import { AppText } from '../app-text' +import { + periodReminderObservable, + savePeriodReminder +} from '../../local-storage' +import styles from '../../styles/index' +import { settings as labels } from '../labels' + +export default class PeriodReminderPicker extends Component { + constructor(props) { + super(props) + this.state = Object.assign({}, periodReminderObservable.value) + } + + render() { + return ( + + + {labels.periodReminder.title} + + + + {labels.periodReminder.reminderText} + + { + this.setState({ enabled: switchOn }) + savePeriodReminder({enabled: true}) + }} + /> + + + ) + } +} \ No newline at end of file diff --git a/local-storage/index.js b/local-storage/index.js index d41d4d7..5f4af70 100644 --- a/local-storage/index.js +++ b/local-storage/index.js @@ -34,6 +34,16 @@ export async function saveTempReminder(reminder) { tempReminderObservable.set(reminder) } +export const periodReminderObservable = Observable() +setObvWithInitValue('periodReminder', periodReminderObservable, { + enabled: false +}) + +export async function savePeriodReminder(reminder) { + await AsyncStorage.setItem('periodReminder', JSON.stringify(reminder)) + periodReminderObservable.set(reminder) +} + export const hasEncryptionObservable = Observable() setObvWithInitValue('hasEncryption', hasEncryptionObservable, false) From 80bec57f69ca57848be7568a593c952ea74fd2dd Mon Sep 17 00:00:00 2001 From: tina Date: Tue, 25 Sep 2018 15:28:04 +0200 Subject: [PATCH 2/4] tries to enable notifications for next period --- components/labels.js | 2 +- components/settings/period-reminder.js | 4 +-- lib/notifications.js | 34 +++++++++++++++++++++++--- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/components/labels.js b/components/labels.js index 60b53fc..6939c51 100644 --- a/components/labels.js +++ b/components/labels.js @@ -57,7 +57,7 @@ export const settings = { periodReminder: { title: 'Next period reminder', reminderText: 'Get a notification 3 days before your next period is likely to start.', - notification: 'your next period is likely to start in x days.' + notification: daysToEndOfPrediction => `Your next period is likely to start in 3 to ${daysToEndOfPrediction} days.` }, passwordSettings: { title: 'App password', diff --git a/components/settings/period-reminder.js b/components/settings/period-reminder.js index 212c39d..70ec0fc 100644 --- a/components/settings/period-reminder.js +++ b/components/settings/period-reminder.js @@ -14,7 +14,7 @@ import { settings as labels } from '../labels' export default class PeriodReminderPicker extends Component { constructor(props) { super(props) - this.state = Object.assign({}, periodReminderObservable.value) + this.state = periodReminderObservable.value } render() { @@ -31,7 +31,7 @@ export default class PeriodReminderPicker extends Component { value={this.state.enabled} onValueChange={switchOn => { this.setState({ enabled: switchOn }) - savePeriodReminder({enabled: true}) + savePeriodReminder({enabled: switchOn}) }} /> diff --git a/lib/notifications.js b/lib/notifications.js index dc1a7a5..6dee83d 100644 --- a/lib/notifications.js +++ b/lib/notifications.js @@ -1,21 +1,28 @@ -import {tempReminderObservable} from '../local-storage' +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 '../components/labels' import { getOrCreateCycleDay } from '../db' +import cycleModule from './cycle' export default function setupNotifications(navigate) { Notification.configure({ onNotification: () => { const todayDateString = LocalDate.now().toString() const cycleDay = getOrCreateCycleDay(todayDateString) - navigate('TemperatureEditView', { cycleDay }) + if (this.id === '1') { + navigate('TemperatureEditView', { cycleDay }) + } else if (this.id === '2') { + navigate('Home') + } else { + navigate('Home') + } } }) tempReminderObservable(reminder => { - Notification.cancelAllLocalNotifications() + Notification.cancelAllLocalNotifications({id: '1'}) if (reminder.enabled) { const [hours, minutes] = reminder.time.split(':') let target = new Moment() @@ -28,6 +35,7 @@ export default function setupNotifications(navigate) { } Notification.localNotificationSchedule({ + id: '1', message: labels.tempReminder.notification, date: target.toDate(), vibrate: false, @@ -35,4 +43,24 @@ export default function setupNotifications(navigate) { }) } }) + + periodReminderObservable(reminder => { + if (reminder.enabled) { + const bleedingPrediction = cycleModule().getPredictedMenses() + if (bleedingPrediction.length > 0) { + const bleedingStart = LocalDate.parse(bleedingPrediction[0][0]) + const reminderDate = bleedingStart.minusDays(3) + // period is likely to start in 3 to 3 + (length of prediction - 1) days + const daysToEndOfPrediction = bleedingPrediction[0].length + 2 + + Notification.localNotificationSchedule({ + id: '2', + message: labels.periodReminder.notification(daysToEndOfPrediction), + date: reminderDate, + vibrate: false, + onNotification: navigate('Home') + }) + } + } + }) } \ No newline at end of file From 7101619318986d36de9fdc39feed0aaf9aab39fb Mon Sep 17 00:00:00 2001 From: tina Date: Tue, 25 Sep 2018 16:55:13 +0200 Subject: [PATCH 3/4] makes period reminder functional --- lib/notifications.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/notifications.js b/lib/notifications.js index 6dee83d..a2ba749 100644 --- a/lib/notifications.js +++ b/lib/notifications.js @@ -8,13 +8,11 @@ import cycleModule from './cycle' export default function setupNotifications(navigate) { Notification.configure({ - onNotification: () => { - const todayDateString = LocalDate.now().toString() - const cycleDay = getOrCreateCycleDay(todayDateString) - if (this.id === '1') { + onNotification: (notification) => { + if (notification.id === '1') { + const todayDateString = LocalDate.now().toString() + const cycleDay = getOrCreateCycleDay(todayDateString) navigate('TemperatureEditView', { cycleDay }) - } else if (this.id === '2') { - navigate('Home') } else { navigate('Home') } @@ -22,7 +20,7 @@ export default function setupNotifications(navigate) { }) tempReminderObservable(reminder => { - Notification.cancelAllLocalNotifications({id: '1'}) + Notification.cancelLocalNotifications({id: '1'}) if (reminder.enabled) { const [hours, minutes] = reminder.time.split(':') let target = new Moment() @@ -45,20 +43,25 @@ export default function setupNotifications(navigate) { }) periodReminderObservable(reminder => { + Notification.cancelLocalNotifications({id: '2'}) if (reminder.enabled) { const bleedingPrediction = cycleModule().getPredictedMenses() if (bleedingPrediction.length > 0) { - const bleedingStart = LocalDate.parse(bleedingPrediction[0][0]) - const reminderDate = bleedingStart.minusDays(3) + const bleedingStart = Moment(bleedingPrediction[0][0], "YYYY-MM-DD") + // 3 days before and at 6 am + const reminderDate = bleedingStart + .subtract(3, 'days') + .hours(6) + .minutes(0) + .seconds(0) // period is likely to start in 3 to 3 + (length of prediction - 1) days const daysToEndOfPrediction = bleedingPrediction[0].length + 2 Notification.localNotificationSchedule({ id: '2', message: labels.periodReminder.notification(daysToEndOfPrediction), - date: reminderDate, - vibrate: false, - onNotification: navigate('Home') + date: reminderDate.toDate(), + vibrate: false }) } } From 09a71a391ed0eca8f2f548b205a5c2ad25112bbb Mon Sep 17 00:00:00 2001 From: tina Date: Wed, 26 Sep 2018 12:15:09 +0200 Subject: [PATCH 4/4] links the period reminder to bleeding days, meaning it gets updated when they change --- lib/notifications.js | 52 +++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/lib/notifications.js b/lib/notifications.js index a2ba749..0605642 100644 --- a/lib/notifications.js +++ b/lib/notifications.js @@ -3,7 +3,7 @@ import Notification from 'react-native-push-notification' import { LocalDate } from 'js-joda' import Moment from 'moment' import { settings as labels } from '../components/labels' -import { getOrCreateCycleDay } from '../db' +import { getOrCreateCycleDay, getBleedingDaysSortedByDate } from '../db' import cycleModule from './cycle' export default function setupNotifications(navigate) { @@ -44,26 +44,34 @@ export default function setupNotifications(navigate) { periodReminderObservable(reminder => { Notification.cancelLocalNotifications({id: '2'}) - if (reminder.enabled) { - const bleedingPrediction = cycleModule().getPredictedMenses() - if (bleedingPrediction.length > 0) { - const bleedingStart = Moment(bleedingPrediction[0][0], "YYYY-MM-DD") - // 3 days before and at 6 am - const reminderDate = bleedingStart - .subtract(3, 'days') - .hours(6) - .minutes(0) - .seconds(0) - // period is likely to start in 3 to 3 + (length of prediction - 1) days - const daysToEndOfPrediction = bleedingPrediction[0].length + 2 - - Notification.localNotificationSchedule({ - id: '2', - message: labels.periodReminder.notification(daysToEndOfPrediction), - date: reminderDate.toDate(), - vibrate: false - }) - } - } + if (reminder.enabled) setupPeriodReminder() }) + + getBleedingDaysSortedByDate().addListener(() => { + Notification.cancelLocalNotifications({id: '2'}) + if (periodReminderObservable.value.enabled) setupPeriodReminder() + }) + +} + +function setupPeriodReminder() { + const bleedingPrediction = cycleModule().getPredictedMenses() + if (bleedingPrediction.length > 0) { + const bleedingStart = Moment(bleedingPrediction[0][0], "YYYY-MM-DD") + // 3 days before and at 6 am + const reminderDate = bleedingStart + .subtract(3, 'days') + .hours(6) + .minutes(0) + .seconds(0) + // period is likely to start in 3 to 3 + (length of prediction - 1) days + const daysToEndOfPrediction = bleedingPrediction[0].length + 2 + + Notification.localNotificationSchedule({ + id: '2', + message: labels.periodReminder.notification(daysToEndOfPrediction), + date: reminderDate.toDate(), + vibrate: false + }) + } } \ No newline at end of file