Ajout du système de notifications : service, configuration et persistance des notifications introduits. Mise à jour de l'UI pour afficher et gérer les notifications Syncshell.
This commit is contained in:
@@ -860,28 +860,34 @@ if (showNearby && pendingInvites > 0)
|
||||
ImGuiHelpers.ScaledDummy(4f);
|
||||
var indent = 18f * ImGuiHelpers.GlobalScale;
|
||||
ImGui.Indent(indent);
|
||||
foreach (var e in nearbyEntries)
|
||||
|
||||
// Use a table to guarantee right-aligned action within the card content area
|
||||
var actionButtonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.UserPlus);
|
||||
if (ImGui.BeginTable("nearby-table", 2, ImGuiTableFlags.SizingStretchProp | ImGuiTableFlags.RowBg | ImGuiTableFlags.PadOuterX | ImGuiTableFlags.BordersInnerV))
|
||||
{
|
||||
if (!e.AcceptPairRequests || string.IsNullOrEmpty(e.Token))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthStretch, 1f);
|
||||
ImGui.TableSetupColumn("Action", ImGuiTableColumnFlags.WidthFixed, actionButtonSize.X);
|
||||
|
||||
var name = e.DisplayName ?? e.Name;
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted(name);
|
||||
var right = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth();
|
||||
ImGui.SameLine();
|
||||
foreach (var e in nearbyEntries)
|
||||
{
|
||||
if (!e.AcceptPairRequests || string.IsNullOrEmpty(e.Token))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui.TableNextRow();
|
||||
|
||||
ImGui.TableSetColumnIndex(0);
|
||||
var name = e.DisplayName ?? e.Name;
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted(name);
|
||||
|
||||
// Right column: action button, aligned to the right within the column
|
||||
ImGui.TableSetColumnIndex(1);
|
||||
var curX = ImGui.GetCursorPosX();
|
||||
var availX = ImGui.GetContentRegionAvail().X; // width of the action column
|
||||
ImGui.SetCursorPosX(curX + MathF.Max(0, availX - actionButtonSize.X));
|
||||
|
||||
var statusButtonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.UserPlus);
|
||||
ImGui.SetCursorPosX(right - statusButtonSize.X);
|
||||
if (!e.AcceptPairRequests)
|
||||
{
|
||||
_uiSharedService.IconText(FontAwesomeIcon.Ban, ImGuiColors.DalamudGrey3);
|
||||
UiSharedService.AttachToolTip("Les demandes sont désactivées pour ce joueur");
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(e.Token))
|
||||
{
|
||||
using (ImRaii.PushId(e.Token ?? e.Uid ?? e.Name ?? string.Empty))
|
||||
{
|
||||
if (_uiSharedService.IconButton(FontAwesomeIcon.UserPlus))
|
||||
@@ -891,12 +897,9 @@ if (showNearby && pendingInvites > 0)
|
||||
}
|
||||
UiSharedService.AttachToolTip("Envoyer une invitation d'apparaige");
|
||||
}
|
||||
else
|
||||
{
|
||||
_uiSharedService.IconText(FontAwesomeIcon.QuestionCircle, ImGuiColors.DalamudGrey3);
|
||||
UiSharedService.AttachToolTip("Impossible d'inviter ce joueur");
|
||||
}
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.Unindent(indent);
|
||||
}, stretchWidth: true);
|
||||
}
|
||||
@@ -1173,6 +1176,9 @@ if (showNearby && pendingInvites > 0)
|
||||
case NotificationCategory.AutoDetect:
|
||||
DrawAutoDetectNotification(notification);
|
||||
break;
|
||||
case NotificationCategory.Syncshell:
|
||||
DrawSyncshellNotification(notification);
|
||||
break;
|
||||
default:
|
||||
UiSharedService.DrawCard($"notification-{notification.Category}-{notification.Id}", () =>
|
||||
{
|
||||
@@ -1237,6 +1243,30 @@ if (showNearby && pendingInvites > 0)
|
||||
}, stretchWidth: true);
|
||||
}
|
||||
|
||||
private void DrawSyncshellNotification(NotificationEntry notification)
|
||||
{
|
||||
UiSharedService.DrawCard($"notification-syncshell-{notification.Id}", () =>
|
||||
{
|
||||
ImGui.TextUnformatted(notification.Title);
|
||||
if (!string.IsNullOrEmpty(notification.Description))
|
||||
{
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudGrey3);
|
||||
ImGui.TextWrapped(notification.Description);
|
||||
ImGui.PopStyleColor();
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(3f);
|
||||
|
||||
using (ImRaii.PushId($"syncshell-{notification.Id}"))
|
||||
{
|
||||
if (ImGui.Button("Effacer"))
|
||||
{
|
||||
_notificationTracker.Remove(NotificationCategory.Syncshell, notification.Id);
|
||||
}
|
||||
}
|
||||
}, stretchWidth: true);
|
||||
}
|
||||
|
||||
private void TriggerAcceptAutoDetectNotification(string uid)
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
|
||||
@@ -11,11 +11,13 @@ using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services;
|
||||
using MareSynchronos.Services.AutoDetect;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using MareSynchronos.Services.Notifications;
|
||||
using MareSynchronos.WebAPI;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MareSynchronos.MareConfiguration.Models;
|
||||
|
||||
namespace MareSynchronos.UI.Components.Popup;
|
||||
|
||||
@@ -28,6 +30,7 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
|
||||
private readonly PairManager _pairManager;
|
||||
private readonly UiSharedService _uiSharedService;
|
||||
private readonly SyncshellDiscoveryService _syncshellDiscoveryService;
|
||||
private readonly NotificationTracker _notificationTracker;
|
||||
private List<BannedGroupUserDto> _bannedUsers = [];
|
||||
private int _multiInvites;
|
||||
private string _newPassword;
|
||||
@@ -54,7 +57,7 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
|
||||
|
||||
public SyncshellAdminUI(ILogger<SyncshellAdminUI> logger, MareMediator mediator, ApiController apiController,
|
||||
UiSharedService uiSharedService, PairManager pairManager, SyncshellDiscoveryService syncshellDiscoveryService,
|
||||
GroupFullInfoDto groupFullInfo, PerformanceCollectorService performanceCollectorService)
|
||||
GroupFullInfoDto groupFullInfo, PerformanceCollectorService performanceCollectorService, NotificationTracker notificationTracker)
|
||||
: base(logger, mediator, "Syncshell Admin Panel (" + groupFullInfo.GroupAliasOrGID + ")", performanceCollectorService)
|
||||
{
|
||||
GroupFullInfo = groupFullInfo;
|
||||
@@ -62,6 +65,7 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
|
||||
_uiSharedService = uiSharedService;
|
||||
_pairManager = pairManager;
|
||||
_syncshellDiscoveryService = syncshellDiscoveryService;
|
||||
_notificationTracker = notificationTracker;
|
||||
_isOwner = string.Equals(GroupFullInfo.OwnerUID, _apiController.UID, StringComparison.Ordinal);
|
||||
_isModerator = GroupFullInfo.GroupUserInfo.IsModerator();
|
||||
_newPassword = string.Empty;
|
||||
@@ -650,6 +654,11 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
|
||||
_autoDetectMessage = desiredVisibility
|
||||
? "La Syncshell est désormais visible dans AutoDetect."
|
||||
: "La Syncshell n'est plus visible dans AutoDetect.";
|
||||
|
||||
if (desiredVisibility)
|
||||
{
|
||||
PublishSyncshellPublicNotification();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -711,6 +720,11 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
|
||||
_autoDetectMessage = _autoDetectDesiredVisibility
|
||||
? "Paramètres AutoDetect envoyés. La Syncshell sera visible selon le planning défini."
|
||||
: "La Syncshell n'est plus visible dans AutoDetect.";
|
||||
|
||||
if (_autoDetectDesiredVisibility)
|
||||
{
|
||||
PublishSyncshellPublicNotification();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -744,4 +758,19 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
|
||||
{
|
||||
Mediator.Publish(new RemoveWindowMessage(this));
|
||||
}
|
||||
|
||||
private void PublishSyncshellPublicNotification()
|
||||
{
|
||||
try
|
||||
{
|
||||
var title = $"Syncshell publique: {GroupFullInfo.GroupAliasOrGID}";
|
||||
var message = "La Syncshell est désormais visible via AutoDetect.";
|
||||
Mediator.Publish(new DualNotificationMessage(title, message, NotificationType.Info, TimeSpan.FromSeconds(4)));
|
||||
_notificationTracker.Upsert(NotificationEntry.SyncshellPublic(GroupFullInfo.GID, GroupFullInfo.GroupAliasOrGID));
|
||||
}
|
||||
catch
|
||||
{
|
||||
// swallow any notification errors to not break UI flow
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user