notifications improvement, working pairs incoming request feature and working user logging in notif
This commit is contained in:
@@ -25,6 +25,7 @@ public sealed class PairManager : DisposableMediatorSubscriberBase
|
|||||||
private readonly LightlessConfigService _configurationService;
|
private readonly LightlessConfigService _configurationService;
|
||||||
private readonly IContextMenu _dalamudContextMenu;
|
private readonly IContextMenu _dalamudContextMenu;
|
||||||
private readonly PairFactory _pairFactory;
|
private readonly PairFactory _pairFactory;
|
||||||
|
private readonly LightlessNotificationService _lightlessNotificationService;
|
||||||
private Lazy<List<Pair>> _directPairsInternal;
|
private Lazy<List<Pair>> _directPairsInternal;
|
||||||
private Lazy<Dictionary<GroupFullInfoDto, List<Pair>>> _groupPairsInternal;
|
private Lazy<Dictionary<GroupFullInfoDto, List<Pair>>> _groupPairsInternal;
|
||||||
private Lazy<Dictionary<Pair, List<GroupFullInfoDto>>> _pairsWithGroupsInternal;
|
private Lazy<Dictionary<Pair, List<GroupFullInfoDto>>> _pairsWithGroupsInternal;
|
||||||
@@ -35,12 +36,14 @@ public sealed class PairManager : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
public PairManager(ILogger<PairManager> logger, PairFactory pairFactory,
|
public PairManager(ILogger<PairManager> logger, PairFactory pairFactory,
|
||||||
LightlessConfigService configurationService, LightlessMediator mediator,
|
LightlessConfigService configurationService, LightlessMediator mediator,
|
||||||
IContextMenu dalamudContextMenu, PairProcessingLimiter pairProcessingLimiter) : base(logger, mediator)
|
IContextMenu dalamudContextMenu, PairProcessingLimiter pairProcessingLimiter,
|
||||||
|
LightlessNotificationService lightlessNotificationService) : base(logger, mediator)
|
||||||
{
|
{
|
||||||
_pairFactory = pairFactory;
|
_pairFactory = pairFactory;
|
||||||
_configurationService = configurationService;
|
_configurationService = configurationService;
|
||||||
_dalamudContextMenu = dalamudContextMenu;
|
_dalamudContextMenu = dalamudContextMenu;
|
||||||
_pairProcessingLimiter = pairProcessingLimiter;
|
_pairProcessingLimiter = pairProcessingLimiter;
|
||||||
|
_lightlessNotificationService = lightlessNotificationService;
|
||||||
Mediator.Subscribe<DisconnectedMessage>(this, (_) => ClearPairs());
|
Mediator.Subscribe<DisconnectedMessage>(this, (_) => ClearPairs());
|
||||||
Mediator.Subscribe<CutsceneEndMessage>(this, (_) => ReapplyPairData());
|
Mediator.Subscribe<CutsceneEndMessage>(this, (_) => ReapplyPairData());
|
||||||
_directPairsInternal = DirectPairsLazy();
|
_directPairsInternal = DirectPairsLazy();
|
||||||
@@ -168,7 +171,7 @@ public sealed class PairManager : DisposableMediatorSubscriberBase
|
|||||||
var msg = !string.IsNullOrEmpty(note)
|
var msg = !string.IsNullOrEmpty(note)
|
||||||
? $"{note} ({pair.UserData.AliasOrUID}) is now online"
|
? $"{note} ({pair.UserData.AliasOrUID}) is now online"
|
||||||
: $"{pair.UserData.AliasOrUID} is now online";
|
: $"{pair.UserData.AliasOrUID} is now online";
|
||||||
Mediator.Publish(new NotificationMessage("User online", msg, NotificationType.Info, TimeSpan.FromSeconds(5)));
|
_lightlessNotificationService.ShowNotification("User Online", msg, NotificationType.Info, TimeSpan.FromSeconds(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
QueuePairCreation(pair, dto);
|
QueuePairCreation(pair, dto);
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
collection.AddSingleton((s) => new DtrEntry(s.GetRequiredService<ILogger<DtrEntry>>(), dtrBar, s.GetRequiredService<LightlessConfigService>(),
|
collection.AddSingleton((s) => new DtrEntry(s.GetRequiredService<ILogger<DtrEntry>>(), dtrBar, s.GetRequiredService<LightlessConfigService>(),
|
||||||
s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<PairManager>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<ServerConfigurationManager>()));
|
s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<PairManager>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<ServerConfigurationManager>()));
|
||||||
collection.AddSingleton(s => new PairManager(s.GetRequiredService<ILogger<PairManager>>(), s.GetRequiredService<PairFactory>(),
|
collection.AddSingleton(s => new PairManager(s.GetRequiredService<ILogger<PairManager>>(), s.GetRequiredService<PairFactory>(),
|
||||||
s.GetRequiredService<LightlessConfigService>(), s.GetRequiredService<LightlessMediator>(), contextMenu, s.GetRequiredService<PairProcessingLimiter>()));
|
s.GetRequiredService<LightlessConfigService>(), s.GetRequiredService<LightlessMediator>(), contextMenu, s.GetRequiredService<PairProcessingLimiter>(), s.GetRequiredService<LightlessNotificationService>()));
|
||||||
collection.AddSingleton<RedrawManager>();
|
collection.AddSingleton<RedrawManager>();
|
||||||
collection.AddSingleton<BroadcastService>();
|
collection.AddSingleton<BroadcastService>();
|
||||||
collection.AddSingleton(addonLifecycle);
|
collection.AddSingleton(addonLifecycle);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using LightlessSync.UI;
|
|||||||
using LightlessSync.UI.Models;
|
using LightlessSync.UI.Models;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.Numerics;
|
|
||||||
namespace LightlessSync.Services;
|
namespace LightlessSync.Services;
|
||||||
public class LightlessNotificationService : DisposableMediatorSubscriberBase, IHostedService
|
public class LightlessNotificationService : DisposableMediatorSubscriberBase, IHostedService
|
||||||
{
|
{
|
||||||
@@ -37,7 +36,7 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
_notificationUI = notificationUI;
|
_notificationUI = notificationUI;
|
||||||
}
|
}
|
||||||
public void ShowNotification(string title, string message, NotificationType type = NotificationType.Info,
|
public void ShowNotification(string title, string message, NotificationType type = NotificationType.Info,
|
||||||
TimeSpan? duration = null, List<LightlessNotificationAction>? actions = null)
|
TimeSpan? duration = null, List<LightlessNotificationAction>? actions = null, uint? soundEffectId = null)
|
||||||
{
|
{
|
||||||
var notification = new LightlessNotification
|
var notification = new LightlessNotification
|
||||||
{
|
{
|
||||||
@@ -45,8 +44,16 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
Message = message,
|
Message = message,
|
||||||
Type = type,
|
Type = type,
|
||||||
Duration = duration ?? TimeSpan.FromSeconds(10),
|
Duration = duration ?? TimeSpan.FromSeconds(10),
|
||||||
Actions = actions ?? new List<LightlessNotificationAction>()
|
Actions = actions ?? new List<LightlessNotificationAction>(),
|
||||||
|
SoundEffectId = soundEffectId ?? NotificationSounds.GetDefaultSound(type)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Play sound effect if specified
|
||||||
|
if (notification.SoundEffectId.HasValue)
|
||||||
|
{
|
||||||
|
PlayNotificationSound(notification.SoundEffectId.Value);
|
||||||
|
}
|
||||||
|
|
||||||
Mediator.Publish(new LightlessNotificationMessage(notification));
|
Mediator.Publish(new LightlessNotificationMessage(notification));
|
||||||
}
|
}
|
||||||
public void ShowPairRequestNotification(string senderName, string senderId, Action onAccept, Action onDecline)
|
public void ShowPairRequestNotification(string senderName, string senderId, Action onAccept, Action onDecline)
|
||||||
@@ -57,6 +64,7 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
Message = $"{senderName} wants to pair with you.",
|
Message = $"{senderName} wants to pair with you.",
|
||||||
Type = NotificationType.Info,
|
Type = NotificationType.Info,
|
||||||
Duration = TimeSpan.FromSeconds(60),
|
Duration = TimeSpan.FromSeconds(60),
|
||||||
|
SoundEffectId = NotificationSounds.PairRequest,
|
||||||
Actions = new List<LightlessNotificationAction>
|
Actions = new List<LightlessNotificationAction>
|
||||||
{
|
{
|
||||||
new()
|
new()
|
||||||
@@ -91,6 +99,13 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Play sound effect
|
||||||
|
if (notification.SoundEffectId.HasValue)
|
||||||
|
{
|
||||||
|
PlayNotificationSound(notification.SoundEffectId.Value);
|
||||||
|
}
|
||||||
|
|
||||||
Mediator.Publish(new LightlessNotificationMessage(notification));
|
Mediator.Publish(new LightlessNotificationMessage(notification));
|
||||||
}
|
}
|
||||||
public void ShowDownloadCompleteNotification(string fileName, int fileCount, Action? onOpenFolder = null)
|
public void ShowDownloadCompleteNotification(string fileName, int fileCount, Action? onOpenFolder = null)
|
||||||
@@ -121,8 +136,16 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
$"Downloaded {fileName} successfully.",
|
$"Downloaded {fileName} successfully.",
|
||||||
Type = NotificationType.Info,
|
Type = NotificationType.Info,
|
||||||
Duration = TimeSpan.FromSeconds(8),
|
Duration = TimeSpan.FromSeconds(8),
|
||||||
Actions = actions
|
Actions = actions,
|
||||||
|
SoundEffectId = NotificationSounds.DownloadComplete
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Play sound effect
|
||||||
|
if (notification.SoundEffectId.HasValue)
|
||||||
|
{
|
||||||
|
PlayNotificationSound(notification.SoundEffectId.Value);
|
||||||
|
}
|
||||||
|
|
||||||
Mediator.Publish(new LightlessNotificationMessage(notification));
|
Mediator.Publish(new LightlessNotificationMessage(notification));
|
||||||
}
|
}
|
||||||
public void ShowErrorNotification(string title, string message, Exception? exception = null, Action? onRetry = null, Action? onViewLog = null)
|
public void ShowErrorNotification(string title, string message, Exception? exception = null, Action? onRetry = null, Action? onViewLog = null)
|
||||||
@@ -161,21 +184,47 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
Message = exception != null ? $"{message}\n\nError: {exception.Message}" : message,
|
Message = exception != null ? $"{message}\n\nError: {exception.Message}" : message,
|
||||||
Type = NotificationType.Error,
|
Type = NotificationType.Error,
|
||||||
Duration = TimeSpan.FromSeconds(15),
|
Duration = TimeSpan.FromSeconds(15),
|
||||||
Actions = actions
|
Actions = actions,
|
||||||
|
SoundEffectId = NotificationSounds.Error
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Play sound effect
|
||||||
|
if (notification.SoundEffectId.HasValue)
|
||||||
|
{
|
||||||
|
PlayNotificationSound(notification.SoundEffectId.Value);
|
||||||
|
}
|
||||||
|
|
||||||
Mediator.Publish(new LightlessNotificationMessage(notification));
|
Mediator.Publish(new LightlessNotificationMessage(notification));
|
||||||
}
|
}
|
||||||
public void ShowPairDownloadNotification(List<(string playerName, float progress, string status)> downloadStatus)
|
public void ShowPairDownloadNotification(List<(string playerName, float progress, string status)> downloadStatus, int queueWaiting = 0)
|
||||||
{
|
{
|
||||||
var totalProgress = downloadStatus.Count > 0 ? downloadStatus.Average(x => x.progress) : 0f;
|
// Filter out queue status from user downloads
|
||||||
var completedCount = downloadStatus.Count(x => x.progress >= 1.0f);
|
var userDownloads = downloadStatus.Where(x => x.playerName != "Pair Queue").ToList();
|
||||||
var totalCount = downloadStatus.Count;
|
|
||||||
|
|
||||||
var message = $"Progress: {completedCount}/{totalCount} completed";
|
var totalProgress = userDownloads.Count > 0 ? userDownloads.Average(x => x.progress) : 0f;
|
||||||
if (downloadStatus.Any(x => x.progress < 1.0f))
|
var completedCount = userDownloads.Count(x => x.progress >= 1.0f);
|
||||||
|
var totalCount = userDownloads.Count;
|
||||||
|
|
||||||
|
var message = "";
|
||||||
|
|
||||||
|
// Add queue status at the top if there are waiting items
|
||||||
|
if (queueWaiting > 0)
|
||||||
{
|
{
|
||||||
var activeDownloads = downloadStatus.Where(x => x.progress < 1.0f).Take(3);
|
message = $"Queue: {queueWaiting} waiting";
|
||||||
message += "\n" + string.Join("\n", activeDownloads.Select(x =>
|
}
|
||||||
|
|
||||||
|
// Add download progress if there are downloads
|
||||||
|
if (totalCount > 0)
|
||||||
|
{
|
||||||
|
var progressMessage = $"Progress: {completedCount}/{totalCount} completed";
|
||||||
|
message = string.IsNullOrEmpty(message) ? progressMessage : $"{message}\n{progressMessage}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userDownloads.Any(x => x.progress < 1.0f))
|
||||||
|
{
|
||||||
|
var maxNamesToShow = _configService.Current.MaxConcurrentPairApplications;
|
||||||
|
var activeDownloads = userDownloads.Where(x => x.progress < 1.0f).Take(maxNamesToShow);
|
||||||
|
var downloadLines = string.Join("\n", activeDownloads.Select(x =>
|
||||||
{
|
{
|
||||||
var statusText = x.status switch
|
var statusText = x.status switch
|
||||||
{
|
{
|
||||||
@@ -188,11 +237,12 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
return $"• {x.playerName}: {statusText}";
|
return $"• {x.playerName}: {statusText}";
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (downloadStatus.Count(x => x.progress < 1.0f) > 3)
|
message += string.IsNullOrEmpty(message) ? downloadLines : $"\n{downloadLines}";
|
||||||
{
|
|
||||||
message += $"\n• ... and {downloadStatus.Count(x => x.progress < 1.0f) - 3} more";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if all downloads are completed
|
||||||
|
var allDownloadsCompleted = userDownloads.All(x => x.progress >= 1.0f) && userDownloads.Any();
|
||||||
|
|
||||||
var notification = new LightlessNotification
|
var notification = new LightlessNotification
|
||||||
{
|
{
|
||||||
Id = "pair_download_progress",
|
Id = "pair_download_progress",
|
||||||
@@ -204,9 +254,33 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
Progress = totalProgress
|
Progress = totalProgress
|
||||||
};
|
};
|
||||||
Mediator.Publish(new LightlessNotificationMessage(notification));
|
Mediator.Publish(new LightlessNotificationMessage(notification));
|
||||||
|
if (allDownloadsCompleted)
|
||||||
|
{
|
||||||
|
DismissPairDownloadNotification();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public void DismissPairDownloadNotification()
|
public void DismissPairDownloadNotification()
|
||||||
{
|
{
|
||||||
Mediator.Publish(new LightlessNotificationDismissMessage("pair_download_progress"));
|
Mediator.Publish(new LightlessNotificationDismissMessage("pair_download_progress"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PlayNotificationSound(uint soundEffectId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// TODO: Implement proper sound playback
|
||||||
|
// The ChatGui.PlaySoundEffect method doesn't exist in the current Dalamud API
|
||||||
|
// For now, just log what sound would be played
|
||||||
|
_logger.LogDebug("Would play notification sound effect {SoundId}", soundEffectId);
|
||||||
|
|
||||||
|
// Future implementation options:
|
||||||
|
// 1. Use UIModule->PlaySound() with proper unsafe interop
|
||||||
|
// 2. Use game's sound system through SigScanner
|
||||||
|
// 3. Wait for official Dalamud sound API
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(ex, "Failed to play notification sound effect {SoundId}", soundEffectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Dalamud.Bindings.ImGui;
|
|
||||||
using Dalamud.Interface.Colors;
|
using Dalamud.Interface.Colors;
|
||||||
using LightlessSync.LightlessConfiguration;
|
using LightlessSync.LightlessConfiguration;
|
||||||
using LightlessSync.PlayerData.Handlers;
|
using LightlessSync.PlayerData.Handlers;
|
||||||
@@ -88,19 +87,7 @@ public class DownloadUi : WindowMediatorSubscriberBase
|
|||||||
if (_configService.Current.ShowTransferWindow)
|
if (_configService.Current.ShowTransferWindow)
|
||||||
{
|
{
|
||||||
var limiterSnapshot = _pairProcessingLimiter.GetSnapshot();
|
var limiterSnapshot = _pairProcessingLimiter.GetSnapshot();
|
||||||
if (limiterSnapshot.IsEnabled)
|
|
||||||
{
|
|
||||||
var queueColor = limiterSnapshot.Waiting > 0 ? ImGuiColors.DalamudYellow : ImGuiColors.DalamudGrey;
|
|
||||||
var queueText = $"Pair queue {limiterSnapshot.InFlight}/{limiterSnapshot.Limit}";
|
|
||||||
queueText += limiterSnapshot.Waiting > 0 ? $" ({limiterSnapshot.Waiting} waiting, {limiterSnapshot.Remaining} free)" : $" ({limiterSnapshot.Remaining} free)";
|
|
||||||
UiSharedService.DrawOutlinedFont(queueText, queueColor, new Vector4(0, 0, 0, 255), 1);
|
|
||||||
ImGui.NewLine();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UiSharedService.DrawOutlinedFont("Pair apply limiter disabled", ImGuiColors.DalamudGrey, new Vector4(0, 0, 0, 255), 1);
|
|
||||||
ImGui.NewLine();
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_fileTransferManager.IsUploading)
|
if (_fileTransferManager.IsUploading)
|
||||||
@@ -138,18 +125,30 @@ public class DownloadUi : WindowMediatorSubscriberBase
|
|||||||
// Use new notification stuff
|
// Use new notification stuff
|
||||||
if (_currentDownloads.Any())
|
if (_currentDownloads.Any())
|
||||||
{
|
{
|
||||||
UpdateDownloadNotification();
|
UpdateDownloadNotification(limiterSnapshot);
|
||||||
_notificationDismissed = false;
|
_notificationDismissed = false;
|
||||||
}
|
}
|
||||||
else if (!_notificationDismissed)
|
else if (!_notificationDismissed)
|
||||||
{
|
{
|
||||||
_notificationService.DismissPairDownloadNotification();
|
_notificationService.DismissPairDownloadNotification();
|
||||||
_notificationDismissed = true;
|
_notificationDismissed = true;
|
||||||
}
|
} }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (limiterSnapshot.IsEnabled)
|
||||||
|
{
|
||||||
|
var queueColor = limiterSnapshot.Waiting > 0 ? ImGuiColors.DalamudYellow : ImGuiColors.DalamudGrey;
|
||||||
|
var queueText = $"Pair queue {limiterSnapshot.InFlight}/{limiterSnapshot.Limit}";
|
||||||
|
queueText += limiterSnapshot.Waiting > 0 ? $" ({limiterSnapshot.Waiting} waiting, {limiterSnapshot.Remaining} free)" : $" ({limiterSnapshot.Remaining} free)";
|
||||||
|
UiSharedService.DrawOutlinedFont(queueText, queueColor, new Vector4(0, 0, 0, 255), 1);
|
||||||
|
ImGui.NewLine();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// text overlay
|
UiSharedService.DrawOutlinedFont("Pair apply limiter disabled", ImGuiColors.DalamudGrey, new Vector4(0, 0, 0, 255), 1);
|
||||||
|
ImGui.NewLine();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var item in _currentDownloads.ToList())
|
foreach (var item in _currentDownloads.ToList())
|
||||||
{
|
{
|
||||||
var dlSlot = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.WaitingForSlot);
|
var dlSlot = item.Value.Count(c => c.Value.DownloadStatus == DownloadStatus.WaitingForSlot);
|
||||||
@@ -292,7 +291,7 @@ public class DownloadUi : WindowMediatorSubscriberBase
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateDownloadNotification()
|
private void UpdateDownloadNotification(PairProcessingLimiterSnapshot limiterSnapshot)
|
||||||
{
|
{
|
||||||
var downloadStatus = new List<(string playerName, float progress, string status)>();
|
var downloadStatus = new List<(string playerName, float progress, string status)>();
|
||||||
|
|
||||||
@@ -319,9 +318,12 @@ public class DownloadUi : WindowMediatorSubscriberBase
|
|||||||
downloadStatus.Add((item.Key.Name, progress, status));
|
downloadStatus.Add((item.Key.Name, progress, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (downloadStatus.Any())
|
// 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)
|
||||||
{
|
{
|
||||||
_notificationService.ShowPairDownloadNotification(downloadStatus);
|
_notificationService.ShowPairDownloadNotification(downloadStatus, queueWaiting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using LightlessSync.LightlessConfiguration.Models;
|
using LightlessSync.LightlessConfiguration.Models;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
namespace LightlessSync.UI.Models;
|
namespace LightlessSync.UI.Models;
|
||||||
@@ -21,6 +21,9 @@ public class LightlessNotification
|
|||||||
public float AnimationProgress { get; set; } = 0f;
|
public float AnimationProgress { get; set; } = 0f;
|
||||||
public bool IsAnimatingIn { get; set; } = true;
|
public bool IsAnimatingIn { get; set; } = true;
|
||||||
public bool IsAnimatingOut { get; set; } = false;
|
public bool IsAnimatingOut { get; set; } = false;
|
||||||
|
|
||||||
|
// Sound properties
|
||||||
|
public uint? SoundEffectId { get; set; } = null;
|
||||||
}
|
}
|
||||||
public class LightlessNotificationAction
|
public class LightlessNotificationAction
|
||||||
{
|
{
|
||||||
|
|||||||
50
LightlessSync/UI/Models/NotificationSounds.cs
Normal file
50
LightlessSync/UI/Models/NotificationSounds.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using LightlessSync.LightlessConfiguration.Models;
|
||||||
|
|
||||||
|
namespace LightlessSync.UI.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Common FFXIV sound effect IDs for notifications
|
||||||
|
/// </summary>
|
||||||
|
public static class NotificationSounds
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// General notification sound (quest complete)
|
||||||
|
/// </summary>
|
||||||
|
public const uint Info = 37;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Warning/alert sound (system error)
|
||||||
|
/// </summary>
|
||||||
|
public const uint Warning = 15;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Error sound (action failed)
|
||||||
|
/// </summary>
|
||||||
|
public const uint Error = 16;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Success sound (level up)
|
||||||
|
/// </summary>
|
||||||
|
public const uint Success = 25;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pair request sound (tell received)
|
||||||
|
/// </summary>
|
||||||
|
public const uint PairRequest = 13;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Download complete sound (item obtained)
|
||||||
|
/// </summary>
|
||||||
|
public const uint DownloadComplete = 30;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get default sound for notification type
|
||||||
|
/// </summary>
|
||||||
|
public static uint GetDefaultSound(NotificationType type) => type switch
|
||||||
|
{
|
||||||
|
NotificationType.Info => Info,
|
||||||
|
NotificationType.Warning => Warning,
|
||||||
|
NotificationType.Error => Error,
|
||||||
|
_ => Info
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -11,12 +11,8 @@ using LightlessSync.Services;
|
|||||||
using LightlessSync.Services.Mediator;
|
using LightlessSync.Services.Mediator;
|
||||||
using LightlessSync.Utils;
|
using LightlessSync.Utils;
|
||||||
using LightlessSync.WebAPI;
|
using LightlessSync.WebAPI;
|
||||||
using Serilog;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Reflection.Emit;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace LightlessSync.UI;
|
namespace LightlessSync.UI;
|
||||||
|
|
||||||
@@ -269,7 +265,6 @@ public class TopTabMenu
|
|||||||
|
|
||||||
_lightlessNotificationService.ShowPairDownloadNotification(downloadStatus);
|
_lightlessNotificationService.ShowPairDownloadNotification(downloadStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (ImGui.Button("Dismiss Download"))
|
if (ImGui.Button("Dismiss Download"))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user