more to notification system with new settings tab
This commit is contained in:
@@ -70,6 +70,31 @@ public class LightlessConfig : ILightlessConfiguration
|
||||
public bool AutoPopulateEmptyNotesFromCharaName { get; set; } = false;
|
||||
public int Version { get; set; } = 1;
|
||||
public NotificationLocation WarningNotification { get; set; } = NotificationLocation.Both;
|
||||
|
||||
// Lightless Notification Configuration
|
||||
// TODO: clean these
|
||||
public bool UseLightlessNotifications { get; set; } = true;
|
||||
public bool EnableNotificationSounds { get; set; } = true;
|
||||
public int DefaultNotificationDurationSeconds { get; set; } = 10;
|
||||
public bool ShowNotificationProgress { get; set; } = true;
|
||||
public NotificationLocation LightlessInfoNotification { get; set; } = NotificationLocation.LightlessUI;
|
||||
public NotificationLocation LightlessWarningNotification { get; set; } = NotificationLocation.LightlessUI;
|
||||
public NotificationLocation LightlessErrorNotification { get; set; } = NotificationLocation.ChatAndLightlessUI;
|
||||
|
||||
public float NotificationOpacity { get; set; } = 0.95f;
|
||||
public bool EnableNotificationAnimations { get; set; } = true;
|
||||
public int MaxSimultaneousNotifications { get; set; } = 5;
|
||||
public bool AutoDismissOnAction { get; set; } = true;
|
||||
public bool ShowNotificationTimestamp { get; set; } = false;
|
||||
public bool EnableNotificationHistory { get; set; } = true;
|
||||
public int NotificationHistorySize { get; set; } = 50;
|
||||
|
||||
public uint CustomInfoSoundId { get; set; } = 2; // Se2
|
||||
public uint CustomWarningSoundId { get; set; } = 15; // Se15
|
||||
public uint CustomErrorSoundId { get; set; } = 16; // Se16
|
||||
public bool UseCustomSounds { get; set; } = false;
|
||||
public float NotificationSoundVolume { get; set; } = 1.0f;
|
||||
// till here c:
|
||||
public bool UseFocusTarget { get; set; } = false;
|
||||
public bool overrideFriendColor { get; set; } = false;
|
||||
public bool overridePartyColor { get; set; } = false;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
namespace LightlessSync.LightlessConfiguration.Models;
|
||||
namespace LightlessSync.LightlessConfiguration.Models;
|
||||
|
||||
public enum NotificationLocation
|
||||
{
|
||||
Nowhere,
|
||||
Chat,
|
||||
Toast,
|
||||
Both
|
||||
Both,
|
||||
LightlessUI,
|
||||
ChatAndLightlessUI,
|
||||
}
|
||||
|
||||
public enum NotificationType
|
||||
|
||||
@@ -179,6 +179,8 @@ public sealed class Plugin : IDalamudPlugin
|
||||
s.GetRequiredService<ILogger<LightlessNotificationService>>(),
|
||||
s.GetRequiredService<LightlessConfigService>(),
|
||||
s.GetRequiredService<DalamudUtilService>(),
|
||||
notificationManager,
|
||||
chatGui,
|
||||
s.GetRequiredService<LightlessMediator>()));
|
||||
collection.AddSingleton((s) =>
|
||||
{
|
||||
@@ -244,7 +246,8 @@ public sealed class Plugin : IDalamudPlugin
|
||||
new LightlessNotificationUI(
|
||||
s.GetRequiredService<ILogger<LightlessNotificationUI>>(),
|
||||
s.GetRequiredService<LightlessMediator>(),
|
||||
s.GetRequiredService<PerformanceCollectorService>()));
|
||||
s.GetRequiredService<PerformanceCollectorService>(),
|
||||
s.GetRequiredService<LightlessConfigService>()));
|
||||
collection.AddScoped<IPopupHandler, CensusPopupHandler>();
|
||||
collection.AddScoped<CacheCreationService>();
|
||||
collection.AddScoped<PlayerDataFactory>();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Dalamud.Plugin.Services;
|
||||
using LightlessSync.LightlessConfiguration;
|
||||
using LightlessSync.LightlessConfiguration.Models;
|
||||
@@ -8,6 +10,7 @@ using LightlessSync.UI.Models;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||
using NotificationType = LightlessSync.LightlessConfiguration.Models.NotificationType;
|
||||
|
||||
namespace LightlessSync.Services;
|
||||
public class LightlessNotificationService : DisposableMediatorSubscriberBase, IHostedService
|
||||
@@ -15,19 +18,26 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
||||
private readonly ILogger<LightlessNotificationService> _logger;
|
||||
private readonly LightlessConfigService _configService;
|
||||
private readonly DalamudUtilService _dalamudUtilService;
|
||||
private readonly INotificationManager _notificationManager;
|
||||
private readonly IChatGui _chatGui;
|
||||
private LightlessNotificationUI? _notificationUI;
|
||||
public LightlessNotificationService(
|
||||
ILogger<LightlessNotificationService> logger,
|
||||
LightlessConfigService configService,
|
||||
DalamudUtilService dalamudUtilService,
|
||||
INotificationManager notificationManager,
|
||||
IChatGui chatGui,
|
||||
LightlessMediator mediator) : base(logger, mediator)
|
||||
{
|
||||
_logger = logger;
|
||||
_configService = configService;
|
||||
_dalamudUtilService = dalamudUtilService;
|
||||
_notificationManager = notificationManager;
|
||||
_chatGui = chatGui;
|
||||
}
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Mediator.Subscribe<NotificationMessage>(this, HandleNotificationMessage);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
@@ -46,12 +56,31 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
||||
Title = title,
|
||||
Message = message,
|
||||
Type = type,
|
||||
Duration = duration ?? TimeSpan.FromSeconds(10),
|
||||
Duration = duration ?? TimeSpan.FromSeconds(_configService.Current.DefaultNotificationDurationSeconds),
|
||||
Actions = actions ?? new List<LightlessNotificationAction>(),
|
||||
SoundEffectId = soundEffectId ?? NotificationSounds.GetDefaultSound(type)
|
||||
SoundEffectId = GetSoundEffectId(type, soundEffectId),
|
||||
ShowProgress = _configService.Current.ShowNotificationProgress,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
};
|
||||
|
||||
if (notification.SoundEffectId.HasValue)
|
||||
if (_configService.Current.AutoDismissOnAction && notification.Actions.Any())
|
||||
{
|
||||
foreach (var action in notification.Actions)
|
||||
{
|
||||
var originalOnClick = action.OnClick;
|
||||
action.OnClick = (n) =>
|
||||
{
|
||||
originalOnClick(n);
|
||||
if (_configService.Current.AutoDismissOnAction)
|
||||
{
|
||||
n.IsDismissed = true;
|
||||
n.IsAnimatingOut = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (notification.SoundEffectId.HasValue && _configService.Current.EnableNotificationSounds)
|
||||
{
|
||||
PlayNotificationSound(notification.SoundEffectId.Value);
|
||||
}
|
||||
@@ -101,18 +130,18 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (notification.SoundEffectId.HasValue)
|
||||
{
|
||||
PlayNotificationSound(notification.SoundEffectId.Value);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
@@ -132,20 +161,20 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
||||
var notification = new LightlessNotification
|
||||
{
|
||||
Title = "Download Complete",
|
||||
Message = fileCount > 1 ?
|
||||
$"Downloaded {fileCount} files successfully." :
|
||||
Message = fileCount > 1 ?
|
||||
$"Downloaded {fileCount} files successfully." :
|
||||
$"Downloaded {fileName} successfully.",
|
||||
Type = NotificationType.Info,
|
||||
Duration = TimeSpan.FromSeconds(8),
|
||||
Actions = actions,
|
||||
SoundEffectId = NotificationSounds.DownloadComplete
|
||||
};
|
||||
|
||||
|
||||
if (notification.SoundEffectId.HasValue)
|
||||
{
|
||||
PlayNotificationSound(notification.SoundEffectId.Value);
|
||||
}
|
||||
|
||||
|
||||
Mediator.Publish(new LightlessNotificationMessage(notification));
|
||||
}
|
||||
public void ShowErrorNotification(string title, string message, Exception? exception = null, Action? onRetry = null, Action? onViewLog = null)
|
||||
@@ -187,40 +216,40 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
||||
Actions = actions,
|
||||
SoundEffectId = NotificationSounds.Error
|
||||
};
|
||||
|
||||
|
||||
if (notification.SoundEffectId.HasValue)
|
||||
{
|
||||
PlayNotificationSound(notification.SoundEffectId.Value);
|
||||
}
|
||||
|
||||
|
||||
Mediator.Publish(new LightlessNotificationMessage(notification));
|
||||
}
|
||||
public void ShowPairDownloadNotification(List<(string playerName, float progress, string status)> downloadStatus, int queueWaiting = 0)
|
||||
{
|
||||
var userDownloads = downloadStatus.Where(x => x.playerName != "Pair Queue").ToList();
|
||||
|
||||
|
||||
var totalProgress = userDownloads.Count > 0 ? userDownloads.Average(x => x.progress) : 0f;
|
||||
var completedCount = userDownloads.Count(x => x.progress >= 1.0f);
|
||||
var totalCount = userDownloads.Count;
|
||||
|
||||
|
||||
var message = "";
|
||||
|
||||
|
||||
if (queueWaiting > 0)
|
||||
{
|
||||
message = $"Queue: {queueWaiting} waiting";
|
||||
}
|
||||
|
||||
|
||||
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 downloadLines = string.Join("\n", activeDownloads.Select(x =>
|
||||
{
|
||||
var statusText = x.status switch
|
||||
{
|
||||
@@ -232,12 +261,12 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
||||
};
|
||||
return $"• {x.playerName}: {statusText}";
|
||||
}));
|
||||
|
||||
|
||||
message += string.IsNullOrEmpty(message) ? downloadLines : $"\n{downloadLines}";
|
||||
}
|
||||
|
||||
|
||||
var allDownloadsCompleted = userDownloads.All(x => x.progress >= 1.0f) && userDownloads.Any();
|
||||
|
||||
|
||||
var notification = new LightlessNotification
|
||||
{
|
||||
Id = "pair_download_progress",
|
||||
@@ -251,15 +280,37 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
||||
Mediator.Publish(new LightlessNotificationMessage(notification));
|
||||
if (allDownloadsCompleted)
|
||||
{
|
||||
DismissPairDownloadNotification();
|
||||
DismissPairDownloadNotification();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void DismissPairDownloadNotification()
|
||||
{
|
||||
Mediator.Publish(new LightlessNotificationDismissMessage("pair_download_progress"));
|
||||
}
|
||||
|
||||
|
||||
private uint? GetSoundEffectId(NotificationType type, uint? overrideSoundId)
|
||||
{
|
||||
if (!_configService.Current.EnableNotificationSounds)
|
||||
return null;
|
||||
|
||||
if (overrideSoundId.HasValue)
|
||||
return overrideSoundId;
|
||||
|
||||
if (_configService.Current.UseCustomSounds)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
NotificationType.Info => _configService.Current.CustomInfoSoundId,
|
||||
NotificationType.Warning => _configService.Current.CustomWarningSoundId,
|
||||
NotificationType.Error => _configService.Current.CustomErrorSoundId,
|
||||
_ => NotificationSounds.GetDefaultSound(type)
|
||||
};
|
||||
}
|
||||
|
||||
return NotificationSounds.GetDefaultSound(type);
|
||||
}
|
||||
|
||||
private void PlayNotificationSound(uint soundEffectId)
|
||||
{
|
||||
try
|
||||
@@ -279,4 +330,172 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
||||
_logger.LogWarning(ex, "Failed to play notification sound effect {SoundId}", soundEffectId);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleNotificationMessage(NotificationMessage msg)
|
||||
{
|
||||
_logger.LogInformation("{msg}", msg.ToString());
|
||||
|
||||
if (!_dalamudUtilService.IsLoggedIn) return;
|
||||
|
||||
// Get both old and new notification locations
|
||||
var oldLocation = msg.Type switch
|
||||
{
|
||||
NotificationType.Info => _configService.Current.InfoNotification,
|
||||
NotificationType.Warning => _configService.Current.WarningNotification,
|
||||
NotificationType.Error => _configService.Current.ErrorNotification,
|
||||
_ => NotificationLocation.Nowhere
|
||||
};
|
||||
|
||||
var newLocation = msg.Type switch
|
||||
{
|
||||
NotificationType.Info => _configService.Current.LightlessInfoNotification,
|
||||
NotificationType.Warning => _configService.Current.LightlessWarningNotification,
|
||||
NotificationType.Error => _configService.Current.LightlessErrorNotification,
|
||||
_ => NotificationLocation.LightlessUI
|
||||
};
|
||||
|
||||
// Show notifications based on system selection with backwards compatibility
|
||||
if (!_configService.Current.UseLightlessNotifications)
|
||||
{
|
||||
// Only use old system when new system is disabled
|
||||
ShowNotificationLocationBased(msg, oldLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use new enhanced system as primary
|
||||
ShowNotificationLocationBased(msg, newLocation);
|
||||
|
||||
// Also use old system as fallback for backwards compatibility
|
||||
// Only if it's different from the new location and not "Nowhere"
|
||||
if (oldLocation != NotificationLocation.Nowhere &&
|
||||
oldLocation != newLocation &&
|
||||
!IsLightlessLocation(oldLocation))
|
||||
{
|
||||
ShowNotificationLocationBased(msg, oldLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowNotificationLocationBased(NotificationMessage msg, NotificationLocation location)
|
||||
{
|
||||
switch (location)
|
||||
{
|
||||
case NotificationLocation.Toast:
|
||||
ShowToast(msg);
|
||||
break;
|
||||
|
||||
case NotificationLocation.Chat:
|
||||
ShowChat(msg);
|
||||
break;
|
||||
|
||||
case NotificationLocation.Both:
|
||||
ShowToast(msg);
|
||||
ShowChat(msg);
|
||||
break;
|
||||
|
||||
case NotificationLocation.LightlessUI:
|
||||
ShowLightlessNotification(msg);
|
||||
break;
|
||||
|
||||
case NotificationLocation.ChatAndLightlessUI:
|
||||
ShowChat(msg);
|
||||
ShowLightlessNotification(msg);
|
||||
break;
|
||||
|
||||
case NotificationLocation.Nowhere:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowLightlessNotification(NotificationMessage msg)
|
||||
{
|
||||
var duration = msg.TimeShownOnScreen ?? TimeSpan.FromSeconds(_configService.Current.DefaultNotificationDurationSeconds);
|
||||
uint? soundId = null;
|
||||
|
||||
if (_configService.Current.EnableNotificationSounds)
|
||||
{
|
||||
if (_configService.Current.UseCustomSounds)
|
||||
{
|
||||
soundId = msg.Type switch
|
||||
{
|
||||
NotificationType.Info => _configService.Current.CustomInfoSoundId,
|
||||
NotificationType.Warning => _configService.Current.CustomWarningSoundId,
|
||||
NotificationType.Error => _configService.Current.CustomErrorSoundId,
|
||||
_ => NotificationSounds.GetDefaultSound(msg.Type)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
soundId = NotificationSounds.GetDefaultSound(msg.Type);
|
||||
}
|
||||
}
|
||||
|
||||
ShowNotification(msg.Title ?? "Lightless Sync", msg.Message ?? string.Empty, msg.Type, duration, null, soundId);
|
||||
}
|
||||
|
||||
private void ShowToast(NotificationMessage msg)
|
||||
{
|
||||
Dalamud.Interface.ImGuiNotification.NotificationType dalamudType = msg.Type switch
|
||||
{
|
||||
NotificationType.Error => Dalamud.Interface.ImGuiNotification.NotificationType.Error,
|
||||
NotificationType.Warning => Dalamud.Interface.ImGuiNotification.NotificationType.Warning,
|
||||
NotificationType.Info => Dalamud.Interface.ImGuiNotification.NotificationType.Info,
|
||||
_ => Dalamud.Interface.ImGuiNotification.NotificationType.Info
|
||||
};
|
||||
|
||||
_notificationManager.AddNotification(new Notification()
|
||||
{
|
||||
Content = msg.Message ?? string.Empty,
|
||||
Title = msg.Title,
|
||||
Type = dalamudType,
|
||||
Minimized = false,
|
||||
InitialDuration = msg.TimeShownOnScreen ?? TimeSpan.FromSeconds(3)
|
||||
});
|
||||
}
|
||||
|
||||
private void ShowChat(NotificationMessage msg)
|
||||
{
|
||||
switch (msg.Type)
|
||||
{
|
||||
case NotificationType.Info:
|
||||
PrintInfoChat(msg.Message);
|
||||
break;
|
||||
|
||||
case NotificationType.Warning:
|
||||
PrintWarnChat(msg.Message);
|
||||
break;
|
||||
|
||||
case NotificationType.Error:
|
||||
PrintErrorChat(msg.Message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void PrintErrorChat(string? message)
|
||||
{
|
||||
SeStringBuilder se = new SeStringBuilder().AddText("[Lightless Sync] Error: " + message);
|
||||
_chatGui.PrintError(se.BuiltString);
|
||||
}
|
||||
|
||||
private void PrintInfoChat(string? message)
|
||||
{
|
||||
SeStringBuilder se = new SeStringBuilder().AddText("[Lightless Sync] Info: ").AddItalics(message ?? string.Empty);
|
||||
_chatGui.Print(se.BuiltString);
|
||||
}
|
||||
|
||||
private void PrintWarnChat(string? message)
|
||||
{
|
||||
SeStringBuilder se = new SeStringBuilder().AddText("[Lightless Sync] ").AddUiForeground("Warning: " + (message ?? string.Empty), 31).AddUiForegroundOff();
|
||||
_chatGui.Print(se.BuiltString);
|
||||
}
|
||||
|
||||
private bool IsLightlessLocation(NotificationLocation location)
|
||||
{
|
||||
return location switch
|
||||
{
|
||||
NotificationLocation.LightlessUI => true,
|
||||
NotificationLocation.ChatAndLightlessUI => true,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,13 @@ using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using LightlessSync.LightlessConfiguration;
|
||||
using LightlessSync.LightlessConfiguration.Models;
|
||||
using LightlessSync.Services;
|
||||
using LightlessSync.Services.Mediator;
|
||||
using LightlessSync.UI.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using System.Numerics;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
|
||||
@@ -17,18 +19,22 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
||||
{
|
||||
private readonly List<LightlessNotification> _notifications = new();
|
||||
private readonly object _notificationLock = new();
|
||||
private readonly LightlessConfigService _configService;
|
||||
|
||||
private const float NotificationWidth = 350f;
|
||||
private const float NotificationMinHeight = 60f;
|
||||
private const float NotificationMaxHeight = 200f;
|
||||
private const float NotificationSpacing = 8f;
|
||||
private const float AnimationSpeed = 10f;
|
||||
|
||||
private const float EdgeXMargin = 0;
|
||||
private const float EdgeYMargin = 30f;
|
||||
private const float SlideDistance = 100f;
|
||||
|
||||
public LightlessNotificationUI(ILogger<LightlessNotificationUI> logger, LightlessMediator mediator, PerformanceCollectorService performanceCollector)
|
||||
public LightlessNotificationUI(ILogger<LightlessNotificationUI> logger, LightlessMediator mediator, PerformanceCollectorService performanceCollector, LightlessConfigService configService)
|
||||
: base(logger, mediator, "Lightless Notifications##LightlessNotifications", performanceCollector)
|
||||
{
|
||||
_configService = configService;
|
||||
Flags = ImGuiWindowFlags.NoDecoration |
|
||||
ImGuiWindowFlags.NoMove |
|
||||
ImGuiWindowFlags.NoResize |
|
||||
@@ -141,6 +147,19 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
||||
{
|
||||
var deltaTime = ImGui.GetIO().DeltaTime;
|
||||
|
||||
var maxNotifications = _configService.Current.MaxSimultaneousNotifications;
|
||||
while (_notifications.Count(n => !n.IsAnimatingOut) > maxNotifications)
|
||||
{
|
||||
var oldestNotification = _notifications
|
||||
.Where(n => !n.IsAnimatingOut)
|
||||
.OrderBy(n => n.CreatedAt)
|
||||
.FirstOrDefault();
|
||||
if (oldestNotification != null)
|
||||
{
|
||||
oldestNotification.IsAnimatingOut = true;
|
||||
oldestNotification.IsAnimatingIn = false;
|
||||
}
|
||||
}
|
||||
for (int i = _notifications.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var notification = _notifications[i];
|
||||
@@ -174,9 +193,16 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
||||
private void DrawNotification(LightlessNotification notification, int index)
|
||||
{
|
||||
var alpha = notification.AnimationProgress;
|
||||
if (alpha <= 0f) return;
|
||||
|
||||
if (_configService.Current.EnableNotificationAnimations && alpha <= 0f)
|
||||
return;
|
||||
|
||||
var slideOffset = 0f;
|
||||
if (_configService.Current.EnableNotificationAnimations)
|
||||
{
|
||||
slideOffset = (1f - alpha) * SlideDistance;
|
||||
}
|
||||
|
||||
var slideOffset = (1f - alpha) * SlideDistance;
|
||||
var originalCursorPos = ImGui.GetCursorPos();
|
||||
ImGui.SetCursorPosX(originalCursorPos.X + slideOffset);
|
||||
|
||||
@@ -198,13 +224,18 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
||||
var windowPos = ImGui.GetWindowPos();
|
||||
var windowSize = ImGui.GetWindowSize();
|
||||
|
||||
var bgColor = new Vector4(30f/255f, 30f/255f, 30f/255f, 0.95f * alpha);
|
||||
var baseOpacity = _configService.Current.NotificationOpacity;
|
||||
var finalOpacity = _configService.Current.EnableNotificationAnimations ? baseOpacity * alpha : baseOpacity;
|
||||
var bgColor = new Vector4(30f/255f, 30f/255f, 30f/255f, finalOpacity);
|
||||
var accentColor = GetNotificationAccentColor(notification.Type);
|
||||
var progressBarColor = UIColors.Get("LightlessBlue");
|
||||
accentColor.W *= alpha;
|
||||
|
||||
var finalAccentAlpha = _configService.Current.EnableNotificationAnimations ? alpha : 1f;
|
||||
accentColor.W *= finalAccentAlpha;
|
||||
|
||||
var shadowOffset = new Vector2(1f, 1f);
|
||||
var shadowColor = new Vector4(0f, 0f, 0f, 0.4f * alpha);
|
||||
var shadowAlpha = _configService.Current.EnableNotificationAnimations ? 0.4f * alpha : 0.4f;
|
||||
var shadowColor = new Vector4(0f, 0f, 0f, shadowAlpha);
|
||||
drawList.AddRectFilled(
|
||||
windowPos + shadowOffset,
|
||||
windowPos + windowSize + shadowOffset,
|
||||
@@ -278,14 +309,31 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
||||
|
||||
ImGui.SetCursorPos(contentPos);
|
||||
|
||||
float titleHeight = 0f;
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, new Vector4(1f, 1f, 1f, alpha)))
|
||||
{
|
||||
ImGui.Text(notification.Title);
|
||||
// Set text wrap position to prevent title overflow
|
||||
ImGui.PushTextWrapPos(ImGui.GetCursorPosX() + contentSize.X);
|
||||
|
||||
var titleStartY = ImGui.GetCursorPosY();
|
||||
|
||||
if (_configService.Current.ShowNotificationTimestamp)
|
||||
{
|
||||
var timestamp = notification.CreatedAt.ToLocalTime().ToString("HH:mm:ss");
|
||||
ImGui.TextWrapped($"[{timestamp}] {notification.Title}");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextWrapped(notification.Title);
|
||||
}
|
||||
|
||||
titleHeight = ImGui.GetCursorPosY() - titleStartY;
|
||||
ImGui.PopTextWrapPos();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(notification.Message))
|
||||
{
|
||||
ImGui.SetCursorPos(contentPos + new Vector2(0f, 18f));
|
||||
ImGui.SetCursorPos(contentPos + new Vector2(0f, titleHeight + 4f));
|
||||
ImGui.PushTextWrapPos(ImGui.GetCursorPosX() + contentSize.X);
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, new Vector4(0.9f, 0.9f, 0.9f, alpha)))
|
||||
{
|
||||
@@ -436,24 +484,40 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
||||
|
||||
private float CalculateNotificationHeight(LightlessNotification notification)
|
||||
{
|
||||
var height = 40f;
|
||||
if (!string.IsNullOrEmpty(notification.Message))
|
||||
var contentWidth = NotificationWidth - 35f; // Account for padding and accent bar
|
||||
var height = 20f; // Base height for padding
|
||||
|
||||
var titleText = notification.Title;
|
||||
if (_configService.Current.ShowNotificationTimestamp)
|
||||
{
|
||||
var textSize = ImGui.CalcTextSize(notification.Message, true, NotificationWidth - 35f);
|
||||
height += textSize.Y + 4f;
|
||||
var timestamp = notification.CreatedAt.ToLocalTime().ToString("HH:mm:ss");
|
||||
titleText = $"[{timestamp}] {titleText}";
|
||||
}
|
||||
|
||||
var titleSize = ImGui.CalcTextSize(titleText, true, contentWidth);
|
||||
height += titleSize.Y + 4f; // Title height + spacing
|
||||
|
||||
// Calculate message height
|
||||
if (!string.IsNullOrEmpty(notification.Message))
|
||||
{
|
||||
var messageSize = ImGui.CalcTextSize(notification.Message, true, contentWidth);
|
||||
height += messageSize.Y + 4f; // Message height + spacing
|
||||
}
|
||||
|
||||
// Add height for progress bar
|
||||
if (notification.ShowProgress)
|
||||
{
|
||||
height += 12f;
|
||||
}
|
||||
|
||||
// Add height for action buttons
|
||||
if (notification.Actions.Count > 0)
|
||||
{
|
||||
height += 28f;
|
||||
}
|
||||
|
||||
return Math.Max(height, NotificationMinHeight);
|
||||
// Allow notifications to grow taller but cap at maximum height
|
||||
return Math.Clamp(height, NotificationMinHeight, NotificationMaxHeight);
|
||||
}
|
||||
|
||||
private Vector4 GetNotificationAccentColor(NotificationType type)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
@@ -61,6 +61,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
private readonly IProgress<(int, int, FileCacheEntity)> _validationProgress;
|
||||
private readonly NameplateService _nameplateService;
|
||||
private readonly NameplateHandler _nameplateHandler;
|
||||
private readonly LightlessNotificationService _lightlessNotificationService;
|
||||
private (int, int, FileCacheEntity) _currentProgress;
|
||||
private bool _deleteAccountPopupModalShown = false;
|
||||
private bool _deleteFilesPopupModalShown = false;
|
||||
@@ -105,7 +106,8 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
IpcManager ipcManager, CacheMonitor cacheMonitor,
|
||||
DalamudUtilService dalamudUtilService, HttpClient httpClient,
|
||||
NameplateService nameplateService,
|
||||
NameplateHandler nameplateHandler) : base(logger, mediator, "Lightless Sync Settings", performanceCollector)
|
||||
NameplateHandler nameplateHandler,
|
||||
LightlessNotificationService lightlessNotificationService) : base(logger, mediator, "Lightless Sync Settings", performanceCollector)
|
||||
{
|
||||
_configService = configService;
|
||||
_pairManager = pairManager;
|
||||
@@ -125,6 +127,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
_uiShared = uiShared;
|
||||
_nameplateService = nameplateService;
|
||||
_nameplateHandler = nameplateHandler;
|
||||
_lightlessNotificationService = lightlessNotificationService;
|
||||
AllowClickthrough = false;
|
||||
AllowPinning = true;
|
||||
_validationProgress = new Progress<(int, int, FileCacheEntity)>(v => _currentProgress = v);
|
||||
@@ -351,13 +354,8 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
_uiShared.UnderlinedBigText("Transfer UI", UIColors.Get("LightlessBlue"));
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
bool useNotificationsForDownloads = _configService.Current.UseNotificationsForDownloads;
|
||||
if (ImGui.Checkbox("Use notifications for download progress", ref useNotificationsForDownloads))
|
||||
{
|
||||
_configService.Current.UseNotificationsForDownloads = useNotificationsForDownloads;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Show download progress as clean notifications instead of overlay text. Notifications update in real-time.");
|
||||
_uiShared.DrawHelpText("Download progress notification settings have been moved to the 'Enhanced Notifications' tab for better organization.");
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
bool showTransferWindow = _configService.Current.ShowTransferWindow;
|
||||
if (ImGui.Checkbox("Show separate transfer window", ref showTransferWindow))
|
||||
@@ -1645,48 +1643,10 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
ImGui.Dummy(new Vector2(10));
|
||||
_uiShared.BigText("Notifications");
|
||||
|
||||
var disableOptionalPluginWarnings = _configService.Current.DisableOptionalPluginWarnings;
|
||||
var onlineNotifs = _configService.Current.ShowOnlineNotifications;
|
||||
var onlineNotifsPairsOnly = _configService.Current.ShowOnlineNotificationsOnlyForIndividualPairs;
|
||||
var onlineNotifsNamedOnly = _configService.Current.ShowOnlineNotificationsOnlyForNamedPairs;
|
||||
|
||||
if (_uiShared.MediumTreeNode("Display", UIColors.Get("LightlessPurple")))
|
||||
{
|
||||
_uiShared.DrawCombo("Info Notification Display##settingsUi", (NotificationLocation[])Enum.GetValues(typeof(NotificationLocation)), (i) => i.ToString(),
|
||||
(i) =>
|
||||
{
|
||||
_configService.Current.InfoNotification = i;
|
||||
_configService.Save();
|
||||
}, _configService.Current.InfoNotification);
|
||||
_uiShared.DrawHelpText("The location where \"Info\" notifications will display."
|
||||
+ Environment.NewLine + "'Nowhere' will not show any Info notifications"
|
||||
+ Environment.NewLine + "'Chat' will print Info notifications in chat"
|
||||
+ Environment.NewLine + "'Toast' will show Warning toast notifications in the bottom right corner"
|
||||
+ Environment.NewLine + "'Both' will show chat as well as the toast notification");
|
||||
|
||||
_uiShared.DrawCombo("Warning Notification Display##settingsUi", (NotificationLocation[])Enum.GetValues(typeof(NotificationLocation)), (i) => i.ToString(),
|
||||
(i) =>
|
||||
{
|
||||
_configService.Current.WarningNotification = i;
|
||||
_configService.Save();
|
||||
}, _configService.Current.WarningNotification);
|
||||
_uiShared.DrawHelpText("The location where \"Warning\" notifications will display."
|
||||
+ Environment.NewLine + "'Nowhere' will not show any Warning notifications"
|
||||
+ Environment.NewLine + "'Chat' will print Warning notifications in chat"
|
||||
+ Environment.NewLine + "'Toast' will show Warning toast notifications in the bottom right corner"
|
||||
+ Environment.NewLine + "'Both' will show chat as well as the toast notification");
|
||||
|
||||
_uiShared.DrawCombo("Error Notification Display##settingsUi", (NotificationLocation[])Enum.GetValues(typeof(NotificationLocation)), (i) => i.ToString(),
|
||||
(i) =>
|
||||
{
|
||||
_configService.Current.ErrorNotification = i;
|
||||
_configService.Save();
|
||||
}, _configService.Current.ErrorNotification);
|
||||
_uiShared.DrawHelpText("The location where \"Error\" notifications will display."
|
||||
+ Environment.NewLine + "'Nowhere' will not show any Error notifications"
|
||||
+ Environment.NewLine + "'Chat' will print Error notifications in chat"
|
||||
+ Environment.NewLine + "'Toast' will show Error toast notifications in the bottom right corner"
|
||||
+ Environment.NewLine + "'Both' will show chat as well as the toast notification");
|
||||
_uiShared.DrawHelpText("Notification settings have been moved to the 'Enhanced Notifications' tab for better organization. You can configure where all notifications appear from there.");
|
||||
|
||||
_uiShared.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
|
||||
ImGui.TreePop();
|
||||
@@ -1694,38 +1654,6 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
if (_uiShared.MediumTreeNode("Toggles", UIColors.Get("LightlessPurple")))
|
||||
{
|
||||
if (ImGui.Checkbox("Disable optional plugin warnings", ref disableOptionalPluginWarnings))
|
||||
{
|
||||
_configService.Current.DisableOptionalPluginWarnings = disableOptionalPluginWarnings;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Enabling this will not show any \"Warning\" labeled messages for missing optional plugins.");
|
||||
if (ImGui.Checkbox("Enable online notifications", ref onlineNotifs))
|
||||
{
|
||||
_configService.Current.ShowOnlineNotifications = onlineNotifs;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Enabling this will show a small notification (type: Info) in the bottom right corner when pairs go online.");
|
||||
|
||||
using var disabled = ImRaii.Disabled(!onlineNotifs);
|
||||
if (ImGui.Checkbox("Notify only for individual pairs", ref onlineNotifsPairsOnly))
|
||||
{
|
||||
_configService.Current.ShowOnlineNotificationsOnlyForIndividualPairs = onlineNotifsPairsOnly;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Enabling this will only show online notifications (type: Info) for individual pairs.");
|
||||
if (ImGui.Checkbox("Notify only for named pairs", ref onlineNotifsNamedOnly))
|
||||
{
|
||||
_configService.Current.ShowOnlineNotificationsOnlyForNamedPairs = onlineNotifsNamedOnly;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Enabling this will only show online notifications (type: Info) for pairs where you have set an individual note.");
|
||||
|
||||
_uiShared.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
|
||||
ImGui.TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPerformance()
|
||||
@@ -2661,6 +2589,12 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui.BeginTabItem("Notifications"))
|
||||
{
|
||||
DrawNotificationSettings();
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui.BeginTabItem("Debug"))
|
||||
{
|
||||
DrawDebug();
|
||||
@@ -2681,4 +2615,568 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
_wasOpen = IsOpen;
|
||||
IsOpen = false;
|
||||
}
|
||||
|
||||
private void DrawNotificationSettings()
|
||||
{
|
||||
_lastTab = "Notifications";
|
||||
_uiShared.UnderlinedBigText("Notification System", UIColors.Get("LightlessBlue"));
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
bool useLightlessNotifications = _configService.Current.UseLightlessNotifications;
|
||||
if (ImGui.Checkbox("Use Enhanced Lightless Notifications", ref useLightlessNotifications))
|
||||
{
|
||||
_configService.Current.UseLightlessNotifications = useLightlessNotifications;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Enable the new enhanced notification system with interactive buttons, animations, and better visual design.");
|
||||
ImGui.Separator();
|
||||
_uiShared.UnderlinedBigText("Notification Locations", UIColors.Get("LightlessBlue"));
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
UiSharedService.ColorTextWrapped("Configure where different types of notifications appear. Enhanced notifications provide modern interactive notifications with backwards compatibility support for classic toast/chat notifications.", ImGuiColors.DalamudGrey);
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
if (useLightlessNotifications)
|
||||
{
|
||||
// Enhanced notification locations (primary)
|
||||
_uiShared.BigText("Enhanced Notification Locations");
|
||||
ImGuiHelpers.ScaledDummy(3);
|
||||
|
||||
var lightlessLocations = GetLightlessNotificationLocations();
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Info Notifications:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
_uiShared.DrawCombo("###enhanced_info", lightlessLocations, GetNotificationLocationLabel, (location) =>
|
||||
{
|
||||
_configService.Current.LightlessInfoNotification = location;
|
||||
_configService.Save();
|
||||
}, _configService.Current.LightlessInfoNotification);
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Warning Notifications:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
_uiShared.DrawCombo("###enhanced_warning", lightlessLocations, GetNotificationLocationLabel, (location) =>
|
||||
{
|
||||
_configService.Current.LightlessWarningNotification = location;
|
||||
_configService.Save();
|
||||
}, _configService.Current.LightlessWarningNotification);
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Error Notifications:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
_uiShared.DrawCombo("###enhanced_error", lightlessLocations, GetNotificationLocationLabel, (location) =>
|
||||
{
|
||||
_configService.Current.LightlessErrorNotification = location;
|
||||
_configService.Save();
|
||||
}, _configService.Current.LightlessErrorNotification);
|
||||
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
// Classic notification locations (backwards compatibility)
|
||||
if (ImGui.CollapsingHeader("Classic Notification Settings (Backwards Compatibility)"))
|
||||
{
|
||||
_uiShared.DrawHelpText("These settings provide backwards compatibility. They will also be used if they're different from the enhanced settings above and don't conflict.");
|
||||
ImGuiHelpers.ScaledDummy(3);
|
||||
|
||||
var classicLocations = GetClassicNotificationLocations();
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Info Fallback:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
_uiShared.DrawCombo("###classic_info", classicLocations, GetNotificationLocationLabel, (location) =>
|
||||
{
|
||||
_configService.Current.InfoNotification = location;
|
||||
_configService.Save();
|
||||
}, _configService.Current.InfoNotification);
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Warning Fallback:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
_uiShared.DrawCombo("###classic_warning", classicLocations, GetNotificationLocationLabel, (location) =>
|
||||
{
|
||||
_configService.Current.WarningNotification = location;
|
||||
_configService.Save();
|
||||
}, _configService.Current.WarningNotification);
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Error Fallback:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
_uiShared.DrawCombo("###classic_error", classicLocations, GetNotificationLocationLabel, (location) =>
|
||||
{
|
||||
_configService.Current.ErrorNotification = location;
|
||||
_configService.Save();
|
||||
}, _configService.Current.ErrorNotification);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only classic notifications when enhanced is disabled
|
||||
var classicLocations = GetClassicNotificationLocations();
|
||||
_uiShared.BigText("Classic Notification Locations");
|
||||
ImGuiHelpers.ScaledDummy(3);
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Info Notifications:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
_uiShared.DrawCombo("###info", classicLocations, GetNotificationLocationLabel, (location) =>
|
||||
{
|
||||
_configService.Current.InfoNotification = location;
|
||||
_configService.Save();
|
||||
}, _configService.Current.InfoNotification);
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Warning Notifications:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
_uiShared.DrawCombo("###warning", classicLocations, GetNotificationLocationLabel, (location) =>
|
||||
{
|
||||
_configService.Current.WarningNotification = location;
|
||||
_configService.Save();
|
||||
}, _configService.Current.WarningNotification);
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Error Notifications:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
_uiShared.DrawCombo("###error", classicLocations, GetNotificationLocationLabel, (location) =>
|
||||
{
|
||||
_configService.Current.ErrorNotification = location;
|
||||
_configService.Save();
|
||||
}, _configService.Current.ErrorNotification);
|
||||
}
|
||||
ImGui.Separator();
|
||||
if (useLightlessNotifications)
|
||||
{
|
||||
UiSharedService.ColorTextWrapped("• Lightless Notifications: Modern animated notifications with interactive buttons", ImGuiColors.DalamudGrey);
|
||||
UiSharedService.ColorTextWrapped("• Chat: Traditional chat messages with colored text", ImGuiColors.DalamudGrey);
|
||||
UiSharedService.ColorTextWrapped("• Combined options: Show in multiple locations simultaneously", ImGuiColors.DalamudGrey);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiSharedService.ColorTextWrapped("• Toast: Dalamud's built-in notification toasts", ImGuiColors.DalamudGrey);
|
||||
UiSharedService.ColorTextWrapped("• Chat: Traditional chat messages with colored text", ImGuiColors.DalamudGrey);
|
||||
UiSharedService.ColorTextWrapped("• Both: Show in both toast and chat", ImGuiColors.DalamudGrey);
|
||||
}
|
||||
ImGui.Separator();
|
||||
if (useLightlessNotifications)
|
||||
{
|
||||
ImGui.Indent();
|
||||
|
||||
// Test notification buttons
|
||||
if (_uiShared.IconTextButton(FontAwesomeIcon.Bell, "Test Info"))
|
||||
{
|
||||
Mediator.Publish(new NotificationMessage("Test Info", "This is a test info notification with the current settings!", NotificationType.Info));
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if (_uiShared.IconTextButton(FontAwesomeIcon.ExclamationTriangle, "Test Warning"))
|
||||
{
|
||||
Mediator.Publish(new NotificationMessage("Test Warning", "This is a test warning notification!", NotificationType.Warning));
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if (_uiShared.IconTextButton(FontAwesomeIcon.ExclamationCircle, "Test Error"))
|
||||
{
|
||||
Mediator.Publish(new NotificationMessage("Test Error", "This is a test error notification!", NotificationType.Error));
|
||||
}
|
||||
_uiShared.DrawHelpText("Click to preview different notification types with your current settings.");
|
||||
|
||||
ImGui.Unindent();
|
||||
|
||||
ImGui.Separator();
|
||||
_uiShared.UnderlinedBigText("Basic Settings", UIColors.Get("LightlessBlue"));
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
int defaultDuration = _configService.Current.DefaultNotificationDurationSeconds;
|
||||
if (ImGui.SliderInt("Default Duration (seconds)", ref defaultDuration, 3, 60))
|
||||
{
|
||||
_configService.Current.DefaultNotificationDurationSeconds = defaultDuration;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("How long notifications stay visible by default.");
|
||||
|
||||
bool showProgress = _configService.Current.ShowNotificationProgress;
|
||||
if (ImGui.Checkbox("Show Progress Bars", ref showProgress))
|
||||
{
|
||||
_configService.Current.ShowNotificationProgress = showProgress;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Display progress bars for download and other progress-based notifications.");
|
||||
|
||||
bool showTimestamp = _configService.Current.ShowNotificationTimestamp;
|
||||
if (ImGui.Checkbox("Show Timestamps", ref showTimestamp))
|
||||
{
|
||||
_configService.Current.ShowNotificationTimestamp = showTimestamp;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Display the time when each notification was created.");
|
||||
|
||||
bool autoDismiss = _configService.Current.AutoDismissOnAction;
|
||||
if (ImGui.Checkbox("Auto-dismiss on Action", ref autoDismiss))
|
||||
{
|
||||
_configService.Current.AutoDismissOnAction = autoDismiss;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Automatically close notifications when you click an action button.");
|
||||
|
||||
if (useLightlessNotifications)
|
||||
{
|
||||
ImGui.Separator();
|
||||
_uiShared.UnderlinedBigText("Appearance & Animation", UIColors.Get("LightlessBlue"));
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
float opacity = _configService.Current.NotificationOpacity;
|
||||
if (ImGui.SliderFloat("Notification Opacity", ref opacity, 0.1f, 1.0f, "%.2f"))
|
||||
{
|
||||
_configService.Current.NotificationOpacity = opacity;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Transparency level of notification windows.");
|
||||
|
||||
bool enableAnimations = _configService.Current.EnableNotificationAnimations;
|
||||
if (ImGui.Checkbox("Enable Animations", ref enableAnimations))
|
||||
{
|
||||
_configService.Current.EnableNotificationAnimations = enableAnimations;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Enable slide-in/out animations for notifications.");
|
||||
|
||||
int maxNotifications = _configService.Current.MaxSimultaneousNotifications;
|
||||
if (ImGui.SliderInt("Max Simultaneous Notifications", ref maxNotifications, 1, 10))
|
||||
{
|
||||
_configService.Current.MaxSimultaneousNotifications = maxNotifications;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Maximum number of notifications that can be shown at once.");
|
||||
|
||||
bool enableHistory = _configService.Current.EnableNotificationHistory;
|
||||
if (ImGui.Checkbox("Enable Notification History", ref enableHistory))
|
||||
{
|
||||
_configService.Current.EnableNotificationHistory = enableHistory;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Keep a history of recent notifications that you can review.");
|
||||
|
||||
if (enableHistory)
|
||||
{
|
||||
ImGui.Indent();
|
||||
int historySize = _configService.Current.NotificationHistorySize;
|
||||
if (ImGui.SliderInt("History Size", ref historySize, 10, 200))
|
||||
{
|
||||
_configService.Current.NotificationHistorySize = historySize;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Number of notifications to keep in history.");
|
||||
ImGui.Unindent();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
_uiShared.UnderlinedBigText("Sound Settings", UIColors.Get("LightlessBlue"));
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
bool enableSounds = _configService.Current.EnableNotificationSounds;
|
||||
if (ImGui.Checkbox("Enable Notification Sounds", ref enableSounds))
|
||||
{
|
||||
_configService.Current.EnableNotificationSounds = enableSounds;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Play FFXIV sound effects when notifications appear.");
|
||||
|
||||
if (enableSounds)
|
||||
{
|
||||
ImGui.Indent();
|
||||
|
||||
// float soundVolume = _configService.Current.NotificationSoundVolume;
|
||||
// if (ImGui.SliderFloat("Sound Volume", ref soundVolume, 0.0f, 1.0f, "%.2f"))
|
||||
// {
|
||||
// _configService.Current.NotificationSoundVolume = soundVolume;
|
||||
// _configService.Save();
|
||||
// }
|
||||
// _uiShared.DrawHelpText("Volume level for notification sounds (Note: FFXIV doesn't support volume control for SE sounds).");
|
||||
|
||||
// bool useCustomSounds = _configService.Current.UseCustomSounds;
|
||||
// if (ImGui.Checkbox("Use Custom Sound Effects", ref useCustomSounds))
|
||||
// {
|
||||
// _configService.Current.UseCustomSounds = useCustomSounds;
|
||||
// _configService.Save();
|
||||
// }
|
||||
// _uiShared.DrawHelpText("Override default sounds with custom FFXIV sound effects.");
|
||||
DrawSoundCustomization();
|
||||
|
||||
// if (useCustomSounds)
|
||||
// {
|
||||
// ImGui.Indent();
|
||||
// DrawSoundCustomization();
|
||||
// ImGui.Unindent();
|
||||
// }
|
||||
|
||||
ImGui.Unindent();
|
||||
}
|
||||
|
||||
|
||||
ImGui.Separator();
|
||||
_uiShared.UnderlinedBigText("Specific Notification Types", UIColors.Get("LightlessBlue"));
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
UiSharedService.ColorTextWrapped("Configure specific types of notifications and their behavior.", ImGuiColors.DalamudGrey);
|
||||
ImGuiHelpers.ScaledDummy(3);
|
||||
|
||||
// Online Notifications Section
|
||||
if (_uiShared.MediumTreeNode("Online Status Notifications", UIColors.Get("LightlessGreen")))
|
||||
{
|
||||
var onlineNotifs = _configService.Current.ShowOnlineNotifications;
|
||||
var onlineNotifsPairsOnly = _configService.Current.ShowOnlineNotificationsOnlyForIndividualPairs;
|
||||
var onlineNotifsNamedOnly = _configService.Current.ShowOnlineNotificationsOnlyForNamedPairs;
|
||||
|
||||
if (ImGui.Checkbox("Enable online notifications", ref onlineNotifs))
|
||||
{
|
||||
_configService.Current.ShowOnlineNotifications = onlineNotifs;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Show notifications when pairs come online. These will use the Info notification location settings above.");
|
||||
|
||||
using var disabled = ImRaii.Disabled(!onlineNotifs);
|
||||
ImGui.Indent();
|
||||
if (ImGui.Checkbox("Notify only for individual pairs", ref onlineNotifsPairsOnly))
|
||||
{
|
||||
_configService.Current.ShowOnlineNotificationsOnlyForIndividualPairs = onlineNotifsPairsOnly;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Only show online notifications for individual pairs (not syncshell members).");
|
||||
|
||||
if (ImGui.Checkbox("Notify only for named pairs", ref onlineNotifsNamedOnly))
|
||||
{
|
||||
_configService.Current.ShowOnlineNotificationsOnlyForNamedPairs = onlineNotifsNamedOnly;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Only show online notifications for pairs where you have set an individual note.");
|
||||
ImGui.Unindent();
|
||||
|
||||
_uiShared.ColoredSeparator(UIColors.Get("LightlessGreen"), 1.5f);
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
// Pairing Request Notifications Section
|
||||
if (_uiShared.MediumTreeNode("Pairing Request Notifications", UIColors.Get("LightlessBlue")))
|
||||
{
|
||||
UiSharedService.ColorTextWrapped("Pairing requests always show as interactive notifications with Accept/Decline buttons. These settings control additional behavior.", ImGuiColors.DalamudGrey);
|
||||
ImGuiHelpers.ScaledDummy(3);
|
||||
|
||||
// Note: Pairing requests are always shown as interactive notifications
|
||||
// This section can be expanded later with additional pairing notification settings
|
||||
|
||||
_uiShared.ColoredSeparator(UIColors.Get("LightlessBlue"), 1.5f);
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
// Download Progress Notifications Section
|
||||
if (_uiShared.MediumTreeNode("Download Progress Notifications", UIColors.Get("LightlessPurple")))
|
||||
{
|
||||
var useNotificationsForDownloads = _configService.Current.UseNotificationsForDownloads;
|
||||
if (ImGui.Checkbox("Show download progress as notifications", ref useNotificationsForDownloads))
|
||||
{
|
||||
_configService.Current.UseNotificationsForDownloads = useNotificationsForDownloads;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Show download progress as clean notifications instead of overlay text. Notifications update in real-time and use the Info notification location settings above.");
|
||||
|
||||
_uiShared.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
// System Notifications Section
|
||||
if (_uiShared.MediumTreeNode("System Notifications", UIColors.Get("LightlessYellow")))
|
||||
{
|
||||
var disableOptionalPluginWarnings = _configService.Current.DisableOptionalPluginWarnings;
|
||||
if (ImGui.Checkbox("Disable optional plugin warnings", ref disableOptionalPluginWarnings))
|
||||
{
|
||||
_configService.Current.DisableOptionalPluginWarnings = disableOptionalPluginWarnings;
|
||||
_configService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("Disable warning notifications for missing optional plugins.");
|
||||
|
||||
_uiShared.ColoredSeparator(UIColors.Get("LightlessYellow"), 1.5f);
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
_uiShared.UnderlinedBigText("Location Descriptions", UIColors.Get("LightlessBlue"));
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
}
|
||||
}
|
||||
|
||||
private NotificationLocation[] GetLightlessNotificationLocations()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
NotificationLocation.LightlessUI,
|
||||
NotificationLocation.ChatAndLightlessUI,
|
||||
NotificationLocation.Nowhere
|
||||
};
|
||||
}
|
||||
|
||||
private NotificationLocation[] GetClassicNotificationLocations()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
NotificationLocation.Toast,
|
||||
NotificationLocation.Chat,
|
||||
NotificationLocation.Both,
|
||||
NotificationLocation.Nowhere
|
||||
};
|
||||
}
|
||||
|
||||
private string GetNotificationLocationLabel(NotificationLocation location)
|
||||
{
|
||||
return location switch
|
||||
{
|
||||
NotificationLocation.Nowhere => "Nowhere",
|
||||
NotificationLocation.Chat => "Chat",
|
||||
NotificationLocation.Toast => "Toast",
|
||||
NotificationLocation.Both => "Toast + Chat",
|
||||
NotificationLocation.LightlessUI => "Lightless Notifications",
|
||||
NotificationLocation.ChatAndLightlessUI => "Chat + Lightless Notifications",
|
||||
_ => location.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
private void DrawSoundCustomization()
|
||||
{
|
||||
var soundEffects = new[]
|
||||
{
|
||||
(1u, "Se1 - Soft chime"),
|
||||
(2u, "Se2 - Higher chime"),
|
||||
(3u, "Se3 - Bell tone"),
|
||||
(4u, "Se4 - Harp tone"),
|
||||
(5u, "Se5 - Drum/percussion"),
|
||||
(6u, "Se6 - Mechanical click"),
|
||||
(7u, "Se7 - Metallic chime"),
|
||||
(8u, "Se8 - Wooden tone"),
|
||||
(9u, "Se9 - Wind/flute tone"),
|
||||
(10u, "Se10 - Magical sparkle"),
|
||||
(11u, "Se11 - Metallic ring"),
|
||||
(12u, "Se12 - Deep thud"),
|
||||
(13u, "Se13 - Tell received ping"),
|
||||
(14u, "Se14 - Success fanfare"),
|
||||
(15u, "Se15 - System warning"),
|
||||
(16u, "Se16 - Error/failure")
|
||||
};
|
||||
|
||||
// Info Sound
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Info Sound:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
var currentInfoSound = _configService.Current.CustomInfoSoundId;
|
||||
var currentInfoIndex = Array.FindIndex(soundEffects, s => s.Item1 == currentInfoSound);
|
||||
if (currentInfoIndex == -1) currentInfoIndex = 1; // Default to Se2
|
||||
|
||||
if (ImGui.Combo("###info_sound", ref currentInfoIndex, soundEffects.Select(s => s.Item2).ToArray(), soundEffects.Length))
|
||||
{
|
||||
_configService.Current.CustomInfoSoundId = soundEffects[currentInfoIndex].Item1;
|
||||
_configService.Save();
|
||||
}
|
||||
ImGui.SameLine();
|
||||
ImGui.PushID("test_info");
|
||||
if (_uiShared.IconButton(FontAwesomeIcon.Play))
|
||||
{
|
||||
try
|
||||
{
|
||||
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomInfoSoundId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to play test sound");
|
||||
}
|
||||
}
|
||||
ImGui.PopID();
|
||||
UiSharedService.AttachToolTip("Test this sound");
|
||||
|
||||
// Warning Sound
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Warning Sound:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
var currentWarningSound = _configService.Current.CustomWarningSoundId;
|
||||
var currentWarningIndex = Array.FindIndex(soundEffects, s => s.Item1 == currentWarningSound);
|
||||
if (currentWarningIndex == -1) currentWarningIndex = 14; // Default to Se15
|
||||
|
||||
if (ImGui.Combo("###warning_sound", ref currentWarningIndex, soundEffects.Select(s => s.Item2).ToArray(), soundEffects.Length))
|
||||
{
|
||||
_configService.Current.CustomWarningSoundId = soundEffects[currentWarningIndex].Item1;
|
||||
_configService.Save();
|
||||
}
|
||||
ImGui.SameLine();
|
||||
ImGui.PushID("test_warning");
|
||||
if (_uiShared.IconButton(FontAwesomeIcon.Play))
|
||||
{
|
||||
try
|
||||
{
|
||||
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomWarningSoundId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to play test sound");
|
||||
}
|
||||
}
|
||||
ImGui.PopID();
|
||||
UiSharedService.AttachToolTip("Test this sound");
|
||||
|
||||
// Error Sound
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Error Sound:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
||||
var currentErrorSound = _configService.Current.CustomErrorSoundId;
|
||||
var currentErrorIndex = Array.FindIndex(soundEffects, s => s.Item1 == currentErrorSound);
|
||||
if (currentErrorIndex == -1) currentErrorIndex = 15; // Default to Se16
|
||||
|
||||
if (ImGui.Combo("###error_sound", ref currentErrorIndex, soundEffects.Select(s => s.Item2).ToArray(), soundEffects.Length))
|
||||
{
|
||||
_configService.Current.CustomErrorSoundId = soundEffects[currentErrorIndex].Item1;
|
||||
_configService.Save();
|
||||
}
|
||||
ImGui.SameLine();
|
||||
ImGui.PushID("test_error");
|
||||
if (_uiShared.IconButton(FontAwesomeIcon.Play))
|
||||
{
|
||||
try
|
||||
{
|
||||
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomErrorSoundId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to play test sound");
|
||||
}
|
||||
}
|
||||
ImGui.PopID();
|
||||
UiSharedService.AttachToolTip("Test this sound");
|
||||
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
if (_uiShared.IconTextButton(FontAwesomeIcon.VolumeUp, "Test All Sounds"))
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomInfoSoundId);
|
||||
await Task.Delay(800);
|
||||
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomWarningSoundId);
|
||||
await Task.Delay(800);
|
||||
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomErrorSoundId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to play test sounds");
|
||||
}
|
||||
});
|
||||
}
|
||||
_uiShared.DrawHelpText("Play all custom sounds in sequence: Info → Warning → Error");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
@@ -204,19 +204,19 @@ public class TopTabMenu
|
||||
"debug-user-id",
|
||||
onAccept: () =>
|
||||
{
|
||||
_lightlessNotificationService.ShowNotification(
|
||||
_lightlessMediator.Publish(new NotificationMessage(
|
||||
"Pair Accepted",
|
||||
"Debug pair request was accepted!",
|
||||
NotificationType.Info,
|
||||
TimeSpan.FromSeconds(3));
|
||||
TimeSpan.FromSeconds(3)));
|
||||
},
|
||||
onDecline: () =>
|
||||
{
|
||||
_lightlessNotificationService.ShowNotification(
|
||||
_lightlessMediator.Publish(new NotificationMessage(
|
||||
"Pair Declined",
|
||||
"Debug pair request was declined.",
|
||||
NotificationType.Warning,
|
||||
TimeSpan.FromSeconds(3));
|
||||
TimeSpan.FromSeconds(3)));
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -224,31 +224,31 @@ public class TopTabMenu
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Test Info"))
|
||||
{
|
||||
_lightlessNotificationService.ShowNotification(
|
||||
_lightlessMediator.Publish(new NotificationMessage(
|
||||
"Information",
|
||||
"This is a test ifno notification with some longer text to see how it wraps. This is a test ifno notification with some longer text to see how it wraps. This is a test ifno notification with some longer text to see how it wraps. This is a test ifno notification with some longer text to see how it wraps.",
|
||||
NotificationType.Info,
|
||||
TimeSpan.FromSeconds(5));
|
||||
TimeSpan.FromSeconds(5)));
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Test Warning"))
|
||||
{
|
||||
_lightlessNotificationService.ShowNotification(
|
||||
_lightlessMediator.Publish(new NotificationMessage(
|
||||
"Warning",
|
||||
"This is a test warning notification.",
|
||||
NotificationType.Warning,
|
||||
TimeSpan.FromSeconds(7));
|
||||
TimeSpan.FromSeconds(7)));
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Test Error"))
|
||||
{
|
||||
_lightlessNotificationService.ShowNotification(
|
||||
_lightlessMediator.Publish(new NotificationMessage(
|
||||
"Error",
|
||||
"This is a test error notification erp police",
|
||||
NotificationType.Error,
|
||||
TimeSpan.FromSeconds(10));
|
||||
TimeSpan.FromSeconds(10)));
|
||||
}
|
||||
|
||||
if (ImGui.Button("Test Download Progress"))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using LightlessSync.API.Data;
|
||||
using LightlessSync.API.Data;
|
||||
using LightlessSync.API.Data.Enum;
|
||||
using LightlessSync.API.Dto;
|
||||
using LightlessSync.API.Dto.CharaData;
|
||||
@@ -122,36 +122,38 @@ public partial class ApiController
|
||||
// Fire and forget async operation
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var myCidHash = (await _dalamudUtil.GetCIDAsync().ConfigureAwait(false)).ToString().GetHash256();
|
||||
await TryPairWithContentId(request.HashedCid, myCidHash).ConfigureAwait(false);
|
||||
_pairRequestService.RemoveRequest(request.HashedCid);
|
||||
try
|
||||
{
|
||||
await TryPairWithContentId(request.HashedCid, myCidHash).ConfigureAwait(false);
|
||||
_pairRequestService.RemoveRequest(request.HashedCid);
|
||||
|
||||
_lightlessNotificationService.ShowNotification(
|
||||
"Pair Request Accepted",
|
||||
$"Sent a pair request back to {senderName}.",
|
||||
NotificationType.Info,
|
||||
TimeSpan.FromSeconds(3));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_lightlessNotificationService.ShowNotification(
|
||||
"Failed to Accept Pair Request",
|
||||
ex.Message,
|
||||
NotificationType.Error,
|
||||
TimeSpan.FromSeconds(5));
|
||||
Mediator.Publish(new NotificationMessage(
|
||||
"Pair Request Accepted",
|
||||
$"Sent a pair request back to {senderName}.",
|
||||
NotificationType.Info,
|
||||
TimeSpan.FromSeconds(3)));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Mediator.Publish(new NotificationMessage(
|
||||
"Failed to Accept Pair Request",
|
||||
ex.Message,
|
||||
NotificationType.Error,
|
||||
TimeSpan.FromSeconds(5)));
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
onDecline: () =>
|
||||
{
|
||||
_pairRequestService.RemoveRequest(request.HashedCid);
|
||||
_lightlessNotificationService.ShowNotification(
|
||||
Mediator.Publish(new NotificationMessage(
|
||||
"Pair Request Declined",
|
||||
$"Declined {senderName}'s pair request.",
|
||||
NotificationType.Info,
|
||||
TimeSpan.FromSeconds(3));
|
||||
TimeSpan.FromSeconds(3)));
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
|
||||
Reference in New Issue
Block a user