Update 0.1.8.2 - Correctif UI, Correctif Nearby CompactUI, Add changelog

This commit is contained in:
2025-09-27 10:02:43 +02:00
parent bf770f19d9
commit 6572fdcc27
11 changed files with 481 additions and 69 deletions

View File

@@ -108,7 +108,7 @@ public class AutoDetectUi : WindowMediatorSubscriberBase
}
else if (ImGui.Button($"Send request##{e.Name}"))
{
_ = _requestService.SendRequestAsync(e.Token!);
_ = _requestService.SendRequestAsync(e.Token!, e.Uid, e.DisplayName);
}
}
}

View File

@@ -0,0 +1,204 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Reflection;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility.Raii;
using MareSynchronos.MareConfiguration;
using MareSynchronos.Services;
using MareSynchronos.Services.Mediator;
using Microsoft.Extensions.Logging;
namespace MareSynchronos.UI;
public sealed class ChangelogUi : WindowMediatorSubscriberBase
{
private const int AlwaysExpandedEntryCount = 2;
private readonly MareConfigService _configService;
private readonly UiSharedService _uiShared;
private readonly Version _currentVersion;
private readonly string _currentVersionLabel;
private readonly IReadOnlyList<ChangelogEntry> _entries;
private bool _showAllEntries;
private bool _hasAcknowledgedVersion;
public ChangelogUi(ILogger<ChangelogUi> logger, UiSharedService uiShared, MareConfigService configService,
MareMediator mediator, PerformanceCollectorService performanceCollectorService)
: base(logger, mediator, "Umbra Sync - Notes de version", performanceCollectorService)
{
_uiShared = uiShared;
_configService = configService;
_currentVersion = Assembly.GetExecutingAssembly().GetName().Version ?? new Version(0, 0, 0, 0);
_currentVersionLabel = _currentVersion.ToString();
_entries = BuildEntries();
_hasAcknowledgedVersion = string.Equals(_configService.Current.LastChangelogVersionSeen, _currentVersionLabel, StringComparison.Ordinal);
RespectCloseHotkey = true;
SizeConstraints = new()
{
MinimumSize = new(520, 360),
MaximumSize = new(900, 1200)
};
Flags |= ImGuiWindowFlags.NoResize;
ShowCloseButton = true;
if (!string.Equals(_configService.Current.LastChangelogVersionSeen, _currentVersionLabel, StringComparison.Ordinal))
{
IsOpen = true;
}
}
public override void OnClose()
{
MarkCurrentVersionAsReadIfNeeded();
base.OnClose();
}
protected override void DrawInternal()
{
_ = _uiShared.DrawOtherPluginState();
DrawHeader();
DrawEntries();
DrawFooter();
}
private void DrawHeader()
{
using (_uiShared.UidFont.Push())
{
ImGui.TextUnformatted("Notes de version");
}
ImGui.TextColored(ImGuiColors.DalamudGrey, $"Version chargée : {_currentVersionLabel}");
ImGui.Separator();
}
private void DrawEntries()
{
bool expandedOldVersions = false;
for (int index = 0; index < _entries.Count; index++)
{
var entry = _entries[index];
if (!_showAllEntries && index >= AlwaysExpandedEntryCount)
{
if (!expandedOldVersions)
{
expandedOldVersions = ImGui.CollapsingHeader("Historique complet");
}
if (!expandedOldVersions)
{
continue;
}
}
DrawEntry(entry);
}
}
private void DrawEntry(ChangelogEntry entry)
{
using (ImRaii.PushId(entry.VersionLabel))
{
ImGui.Spacing();
UiSharedService.ColorText(entry.VersionLabel, entry.Version == _currentVersion
? ImGuiColors.HealerGreen
: ImGuiColors.DalamudWhite);
ImGui.Spacing();
foreach (var line in entry.Lines)
{
DrawLine(line);
}
ImGui.Spacing();
ImGui.Separator();
}
}
private static void DrawLine(ChangelogLine line)
{
using var indent = line.IndentLevel > 0 ? ImRaii.PushIndent(line.IndentLevel) : null;
if (line.Color != null)
{
ImGui.TextColored(line.Color.Value, $"- {line.Text}");
}
else
{
ImGui.TextUnformatted($"- {line.Text}");
}
}
private void DrawFooter()
{
ImGui.Spacing();
if (!_showAllEntries && _entries.Count > AlwaysExpandedEntryCount)
{
if (ImGui.Button("Tout afficher"))
{
_showAllEntries = true;
}
ImGui.SameLine();
}
if (ImGui.Button("Marquer comme lu"))
{
MarkCurrentVersionAsReadIfNeeded();
IsOpen = false;
}
}
private void MarkCurrentVersionAsReadIfNeeded()
{
if (_hasAcknowledgedVersion)
return;
_configService.Current.LastChangelogVersionSeen = _currentVersionLabel;
_configService.Save();
_hasAcknowledgedVersion = true;
}
private static IReadOnlyList<ChangelogEntry> BuildEntries()
{
return new List<ChangelogEntry>
{
new(new Version(0, 1, 8, 2), "0.1.8.2", new List<ChangelogLine>
{
new("Détection Nearby : la liste rapide ne montre plus que les joueurs réellement invitables."),
new("Sont filtrés automatiquement les personnes refusées ou déjà appairées."),
new("Invitations Nearby : anti-spam de 5 minutes par personne, blocage 15 minutes après trois refus."),
new("Affichage : Correction de l'affichage des notes par défaut plutôt que de l'ID si disponible."),
new("Les notifications de blocage sont envoyées directement dans le tchat."),
new("Overlay DTR : affiche le nombre d'invitations Nearby disponibles dans le titre et l'infobulle."),
new("Poses Nearby : le filtre re-fonctionne avec vos notes locales pour retrouver les entrées correspondantes."),
}),
new(new Version(0, 1, 8, 1), "0.1.8.1", new List<ChangelogLine>
{
new("Correctif 'Vu sous' : l'infobulle affiche désormais le dernier personnage observé."),
new("Invitations AutoDetect : triées en tête de liste pour mieux les repérer."),
new("Invitations AutoDetect : conservées entre les redémarrages du plugin ou du jeu."),
new("Barre de statut serveur : couleur violette adoptée par défaut."),
}),
new(new Version(0, 1, 8, 0), "0.1.8.0", new List<ChangelogLine>
{
new("AutoDetect : détection automatique des joueurs Umbra autour de vous et propositions d'appairage."),
new("AutoDetect : désactivé par défaut pour préserver la confidentialité.", 1, ImGuiColors.DalamudGrey),
new("AutoDetect : activez-le dans 'Transfers' avec les options Nearby detection et Allow pair requests.", 1, ImGuiColors.DalamudGrey),
new("Syncshell temporaire : durée configurable de 1 h à 7 jours, expiration automatique."),
new("Syncshell permanente : possibilité de nommer et d'organiser vos groupes sur la durée."),
new("Interface : palette UmbraSync harmonisée et menus allégés pour l'usage RP."),
}),
};
}
private readonly record struct ChangelogEntry(Version Version, string VersionLabel, IReadOnlyList<ChangelogLine> Lines);
private readonly record struct ChangelogLine(string Text, int IndentLevel = 0, System.Numerics.Vector4? Color = null);
}

