Files
LightlessClient/LightlessSync/Services/LightlessNotificationService.cs

212 lines
8.0 KiB
C#

using Dalamud.Interface;
using LightlessSync.LightlessConfiguration;
using LightlessSync.LightlessConfiguration.Models;
using LightlessSync.Services.Mediator;
using LightlessSync.UI;
using LightlessSync.UI.Models;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Numerics;
namespace LightlessSync.Services;
public class LightlessNotificationService : DisposableMediatorSubscriberBase, IHostedService
{
private readonly ILogger<LightlessNotificationService> _logger;
private readonly LightlessConfigService _configService;
private readonly DalamudUtilService _dalamudUtilService;
private LightlessNotificationUI? _notificationUI;
public LightlessNotificationService(
ILogger<LightlessNotificationService> logger,
LightlessConfigService configService,
DalamudUtilService dalamudUtilService,
LightlessMediator mediator) : base(logger, mediator)
{
_logger = logger;
_configService = configService;
_dalamudUtilService = dalamudUtilService;
}
public Task StartAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
public void SetNotificationUI(LightlessNotificationUI notificationUI)
{
_notificationUI = notificationUI;
}
public void ShowNotification(string title, string message, NotificationType type = NotificationType.Info,
TimeSpan? duration = null, List<LightlessNotificationAction>? actions = null)
{
var notification = new LightlessNotification
{
Title = title,
Message = message,
Type = type,
Duration = duration ?? TimeSpan.FromSeconds(10),
Actions = actions ?? new List<LightlessNotificationAction>()
};
Mediator.Publish(new LightlessNotificationMessage(notification));
}
public void ShowPairRequestNotification(string senderName, string senderId, Action onAccept, Action onDecline)
{
var notification = new LightlessNotification
{
Title = "Pair Request Received",
Message = $"{senderName} wants to pair with you.",
Type = NotificationType.Info,
Duration = TimeSpan.FromSeconds(60),
Actions = new List<LightlessNotificationAction>
{
new()
{
Id = "accept",
Label = "Accept",
Icon = FontAwesomeIcon.Check,
Color = UIColors.Get("LightlessGreen"),
IsPrimary = true,
OnClick = (n) =>
{
_logger.LogInformation("Pair request accepted");
onAccept();
n.IsDismissed = true;
n.IsAnimatingOut = true;
}
},
new()
{
Id = "decline",
Label = "Decline",
Icon = FontAwesomeIcon.Times,
Color = UIColors.Get("DimRed"),
IsDestructive = true,
OnClick = (n) =>
{
_logger.LogInformation("Pair request declined");
onDecline();
n.IsDismissed = true;
n.IsAnimatingOut = true;
}
}
}
};
Mediator.Publish(new LightlessNotificationMessage(notification));
}
public void ShowDownloadCompleteNotification(string fileName, int fileCount, Action? onOpenFolder = null)
{
var actions = new List<LightlessNotificationAction>();
if (onOpenFolder != null)
{
actions.Add(new LightlessNotificationAction
{
Id = "open_folder",
Label = "Open Folder",
Icon = FontAwesomeIcon.FolderOpen,
Color = UIColors.Get("LightlessBlue"),
OnClick = (n) =>
{
onOpenFolder();
n.IsDismissed = true;
n.IsAnimatingOut = true;
}
});
}
var notification = new LightlessNotification
{
Title = "Download Complete",
Message = fileCount > 1 ?
$"Downloaded {fileCount} files successfully." :
$"Downloaded {fileName} successfully.",
Type = NotificationType.Info,
Duration = TimeSpan.FromSeconds(8),
Actions = actions
};
Mediator.Publish(new LightlessNotificationMessage(notification));
}
public void ShowErrorNotification(string title, string message, Exception? exception = null, Action? onRetry = null, Action? onViewLog = null)
{
var actions = new List<LightlessNotificationAction>();
if (onRetry != null)
{
actions.Add(new LightlessNotificationAction
{
Id = "retry",
Label = "Retry",
Icon = FontAwesomeIcon.Redo,
Color = UIColors.Get("LightlessBlue"),
OnClick = (n) =>
{
onRetry();
n.IsDismissed = true;
n.IsAnimatingOut = true;
}
});
}
if (onViewLog != null)
{
actions.Add(new LightlessNotificationAction
{
Id = "view_log",
Label = "View Log",
Icon = FontAwesomeIcon.FileAlt,
Color = UIColors.Get("LightlessYellow"),
OnClick = (n) => onViewLog()
});
}
var notification = new LightlessNotification
{
Title = title,
Message = exception != null ? $"{message}\n\nError: {exception.Message}" : message,
Type = NotificationType.Error,
Duration = TimeSpan.FromSeconds(15),
Actions = actions
};
Mediator.Publish(new LightlessNotificationMessage(notification));
}
public void ShowPairDownloadNotification(List<(string playerName, float progress, string status)> downloadStatus)
{
var totalProgress = downloadStatus.Count > 0 ? downloadStatus.Average(x => x.progress) : 0f;
var completedCount = downloadStatus.Count(x => x.progress >= 1.0f);
var totalCount = downloadStatus.Count;
var message = $"Progress: {completedCount}/{totalCount} completed";
if (downloadStatus.Any(x => x.progress < 1.0f))
{
var activeDownloads = downloadStatus.Where(x => x.progress < 1.0f).Take(3);
message += "\n" + string.Join("\n", activeDownloads.Select(x =>
{
var statusText = x.status switch
{
"downloading" => $"{x.progress:P0}",
"decompressing" => "decompressing",
"queued" => "queued",
"waiting" => "waiting for slot",
_ => x.status
};
return $"• {x.playerName}: {statusText}";
}));
if (downloadStatus.Count(x => x.progress < 1.0f) > 3)
{
message += $"\n• ... and {downloadStatus.Count(x => x.progress < 1.0f) - 3} more";
}
}
var notification = new LightlessNotification
{
Id = "pair_download_progress",
Title = "Downloading Pair Data",
Message = message,
Type = NotificationType.Info,
Duration = TimeSpan.FromMinutes(5),
ShowProgress = true,
Progress = totalProgress
};
Mediator.Publish(new LightlessNotificationMessage(notification));
}
public void DismissPairDownloadNotification()
{
Mediator.Publish(new LightlessNotificationDismissMessage("pair_download_progress"));
}
}