using System.Windows;
using System.Windows.Threading;
using Notification.Core;
using Notification.Wpf;
using Notification.Wpf.Constants;
using ytLive.Helpers;
namespace ytLive.Services;
///
/// Toast notifications rendered inside the main window's ToastArea, whose
/// position is configurable in App Settings (bottom-right by default). Info/success auto-dismiss after ~4s,
/// warnings ~8s, errors stay until dismissed. App Settings can make all alerts sticky and
/// dismissible by clicking the card. Calls from any thread are
/// marshalled to the captured dispatcher.
///
public sealed class NotificationService : INotificationService
{
public const string AreaName = "ToastArea";
internal static readonly IReadOnlyDictionary Cards
= new Dictionary
{
[AppNotificationSeverity.Info] = (ThemeBrush.Hex("Brush.InfoContainer"), 4),
[AppNotificationSeverity.Success] = (ThemeBrush.Hex("Brush.SuccessContainer"), 4),
[AppNotificationSeverity.Warning] = (ThemeBrush.Hex("Brush.WarningContainer"), 8),
[AppNotificationSeverity.Error] = (ThemeBrush.Hex("Brush.ErrorContainer"), 0),
};
private readonly NotificationManager _manager = new();
private readonly Dispatcher _dispatcher;
private readonly Func _stickyAlertsUntilDismissed;
public NotificationService()
: this(Application.Current?.Dispatcher, static () => false)
{
}
internal NotificationService(Dispatcher? dispatcher)
: this(dispatcher, static () => false)
{
}
internal NotificationService(Dispatcher? dispatcher, Func stickyAlertsUntilDismissed)
{
_dispatcher = dispatcher ?? Dispatcher.CurrentDispatcher;
_stickyAlertsUntilDismissed = stickyAlertsUntilDismissed;
NotificationConstants.NotificationCornerRadius = new CornerRadius(8);
NotificationConstants.KeepNotificationVisibleOnMouseOver = true;
}
public void Show(string title, string message, AppNotificationSeverity severity)
{
_dispatcher.Invoke(() => _manager.Show(BuildRequestForCurrentSettings(title, message, severity)));
}
internal NotificationRequest BuildRequestForCurrentSettings(string title, string message,
AppNotificationSeverity severity)
=> BuildRequest(title, message, severity, _stickyAlertsUntilDismissed());
internal static NotificationRequest BuildRequest(string title, string message,
AppNotificationSeverity severity, bool stickyUntilDismissed = false)
{
var (backgroundHex, expirationSeconds) = Cards[severity];
var builder = NotificationBuilder
.Create(title, message)
.InArea(AreaName)
.WithBackground(NotificationColor.FromHex(backgroundHex))
.WithForeground(NotificationColor.FromHex(ThemeBrush.Hex("Brush.OnSurface")))
.CloseOnClick(stickyUntilDismissed);
if (stickyUntilDismissed)
builder.NeverExpires();
else if (severity == AppNotificationSeverity.Error)
builder.NeverExpires();
else
builder.ExpiresInSeconds(expirationSeconds);
return builder.Build();
}
}