View File

@@ -471,69 +471,58 @@ public class CompactUi : WindowMediatorSubscriberBase
_uiSharedService.IconText(icon);
if (ImGui.IsItemClicked(ImGuiMouseButton.Left)) _nearbyOpen = !_nearbyOpen;
ImGui.SameLine();
var onUmbra = _nearbyEntries?.Count(e => e.IsMatch) ?? 0;
var onUmbra = _nearbyEntries?.Count(e => e.IsMatch && e.AcceptPairRequests && !string.IsNullOrEmpty(e.Token) && !IsAlreadyPairedQuickMenu(e)) ?? 0;
ImGui.TextUnformatted($"Nearby ({onUmbra})");
if (ImGui.IsItemClicked(ImGuiMouseButton.Left)) _nearbyOpen = !_nearbyOpen;
var btnWidth = _uiSharedService.GetIconTextButtonSize(FontAwesomeIcon.UserPlus, "Nearby");
var headerRight = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth();
ImGui.SameLine();
ImGui.SetCursorPosX(headerRight - btnWidth);
if (_uiSharedService.IconTextButton(FontAwesomeIcon.UserPlus, "Nearby", btnWidth))
{
Mediator.Publish(new UiToggleMessage(typeof(AutoDetectUi)));
}
if (_nearbyOpen)
{
var btnWidth = _uiSharedService.GetIconTextButtonSize(FontAwesomeIcon.UserPlus, "Nearby");
var headerRight = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth();
ImGui.SameLine();
ImGui.SetCursorPosX(headerRight - btnWidth);
if (_uiSharedService.IconTextButton(FontAwesomeIcon.UserPlus, "Nearby", btnWidth))
{
Mediator.Publish(new UiToggleMessage(typeof(AutoDetectUi)));
}
ImGui.Indent();
var nearby = _nearbyEntries == null
? new List<Services.Mediator.NearbyEntry>()
: _nearbyEntries.Where(e => e.IsMatch)
: _nearbyEntries.Where(e => e.IsMatch && e.AcceptPairRequests && !string.IsNullOrEmpty(e.Token) && !IsAlreadyPairedQuickMenu(e))
.OrderBy(e => e.Distance)
.ToList();
if (nearby.Count == 0)
{
UiSharedService.ColorTextWrapped("Aucun joueur detecté.", ImGuiColors.DalamudGrey3);
UiSharedService.ColorTextWrapped("Aucun nouveau joueur detecté.", ImGuiColors.DalamudGrey3);
}
else
{
foreach (var e in nearby)
{
if (!e.AcceptPairRequests || string.IsNullOrEmpty(e.Token))
continue;
var name = e.DisplayName ?? e.Name;
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(name);
var right = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth();
ImGui.SameLine();
bool isPaired = false;
try
{
isPaired = _pairManager.DirectPairs.Any(p => string.Equals(p.UserData.UID, e.Uid, StringComparison.Ordinal));
}
catch
{
var key = (e.DisplayName ?? e.Name) ?? string.Empty;
isPaired = _pairManager.DirectPairs.Any(p => string.Equals(p.UserData.AliasOrUID, key, StringComparison.OrdinalIgnoreCase));
}
var statusButtonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.UserPlus);
ImGui.SetCursorPosX(right - statusButtonSize.X);
if (isPaired)
{
_uiSharedService.IconText(FontAwesomeIcon.Check, ImGuiColors.ParsedGreen);
UiSharedService.AttachToolTip("Déjà appairé");
}
else if (!e.AcceptPairRequests)
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))
{
if (_uiSharedService.IconButton(FontAwesomeIcon.UserPlus))
using (ImRaii.PushId(e.Token ?? e.Uid ?? e.Name ?? string.Empty))
{
_ = _autoDetectRequestService.SendRequestAsync(e.Token!);
if (_uiSharedService.IconButton(FontAwesomeIcon.UserPlus))
{
_ = _autoDetectRequestService.SendRequestAsync(e.Token!, e.Uid, e.DisplayName);
}
}
UiSharedService.AttachToolTip("Envoyer une invitation d'apparaige");
}
@@ -553,6 +542,27 @@ public class CompactUi : WindowMediatorSubscriberBase
ImGui.EndChild();
}
private bool IsAlreadyPairedQuickMenu(Services.Mediator.NearbyEntry entry)
{
try
{
if (!string.IsNullOrEmpty(entry.Uid))
{
if (_pairManager.DirectPairs.Any(p => string.Equals(p.UserData.UID, entry.Uid, StringComparison.Ordinal)))
return true;
}
var key = (entry.DisplayName ?? entry.Name) ?? string.Empty;
if (string.IsNullOrEmpty(key)) return false;
return _pairManager.DirectPairs.Any(p => string.Equals(p.UserData.AliasOrUID, key, StringComparison.OrdinalIgnoreCase));
}
catch
{
return false;
}
}
private void DrawServerStatus()
{
var buttonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.Link);

