diff --git a/src/components/ble/NotificationManager.cpp b/src/components/ble/NotificationManager.cpp index 223f6221af..c2490b512d 100644 --- a/src/components/ble/NotificationManager.cpp +++ b/src/components/ble/NotificationManager.cpp @@ -10,6 +10,7 @@ constexpr uint8_t NotificationManager::MessageSize; void NotificationManager::Push(NotificationManager::Notification&& notif) { notif.id = GetNextId(); notif.valid = true; + notif.timeArrived = std::chrono::system_clock::to_time_t(dateTimeController.CurrentDateTime()); newNotification = true; if (beginIdx > 0) { --beginIdx; diff --git a/src/components/ble/NotificationManager.h b/src/components/ble/NotificationManager.h index 4c199dbf50..ba33caab66 100644 --- a/src/components/ble/NotificationManager.h +++ b/src/components/ble/NotificationManager.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include "components/datetime/DateTimeController.h" namespace Pinetime { namespace Controllers { @@ -30,6 +32,7 @@ namespace Pinetime { Id id = 0; bool valid = false; uint8_t size; + std::time_t timeArrived; std::array message; Categories category = Categories::Unknown; @@ -37,6 +40,8 @@ namespace Pinetime { const char* Title() const; }; + NotificationManager(Controllers::DateTime& dateTimeController) : dateTimeController {dateTimeController} { + } void Push(Notification&& notif); Notification GetLastNotification() const; Notification Get(Notification::Id id) const; @@ -57,6 +62,7 @@ namespace Pinetime { size_t NbNotifications() const; private: + Controllers::DateTime& dateTimeController; Notification::Id nextId {0}; Notification::Id GetNextId(); const Notification& At(Notification::Idx idx) const; diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 3174a65832..c5948379ad 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -349,6 +349,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) notificationManager, systemTask->nimble().alertService(), motorController, + dateTimeController, *systemTask, Screens::Notifications::Modes::Normal); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); @@ -358,6 +359,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) notificationManager, systemTask->nimble().alertService(), motorController, + dateTimeController, *systemTask, Screens::Notifications::Modes::Preview); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 1479cf5dbb..a1c3ab5c54 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -13,12 +13,14 @@ Notifications::Notifications(DisplayApp* app, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::AlertNotificationService& alertNotificationService, Pinetime::Controllers::MotorController& motorController, + Pinetime::Controllers::DateTime& dateTimeController, System::SystemTask& systemTask, Modes mode) : Screen(app), notificationManager {notificationManager}, alertNotificationService {alertNotificationService}, motorController {motorController}, + dateTimeController {dateTimeController}, systemTask {systemTask}, mode {mode} { @@ -30,6 +32,8 @@ Notifications::Notifications(DisplayApp* app, notification.Message(), 1, notification.category, + notification.timeArrived, + std::chrono::system_clock::to_time_t(this->dateTimeController.CurrentDateTime()), notificationManager.NbNotifications(), alertNotificationService, motorController); @@ -105,6 +109,8 @@ void Notifications::Refresh() { notification.Message(), currentIdx + 1, notification.category, + notification.timeArrived, + std::chrono::system_clock::to_time_t(this->dateTimeController.CurrentDateTime()), notificationManager.NbNotifications(), alertNotificationService, motorController); @@ -186,6 +192,8 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { previousNotification.Message(), currentIdx + 1, previousNotification.category, + previousNotification.timeArrived, + std::chrono::system_clock::to_time_t(dateTimeController.CurrentDateTime()), notificationManager.NbNotifications(), alertNotificationService, motorController); @@ -213,6 +221,8 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { nextNotification.Message(), currentIdx + 1, nextNotification.category, + nextNotification.timeArrived, + std::chrono::system_clock::to_time_t(dateTimeController.CurrentDateTime()), notificationManager.NbNotifications(), alertNotificationService, motorController); @@ -237,6 +247,8 @@ Notifications::NotificationItem::NotificationItem(Pinetime::Controllers::AlertNo 0, Controllers::NotificationManager::Categories::Unknown, 0, + 0, + 0, alertNotificationService, motorController) { } @@ -245,6 +257,8 @@ Notifications::NotificationItem::NotificationItem(const char* title, const char* msg, uint8_t notifNr, Controllers::NotificationManager::Categories category, + std::time_t timeArrived, + std::time_t timeNow, uint8_t notifNb, Pinetime::Controllers::AlertNotificationService& alertNotificationService, Pinetime::Controllers::MotorController& motorController) @@ -270,6 +284,26 @@ Notifications::NotificationItem::NotificationItem(const char* title, lv_obj_t* alert_count = lv_label_create(container, nullptr); lv_label_set_text_fmt(alert_count, "%i/%i", notifNr, notifNb); lv_obj_align(alert_count, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 16); + // almost impossible to receive a real notification at time 0, so skip because it is the "no notifications" notification + if (timeNow != 0) { + auto diff = std::chrono::system_clock::from_time_t(timeNow) - std::chrono::system_clock::from_time_t(timeArrived); + std::chrono::minutes age = std::chrono::duration_cast(diff); + uint32_t ageInt = static_cast(age.count()); + char timeUnit; + if ((ageInt / (60 * 24)) >= 1) { + ageInt /= (60 * 24); + timeUnit = 'd'; + } else if ((ageInt / 60) >= 1) { + ageInt /= 60; + timeUnit = 'h'; + } else { + timeUnit = 'm'; + } + lv_obj_t* alert_age = lv_label_create(container, nullptr); + lv_label_set_text_fmt(alert_age, "%d%c ago", ageInt, timeUnit); + // same format as alert_count + lv_obj_align(alert_age, container, LV_ALIGN_IN_BOTTOM_RIGHT, 0, -16); + } lv_obj_t* alert_type = lv_label_create(container, nullptr); lv_obj_set_style_local_text_color(alert_type, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 9d843a9b13..54f302b609 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -4,8 +4,10 @@ #include #include #include +#include #include "displayapp/screens/Screen.h" #include "components/ble/NotificationManager.h" +#include "components/datetime/DateTimeController.h" #include "components/motor/MotorController.h" #include "systemtask/SystemTask.h" @@ -23,6 +25,7 @@ namespace Pinetime { Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::AlertNotificationService& alertNotificationService, Pinetime::Controllers::MotorController& motorController, + Pinetime::Controllers::DateTime& dateTimeController, System::SystemTask& systemTask, Modes mode); ~Notifications() override; @@ -39,6 +42,8 @@ namespace Pinetime { const char* msg, uint8_t notifNr, Controllers::NotificationManager::Categories, + std::time_t timeArrived, + std::time_t timeNow, uint8_t notifNb, Pinetime::Controllers::AlertNotificationService& alertNotificationService, Pinetime::Controllers::MotorController& motorController); @@ -66,6 +71,7 @@ namespace Pinetime { private: Pinetime::Controllers::NotificationManager& notificationManager; Pinetime::Controllers::AlertNotificationService& alertNotificationService; + Pinetime::Controllers::DateTime& dateTimeController; Pinetime::Controllers::MotorController& motorController; System::SystemTask& systemTask; Modes mode = Modes::Normal; diff --git a/src/main.cpp b/src/main.cpp index 109971bca0..9560f9aaa6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -108,7 +108,7 @@ Pinetime::Controllers::MotorController motorController {}; Pinetime::Controllers::DateTime dateTimeController {settingsController}; Pinetime::Drivers::Watchdog watchdog; Pinetime::Drivers::WatchdogView watchdogView(watchdog); -Pinetime::Controllers::NotificationManager notificationManager; +Pinetime::Controllers::NotificationManager notificationManager {dateTimeController}; Pinetime::Controllers::MotionController motionController; Pinetime::Controllers::TimerController timerController; Pinetime::Controllers::AlarmController alarmController {dateTimeController};