Merge pull request 'notification-changes' (#62) from notification-changes into 1.12.3

Reviewed-on: #62
This commit was merged in pull request #62.
This commit is contained in:
2025-10-12 23:33:42 +02:00
2 changed files with 47 additions and 21 deletions

View File

@@ -24,6 +24,7 @@ public class DownloadUi : WindowMediatorSubscriberBase
private readonly ConcurrentDictionary<GameObjectHandler, bool> _uploadingPlayers = new(); private readonly ConcurrentDictionary<GameObjectHandler, bool> _uploadingPlayers = new();
private readonly NotificationService _notificationService; private readonly NotificationService _notificationService;
private bool _notificationDismissed = true; private bool _notificationDismissed = true;
private int _lastDownloadStateHash = 0;
public DownloadUi(ILogger<DownloadUi> logger, DalamudUtilService dalamudUtilService, LightlessConfigService configService, public DownloadUi(ILogger<DownloadUi> logger, DalamudUtilService dalamudUtilService, LightlessConfigService configService,
PairProcessingLimiter pairProcessingLimiter, FileUploadManager fileTransferManager, LightlessMediator mediator, UiSharedService uiShared, PairProcessingLimiter pairProcessingLimiter, FileUploadManager fileTransferManager, LightlessMediator mediator, UiSharedService uiShared,
@@ -128,16 +129,17 @@ public class DownloadUi : WindowMediatorSubscriberBase
if (useNotifications) if (useNotifications)
{ {
// Use notification system // Use notification system - only update when data actually changes
if (_currentDownloads.Any()) if (_currentDownloads.Any())
{ {
UpdateDownloadNotification(limiterSnapshot); UpdateDownloadNotificationIfChanged(limiterSnapshot);
_notificationDismissed = false; _notificationDismissed = false;
} }
else if (!_notificationDismissed) else if (!_notificationDismissed)
{ {
_notificationService.DismissPairDownloadNotification(); _notificationService.DismissPairDownloadNotification();
_notificationDismissed = true; _notificationDismissed = true;
_lastDownloadStateHash = 0;
} }
} }
else else
@@ -298,20 +300,34 @@ public class DownloadUi : WindowMediatorSubscriberBase
}; };
} }
private void UpdateDownloadNotification(PairProcessingLimiterSnapshot limiterSnapshot) private void UpdateDownloadNotificationIfChanged(PairProcessingLimiterSnapshot limiterSnapshot)
{ {
var downloadStatus = new List<(string playerName, float progress, string status)>(); var downloadStatus = new List<(string playerName, float progress, string status)>(_currentDownloads.Count);
var hashCode = new HashCode();
foreach (var item in _currentDownloads.ToList()) foreach (var item in _currentDownloads)
{ {
var dlSlot = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.WaitingForSlot); var dlSlot = 0;
var dlQueue = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.WaitingForQueue); var dlQueue = 0;
var dlProg = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.Downloading); var dlProg = 0;
var dlDecomp = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.Decompressing); var dlDecomp = 0;
var totalFiles = item.Value.Sum(c => c.Value.TotalFiles); long totalBytes = 0;
var transferredFiles = item.Value.Sum(c => c.Value.TransferredFiles); long transferredBytes = 0;
var totalBytes = item.Value.Sum(c => c.Value.TotalBytes);
var transferredBytes = item.Value.Sum(c => c.Value.TransferredBytes); // Single pass through the dictionary to count everything - avoid multiple LINQ iterations
foreach (var entry in item.Value)
{
var fileStatus = entry.Value;
switch (fileStatus.DownloadStatus)
{
case DownloadStatus.WaitingForSlot: dlSlot++; break;
case DownloadStatus.WaitingForQueue: dlQueue++; break;
case DownloadStatus.Downloading: dlProg++; break;
case DownloadStatus.Decompressing: dlDecomp++; break;
}
totalBytes += fileStatus.TotalBytes;
transferredBytes += fileStatus.TransferredBytes;
}
var progress = totalBytes > 0 ? (float)transferredBytes / totalBytes : 0f; var progress = totalBytes > 0 ? (float)transferredBytes / totalBytes : 0f;
@@ -323,13 +339,27 @@ public class DownloadUi : WindowMediatorSubscriberBase
else status = "completed"; else status = "completed";
downloadStatus.Add((item.Key.Name, progress, status)); downloadStatus.Add((item.Key.Name, progress, status));
// Build hash from meaningful state
hashCode.Add(item.Key.Name);
hashCode.Add(transferredBytes);
hashCode.Add(totalBytes);
hashCode.Add(status);
} }
// Pass queue waiting count separately, show notification if there are downloads or queue items
var queueWaiting = limiterSnapshot.IsEnabled ? limiterSnapshot.Waiting : 0; var queueWaiting = limiterSnapshot.IsEnabled ? limiterSnapshot.Waiting : 0;
if (downloadStatus.Any() || queueWaiting > 0) hashCode.Add(queueWaiting);
var currentHash = hashCode.ToHashCode();
// Only update notification if state has actually changed
if (currentHash != _lastDownloadStateHash)
{ {
_notificationService.ShowPairDownloadNotification(downloadStatus, queueWaiting); _lastDownloadStateHash = currentHash;
if (downloadStatus.Count > 0 || queueWaiting > 0)
{
_notificationService.ShowPairDownloadNotification(downloadStatus, queueWaiting);
}
} }
} }

View File

@@ -134,11 +134,7 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
var viewport = ImGui.GetMainViewport(); var viewport = ImGui.GetMainViewport();
// Set window to full viewport height // Window auto-resizes based on content (AlwaysAutoResize flag)
var width = _configService.Current.NotificationWidth;
Size = new Vector2(width, viewport.WorkSize.Y);
SizeCondition = ImGuiCond.Always;
Position = CalculateWindowPosition(viewport); Position = CalculateWindowPosition(viewport);
PositionCondition = ImGuiCond.Always; PositionCondition = ImGuiCond.Always;