From 6c0d00dc390667621263154a267f8e02c210338c Mon Sep 17 00:00:00 2001 From: choco Date: Sun, 12 Oct 2025 21:07:32 +0200 Subject: [PATCH 1/2] update intervall prevent spam better performance --- LightlessSync/UI/DownloadUi.cs | 68 ++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/LightlessSync/UI/DownloadUi.cs b/LightlessSync/UI/DownloadUi.cs index 301f177..a520f0a 100644 --- a/LightlessSync/UI/DownloadUi.cs +++ b/LightlessSync/UI/DownloadUi.cs @@ -24,6 +24,9 @@ public class DownloadUi : WindowMediatorSubscriberBase private readonly ConcurrentDictionary _uploadingPlayers = new(); private readonly NotificationService _notificationService; private bool _notificationDismissed = true; + private int _lastDownloadStateHash = 0; + private DateTime _lastNotificationUpdate = DateTime.MinValue; + private const int MinUpdateIntervalMs = 1000; public DownloadUi(ILogger logger, DalamudUtilService dalamudUtilService, LightlessConfigService configService, PairProcessingLimiter pairProcessingLimiter, FileUploadManager fileTransferManager, LightlessMediator mediator, UiSharedService uiShared, @@ -128,16 +131,18 @@ public class DownloadUi : WindowMediatorSubscriberBase if (useNotifications) { - // Use notification system + // Use notification system - only update when data actually changes if (_currentDownloads.Any()) { - UpdateDownloadNotification(limiterSnapshot); + UpdateDownloadNotificationIfChanged(limiterSnapshot); _notificationDismissed = false; } else if (!_notificationDismissed) { _notificationService.DismissPairDownloadNotification(); _notificationDismissed = true; + _lastDownloadStateHash = 0; + _lastNotificationUpdate = DateTime.MinValue; } } else @@ -298,20 +303,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 dlQueue = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.WaitingForQueue); - var dlProg = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.Downloading); - var dlDecomp = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.Decompressing); - var totalFiles = item.Value.Sum(c => c.Value.TotalFiles); - var transferredFiles = item.Value.Sum(c => c.Value.TransferredFiles); - var totalBytes = item.Value.Sum(c => c.Value.TotalBytes); - var transferredBytes = item.Value.Sum(c => c.Value.TransferredBytes); + var dlSlot = 0; + var dlQueue = 0; + var dlProg = 0; + var dlDecomp = 0; + long totalBytes = 0; + long transferredBytes = 0; + + // 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; @@ -323,13 +342,30 @@ public class DownloadUi : WindowMediatorSubscriberBase else status = "completed"; 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; - if (downloadStatus.Any() || queueWaiting > 0) + hashCode.Add(queueWaiting); + + var currentHash = hashCode.ToHashCode(); + var now = DateTime.UtcNow; + var timeSinceLastUpdate = (now - _lastNotificationUpdate).TotalMilliseconds; + + // Only update notification if state has changed AND at least 1 second has passed + if (currentHash != _lastDownloadStateHash && timeSinceLastUpdate >= MinUpdateIntervalMs) { - _notificationService.ShowPairDownloadNotification(downloadStatus, queueWaiting); + _lastDownloadStateHash = currentHash; + _lastNotificationUpdate = now; + if (downloadStatus.Count > 0 || queueWaiting > 0) + { + _notificationService.ShowPairDownloadNotification(downloadStatus, queueWaiting); + } } } From 118edb9deaeb8b2374b0a264af3dc16174a8e2b7 Mon Sep 17 00:00:00 2001 From: choco Date: Sun, 12 Oct 2025 23:11:18 +0200 Subject: [PATCH 2/2] notif overlay flex with 1 sec delay removal --- LightlessSync/UI/DownloadUi.cs | 10 ++-------- LightlessSync/UI/LightlessNotificationUI.cs | 6 +----- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/LightlessSync/UI/DownloadUi.cs b/LightlessSync/UI/DownloadUi.cs index a520f0a..93cc623 100644 --- a/LightlessSync/UI/DownloadUi.cs +++ b/LightlessSync/UI/DownloadUi.cs @@ -25,8 +25,6 @@ public class DownloadUi : WindowMediatorSubscriberBase private readonly NotificationService _notificationService; private bool _notificationDismissed = true; private int _lastDownloadStateHash = 0; - private DateTime _lastNotificationUpdate = DateTime.MinValue; - private const int MinUpdateIntervalMs = 1000; public DownloadUi(ILogger logger, DalamudUtilService dalamudUtilService, LightlessConfigService configService, PairProcessingLimiter pairProcessingLimiter, FileUploadManager fileTransferManager, LightlessMediator mediator, UiSharedService uiShared, @@ -142,7 +140,6 @@ public class DownloadUi : WindowMediatorSubscriberBase _notificationService.DismissPairDownloadNotification(); _notificationDismissed = true; _lastDownloadStateHash = 0; - _lastNotificationUpdate = DateTime.MinValue; } } else @@ -354,14 +351,11 @@ public class DownloadUi : WindowMediatorSubscriberBase hashCode.Add(queueWaiting); var currentHash = hashCode.ToHashCode(); - var now = DateTime.UtcNow; - var timeSinceLastUpdate = (now - _lastNotificationUpdate).TotalMilliseconds; - // Only update notification if state has changed AND at least 1 second has passed - if (currentHash != _lastDownloadStateHash && timeSinceLastUpdate >= MinUpdateIntervalMs) + // Only update notification if state has actually changed + if (currentHash != _lastDownloadStateHash) { _lastDownloadStateHash = currentHash; - _lastNotificationUpdate = now; if (downloadStatus.Count > 0 || queueWaiting > 0) { _notificationService.ShowPairDownloadNotification(downloadStatus, queueWaiting); diff --git a/LightlessSync/UI/LightlessNotificationUI.cs b/LightlessSync/UI/LightlessNotificationUI.cs index 36fa508..7ced889 100644 --- a/LightlessSync/UI/LightlessNotificationUI.cs +++ b/LightlessSync/UI/LightlessNotificationUI.cs @@ -134,11 +134,7 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase var viewport = ImGui.GetMainViewport(); - // Set window to full viewport height - var width = _configService.Current.NotificationWidth; - Size = new Vector2(width, viewport.WorkSize.Y); - SizeCondition = ImGuiCond.Always; - + // Window auto-resizes based on content (AlwaysAutoResize flag) Position = CalculateWindowPosition(viewport); PositionCondition = ImGuiCond.Always;