208 lines
7.8 KiB
C#
208 lines
7.8 KiB
C#
// Copyright (c) 2024- schick Informatik
|
|
// Description: Helper (static) class to handle polled API notifications
|
|
//
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using ToastNotifications.Core;
|
|
using BreCalClient.misc.Model;
|
|
|
|
namespace BreCalClient
|
|
{
|
|
internal class AppNotification(int id)
|
|
{
|
|
private static readonly Dictionary<int, AppNotification> _notifications = [];
|
|
private static readonly ObservableCollection<AppNotification> _notificationsCollection = [];
|
|
|
|
#region Properties
|
|
|
|
public int Id { get { return id; } }
|
|
|
|
public string? NotificationType
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
public string? NotificationDisplay
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
public string? NotificationDate
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
public string? Ship
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
public string? ShipcallType
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
public string? Berth
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
public string? ETA
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
public string? Message
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
|
|
public static ObservableCollection<AppNotification> AppNotifications { get { return _notificationsCollection; } }
|
|
|
|
#endregion
|
|
|
|
#region internal statics
|
|
|
|
internal static void LoadFromSettings()
|
|
{
|
|
_notifications.Clear();
|
|
|
|
if (Properties.Settings.Default.Notifications != null)
|
|
{
|
|
// load notification ids that have been processed
|
|
foreach (string? notification_id in Properties.Settings.Default.Notifications)
|
|
{
|
|
if (Int32.TryParse(notification_id, out int result))
|
|
_notifications.Add(result, new AppNotification(result));
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static void Clear()
|
|
{
|
|
_notifications.Clear();
|
|
SaveNotifications();
|
|
}
|
|
|
|
internal static bool UpdateNotifications(List<Notification> notifications, System.Collections.Concurrent.ConcurrentDictionary<int, ShipcallControlModel> currentShipcalls, ToastViewModel vm, LoginResult loginResult)
|
|
{
|
|
bool result = false;
|
|
|
|
foreach (Notification notification in notifications)
|
|
{
|
|
if (notification.ParticipantId.HasValue && notification.ParticipantId.Value != App.Participant.Id) // not meant for us
|
|
continue;
|
|
|
|
if (!currentShipcalls.ContainsKey(notification.ShipcallId)) // not one of our shipcalls (maybe for another port or filtered)
|
|
continue;
|
|
|
|
// filter out notifications for shipcalls where we are not nomiated/assigned
|
|
if (!notification.ParticipantId.HasValue)
|
|
{
|
|
bool iAmAssigned = false;
|
|
foreach (ParticipantAssignment p in currentShipcalls[notification.ShipcallId].AssignedParticipants.Values)
|
|
{
|
|
if (p.ParticipantId.Equals(App.Participant.Id))
|
|
{
|
|
iAmAssigned = true; break;
|
|
}
|
|
}
|
|
if (!iAmAssigned) continue;
|
|
}
|
|
|
|
// filter out notifications the user is not interested in
|
|
if((notification.Type != null) && !loginResult.NotifyOn.Contains(notification.Type.Value))
|
|
continue;
|
|
|
|
if (!_notificationsCollection.Where(x => x.Id == notification.Id).Any())
|
|
{
|
|
List<AppNotification> newList = new(_notificationsCollection);
|
|
|
|
AppNotification ap = new(notification.Id)
|
|
{
|
|
NotificationType = notification.Type.ToString(),
|
|
NotificationDate = notification.Created.ToString(),
|
|
Ship = currentShipcalls[notification.ShipcallId]?.Ship?.Name,
|
|
ShipcallType = currentShipcalls[notification.ShipcallId]?.Shipcall?.Type.ToString(),
|
|
ETA = currentShipcalls[notification.ShipcallId]?.GetETAETD(true)
|
|
};
|
|
Times? agencyTimes = currentShipcalls[notification.ShipcallId]?.GetTimesForParticipantType(Extensions.ParticipantType.AGENCY);
|
|
ap.Berth = currentShipcalls[notification.ShipcallId]?.GetBerthText(agencyTimes);
|
|
ap.Message = notification.Message;
|
|
|
|
System.Diagnostics.Trace.WriteLine($"Notification {notification.Id} Type {notification.Type}");
|
|
MessageOptions options = new()
|
|
{
|
|
FontSize = 14,
|
|
ShowCloseButton = true,
|
|
Tag = ap
|
|
};
|
|
|
|
newList.Add(ap);
|
|
newList.Sort((a, b) => (a.NotificationDate ?? "").CompareTo(b.NotificationDate));
|
|
_notificationsCollection.Clear();
|
|
foreach(AppNotification newAp in newList)
|
|
_notificationsCollection.Add(newAp);
|
|
|
|
ap.NotificationDisplay = string.Empty;
|
|
switch(notification.Type)
|
|
{
|
|
case misc.Model.NotificationType.Assignment:
|
|
ap.NotificationDisplay = Resources.Resources.textAssignment; break;
|
|
case misc.Model.NotificationType.Next24h:
|
|
ap.NotificationDisplay = Resources.Resources.textNext24h; break;
|
|
case misc.Model.NotificationType.TimeConflict:
|
|
ap.NotificationDisplay = Resources.Resources.textTimeConflict; break;
|
|
case misc.Model.NotificationType.TimeConflictResolved:
|
|
ap.NotificationDisplay = Resources.Resources.textTimeConflictResolved; break;
|
|
case misc.Model.NotificationType.MissingData:
|
|
ap.NotificationDisplay = Resources.Resources.textMissingData; break;
|
|
case misc.Model.NotificationType.Cancelled:
|
|
ap.NotificationDisplay = Resources.Resources.textCancelled; break;
|
|
case misc.Model.NotificationType.Unassigned:
|
|
ap.NotificationDisplay = Resources.Resources.textUnassigned; break;
|
|
}
|
|
|
|
string toastText = ap.NotificationDisplay + "\n";
|
|
|
|
toastText += $"{ap.Ship} ({ap.ShipcallType}) - {ap.ETA} - {ap.Berth}";
|
|
if (!string.IsNullOrEmpty(ap.Message))
|
|
toastText += $" \n{ap.Message}";
|
|
|
|
if (_notifications.TryAdd(notification.Id, ap))
|
|
{
|
|
App.Current.Dispatcher.Invoke(() =>
|
|
{
|
|
vm.ShowAppNotification(toastText, options);
|
|
});
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (result)
|
|
SaveNotifications(); // store notification ids in config array on change
|
|
|
|
return result;
|
|
}
|
|
|
|
internal static void SaveNotifications()
|
|
{
|
|
if (Properties.Settings.Default.Notifications == null)
|
|
Properties.Settings.Default.Notifications = [];
|
|
else
|
|
Properties.Settings.Default.Notifications.Clear();
|
|
foreach (int notification_id in _notifications.Keys)
|
|
{
|
|
Properties.Settings.Default.Notifications.Add(notification_id.ToString());
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|