Update 0.1.6 - UI change

This commit is contained in:
2025-09-13 22:42:08 +02:00
parent a0957715a5
commit 4a388dcfa9
9 changed files with 129 additions and 53 deletions

View File

@@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<AssemblyName>UmbraSync</AssemblyName> <AssemblyName>UmbraSync</AssemblyName>
<RootNamespace>UmbraSync</RootNamespace> <RootNamespace>UmbraSync</RootNamespace>
<Version>0.1.6.3</Version> <Version>0.1.6.4</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@@ -108,7 +108,7 @@ public record GPoseLobbyReceiveCharaData(CharaDataDownloadDto CharaDataDownloadD
public record GPoseLobbyReceivePoseData(UserData UserData, PoseData PoseData) : MessageBase; public record GPoseLobbyReceivePoseData(UserData UserData, PoseData PoseData) : MessageBase;
public record GPoseLobbyReceiveWorldData(UserData UserData, WorldData WorldData) : MessageBase; public record GPoseLobbyReceiveWorldData(UserData UserData, WorldData WorldData) : MessageBase;
public record NearbyEntry(string Name, ushort WorldId, float Distance, bool IsMatch, string? Token, string? DisplayName, string? Uid); public record NearbyEntry(string Name, ushort WorldId, float Distance, bool IsMatch, string? Token, string? DisplayName, string? Uid, bool AcceptPairRequests = true);
public record DiscoveryListUpdated(List<NearbyEntry> Entries) : MessageBase; public record DiscoveryListUpdated(List<NearbyEntry> Entries) : MessageBase;
public record NearbyDetectionToggled(bool Enabled) : MessageBase; public record NearbyDetectionToggled(bool Enabled) : MessageBase;
public record AllowPairRequestsToggled(bool Enabled) : MessageBase; public record AllowPairRequestsToggled(bool Enabled) : MessageBase;

View File

@@ -377,7 +377,6 @@ public class CompactUi : WindowMediatorSubscriberBase
// Always show a Nearby group when detection is enabled, even if empty // Always show a Nearby group when detection is enabled, even if empty
if (_configService.Current.EnableAutoDetectDiscovery) if (_configService.Current.EnableAutoDetectDiscovery)
{ {
ImGui.Separator();
using (ImRaii.PushId("group-Nearby")) using (ImRaii.PushId("group-Nearby"))
{ {
var icon = _nearbyOpen ? FontAwesomeIcon.CaretSquareDown : FontAwesomeIcon.CaretSquareRight; var icon = _nearbyOpen ? FontAwesomeIcon.CaretSquareDown : FontAwesomeIcon.CaretSquareRight;
@@ -401,14 +400,61 @@ public class CompactUi : WindowMediatorSubscriberBase
if (_nearbyOpen) if (_nearbyOpen)
{ {
ImGui.Indent(); ImGui.Indent();
if (onUmbra == 0) var nearby = _nearbyEntries == null
? new List<Services.Mediator.NearbyEntry>()
: _nearbyEntries.Where(e => e.IsMatch)
.OrderBy(e => e.Distance)
.ToList();
if (nearby.Count == 0)
{ {
UiSharedService.ColorTextWrapped("No nearby players detected.", ImGuiColors.DalamudGrey3); UiSharedService.ColorTextWrapped("No nearby players detected.", ImGuiColors.DalamudGrey3);
} }
else else
{ {
UiSharedService.ColorTextWrapped("Open Nearby for details.", ImGuiColors.DalamudGrey3); foreach (var e in nearby)
{
// name
var name = e.DisplayName ?? e.Name;
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(name);
// right side status/action
var right = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth();
ImGui.SameLine();
// detect if already paired (prefer UID if present)
bool isPaired = false;
try
{
isPaired = _pairManager.DirectPairs.Any(p => string.Equals(p.UserData.UID, e.Uid, StringComparison.Ordinal));
} }
catch
{
// fall back to display name/alias matching if UID is not available
var key = (e.DisplayName ?? e.Name) ?? string.Empty;
isPaired = _pairManager.DirectPairs.Any(p => string.Equals(p.UserData.AliasOrUID, key, StringComparison.OrdinalIgnoreCase));
}
var statusText = isPaired ? "✔ Paired" : (e.AcceptPairRequests ? " Invite" : "⛔ Requests disabled");
var statusSize = ImGui.CalcTextSize(statusText);
ImGui.SetCursorPosX(right - statusSize.X);
if (isPaired || !e.AcceptPairRequests)
{
// just paint the status
ImGui.TextUnformatted(statusText);
}
else
{
// no direct send from Compact; open Nearby window to send the invite there
if (_uiSharedService.IconTextButton(FontAwesomeIcon.UserPlus, "Invite", statusSize.X))
{
Mediator.Publish(new UiToggleMessage(typeof(AutoDetectUi)));
}
}
}
}
// Pending Nearby requests (Accept / Dismiss) // Pending Nearby requests (Accept / Dismiss)
try try
{ {
@@ -416,7 +462,7 @@ public class CompactUi : WindowMediatorSubscriberBase
if (inbox != null && inbox.Pending.Count > 0) if (inbox != null && inbox.Pending.Count > 0)
{ {
ImGuiHelpers.ScaledDummy(6); ImGuiHelpers.ScaledDummy(6);
_uiSharedService.BigText("Requests"); _uiSharedService.BigText("Incoming requests");
foreach (var kv in inbox.Pending) foreach (var kv in inbox.Pending)
{ {
ImGui.AlignTextToFramePadding(); ImGui.AlignTextToFramePadding();
@@ -483,8 +529,9 @@ public class CompactUi : WindowMediatorSubscriberBase
{ {
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((userSize.Y + textSize.Y) / 2 + shardTextSize.Y) / 2 - ImGui.GetStyle().ItemSpacing.Y + buttonSize.Y / 2); ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((userSize.Y + textSize.Y) / 2 + shardTextSize.Y) / 2 - ImGui.GetStyle().ItemSpacing.Y + buttonSize.Y / 2);
} }
var color = UiSharedService.GetBoolColor(!_serverManager.CurrentServer!.FullPause); var isLinked = !_serverManager.CurrentServer!.FullPause;
var connectedIcon = !_serverManager.CurrentServer.FullPause ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink; var color = isLinked ? new Vector4(0.63f, 0.25f, 1f, 1f) : UiSharedService.GetBoolColor(isLinked);
var connectedIcon = isLinked ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink;
if (_apiController.ServerState is ServerState.Connected) if (_apiController.ServerState is ServerState.Connected)
{ {

View File

@@ -1,4 +1,5 @@
using Dalamud.Bindings.ImGui; using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility; using Dalamud.Interface.Utility;
@@ -38,15 +39,19 @@ public class DrawGroupPair : DrawPairBase
var entryIsMod = _fullInfoDto.GroupPairStatusInfo.IsModerator(); var entryIsMod = _fullInfoDto.GroupPairStatusInfo.IsModerator();
var entryIsOwner = string.Equals(_pair.UserData.UID, _group.OwnerUID, StringComparison.Ordinal); var entryIsOwner = string.Equals(_pair.UserData.UID, _group.OwnerUID, StringComparison.Ordinal);
var entryIsPinned = _fullInfoDto.GroupPairStatusInfo.IsPinned(); var entryIsPinned = _fullInfoDto.GroupPairStatusInfo.IsPinned();
var presenceIcon = _pair.IsVisible ? FontAwesomeIcon.Eye : (_pair.IsOnline ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink); var presenceIcon = _pair.IsVisible ? FontAwesomeIcon.Eye : FontAwesomeIcon.CloudMoon;
var presenceColor = (_pair.IsOnline || _pair.IsVisible) ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed; var presenceColor = (_pair.IsOnline || _pair.IsVisible) ? new Vector4(0.63f, 0.25f, 1f, 1f) : ImGuiColors.DalamudGrey;
var presenceText = entryUID + " is offline"; var presenceText = entryUID + " is offline";
ImGui.SetCursorPosY(textPosY); ImGui.SetCursorPosY(textPosY);
// We'll draw an optional prefix icon (pause or paired-moon). If we draw one,
// we add a SameLine() before drawing the presence icon. Otherwise, we draw
// the presence icon directly at the current cursor position to avoid gaps.
bool drewPrefixIcon = false;
if (_pair.IsPaused) if (_pair.IsPaused)
{ {
presenceIcon = FontAwesomeIcon.Question;
presenceColor = ImGuiColors.DalamudGrey;
presenceText = entryUID + " online status is unknown (paused)"; presenceText = entryUID + " online status is unknown (paused)";
ImGui.PushFont(UiBuilder.IconFont); ImGui.PushFont(UiBuilder.IconFont);
@@ -54,24 +59,37 @@ public class DrawGroupPair : DrawPairBase
ImGui.PopFont(); ImGui.PopFont();
UiSharedService.AttachToolTip("Pairing status with " + entryUID + " is paused"); UiSharedService.AttachToolTip("Pairing status with " + entryUID + " is paused");
drewPrefixIcon = true;
} }
else else
{ {
ImGui.PushFont(UiBuilder.IconFont); bool individuallyPaired = _pair.UserPair != null;
UiSharedService.ColorText(FontAwesomeIcon.Check.ToIconString(), ImGuiColors.ParsedGreen); var violet = new Vector4(0.63f, 0.25f, 1f, 1f);
ImGui.PopFont();
UiSharedService.AttachToolTip("You are paired with " + entryUID); // Show a violet moon only when individually paired AND online/visible.
// If offline or not individually paired, do not draw a moon at all.
if (individuallyPaired && (_pair.IsOnline || _pair.IsVisible))
{
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(FontAwesomeIcon.Moon.ToIconString(), violet);
ImGui.PopFont();
UiSharedService.AttachToolTip("You are individually paired with " + entryUID);
drewPrefixIcon = true;
}
} }
if (_pair.IsOnline && !_pair.IsVisible) presenceText = entryUID + " is online"; // Presence status icon (eye when visible, cloud-moon otherwise)
else if (_pair.IsOnline && _pair.IsVisible) presenceText = entryUID + " is visible: " + _pair.PlayerName + Environment.NewLine + "Click to target this player"; if (drewPrefixIcon)
ImGui.SameLine(); ImGui.SameLine();
ImGui.SetCursorPosY(textPosY); ImGui.SetCursorPosY(textPosY);
ImGui.PushFont(UiBuilder.IconFont); ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(presenceIcon.ToIconString(), presenceColor); UiSharedService.ColorText(presenceIcon.ToIconString(), presenceColor);
ImGui.PopFont(); ImGui.PopFont();
if (_pair.IsOnline && !_pair.IsVisible) presenceText = entryUID + " is online";
else if (_pair.IsOnline && _pair.IsVisible) presenceText = entryUID + " is visible: " + _pair.PlayerName + Environment.NewLine + "Click to target this player";
if (_pair.IsVisible) if (_pair.IsVisible)
{ {
if (ImGui.IsItemClicked()) if (ImGui.IsItemClicked())
@@ -94,6 +112,7 @@ public class DrawGroupPair : DrawPairBase
} }
} }
} }
UiSharedService.AttachToolTip(presenceText); UiSharedService.AttachToolTip(presenceText);
if (entryIsOwner) if (entryIsOwner)

View File

@@ -38,33 +38,41 @@ public class DrawUserPair : DrawPairBase
protected override void DrawLeftSide(float textPosY, float originalY) protected override void DrawLeftSide(float textPosY, float originalY)
{ {
FontAwesomeIcon connectionIcon; // Primary presence indicator: moon (online = violet, offline = grey)
Vector4 connectionColor; var online = _pair.IsOnline;
string connectionText; // Violet accent (#BA70EF)
if (!(_pair.UserPair!.OwnPermissions.IsPaired() && _pair.UserPair!.OtherPermissions.IsPaired())) var violet = new Vector4(0.69f, 0.27f, 0.93f, 1f);
{ var offlineGrey = ImGuiColors.DalamudGrey3;
connectionIcon = FontAwesomeIcon.ArrowUp;
connectionText = _pair.UserData.AliasOrUID + " has not added you back";
connectionColor = ImGuiColors.DalamudRed;
}
else if (_pair.UserPair!.OwnPermissions.IsPaused() || _pair.UserPair!.OtherPermissions.IsPaused())
{
connectionIcon = FontAwesomeIcon.PauseCircle;
connectionText = "Pairing status with " + _pair.UserData.AliasOrUID + " is paused";
connectionColor = ImGuiColors.DalamudYellow;
}
else
{
connectionIcon = FontAwesomeIcon.Check;
connectionText = "You are paired with " + _pair.UserData.AliasOrUID;
connectionColor = ImGuiColors.ParsedGreen;
}
ImGui.SetCursorPosY(textPosY); ImGui.SetCursorPosY(textPosY);
ImGui.PushFont(UiBuilder.IconFont); ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(connectionIcon.ToIconString(), connectionColor); UiSharedService.ColorText(FontAwesomeIcon.Moon.ToIconString(), online ? violet : offlineGrey);
ImGui.PopFont(); ImGui.PopFont();
UiSharedService.AttachToolTip(connectionText); UiSharedService.AttachToolTip(online
? "User is online"
: "User is offline");
// Secondary pairing state badges (only if needed)
// Not mutually paired -> red ArrowUp
if (!(_pair.UserPair!.OwnPermissions.IsPaired() && _pair.UserPair!.OtherPermissions.IsPaired()))
{
ImGui.SameLine();
ImGui.SetCursorPosY(textPosY);
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(FontAwesomeIcon.ArrowUp.ToIconString(), ImGuiColors.DalamudRed);
ImGui.PopFont();
UiSharedService.AttachToolTip(_pair.UserData.AliasOrUID + " has not added you back");
}
// Paused (either side) -> yellow PauseCircle
else if (_pair.UserPair!.OwnPermissions.IsPaused() || _pair.UserPair!.OtherPermissions.IsPaused())
{
ImGui.SameLine();
ImGui.SetCursorPosY(textPosY);
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(FontAwesomeIcon.PauseCircle.ToIconString(), ImGuiColors.DalamudYellow);
ImGui.PopFont();
UiSharedService.AttachToolTip("Pairing with " + _pair.UserData.AliasOrUID + " is paused");
}
if (_pair is { IsOnline: true, IsVisible: true }) if (_pair is { IsOnline: true, IsVisible: true })
{ {
ImGui.SameLine(); ImGui.SameLine();

View File

@@ -1,4 +1,4 @@
using Dalamud.Bindings.ImGui; using Dalamud.Bindings.ImGui;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility; using Dalamud.Interface.Utility;
@@ -464,7 +464,9 @@ internal sealed class GroupPanel
if (offlineUsers.Count > 0) if (offlineUsers.Count > 0)
{ {
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudGrey);
ImGui.TextUnformatted("Offline/Unknown"); ImGui.TextUnformatted("Offline/Unknown");
ImGui.PopStyleColor();
ImGui.Separator(); ImGui.Separator();
if (hideOfflineUsers) if (hideOfflineUsers)
{ {

View File

@@ -157,7 +157,7 @@ public class PairGroupsUi
{ {
TagHandler.CustomUnpairedTag => "Unpaired", TagHandler.CustomUnpairedTag => "Unpaired",
TagHandler.CustomOfflineTag => "Offline", TagHandler.CustomOfflineTag => "Offline",
TagHandler.CustomOnlineTag => _mareConfig.Current.ShowOfflineUsersSeparately ? "Online/Paused" : "Contacts", TagHandler.CustomOnlineTag => _mareConfig.Current.ShowOfflineUsersSeparately ? "Online" : "Contacts",
TagHandler.CustomVisibleTag => "Visible", TagHandler.CustomVisibleTag => "Visible",
_ => tag _ => tag
}; };

View File

@@ -652,7 +652,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
ImGui.SameLine(300.0f * ImGuiHelpers.GlobalScale); ImGui.SameLine(300.0f * ImGuiHelpers.GlobalScale);
if (_ipcProvider.ImpersonationActive) if (_ipcProvider.ImpersonationActive)
{ {
UiSharedService.ColorTextWrapped("Umbra API active!", ImGuiColors.HealerGreen); UiSharedService.ColorTextWrapped("Umbra API active!", UiSharedService.AccentColor);
} }
else else
{ {
@@ -991,7 +991,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
_uiShared.DrawHelpText("If this option is selected all already existing notes for UIDs will be overwritten by the imported notes."); _uiShared.DrawHelpText("If this option is selected all already existing notes for UIDs will be overwritten by the imported notes.");
if (_notesSuccessfullyApplied.HasValue && _notesSuccessfullyApplied.Value) if (_notesSuccessfullyApplied.HasValue && _notesSuccessfullyApplied.Value)
{ {
UiSharedService.ColorTextWrapped("User Notes successfully imported", ImGuiColors.HealerGreen); UiSharedService.ColorTextWrapped("User Notes successfully imported", UiSharedService.AccentColor);
} }
else if (_notesSuccessfullyApplied.HasValue && !_notesSuccessfullyApplied.Value) else if (_notesSuccessfullyApplied.HasValue && !_notesSuccessfullyApplied.Value)
{ {
@@ -1310,7 +1310,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
ImGui.TextUnformatted("Current VRAM utilization by all nearby players:"); ImGui.TextUnformatted("Current VRAM utilization by all nearby players:");
ImGui.SameLine(); ImGui.SameLine();
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.HealerGreen, totalVramBytes < 2.0 * 1024.0 * 1024.0 * 1024.0)) using (ImRaii.PushColor(ImGuiCol.Text, UiSharedService.AccentColor, totalVramBytes < 2.0 * 1024.0 * 1024.0 * 1024.0))
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudYellow, totalVramBytes >= 4.0 * 1024.0 * 1024.0 * 1024.0)) using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudYellow, totalVramBytes >= 4.0 * 1024.0 * 1024.0 * 1024.0))
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed, totalVramBytes >= 6.0 * 1024.0 * 1024.0 * 1024.0)) using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed, totalVramBytes >= 6.0 * 1024.0 * 1024.0 * 1024.0))
ImGui.TextUnformatted($"{totalVramBytes / 1024.0 / 1024.0 / 1024.0:0.00} GiB"); ImGui.TextUnformatted($"{totalVramBytes / 1024.0 / 1024.0 / 1024.0:0.00} GiB");
@@ -1903,11 +1903,11 @@ public class SettingsUi : WindowMediatorSubscriberBase
{ {
ImGui.TextUnformatted("Service " + _serverConfigurationManager.CurrentServer!.ServerName + ":"); ImGui.TextUnformatted("Service " + _serverConfigurationManager.CurrentServer!.ServerName + ":");
ImGui.SameLine(); ImGui.SameLine();
ImGui.TextColored(ImGuiColors.ParsedGreen, "Available"); ImGui.TextColored(UiSharedService.AccentColor, "Available");
ImGui.SameLine(); ImGui.SameLine();
ImGui.TextUnformatted("("); ImGui.TextUnformatted("(");
ImGui.SameLine(); ImGui.SameLine();
ImGui.TextColored(ImGuiColors.ParsedGreen, _apiController.OnlineUsers.ToString(CultureInfo.InvariantCulture)); ImGui.TextColored(UiSharedService.AccentColor, _apiController.OnlineUsers.ToString(CultureInfo.InvariantCulture));
ImGui.SameLine(); ImGui.SameLine();
ImGui.TextUnformatted("Users Online"); ImGui.TextUnformatted("Users Online");
ImGui.SameLine(); ImGui.SameLine();

View File

@@ -36,7 +36,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollbar |
ImGuiWindowFlags.NoScrollWithMouse; ImGuiWindowFlags.NoScrollWithMouse;
public static Vector4 AccentColor { get; set; } = ImGuiColors.DalamudYellow; public static Vector4 AccentColor { get; set; } = ImGuiColors.DalamudViolet;
public readonly FileDialogManager FileDialogManager; public readonly FileDialogManager FileDialogManager;
@@ -310,7 +310,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
} }
} }
public static Vector4 GetBoolColor(bool input) => input ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed; public static Vector4 GetBoolColor(bool input) => input ? AccentColor : ImGuiColors.DalamudRed;
public float GetIconTextButtonSize(FontAwesomeIcon icon, string text) public float GetIconTextButtonSize(FontAwesomeIcon icon, string text)
{ {
@@ -517,7 +517,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
public void BooleanToColoredIcon(bool value, bool inline = true) public void BooleanToColoredIcon(bool value, bool inline = true)
{ {
using var colorgreen = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.HealerGreen, value); using var colorgreen = ImRaii.PushColor(ImGuiCol.Text, AccentColor, value);
using var colorred = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed, !value); using var colorred = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed, !value);
if (inline) ImGui.SameLine(); if (inline) ImGui.SameLine();