View File

@@ -6,6 +6,7 @@ using Dalamud.Interface;
using MareSynchronos.MareConfiguration;
using MareSynchronos.MareConfiguration.Configurations;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.Services.AutoDetect;
using MareSynchronos.Services.Mediator;
using MareSynchronos.WebAPI;
using Microsoft.Extensions.Hosting;
@@ -41,12 +42,13 @@ public sealed class DtrEntry : IDisposable, IHostedService
private readonly ILogger<DtrEntry> _logger;
private readonly MareMediator _mareMediator;
private readonly PairManager _pairManager;
private readonly NearbyPendingService _nearbyPendingService;
private Task? _runTask;
private string? _text;
private string? _tooltip;
private Colors _colors;
public DtrEntry(ILogger<DtrEntry> logger, IDtrBar dtrBar, MareConfigService configService, MareMediator mareMediator, PairManager pairManager, ApiController apiController)
public DtrEntry(ILogger<DtrEntry> logger, IDtrBar dtrBar, MareConfigService configService, MareMediator mareMediator, PairManager pairManager, ApiController apiController, NearbyPendingService nearbyPendingService)
{
_logger = logger;
_dtrBar = dtrBar;
@@ -55,6 +57,7 @@ public sealed class DtrEntry : IDisposable, IHostedService
_mareMediator = mareMediator;
_pairManager = pairManager;
_apiController = apiController;
_nearbyPendingService = nearbyPendingService;
}
public void Dispose()
@@ -147,8 +150,9 @@ public sealed class DtrEntry : IDisposable, IHostedService
if (_apiController.IsConnected)
{
var pairCount = _pairManager.GetVisibleUserCount();
text = RenderDtrStyle(_configService.Current.DtrStyle, pairCount.ToString());
var baseText = RenderDtrStyle(_configService.Current.DtrStyle, pairCount.ToString());
var pendingNearby = _nearbyPendingService.Pending.Count;
text = pendingNearby > 0 ? $"{baseText} ({pendingNearby})" : baseText;
if (pairCount > 0)
{
IEnumerable<string> visiblePairs;
@@ -165,12 +169,21 @@ public sealed class DtrEntry : IDisposable, IHostedService
.Select(x => string.Format("{0}", _configService.Current.PreferNoteInDtrTooltip ? x.GetNoteOrName() : x.PlayerName));
}
tooltip = $"Umbra: Connected{Environment.NewLine}----------{Environment.NewLine}{string.Join(Environment.NewLine, visiblePairs)}";
tooltip = $"Umbra: Connected";
if (pendingNearby > 0)
{
tooltip += $"{Environment.NewLine}Invitation en attente : {pendingNearby}";
}
tooltip += $"{Environment.NewLine}----------{Environment.NewLine}{string.Join(Environment.NewLine, visiblePairs)}";
colors = _configService.Current.DtrColorsPairsInRange;
}
else
{
tooltip = "Umbra: Connected";
if (pendingNearby > 0)
{
tooltip += $"{Environment.NewLine}Invitation en attente : {pendingNearby}";
}
colors = _configService.Current.DtrColorsDefault;
}
}

