diff --git a/include/pbl/services/notifications/alerts_preferences.h b/include/pbl/services/notifications/alerts_preferences.h index 24744dee5..c978ffba2 100644 --- a/include/pbl/services/notifications/alerts_preferences.h +++ b/include/pbl/services/notifications/alerts_preferences.h @@ -55,6 +55,14 @@ void alerts_preferences_dnd_set_mute_speaker(bool enable); //! @return Whether the speaker is muted while DND is active bool alerts_preferences_dnd_get_mute_speaker(void); +//! Set whether notifications should auto-dismiss even when DND is active. +//! When false (default), notifications stay on screen during DND. +//! @param enable true to allow auto-dismiss during DND, false to suppress it +void alerts_preferences_dnd_set_auto_dismiss(bool enable); + +//! @return Whether auto-dismiss is allowed while DND is active +bool alerts_preferences_dnd_get_auto_dismiss(void); + //! Set the always-on speaker mute. When set, the speaker is silenced //! regardless of DND state. //! @param muted true to mute the speaker, false to allow audio diff --git a/src/fw/apps/system/settings/quiet_time.c b/src/fw/apps/system/settings/quiet_time.c index 52a3b270e..321d8545a 100644 --- a/src/fw/apps/system/settings/quiet_time.c +++ b/src/fw/apps/system/settings/quiet_time.c @@ -109,35 +109,6 @@ static const char *prv_get_dnd_mask_subtitle(void *i18n_key) { return title; } -static const DndNotificationMode s_dnd_notification_mode_cycle[] = { - DndNotificationModeShow, - DndNotificationModeHide, -}; - -static DndNotificationMode prv_cycle_dnd_notification_mode(void) { - DndNotificationMode mode = alerts_preferences_dnd_get_show_notifications(); - int index = 0; - for (size_t i = 0; i < ARRAY_LENGTH(s_dnd_notification_mode_cycle); i++) { - if (s_dnd_notification_mode_cycle[i] == mode) { - index = i; - break; - } - } - mode = s_dnd_notification_mode_cycle[(index + 1) % ARRAY_LENGTH(s_dnd_notification_mode_cycle)]; - alerts_preferences_dnd_set_show_notifications(mode); - return mode; -} - -static const char *prv_get_dnd_notifications_enable(void *i18n_key) { - switch (alerts_preferences_dnd_get_show_notifications()) { - case DndNotificationModeShow: - return i18n_get("Show", i18n_key); - case DndNotificationModeHide: - return i18n_get("Hide", i18n_key); - default: - return "???"; - } -} static void prv_get_dnd_time(DoNotDisturbScheduleType type, char *time_string, const uint8_t len) { DoNotDisturbSchedule schedule; @@ -357,6 +328,28 @@ static void prv_schedule_submenu_push(void) { app_window_stack_push(window, true /* animated */); } +static const char *prv_get_dnd_notifications_subtitle(void *i18n_key) { + if (alerts_preferences_dnd_get_show_notifications() == DndNotificationModeHide) { + return i18n_get("Off", i18n_key); + } + if (alerts_preferences_dnd_get_auto_dismiss()) { + return i18n_get("On - Auto Dismiss", i18n_key); + } + return i18n_get("On - Persistent", i18n_key); +} + +static void prv_cycle_dnd_notifications(void) { + if (alerts_preferences_dnd_get_show_notifications() == DndNotificationModeHide) { + alerts_preferences_dnd_set_show_notifications(DndNotificationModeShow); + alerts_preferences_dnd_set_auto_dismiss(false); + } else if (!alerts_preferences_dnd_get_auto_dismiss()) { + alerts_preferences_dnd_set_auto_dismiss(true); + } else { + alerts_preferences_dnd_set_show_notifications(DndNotificationModeHide); + alerts_preferences_dnd_set_auto_dismiss(false); + } +} + /////////////////////////////// // Backlight sub-menu (touch boards) /////////////////////////////// @@ -453,7 +446,7 @@ static void prv_draw_row_cb(SettingsCallbacks *context, GContext *ctx, break; case QuietTimeItemNotifications: title = i18n_get("Notifications", data); - subtitle = prv_get_dnd_notifications_enable(data); + subtitle = prv_get_dnd_notifications_subtitle(data); break; #ifdef CONFIG_TOUCH case QuietTimeItemBacklight: @@ -491,7 +484,7 @@ static void prv_select_click_cb(SettingsCallbacks *context, uint16_t row) { prv_cycle_dnd_mask(); break; case QuietTimeItemNotifications: - prv_cycle_dnd_notification_mode(); + prv_cycle_dnd_notifications(); break; #ifdef CONFIG_TOUCH case QuietTimeItemBacklight: diff --git a/src/fw/popups/notifications/notification_window.c b/src/fw/popups/notifications/notification_window.c index 6a7507663..564eddf91 100644 --- a/src/fw/popups/notifications/notification_window.c +++ b/src/fw/popups/notifications/notification_window.c @@ -559,8 +559,9 @@ T_STATIC LayoutLayer *prv_get_layout_handler(SwapLayer *swap_layer, int8_t rel_p static bool prv_should_pop_due_to_inactivity(void) { // If not a modal, then we are in the notification history app and the pop timer makes no sense - // If in DND mode we want to keep the notifications on the screen - return s_in_use && s_notification_window_data.is_modal && !do_not_disturb_is_active(); + // If in DND mode we keep notifications on screen unless the user opted into auto-dismiss + return s_in_use && s_notification_window_data.is_modal && + (!do_not_disturb_is_active() || alerts_preferences_dnd_get_auto_dismiss()); } static void prv_pop_timer_callback(void *data) { diff --git a/src/fw/services/notifications/alerts_preferences.c b/src/fw/services/notifications/alerts_preferences.c index c93ab222c..3db789bc9 100644 --- a/src/fw/services/notifications/alerts_preferences.c +++ b/src/fw/services/notifications/alerts_preferences.c @@ -43,6 +43,9 @@ static bool s_dnd_touch_backlight = true; #define PREF_KEY_DND_MUTE_SPEAKER "dndMuteSpeaker" static bool s_dnd_mute_speaker = false; +#define PREF_KEY_DND_AUTO_DISMISS "dndAutoDismiss" +static bool s_dnd_auto_dismiss = false; + #define PREF_KEY_SPEAKER_MUTED "speakerMuted" static bool s_speaker_muted = false; @@ -342,6 +345,7 @@ void alerts_preferences_init(void) { RESTORE_PREF(PREF_KEY_NOTIF_VIBE_DELAY, s_notification_vibe_delay); RESTORE_PREF(PREF_KEY_NOTIF_BACKLIGHT, s_notification_backlight); RESTORE_PREF(PREF_KEY_NOTIF_STATUS_BAR_STYLE, s_notification_status_bar_style); + RESTORE_PREF(PREF_KEY_DND_AUTO_DISMISS, s_dnd_auto_dismiss); #undef RESTORE_PREF prv_migrate_legacy_dnd_schedule(&file); @@ -581,6 +585,15 @@ bool alerts_preferences_dnd_get_mute_speaker(void) { return s_dnd_mute_speaker; } +void alerts_preferences_dnd_set_auto_dismiss(bool enable) { + s_dnd_auto_dismiss = enable; + SET_PREF(PREF_KEY_DND_AUTO_DISMISS, s_dnd_auto_dismiss); +} + +bool alerts_preferences_dnd_get_auto_dismiss(void) { + return s_dnd_auto_dismiss; +} + bool alerts_preferences_dnd_is_manually_enabled(void) { return s_do_not_disturb_manually_enabled; } @@ -698,6 +711,7 @@ void alerts_preferences_handle_blob_db_event(PebbleBlobDBEvent *event) { RELOAD_IF_MATCH(PREF_KEY_DND_TOUCH_BACKLIGHT, s_dnd_touch_backlight); RELOAD_IF_MATCH(PREF_KEY_DND_MUTE_SPEAKER, s_dnd_mute_speaker); RELOAD_IF_MATCH(PREF_KEY_SPEAKER_MUTED, s_speaker_muted); + RELOAD_IF_MATCH(PREF_KEY_DND_AUTO_DISMISS, s_dnd_auto_dismiss); RELOAD_IF_MATCH(PREF_KEY_SPEAKER_VOLUME, s_speaker_volume); #undef RELOAD_IF_MATCH diff --git a/tests/fw/ui/test_notification_window.c b/tests/fw/ui/test_notification_window.c index 2332d984e..ebb034dae 100644 --- a/tests/fw/ui/test_notification_window.c +++ b/tests/fw/ui/test_notification_window.c @@ -115,6 +115,10 @@ DndNotificationMode alerts_preferences_dnd_get_show_notifications(void) { return DndNotificationModeShow; } +bool alerts_preferences_dnd_get_auto_dismiss(void) { + return false; +} + bool alerts_preferences_get_notification_vibe_delay(void) { return false; } diff --git a/tests/stubs/stubs_alerts_preferences.h b/tests/stubs/stubs_alerts_preferences.h index 0ca865e1e..741c4b3e1 100644 --- a/tests/stubs/stubs_alerts_preferences.h +++ b/tests/stubs/stubs_alerts_preferences.h @@ -22,6 +22,10 @@ DndNotificationMode WEAK alerts_preferences_dnd_get_show_notifications(void) { return DndNotificationModeShow; } +bool WEAK alerts_preferences_dnd_get_auto_dismiss(void) { + return false; +} + bool WEAK alerts_preferences_get_notification_vibe_delay(void) { return false; }