1using System.Diagnostics.CodeAnalysis;
14 private const int nrTypes = 4;
16 private readonly SortedDictionary<CaseInsensitiveString, List<NotificationEvent>>[] events;
17 private readonly LinkedList<KeyValuePair<Type, DateTime>> expected;
26 this.events =
new SortedDictionary<CaseInsensitiveString, List<NotificationEvent>>[nrTypes];
27 this.expected =
new LinkedList<KeyValuePair<Type, DateTime>>();
29 for (i = 0; i < nrTypes; i++)
38 public override async Task
Load(
bool isResuming, CancellationToken cancellationToken)
40 SortedDictionary<CaseInsensitiveString, List<NotificationEvent>>? ByCategory =
null;
41 List<NotificationEvent>? Events =
null;
42 string? PrevCategory =
null;
46 IEnumerable<NotificationEvent> LoadedEvents;
66 if (Type < 0 || Type >= nrTypes)
71 Log.
Debug(
"Notification event of type " +
Event.GetType().FullName +
" lacked Category.");
78 if (ByCategory is
null || Type != PrevType)
80 ByCategory = this.events[Type];
84 if (Events is
null ||
Event.Category != PrevCategory)
86 if (!ByCategory.TryGetValue(
Event.Category, out Events))
89 ByCategory[
Event.Category] = Events;
92 PrevCategory =
Event.Category;
99 await base.Load(isResuming, cancellationToken);
112 this.expected.AddLast(
new KeyValuePair<Type, DateTime>(typeof(T), Before));
125 DateTime Now = DateTime.Now;
126 bool Expected =
false;
130 LinkedListNode<KeyValuePair<Type, DateTime>>? Loop = this.expected.First;
131 LinkedListNode<KeyValuePair<Type, DateTime>>? Next;
134 while (Loop is not
null)
138 if (Loop.Value.Value < Now)
139 this.expected.Remove(Loop);
142 this.expected.Remove(Loop);
153 MainThread.BeginInvokeOnMainThread(async () =>
170 if (Type >= 0 && Type < nrTypes)
174 SortedDictionary<CaseInsensitiveString, List<NotificationEvent>> ByCategory = this.events[Type];
176 if (!ByCategory.TryGetValue(
Event.Category, out List<NotificationEvent>? Events))
179 ByCategory[
Event.Category] = Events;
195 Task _ = Task.Run(async () =>
199 await
Event.Prepare();
216 int TypeIndex = (int)Type;
218 if (TypeIndex >= 0 && TypeIndex < nrTypes)
224 SortedDictionary<CaseInsensitiveString, List<NotificationEvent>> ByCategory = this.events[TypeIndex];
226 if (!ByCategory.TryGetValue(Category, out List<NotificationEvent>? Events))
229 ToDelete = [.. Events];
230 ByCategory.Remove(Category);
233 await this.DoDeleteEvents(ToDelete);
250 if (TypeIndex >= 0 && TypeIndex < nrTypes)
254 SortedDictionary<CaseInsensitiveString, List<NotificationEvent>> ByCategory = this.events[TypeIndex];
256 if (ByCategory.TryGetValue(
Event.Category, out List<NotificationEvent>? List) &&
257 List.Remove(
Event) &&
260 ByCategory.Remove(
Event.Category);
267 return this.DoDeleteEvents(Events);
284 catch (KeyNotFoundException)
299 ServiceRef.LogService.LogException(ex);
311 if (i < 0 || i >= nrTypes)
316 SortedDictionary<CaseInsensitiveString, List<NotificationEvent>> ByCategory = this.events[i];
317 List<NotificationEvent> Result = [];
319 foreach (List<NotificationEvent> Events
in ByCategory.Values)
320 Result.AddRange(Events);
334 if (i < 0 || i >= nrTypes)
339 SortedDictionary<CaseInsensitiveString, List<NotificationEvent>> ByCategory = this.events[i];
340 List<CaseInsensitiveString> Result = [.. ByCategory.Keys];
354 if (i < 0 || i >= nrTypes)
359 SortedDictionary<CaseInsensitiveString, List<NotificationEvent>> ByCategory = this.events[i];
360 SortedDictionary<CaseInsensitiveString, NotificationEvent[]> Result = [];
363 Result[P.Key] = [.. P.Value];
378 if (i < 0 || i >= nrTypes)
383 SortedDictionary<CaseInsensitiveString, List<NotificationEvent>> ByCategory = this.events[i];
384 SortedDictionary<CaseInsensitiveString, T[]> Result = [];
388 List<T>? Items =
null;
392 if (
Event is T TypedItem)
395 Items.Add(TypedItem);
399 if (Items is not
null)
400 Result[P.Key] = [.. Items];
418 if (i < 0 || i >= nrTypes)
426 SortedDictionary<CaseInsensitiveString, List<NotificationEvent>> ByCategory = this.events[i];
428 if (!ByCategory.TryGetValue(Category, out List<NotificationEvent>? Events2))
434 Events = [.. Events2];
469 private int Count(
int Index)
473 SortedDictionary<CaseInsensitiveString, List<NotificationEvent>> Events = this.events[Index];
476 foreach (List<NotificationEvent> List
in Events.Values)
477 Result += List.Count;
489 List<NotificationEvent>? Resolved =
null;
509 if (Resolved is not
null)
SortedDictionary< CaseInsensitiveString, T[]> GetEventsByCategory< T >(NotificationEventType Type)
Gets available notification events for a button, sorted by category.
void ExpectEvent< T >(DateTime Before)
Registers a type of notification as expected.
NotificationEvent[] GetEvents(NotificationEventType Type)
Gets available notification events for a button.
int NrNotificationsThings
Number of notifications but button Things
async Task NewEvent(NotificationEvent Event)
Registers a new event and notifies the user.
NotificationService()
Notification service
NotificationEventsHandler? OnNotificationsDeleted
Event raised when notifications have been deleted.
int NrNotificationsContracts
Number of notifications but button Contracts
NotificationEventHandler? OnNewNotification
Event raised when a new notification has been logged.
int NrNotificationsWallet
Number of notifications but button Wallet
int NrNotificationsContacts
Number of notifications but button Contacts
override async Task Load(bool isResuming, CancellationToken cancellationToken)
Loads the specified service.
SortedDictionary< CaseInsensitiveString, NotificationEvent[]> GetEventsByCategory(NotificationEventType Type)
Gets available notification events for a button, sorted by category.
bool TryGetNotificationEvents(NotificationEventType Type, CaseInsensitiveString Category, [NotNullWhen(true)] out NotificationEvent[]? Events)
Tries to get available notification events.
CaseInsensitiveString[] GetCategories(NotificationEventType Type)
Gets available categories for a button.
async Task DeleteEvents(NotificationEventType Type, CaseInsensitiveString Category)
Deletes events for a given button and category.
Task DeleteEvents(params NotificationEvent[] Events)
Deletes a specified set of events.
async Task DeleteResolvedEvents(IEventResolver Resolver)
Deletes pending events that have already been resolved.
Base class that references services in the app.
static ILogService LogService
Log service.
Class representing an event.
EventType Type
Type of event.
Static class managing the application event log. Applications and services log events on this static ...
static void Debug(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs a debug event.
Represents a case-insensitive string.
static bool IsNullOrEmpty(CaseInsensitiveString value)
Indicates whether the specified string is null or an CaseInsensitiveString.Empty string.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static Task EndBulk()
Ends bulk-processing of data. Must be called once for every call to StartBulk.
static Task StartBulk()
Starts bulk-proccessing of data. Must be followed by a call to EndBulk.
static async Task Delete(object Object)
Deletes an object in the database.
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
static async Task Clear(string CollectionName)
Clears a collection of all objects.
Interface for event resolvers. Such can be used to resolve multiple pending notifications at once.
bool Resolves(NotificationEvent Event)
If the resolver resolves an event.
Interface for push notification services.
abstract class NotificationEvent()
Abstract base class of notification events.
class NotificationEventsArgs(NotificationEvent[] Events)
Event argument for notification events.
class NotificationEventArgs(NotificationEvent Event)
Event argument for notification events.
delegate void NotificationEventHandler(object? Sender, NotificationEventArgs e)
Delegate for notification event handlers.
NotificationEventType
Button on which event is to be displayed.
delegate void NotificationEventsHandler(object? Sender, NotificationEventsArgs e)
Delegate for notification events handlers.