View File

@@ -154,16 +154,15 @@ public class UidDisplayHandler
public (bool isUid, string text) GetPlayerText(Pair pair)
{
// When the user is offline or not visible, always show the raw UID (no alias/note/character name)
if (!pair.IsOnline || !pair.IsVisible)
bool showUidInsteadOfName = ShowUidInsteadOfName(pair);
if (showUidInsteadOfName)
{
return (true, pair.UserData.UID);
}
var textIsUid = true;
bool showUidInsteadOfName = ShowUidInsteadOfName(pair);
string? playerText = _serverManager.GetNoteForUid(pair.UserData.UID);
if (!showUidInsteadOfName && playerText != null)
if (playerText != null)
{
if (string.IsNullOrEmpty(playerText))
{
@@ -179,7 +178,7 @@ public class UidDisplayHandler
playerText = pair.UserData.AliasOrUID;
}
if (_mareConfigService.Current.ShowCharacterNames && textIsUid && !showUidInsteadOfName)
if (_mareConfigService.Current.ShowCharacterNames && textIsUid && pair.IsOnline && pair.IsVisible)
{
var name = pair.PlayerName;
if (name != null)
@@ -215,8 +214,11 @@ public class UidDisplayHandler
private bool ShowUidInsteadOfName(Pair pair)
{
_showUidForEntry.TryGetValue(pair.UserData.UID, out var showUidInsteadOfName);
if (_showUidForEntry.TryGetValue(pair.UserData.UID, out var showUidInsteadOfName))
{
return showUidInsteadOfName;
}
return showUidInsteadOfName;
return false;
}
}
}