InfiniTime/src/components/ble/NotificationManager.h
Simon Willshire 2c75e7aad8 Dismiss notifications by swiping right
Add a new interface `NotificationManager::Dismiss(id)` to delete a
notification with the specified `id`.

The animate the notification dismiss the `RightAnim` transition to a
black screen is used. After the dismiss the new message is swiped in
from below or above.

If we dismiss the oldest message (when we are at 5/5, or 3/3), then the
new message after a dismiss should appear to come from below.

Otherwise (when we are at 2/3) the new message after a dismiss should
appear to come from above.

Rework the index code to show the index of the currently viewed
notification. Instead of calculating the index relative to the oldest
`id` introduce a new interface `NotificationManager::IndexOf(id)`. This
is done because the `id` of the notifications in the buffer aren't
continuous anymore (as some messages could have been dismissed).

Rework notification ring buffer to have a beginIdx and a size
internally to make the dismissal of notifications easier.

Fixes: https://github.com/InfiniTimeOrg/InfiniTime/issues/176

Co-authored-by: Simon Willshire <me@simonwillshire.com>
Co-authored-by: Reinhold Gschweicher <pyro4hell@gmail.com>
2022-06-28 18:50:10 +02:00

75 lines
2.1 KiB
C++

#pragma once
#include <array>
#include <atomic>
#include <cstddef>
#include <cstdint>
namespace Pinetime {
namespace Controllers {
class NotificationManager {
public:
enum class Categories {
Unknown,
SimpleAlert,
Email,
News,
IncomingCall,
MissedCall,
Sms,
VoiceMail,
Schedule,
HighProriotyAlert,
InstantMessage
};
static constexpr uint8_t MessageSize {100};
struct Notification {
using Id = uint8_t;
using Idx = uint8_t;
Id id = 0;
bool valid = false;
uint8_t size;
std::array<char, MessageSize + 1> message;
Categories category = Categories::Unknown;
const char* Message() const;
const char* Title() const;
};
void Push(Notification&& notif);
Notification GetLastNotification() const;
Notification Get(Notification::Id id) const;
Notification GetNext(Notification::Id id) const;
Notification GetPrevious(Notification::Id id) const;
// Return the index of the notification with the specified id, if not found return NbNotifications()
Notification::Idx IndexOf(Notification::Id id) const;
bool ClearNewNotificationFlag();
bool AreNewNotificationsAvailable() const;
void Dismiss(Notification::Id id);
static constexpr size_t MaximumMessageSize() {
return MessageSize;
};
bool IsEmpty() const {
return size == 0;
}
size_t NbNotifications() const;
private:
Notification::Id nextId {0};
Notification::Id GetNextId();
const Notification& At(Notification::Idx idx) const;
Notification& At(Notification::Idx idx);
void DismissIdx(Notification::Idx idx);
static constexpr uint8_t TotalNbNotifications = 5;
std::array<Notification, TotalNbNotifications> notifications;
size_t beginIdx = TotalNbNotifications - 1; // index of the newest notification
size_t size = 0; // number of valid notifications in buffer
std::atomic<bool> newNotification {false};
};
}
}