rework for ui shit

This commit is contained in:
rootdarkarchon
2023-03-18 21:39:17 +01:00
parent d817eda5e2
commit f6a471f457
19 changed files with 821 additions and 681 deletions

View File

@@ -27,9 +27,6 @@ namespace MareSynchronos.UI;
public class CompactUi : WindowMediatorSubscriberBase
{
public readonly Dictionary<string, bool> ShowUidForEntry = new(StringComparer.Ordinal);
public string EditNickEntry = string.Empty;
public string EditUserComment = string.Empty;
public float TransferPartHeight;
public float WindowContentWidth;
private readonly ApiController _apiController;
@@ -43,6 +40,7 @@ public class CompactUi : WindowMediatorSubscriberBase
private readonly SelectPairForGroupUi _selectPairsForGroupUi;
private readonly ServerConfigurationManager _serverManager;
private readonly Stopwatch _timeout = new();
private readonly UidDisplayHandler _uidDisplayHandler;
private readonly UiSharedService _uiShared;
private bool _buttonState;
private string _characterOrCommentFilter = string.Empty;
@@ -55,7 +53,7 @@ public class CompactUi : WindowMediatorSubscriberBase
private bool _wasOpen;
public CompactUi(ILogger<CompactUi> logger, UiSharedService uiShared, MareConfigService configService, ApiController apiController, PairManager pairManager,
ServerConfigurationManager serverManager, MareMediator mediator, FileUploadManager fileTransferManager) : base(logger, mediator, "###MareSynchronosMainUI")
ServerConfigurationManager serverManager, MareMediator mediator, FileUploadManager fileTransferManager, UidDisplayHandler uidDisplayHandler) : base(logger, mediator, "###MareSynchronosMainUI")
{
_uiShared = uiShared;
_configService = configService;
@@ -63,12 +61,13 @@ public class CompactUi : WindowMediatorSubscriberBase
_pairManager = pairManager;
_serverManager = serverManager;
_fileTransferManager = fileTransferManager;
_uidDisplayHandler = uidDisplayHandler;
var tagHandler = new TagHandler(_serverManager);
_groupPanel = new(this, uiShared, _pairManager, _serverManager, _configService);
_selectGroupForPairUi = new(tagHandler);
_selectPairsForGroupUi = new(tagHandler);
_pairGroupsUi = new(configService, tagHandler, DrawPairedClient, apiController, _selectPairsForGroupUi);
_groupPanel = new(this, uiShared, _pairManager, uidDisplayHandler, _serverManager);
_selectGroupForPairUi = new(tagHandler, uidDisplayHandler);
_selectPairsForGroupUi = new(tagHandler, uidDisplayHandler);
_pairGroupsUi = new(configService, tagHandler, apiController, _selectPairsForGroupUi);
#if DEBUG
string dev = "Dev Build";
@@ -164,8 +163,8 @@ public class CompactUi : WindowMediatorSubscriberBase
ImGui.Separator();
UiSharedService.DrawWithID("transfers", DrawTransfers);
TransferPartHeight = ImGui.GetCursorPosY() - TransferPartHeight;
UiSharedService.DrawWithID("group-user-popup", () => _selectPairsForGroupUi.Draw(_pairManager.DirectPairs, ShowUidForEntry));
UiSharedService.DrawWithID("grouping-popup", () => _selectGroupForPairUi.Draw(ShowUidForEntry));
UiSharedService.DrawWithID("group-user-popup", () => _selectPairsForGroupUi.Draw(_pairManager.DirectPairs));
UiSharedService.DrawWithID("grouping-popup", () => _selectGroupForPairUi.Draw());
}
if (_configService.Current.OpenPopupOnAdd && _pairManager.LastAddedUser != null)
@@ -202,8 +201,7 @@ public class CompactUi : WindowMediatorSubscriberBase
public override void OnClose()
{
EditNickEntry = string.Empty;
EditUserComment = string.Empty;
_uidDisplayHandler.Clear();
base.OnClose();
}
@@ -213,8 +211,6 @@ public class CompactUi : WindowMediatorSubscriberBase
var keys = _serverManager.CurrentServer!.SecretKeys;
if (keys.TryGetValue(_secretKeyIdx, out var secretKey))
{
var friendlyName = secretKey.FriendlyName;
if (UiSharedService.IconTextButton(FontAwesomeIcon.Plus, "Add current character with secret key"))
{
_serverManager.CurrentServer!.Authentications.Add(new MareConfiguration.Models.Authentication()
@@ -350,210 +346,6 @@ public class CompactUi : WindowMediatorSubscriberBase
}
}
private void DrawPairedClient(Pair entry)
{
if (entry.UserPair == null) return;
var pauseIcon = entry.UserPair!.OwnPermissions.IsPaused() ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
var pauseIconSize = UiSharedService.GetIconButtonSize(pauseIcon);
var barButtonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Bars);
var entryUID = entry.UserData.AliasOrUID;
var textSize = ImGui.CalcTextSize(entryUID);
var originalY = ImGui.GetCursorPosY();
var buttonSizes = pauseIconSize.Y + barButtonSize.Y;
var spacingX = ImGui.GetStyle().ItemSpacing.X;
var windowEndX = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth();
var textPos = originalY + pauseIconSize.Y / 2 - textSize.Y / 2;
ImGui.SetCursorPosY(textPos);
FontAwesomeIcon connectionIcon;
string connectionText = string.Empty;
Vector4 connectionColor;
if (!(entry.UserPair!.OwnPermissions.IsPaired() && entry.UserPair!.OtherPermissions.IsPaired()))
{
connectionIcon = FontAwesomeIcon.ArrowUp;
connectionText = entryUID + " has not added you back";
connectionColor = ImGuiColors.DalamudRed;
}
else if (entry.UserPair!.OwnPermissions.IsPaused() || entry.UserPair!.OtherPermissions.IsPaused())
{
connectionIcon = FontAwesomeIcon.PauseCircle;
connectionText = "Pairing status with " + entryUID + " is paused";
connectionColor = ImGuiColors.DalamudYellow;
}
else
{
connectionIcon = FontAwesomeIcon.Check;
connectionText = "You are paired with " + entryUID;
connectionColor = ImGuiColors.ParsedGreen;
}
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(connectionIcon.ToIconString(), connectionColor);
ImGui.PopFont();
UiSharedService.AttachToolTip(connectionText);
ImGui.SameLine();
ImGui.SetCursorPosY(textPos);
if (entry is { IsOnline: true, IsVisible: true })
{
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(FontAwesomeIcon.Eye.ToIconString(), ImGuiColors.ParsedGreen);
ImGui.PopFont();
UiSharedService.AttachToolTip(entryUID + " is visible: " + entry.PlayerName!);
}
var textIsUid = true;
ShowUidForEntry.TryGetValue(entry.UserPair!.User.UID, out var showUidInsteadOfName);
string? playerText = _serverManager.GetNoteForUid(entry.UserPair!.User.UID);
if (!showUidInsteadOfName && playerText != null)
{
if (string.IsNullOrEmpty(playerText))
{
playerText = entryUID;
}
else
{
textIsUid = false;
}
}
else
{
playerText = entryUID;
}
if (_configService.Current.ShowCharacterNameInsteadOfNotesForVisible && entry.IsVisible && !showUidInsteadOfName)
{
playerText = entry.PlayerName;
textIsUid = false;
}
ImGui.SameLine();
if (!string.Equals(EditNickEntry, entry.UserData.UID, StringComparison.Ordinal))
{
ImGui.SetCursorPosY(textPos);
if (textIsUid) ImGui.PushFont(UiBuilder.MonoFont);
ImGui.TextUnformatted(playerText);
if (textIsUid) ImGui.PopFont();
UiSharedService.AttachToolTip("Left click to switch between UID display and nick" + Environment.NewLine +
"Right click to change nick for " + entryUID);
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
{
var prevState = textIsUid;
if (ShowUidForEntry.ContainsKey(entry.UserPair!.User.UID))
{
prevState = ShowUidForEntry[entry.UserPair!.User.UID];
}
ShowUidForEntry[entry.UserPair!.User.UID] = !prevState;
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
var pair = _pairManager.DirectPairs.Find(p => string.Equals(p.UserData.UID, EditNickEntry, StringComparison.Ordinal));
if (pair != null)
{
pair.SetNote(EditUserComment);
_configService.Save();
}
EditUserComment = entry.GetNote() ?? string.Empty;
EditNickEntry = entry.UserPair!.User.UID;
}
}
else
{
ImGui.SetCursorPosY(originalY);
ImGui.SetNextItemWidth(UiSharedService.GetWindowContentRegionWidth() - ImGui.GetCursorPosX() - buttonSizes - ImGui.GetStyle().ItemSpacing.X * 2);
if (ImGui.InputTextWithHint("", "Nick/Notes", ref EditUserComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
{
_serverManager.SetNoteForUid(entry.UserPair!.User.UID, EditUserComment);
EditNickEntry = string.Empty;
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
EditNickEntry = string.Empty;
}
UiSharedService.AttachToolTip("Hit ENTER to save\nRight click to cancel");
}
// Pause Button && sound warnings
if (entry.UserPair!.OwnPermissions.IsPaired() && entry.UserPair!.OtherPermissions.IsPaired())
{
var individualSoundsDisabled = (entry.UserPair?.OwnPermissions.IsDisableSounds() ?? false) || (entry.UserPair?.OtherPermissions.IsDisableSounds() ?? false);
var individualAnimDisabled = (entry.UserPair?.OwnPermissions.IsDisableAnimations() ?? false) || (entry.UserPair?.OtherPermissions.IsDisableAnimations() ?? false);
if (individualAnimDisabled || individualSoundsDisabled)
{
var infoIconPosDist = windowEndX - barButtonSize.X - spacingX - pauseIconSize.X - spacingX;
var icon = FontAwesomeIcon.ExclamationTriangle;
var iconwidth = UiSharedService.GetIconSize(icon);
ImGui.SameLine(infoIconPosDist - iconwidth.X);
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudYellow);
UiSharedService.FontText(icon.ToIconString(), UiBuilder.IconFont);
ImGui.PopStyleColor();
if (ImGui.IsItemHovered())
{
ImGui.BeginTooltip();
ImGui.Text("Individual User permissions");
if (individualSoundsDisabled)
{
var userSoundsText = "Sound sync disabled with " + entry.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.VolumeOff.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userSoundsText);
ImGui.NewLine();
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text("You: " + (entry.UserPair!.OwnPermissions.IsDisableSounds() ? "Disabled" : "Enabled") + ", They: " + (entry.UserPair!.OtherPermissions.IsDisableSounds() ? "Disabled" : "Enabled"));
}
if (individualAnimDisabled)
{
var userAnimText = "Animation sync disabled with " + entry.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.Stop.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userAnimText);
ImGui.NewLine();
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text("You: " + (entry.UserPair!.OwnPermissions.IsDisableAnimations() ? "Disabled" : "Enabled") + ", They: " + (entry.UserPair!.OtherPermissions.IsDisableAnimations() ? "Disabled" : "Enabled"));
}
ImGui.EndTooltip();
}
}
ImGui.SameLine(windowEndX - barButtonSize.X - spacingX - pauseIconSize.X);
ImGui.SetCursorPosY(originalY);
if (ImGuiComponents.IconButton(pauseIcon))
{
var perm = entry.UserPair!.OwnPermissions;
perm.SetPaused(!perm.IsPaused());
_ = _apiController.UserSetPairPermissions(new(entry.UserData, perm));
}
UiSharedService.AttachToolTip(!entry.UserPair!.OwnPermissions.IsPaused()
? "Pause pairing with " + entryUID
: "Resume pairing with " + entryUID);
}
// Flyout Menu
ImGui.SameLine(windowEndX - barButtonSize.X);
ImGui.SetCursorPosY(originalY);
if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars))
{
ImGui.OpenPopup("User Flyout Menu");
}
if (ImGui.BeginPopup("User Flyout Menu"))
{
UiSharedService.DrawWithID($"buttons-{entry.UserPair!.User.UID}", () => DrawPairedClientMenu(entry));
ImGui.EndPopup();
}
}
private void DrawPairedClientMenu(Pair entry)
{
if (entry.IsVisible)
@@ -617,14 +409,15 @@ public class CompactUi : WindowMediatorSubscriberBase
.OrderBy(
u => _configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(u.PlayerName)
? u.PlayerName
: (u.GetNote() ?? u.UserData.AliasOrUID), StringComparer.OrdinalIgnoreCase).ToList();
: (u.GetNote() ?? u.UserData.AliasOrUID), StringComparer.OrdinalIgnoreCase)
.Select(c => new DrawUserPair(c, _uidDisplayHandler, _apiController, _selectGroupForPairUi)).ToList();
if (_configService.Current.ReverseUserSort)
{
users.Reverse();
}
var onlineUsers = users.Where(u => u.IsOnline || u.UserPair.OwnPermissions.IsPaused()).ToList();
var onlineUsers = users.Where(u => u.IsOnline || u.UserPair!.OwnPermissions.IsPaused()).ToList();
var visibleUsers = onlineUsers.Where(u => u.IsVisible).ToList();
var offlineUsers = users.Except(onlineUsers).ToList();

View File

@@ -0,0 +1,299 @@
using Dalamud.Interface.Colors;
using Dalamud.Interface.Components;
using Dalamud.Interface;
using ImGuiNET;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.API.Data.Extensions;
using MareSynchronos.WebAPI;
using MareSynchronos.API.Dto.User;
using MareSynchronos.UI.Handlers;
using MareSynchronos.API.Dto.Group;
using MareSynchronos.API.Data.Enum;
namespace MareSynchronos.UI.Components;
public class DrawGroupPair : DrawPairBase
{
private readonly ApiController _apiController;
private readonly GroupPairFullInfoDto _fullInfoDto;
private readonly GroupFullInfoDto _group;
private string _banReason = string.Empty;
private bool _banUserPopupOpen;
private bool _showModalBanUser;
public DrawGroupPair(Pair entry, ApiController apiController, GroupFullInfoDto group, GroupPairFullInfoDto fullInfoDto, UidDisplayHandler handler) : base(entry, handler)
{
_apiController = apiController;
_group = group;
_fullInfoDto = fullInfoDto;
}
protected override void DrawLeftSide(float textPosY, float originalY)
{
var entryUID = _pair.UserData.AliasOrUID;
var entryIsMod = _fullInfoDto.GroupPairStatusInfo.IsModerator();
var entryIsOwner = string.Equals(_pair.UserData.UID, _group.OwnerUID, StringComparison.Ordinal);
var entryIsPinned = _fullInfoDto.GroupPairStatusInfo.IsPinned();
var presenceIcon = _pair.IsVisible ? FontAwesomeIcon.Eye : (_pair.IsOnline ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink);
var presenceColor = (_pair.IsOnline || _pair.IsVisible) ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
var presenceText = entryUID + " is offline";
ImGui.SetCursorPosY(textPosY);
if (_pair.IsPaused)
{
presenceIcon = FontAwesomeIcon.Question;
presenceColor = ImGuiColors.DalamudGrey;
presenceText = entryUID + " online status is unknown (paused)";
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(FontAwesomeIcon.PauseCircle.ToIconString(), ImGuiColors.DalamudYellow);
ImGui.PopFont();
UiSharedService.AttachToolTip("Pairing status with " + entryUID + " is paused");
}
else
{
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(FontAwesomeIcon.Check.ToIconString(), ImGuiColors.ParsedGreen);
ImGui.PopFont();
UiSharedService.AttachToolTip("You are paired with " + entryUID);
}
if (_pair.IsOnline && !_pair.IsVisible) presenceText = entryUID + " is online";
else if (_pair.IsOnline && _pair.IsVisible) presenceText = entryUID + " is visible: " + _pair.PlayerName;
ImGui.SameLine();
ImGui.SetCursorPosY(textPosY);
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(presenceIcon.ToIconString(), presenceColor);
ImGui.PopFont();
UiSharedService.AttachToolTip(presenceText);
if (entryIsOwner)
{
ImGui.SameLine();
ImGui.SetCursorPosY(textPosY);
ImGui.PushFont(UiBuilder.IconFont);
ImGui.TextUnformatted(FontAwesomeIcon.Crown.ToIconString());
ImGui.PopFont();
UiSharedService.AttachToolTip("User is owner of this Syncshell");
}
else if (entryIsMod)
{
ImGui.SameLine();
ImGui.SetCursorPosY(textPosY);
ImGui.PushFont(UiBuilder.IconFont);
ImGui.TextUnformatted(FontAwesomeIcon.UserShield.ToIconString());
ImGui.PopFont();
UiSharedService.AttachToolTip("User is moderator of this Syncshell");
}
else if (entryIsPinned)
{
ImGui.SameLine();
ImGui.SetCursorPosY(textPosY);
ImGui.PushFont(UiBuilder.IconFont);
ImGui.TextUnformatted(FontAwesomeIcon.Thumbtack.ToIconString());
ImGui.PopFont();
UiSharedService.AttachToolTip("User is pinned in this Syncshell");
}
}
protected override float DrawRightSide(float textPosY, float originalY)
{
var entryUID = _fullInfoDto.UserAliasOrUID;
var entryIsMod = _fullInfoDto.GroupPairStatusInfo.IsModerator();
var entryIsOwner = string.Equals(_pair.UserData.UID, _group.OwnerUID, StringComparison.Ordinal);
var entryIsPinned = _fullInfoDto.GroupPairStatusInfo.IsPinned();
var userIsOwner = string.Equals(_group.OwnerUID, _apiController.UID, StringComparison.OrdinalIgnoreCase);
var userIsModerator = _group.GroupUserInfo.IsModerator();
var soundsDisabled = _fullInfoDto.GroupUserPermissions.IsDisableSounds();
var animDisabled = _fullInfoDto.GroupUserPermissions.IsDisableAnimations();
var individualSoundsDisabled = (_pair.UserPair?.OwnPermissions.IsDisableSounds() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableSounds() ?? false);
var individualAnimDisabled = (_pair.UserPair?.OwnPermissions.IsDisableAnimations() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableAnimations() ?? false);
bool showInfo = (individualAnimDisabled || individualSoundsDisabled || animDisabled || soundsDisabled);
bool showPlus = _pair.UserPair == null;
bool showBars = userIsOwner || (userIsModerator && !entryIsMod && !entryIsOwner);
var spacing = ImGui.GetStyle().ItemSpacing.X;
var permIcon = (individualAnimDisabled || individualSoundsDisabled) ? FontAwesomeIcon.ExclamationTriangle
: ((soundsDisabled || animDisabled) ? FontAwesomeIcon.InfoCircle : FontAwesomeIcon.None);
var infoIconWidth = UiSharedService.GetIconSize(permIcon).X;
var plusButtonWidth = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Plus).X;
var barButtonWidth = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Bars).X;
var pos = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() + spacing
- (showInfo ? (infoIconWidth + spacing) : 0)
- (showPlus ? (plusButtonWidth + spacing) : 0)
- (showBars ? (barButtonWidth + spacing) : 0);
ImGui.SameLine(pos);
if (individualAnimDisabled || individualSoundsDisabled)
{
ImGui.SetCursorPosY(textPosY);
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudYellow);
UiSharedService.FontText(permIcon.ToIconString(), UiBuilder.IconFont);
ImGui.PopStyleColor();
if (ImGui.IsItemHovered())
{
ImGui.BeginTooltip();
ImGui.Text("Individual User permissions");
if (individualSoundsDisabled)
{
var userSoundsText = "Sound sync disabled with " + _pair.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.VolumeOff.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userSoundsText);
ImGui.NewLine();
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text("You: " + (_pair.UserPair!.OwnPermissions.IsDisableSounds() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableSounds() ? "Disabled" : "Enabled"));
}
if (individualAnimDisabled)
{
var userAnimText = "Animation sync disabled with " + _pair.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.Stop.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userAnimText);
ImGui.NewLine();
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text("You: " + (_pair.UserPair!.OwnPermissions.IsDisableAnimations() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableAnimations() ? "Disabled" : "Enabled"));
}
ImGui.EndTooltip();
}
ImGui.SameLine();
}
else if ((animDisabled || soundsDisabled))
{
ImGui.SetCursorPosY(textPosY);
UiSharedService.FontText(permIcon.ToIconString(), UiBuilder.IconFont);
if (ImGui.IsItemHovered())
{
ImGui.BeginTooltip();
ImGui.Text("Sycnshell User permissions");
if (soundsDisabled)
{
var userSoundsText = "Sound sync disabled by " + _pair.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.VolumeOff.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userSoundsText);
}
if (animDisabled)
{
var userAnimText = "Animation sync disabled by " + _pair.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.Stop.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userAnimText);
}
ImGui.EndTooltip();
}
ImGui.SameLine();
}
if (showPlus)
{
ImGui.SetCursorPosY(originalY);
if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
{
_ = _apiController.UserAddPair(new UserDto(new(_pair.UserData.UID)));
}
UiSharedService.AttachToolTip("Pair with " + entryUID + " individually");
ImGui.SameLine();
}
if (showBars)
{
ImGui.SetCursorPosY(originalY);
if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars))
{
ImGui.OpenPopup("Popup");
}
}
if (ImGui.BeginPopup("Popup"))
{
if ((userIsModerator || userIsOwner) && !(entryIsMod || entryIsOwner))
{
var pinText = entryIsPinned ? "Unpin user" : "Pin user";
if (UiSharedService.IconTextButton(FontAwesomeIcon.Thumbtack, pinText))
{
ImGui.CloseCurrentPopup();
var userInfo = _fullInfoDto.GroupPairStatusInfo ^ GroupUserInfo.IsPinned;
_ = _apiController.GroupSetUserInfo(new GroupPairUserInfoDto(_fullInfoDto.Group, _fullInfoDto.User, userInfo));
}
UiSharedService.AttachToolTip("Pin this user to the Syncshell. Pinned users will not be deleted in case of a manually initiated Syncshell clean");
if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Remove user") && UiSharedService.CtrlPressed())
{
ImGui.CloseCurrentPopup();
_ = _apiController.GroupRemoveUser(_fullInfoDto);
}
UiSharedService.AttachToolTip("Hold CTRL and click to remove user " + (_pair.UserData.AliasOrUID) + " from Syncshell");
if (UiSharedService.IconTextButton(FontAwesomeIcon.UserSlash, "Ban User"))
{
_showModalBanUser = true;
ImGui.CloseCurrentPopup();
}
UiSharedService.AttachToolTip("Ban user from this Syncshell");
}
if (userIsOwner)
{
string modText = entryIsMod ? "Demod user" : "Mod user";
if (UiSharedService.IconTextButton(FontAwesomeIcon.UserShield, modText) && UiSharedService.CtrlPressed())
{
ImGui.CloseCurrentPopup();
var userInfo = _fullInfoDto.GroupPairStatusInfo ^ GroupUserInfo.IsModerator;
_ = _apiController.GroupSetUserInfo(new GroupPairUserInfoDto(_fullInfoDto.Group, _fullInfoDto.User, userInfo));
}
UiSharedService.AttachToolTip("Hold CTRL to change the moderator status for " + (_fullInfoDto.UserAliasOrUID) + Environment.NewLine +
"Moderators can kick, ban/unban, pin/unpin users and clear the Syncshell.");
if (UiSharedService.IconTextButton(FontAwesomeIcon.Crown, "Transfer Ownership") && UiSharedService.CtrlPressed() && UiSharedService.ShiftPressed())
{
ImGui.CloseCurrentPopup();
_ = _apiController.GroupChangeOwnership(_fullInfoDto);
}
UiSharedService.AttachToolTip("Hold CTRL and SHIFT and click to transfer ownership of this Syncshell to " + (_fullInfoDto.UserAliasOrUID) + Environment.NewLine + "WARNING: This action is irreversible.");
}
ImGui.EndPopup();
}
if (_showModalBanUser && !_banUserPopupOpen)
{
ImGui.OpenPopup("Ban User");
_banUserPopupOpen = true;
}
if (!_showModalBanUser) _banUserPopupOpen = false;
if (ImGui.BeginPopupModal("Ban User", ref _showModalBanUser, UiSharedService.PopupWindowFlags))
{
UiSharedService.TextWrapped("User " + (_fullInfoDto.UserAliasOrUID) + " will be banned and removed from this Syncshell.");
ImGui.InputTextWithHint("##banreason", "Ban Reason", ref _banReason, 255);
if (ImGui.Button("Ban User"))
{
ImGui.CloseCurrentPopup();
var reason = _banReason;
_ = _apiController.GroupBanUser(new GroupPairDto(_group.Group, _fullInfoDto.User), reason);
_banReason = string.Empty;
}
UiSharedService.TextWrapped("The reason will be displayed in the banlist. The current server-side alias if present (Vanity ID) will automatically be attached to the reason.");
UiSharedService.SetScaledWindowSize(300);
ImGui.EndPopup();
}
return pos - spacing;
}
}

View File

@@ -0,0 +1,43 @@
using Dalamud.Interface;
using ImGuiNET;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.UI.Handlers;
namespace MareSynchronos.UI.Components;
public abstract class DrawPairBase
{
protected Pair _pair;
private readonly UidDisplayHandler _displayHandler;
protected DrawPairBase(Pair entry, UidDisplayHandler uIDDisplayHandler)
{
_pair = entry;
_displayHandler = uIDDisplayHandler;
}
public string UID => _pair.UserData.UID;
public void DrawPairedClient()
{
var originalY = ImGui.GetCursorPosY();
var pauseIconSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Play);
var textSize = ImGui.CalcTextSize(_pair.UserData.AliasOrUID);
var textPosY = originalY + pauseIconSize.Y / 2 - textSize.Y / 2;
DrawLeftSide(textPosY, originalY);
ImGui.SameLine();
var posX = ImGui.GetCursorPosX();
var rightSide = DrawRightSide(textPosY, originalY);
DrawName(originalY, posX, rightSide);
}
protected abstract void DrawLeftSide(float textPosY, float originalY);
protected abstract float DrawRightSide(float textPosY, float originalY);
private void DrawName(float originalY, float leftSide, float rightSide)
{
_displayHandler.DrawPairText(_pair, leftSide, originalY, () => rightSide - leftSide);
}
}

View File

@@ -0,0 +1,213 @@
using Dalamud.Interface.Colors;
using Dalamud.Interface.Components;
using Dalamud.Interface;
using ImGuiNET;
using MareSynchronos.PlayerData.Pairs;
using System.Numerics;
using MareSynchronos.API.Data.Extensions;
using MareSynchronos.WebAPI;
using MareSynchronos.API.Dto.User;
using MareSynchronos.UI.Handlers;
namespace MareSynchronos.UI.Components;
public class DrawUserPair : DrawPairBase
{
private readonly ApiController _apiController;
private readonly SelectGroupForPairUi _selectGroupForPairUi;
public DrawUserPair(Pair entry, UidDisplayHandler displayHandler, ApiController apiController, SelectGroupForPairUi selectGroupForPairUi) : base(entry, displayHandler)
{
if (_pair.UserPair == null) throw new ArgumentException("Pair must be UserPair", nameof(entry));
_pair = entry;
_apiController = apiController;
_selectGroupForPairUi = selectGroupForPairUi;
}
public bool IsOnline => _pair.IsOnline;
public bool IsVisible => _pair.IsVisible;
public UserPairDto UserPair => _pair.UserPair!;
protected override void DrawLeftSide(float textPos, float originalY)
{
FontAwesomeIcon connectionIcon;
Vector4 connectionColor;
string connectionText;
if (!(_pair.UserPair!.OwnPermissions.IsPaired() && _pair.UserPair!.OtherPermissions.IsPaired()))
{
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(textPos);
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(connectionIcon.ToIconString(), connectionColor);
ImGui.PopFont();
UiSharedService.AttachToolTip(connectionText);
if (_pair is { IsOnline: true, IsVisible: true })
{
ImGui.SameLine();
ImGui.SetCursorPosY(textPos);
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(FontAwesomeIcon.Eye.ToIconString(), ImGuiColors.ParsedGreen);
ImGui.PopFont();
UiSharedService.AttachToolTip(_pair.UserData.AliasOrUID + " is visible: " + _pair.PlayerName!);
}
}
protected override float DrawRightSide(float textPosY, float originalY)
{
var pauseIcon = _pair.UserPair!.OwnPermissions.IsPaused() ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
var pauseIconSize = UiSharedService.GetIconButtonSize(pauseIcon);
var barButtonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Bars);
var entryUID = _pair.UserData.AliasOrUID;
var spacingX = ImGui.GetStyle().ItemSpacing.X;
var windowEndX = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth();
var rightSideStart = 0f;
if (_pair.UserPair!.OwnPermissions.IsPaired() && _pair.UserPair!.OtherPermissions.IsPaired())
{
var individualSoundsDisabled = (_pair.UserPair?.OwnPermissions.IsDisableSounds() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableSounds() ?? false);
var individualAnimDisabled = (_pair.UserPair?.OwnPermissions.IsDisableAnimations() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableAnimations() ?? false);
if (individualAnimDisabled || individualSoundsDisabled)
{
var infoIconPosDist = windowEndX - barButtonSize.X - spacingX - pauseIconSize.X - spacingX;
var icon = FontAwesomeIcon.ExclamationTriangle;
var iconwidth = UiSharedService.GetIconSize(icon);
rightSideStart = infoIconPosDist - iconwidth.X;
ImGui.SameLine(infoIconPosDist - iconwidth.X);
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudYellow);
UiSharedService.FontText(icon.ToIconString(), UiBuilder.IconFont);
ImGui.PopStyleColor();
if (ImGui.IsItemHovered())
{
ImGui.BeginTooltip();
ImGui.Text("Individual User permissions");
if (individualSoundsDisabled)
{
var userSoundsText = "Sound sync disabled with " + _pair.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.VolumeOff.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userSoundsText);
ImGui.NewLine();
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text("You: " + (_pair.UserPair!.OwnPermissions.IsDisableSounds() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableSounds() ? "Disabled" : "Enabled"));
}
if (individualAnimDisabled)
{
var userAnimText = "Animation sync disabled with " + _pair.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.Stop.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userAnimText);
ImGui.NewLine();
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text("You: " + (_pair.UserPair!.OwnPermissions.IsDisableAnimations() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableAnimations() ? "Disabled" : "Enabled"));
}
ImGui.EndTooltip();
}
}
if (rightSideStart == 0f)
{
rightSideStart = windowEndX - barButtonSize.X - spacingX * 2 - pauseIconSize.X;
}
ImGui.SameLine(windowEndX - barButtonSize.X - spacingX - pauseIconSize.X);
ImGui.SetCursorPosY(originalY);
if (ImGuiComponents.IconButton(pauseIcon))
{
var perm = _pair.UserPair!.OwnPermissions;
perm.SetPaused(!perm.IsPaused());
_ = _apiController.UserSetPairPermissions(new(_pair.UserData, perm));
}
UiSharedService.AttachToolTip(!_pair.UserPair!.OwnPermissions.IsPaused()
? "Pause pairing with " + entryUID
: "Resume pairing with " + entryUID);
}
// Flyout Menu
if (rightSideStart == 0f)
{
rightSideStart = windowEndX - barButtonSize.X;
}
ImGui.SameLine(windowEndX - barButtonSize.X);
ImGui.SetCursorPosY(originalY);
if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars))
{
ImGui.OpenPopup("User Flyout Menu");
}
if (ImGui.BeginPopup("User Flyout Menu"))
{
UiSharedService.DrawWithID($"buttons-{_pair.UserData.UID}", () => DrawPairedClientMenu(_pair));
ImGui.EndPopup();
}
return rightSideStart;
}
private void DrawPairedClientMenu(Pair entry)
{
if (entry.IsVisible)
{
if (UiSharedService.IconTextButton(FontAwesomeIcon.Sync, "Reload last data"))
{
entry.ApplyLastReceivedData(forced: true);
ImGui.CloseCurrentPopup();
}
UiSharedService.AttachToolTip("This reapplies the last received character data to this character");
}
var entryUID = entry.UserData.AliasOrUID;
if (UiSharedService.IconTextButton(FontAwesomeIcon.Folder, "Pair Groups"))
{
_selectGroupForPairUi.Open(entry);
}
UiSharedService.AttachToolTip("Choose pair groups for " + entryUID);
var isDisableSounds = entry.UserPair!.OwnPermissions.IsDisableSounds();
string disableSoundsText = isDisableSounds ? "Enable sound sync" : "Disable sound sync";
var disableSoundsIcon = isDisableSounds ? FontAwesomeIcon.VolumeUp : FontAwesomeIcon.VolumeMute;
if (UiSharedService.IconTextButton(disableSoundsIcon, disableSoundsText))
{
var permissions = entry.UserPair.OwnPermissions;
permissions.SetDisableSounds(!isDisableSounds);
_ = _apiController.UserSetPairPermissions(new UserPermissionsDto(entry.UserData, permissions));
}
var isDisableAnims = entry.UserPair!.OwnPermissions.IsDisableAnimations();
string disableAnimsText = isDisableAnims ? "Enable animation sync" : "Disable animation sync";
var disableAnimsIcon = isDisableAnims ? FontAwesomeIcon.Running : FontAwesomeIcon.Stop;
if (UiSharedService.IconTextButton(disableAnimsIcon, disableAnimsText))
{
var permissions = entry.UserPair.OwnPermissions;
permissions.SetDisableAnimations(!isDisableAnims);
_ = _apiController.UserSetPairPermissions(new UserPermissionsDto(entry.UserData, permissions));
}
if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Unpair Permanently") && UiSharedService.CtrlPressed())
{
_ = _apiController.UserRemovePair(new(entry.UserData));
}
UiSharedService.AttachToolTip("Hold CTRL and click to unpair permanently from " + entryUID);
}
}

View File

@@ -1,5 +1,4 @@
using Dalamud.Interface.Colors;
using Dalamud.Interface.Components;
using Dalamud.Interface.Components;
using Dalamud.Interface;
using Dalamud.Utility;
using ImGuiNET;
@@ -8,28 +7,26 @@ using System.Numerics;
using System.Globalization;
using MareSynchronos.API.Data;
using MareSynchronos.API.Dto.Group;
using MareSynchronos.API.Dto.User;
using MareSynchronos.API.Data.Enum;
using MareSynchronos.API.Data.Extensions;
using MareSynchronos.API.Data.Comparer;
using MareSynchronos.MareConfiguration;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.Services.ServerConfiguration;
using MareSynchronos.UI.Components;
using MareSynchronos.UI.Handlers;
namespace MareSynchronos.UI;
internal sealed class GroupPanel
{
private readonly MareConfigService _configService;
private readonly Dictionary<string, bool> _expandedGroupState = new(StringComparer.Ordinal);
private readonly CompactUi _mainUi;
private readonly PairManager _pairManager;
private readonly ServerConfigurationManager _serverConfigurationManager;
private readonly Dictionary<string, bool> _showGidForEntry = new(StringComparer.Ordinal);
private readonly UidDisplayHandler _uidDisplayHandler;
private readonly UiSharedService _uiShared;
private List<BannedGroupUserDto> _bannedUsers = new();
private string _banReason = string.Empty;
private bool _banUserPopupOpen;
private int _bulkInviteCount = 10;
private List<string> _bulkOneTimeInvites = new();
private string _editGroupComment = string.Empty;
@@ -43,7 +40,6 @@ internal sealed class GroupPanel
private bool _modalChangePwOpened;
private string _newSyncShellPassword = string.Empty;
private bool _showModalBanList = false;
private bool _showModalBanUser;
private bool _showModalBulkOneTimeInvites = false;
private bool _showModalChangePassword;
private bool _showModalCreateGroup;
@@ -51,13 +47,13 @@ internal sealed class GroupPanel
private string _syncShellPassword = string.Empty;
private string _syncShellToJoin = string.Empty;
public GroupPanel(CompactUi mainUi, UiSharedService uiShared, PairManager pairManager, ServerConfigurationManager serverConfigurationManager, MareConfigService configurationService)
public GroupPanel(CompactUi mainUi, UiSharedService uiShared, PairManager pairManager, UidDisplayHandler uidDisplayHandler, ServerConfigurationManager serverConfigurationManager)
{
_mainUi = mainUi;
_uiShared = uiShared;
_pairManager = pairManager;
_uidDisplayHandler = uidDisplayHandler;
_serverConfigurationManager = serverConfigurationManager;
_configService = configurationService;
}
private ApiController ApiController => _uiShared.ApiController;
@@ -406,18 +402,24 @@ internal sealed class GroupPanel
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator())
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned())
.ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase)
.Select(c => new DrawGroupPair(c, ApiController, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
_uidDisplayHandler))
.ToList();
var onlineUsers = pairsInGroup.Where(u => u.IsOnline && !u.IsVisible)
.OrderByDescending(u => string.Equals(u.UserData.UID, groupDto.OwnerUID, StringComparison.Ordinal))
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator())
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned())
.ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase)
.Select(c => new DrawGroupPair(c, ApiController, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
_uidDisplayHandler))
.ToList();
var offlineUsers = pairsInGroup.Where(u => !u.IsOnline && !u.IsVisible)
.OrderByDescending(u => string.Equals(u.UserData.UID, groupDto.OwnerUID, StringComparison.Ordinal))
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator())
.ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned())
.ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase)
.Select(c => new DrawGroupPair(c, ApiController, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
_uidDisplayHandler))
.ToList();
if (visibleUsers.Any())
@@ -426,12 +428,7 @@ internal sealed class GroupPanel
ImGui.Separator();
foreach (var entry in visibleUsers)
{
UiSharedService.DrawWithID(groupDto.GID + entry.UserData.UID, () => DrawSyncshellPairedClient(
entry,
entry.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
groupDto.OwnerUID,
string.Equals(groupDto.OwnerUID, ApiController.UID, StringComparison.Ordinal),
groupDto.GroupUserInfo.IsModerator()));
UiSharedService.DrawWithID(groupDto.GID + entry.UID, () => entry.DrawPairedClient());
}
}
@@ -441,12 +438,7 @@ internal sealed class GroupPanel
ImGui.Separator();
foreach (var entry in onlineUsers)
{
UiSharedService.DrawWithID(groupDto.GID + entry.UserData.UID, () => DrawSyncshellPairedClient(
entry,
entry.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
groupDto.OwnerUID,
string.Equals(groupDto.OwnerUID, ApiController.UID, StringComparison.Ordinal),
groupDto.GroupUserInfo.IsModerator()));
UiSharedService.DrawWithID(groupDto.GID + entry.UID, () => entry.DrawPairedClient());
}
}
@@ -456,12 +448,7 @@ internal sealed class GroupPanel
ImGui.Separator();
foreach (var entry in offlineUsers)
{
UiSharedService.DrawWithID(groupDto.GID + entry.UserData.UID, () => DrawSyncshellPairedClient(
entry,
entry.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
groupDto.OwnerUID,
string.Equals(groupDto.OwnerUID, ApiController.UID, StringComparison.Ordinal),
groupDto.GroupUserInfo.IsModerator()));
UiSharedService.DrawWithID(groupDto.GID + entry.UID, () => entry.DrawPairedClient());
}
}
@@ -724,337 +711,4 @@ internal sealed class GroupPanel
}
ImGui.EndChild();
}
private void DrawSyncshellPairedClient(Pair pair, GroupPairFullInfoDto entry, string ownerUid, bool userIsOwner, bool userIsModerator)
{
var plusButtonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Plus);
var barButtonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Bars);
var entryUID = entry.UserAliasOrUID;
var textSize = ImGui.CalcTextSize(entryUID);
var originalY = ImGui.GetCursorPosY();
var entryIsMod = entry.GroupPairStatusInfo.IsModerator();
var entryIsOwner = string.Equals(pair.UserData.UID, ownerUid, StringComparison.Ordinal);
var entryIsPinned = entry.GroupPairStatusInfo.IsPinned();
var presenceIcon = pair.IsVisible ? FontAwesomeIcon.Eye : (pair.IsOnline ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink);
var presenceColor = (pair.IsOnline || pair.IsVisible) ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
var presenceText = entryUID + " is offline";
var soundsDisabled = entry.GroupUserPermissions.IsDisableSounds();
var animDisabled = entry.GroupUserPermissions.IsDisableAnimations();
var individualSoundsDisabled = (pair.UserPair?.OwnPermissions.IsDisableSounds() ?? false) || (pair.UserPair?.OtherPermissions.IsDisableSounds() ?? false);
var individualAnimDisabled = (pair.UserPair?.OwnPermissions.IsDisableAnimations() ?? false) || (pair.UserPair?.OtherPermissions.IsDisableAnimations() ?? false);
var textPos = originalY + barButtonSize.Y / 2 - textSize.Y / 2;
ImGui.SetCursorPosY(textPos);
if (pair.IsPaused)
{
presenceIcon = FontAwesomeIcon.Question;
presenceColor = ImGuiColors.DalamudGrey;
presenceText = entryUID + " online status is unknown (paused)";
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(FontAwesomeIcon.PauseCircle.ToIconString(), ImGuiColors.DalamudYellow);
ImGui.PopFont();
UiSharedService.AttachToolTip("Pairing status with " + entryUID + " is paused");
}
else
{
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(FontAwesomeIcon.Check.ToIconString(), ImGuiColors.ParsedGreen);
ImGui.PopFont();
UiSharedService.AttachToolTip("You are paired with " + entryUID);
}
if (pair.IsOnline && !pair.IsVisible) presenceText = entryUID + " is online";
else if (pair.IsOnline && pair.IsVisible) presenceText = entryUID + " is visible: " + pair.PlayerName;
ImGui.SameLine();
ImGui.SetCursorPosY(textPos);
ImGui.PushFont(UiBuilder.IconFont);
UiSharedService.ColorText(presenceIcon.ToIconString(), presenceColor);
ImGui.PopFont();
UiSharedService.AttachToolTip(presenceText);
if (entryIsOwner)
{
ImGui.SameLine();
ImGui.SetCursorPosY(textPos);
ImGui.PushFont(UiBuilder.IconFont);
ImGui.TextUnformatted(FontAwesomeIcon.Crown.ToIconString());
ImGui.PopFont();
UiSharedService.AttachToolTip("User is owner of this Syncshell");
}
else if (entryIsMod)
{
ImGui.SameLine();
ImGui.SetCursorPosY(textPos);
ImGui.PushFont(UiBuilder.IconFont);
ImGui.TextUnformatted(FontAwesomeIcon.UserShield.ToIconString());
ImGui.PopFont();
UiSharedService.AttachToolTip("User is moderator of this Syncshell");
}
else if (entryIsPinned)
{
ImGui.SameLine();
ImGui.SetCursorPosY(textPos);
ImGui.PushFont(UiBuilder.IconFont);
ImGui.TextUnformatted(FontAwesomeIcon.Thumbtack.ToIconString());
ImGui.PopFont();
UiSharedService.AttachToolTip("User is pinned in this Syncshell");
}
var textIsUid = true;
_mainUi.ShowUidForEntry.TryGetValue(entry.UID, out var showUidInsteadOfName);
var playerText = _serverConfigurationManager.GetNoteForUid(entry.UID);
if (showUidInsteadOfName || string.IsNullOrEmpty(playerText))
{
playerText = entryUID;
}
else
{
textIsUid = false;
}
if (_configService.Current.ShowCharacterNameInsteadOfNotesForVisible && pair.IsVisible && !showUidInsteadOfName)
{
playerText = pair.PlayerName;
textIsUid = false;
}
bool plusButtonShown = !_pairManager.DirectPairs.Any(p => string.Equals(p.UserData.UID, entry.UID, StringComparison.Ordinal));
ImGui.SameLine();
if (!string.Equals(_mainUi.EditNickEntry, entry.UID, StringComparison.Ordinal))
{
ImGui.SetCursorPosY(textPos);
if (textIsUid) ImGui.PushFont(UiBuilder.MonoFont);
ImGui.TextUnformatted(playerText);
if (textIsUid) ImGui.PopFont();
UiSharedService.AttachToolTip("Left click to switch between UID display and nick" + Environment.NewLine +
"Right click to change nick for " + entryUID);
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
{
var prevState = textIsUid;
if (_mainUi.ShowUidForEntry.ContainsKey(entry.UID))
{
prevState = _mainUi.ShowUidForEntry[entry.UID];
}
_mainUi.ShowUidForEntry[entry.UID] = !prevState;
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
_serverConfigurationManager.SetNoteForUid(_mainUi.EditNickEntry, _mainUi.EditUserComment);
_mainUi.EditUserComment = _serverConfigurationManager.GetNoteForUid(entry.UID) ?? string.Empty;
_mainUi.EditNickEntry = entry.UID;
}
}
else
{
ImGui.SetCursorPosY(originalY);
var buttonSizes = (plusButtonShown ? plusButtonSize.X : 0) + barButtonSize.X;
var buttons = plusButtonShown ? 2 : 1;
ImGui.SetNextItemWidth(UiSharedService.GetWindowContentRegionWidth() - ImGui.GetCursorPosX() - buttonSizes - ImGui.GetStyle().ItemSpacing.X * buttons);
if (ImGui.InputTextWithHint("", "Nick/Notes", ref _mainUi.EditUserComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
{
_serverConfigurationManager.SetNoteForUid(entry.UID, _mainUi.EditUserComment);
_mainUi.EditNickEntry = string.Empty;
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
_mainUi.EditNickEntry = string.Empty;
}
UiSharedService.AttachToolTip("Hit ENTER to save\nRight click to cancel");
}
if (plusButtonShown)
{
var barWidth = userIsOwner || (userIsModerator && !entryIsMod && !entryIsOwner)
? barButtonSize.X + ImGui.GetStyle().ItemSpacing.X
: 0;
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() - plusButtonSize.X - barWidth);
ImGui.SetCursorPosY(originalY);
if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
{
_ = ApiController.UserAddPair(new UserDto(entry.User));
}
UiSharedService.AttachToolTip("Pair with " + entryUID + " individually");
}
if (userIsOwner || (userIsModerator && !entryIsMod && !entryIsOwner))
{
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() - barButtonSize.X);
ImGui.SetCursorPosY(originalY);
if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars))
{
ImGui.OpenPopup("Popup");
}
}
if (individualAnimDisabled || individualSoundsDisabled)
{
var infoIconPosDist = (plusButtonShown ? plusButtonSize.X + ImGui.GetStyle().ItemSpacing.X : 0)
+ ((userIsOwner || (userIsModerator && !entryIsMod && !entryIsOwner)) ? barButtonSize.X + ImGui.GetStyle().ItemSpacing.X : 0);
var icon = FontAwesomeIcon.ExclamationTriangle;
var iconwidth = UiSharedService.GetIconSize(icon);
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() - infoIconPosDist - iconwidth.X);
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudYellow);
UiSharedService.FontText(icon.ToIconString(), UiBuilder.IconFont);
ImGui.PopStyleColor();
if (ImGui.IsItemHovered())
{
ImGui.BeginTooltip();
ImGui.Text("Individual User permissions");
if (individualSoundsDisabled)
{
var userSoundsText = "Sound sync disabled with " + pair.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.VolumeOff.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userSoundsText);
ImGui.NewLine();
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text("You: " + (pair.UserPair!.OwnPermissions.IsDisableSounds() ? "Disabled" : "Enabled") + ", They: " + (pair.UserPair!.OtherPermissions.IsDisableSounds() ? "Disabled" : "Enabled"));
}
if (individualAnimDisabled)
{
var userAnimText = "Animation sync disabled with " + pair.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.Stop.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userAnimText);
ImGui.NewLine();
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text("You: " + (pair.UserPair!.OwnPermissions.IsDisableAnimations() ? "Disabled" : "Enabled") + ", They: " + (pair.UserPair!.OtherPermissions.IsDisableAnimations() ? "Disabled" : "Enabled"));
}
ImGui.EndTooltip();
}
}
else if ((animDisabled || soundsDisabled))
{
var infoIconPosDist = (plusButtonShown ? plusButtonSize.X + ImGui.GetStyle().ItemSpacing.X : 0)
+ ((userIsOwner || (userIsModerator && !entryIsMod && !entryIsOwner)) ? barButtonSize.X + ImGui.GetStyle().ItemSpacing.X : 0);
var icon = FontAwesomeIcon.InfoCircle;
var iconwidth = UiSharedService.GetIconSize(icon);
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() - infoIconPosDist - iconwidth.X);
ImGui.SetCursorPosY(originalY);
UiSharedService.FontText(icon.ToIconString(), UiBuilder.IconFont);
if (ImGui.IsItemHovered())
{
ImGui.BeginTooltip();
ImGui.Text("Sycnshell User permissions");
if (soundsDisabled)
{
var userSoundsText = "Sound sync disabled by " + pair.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.VolumeOff.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userSoundsText);
}
if (animDisabled)
{
var userAnimText = "Animation sync disabled by " + pair.UserData.AliasOrUID;
UiSharedService.FontText(FontAwesomeIcon.Stop.ToIconString(), UiBuilder.IconFont);
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
ImGui.Text(userAnimText);
}
ImGui.EndTooltip();
}
}
if (!plusButtonShown && !(userIsOwner || (userIsModerator && !entryIsMod && !entryIsOwner)))
{
ImGui.SameLine();
ImGui.Dummy(barButtonSize with { X = 0 });
}
if (ImGui.BeginPopup("Popup"))
{
if ((userIsModerator || userIsOwner) && !(entryIsMod || entryIsOwner))
{
var pinText = entryIsPinned ? "Unpin user" : "Pin user";
if (UiSharedService.IconTextButton(FontAwesomeIcon.Thumbtack, pinText))
{
ImGui.CloseCurrentPopup();
var userInfo = entry.GroupPairStatusInfo ^ GroupUserInfo.IsPinned;
_ = ApiController.GroupSetUserInfo(new GroupPairUserInfoDto(entry.Group, entry.User, userInfo));
}
UiSharedService.AttachToolTip("Pin this user to the Syncshell. Pinned users will not be deleted in case of a manually initiated Syncshell clean");
if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Remove user") && UiSharedService.CtrlPressed())
{
ImGui.CloseCurrentPopup();
_ = ApiController.GroupRemoveUser(entry);
}
UiSharedService.AttachToolTip("Hold CTRL and click to remove user " + (entry.UserAliasOrUID) + " from Syncshell");
if (UiSharedService.IconTextButton(FontAwesomeIcon.UserSlash, "Ban User"))
{
_showModalBanUser = true;
ImGui.CloseCurrentPopup();
}
UiSharedService.AttachToolTip("Ban user from this Syncshell");
}
if (userIsOwner)
{
string modText = entryIsMod ? "Demod user" : "Mod user";
if (UiSharedService.IconTextButton(FontAwesomeIcon.UserShield, modText) && UiSharedService.CtrlPressed())
{
ImGui.CloseCurrentPopup();
var userInfo = entry.GroupPairStatusInfo ^ GroupUserInfo.IsModerator;
_ = ApiController.GroupSetUserInfo(new GroupPairUserInfoDto(entry.Group, entry.User, userInfo));
}
UiSharedService.AttachToolTip("Hold CTRL to change the moderator status for " + (entry.UserAliasOrUID) + Environment.NewLine +
"Moderators can kick, ban/unban, pin/unpin users and clear the Syncshell.");
if (UiSharedService.IconTextButton(FontAwesomeIcon.Crown, "Transfer Ownership") && UiSharedService.CtrlPressed() && UiSharedService.ShiftPressed())
{
ImGui.CloseCurrentPopup();
_ = ApiController.GroupChangeOwnership(entry);
}
UiSharedService.AttachToolTip("Hold CTRL and SHIFT and click to transfer ownership of this Syncshell to " + (entry.UserAliasOrUID) + Environment.NewLine + "WARNING: This action is irreversible.");
}
ImGui.EndPopup();
}
if (_showModalBanUser && !_banUserPopupOpen)
{
ImGui.OpenPopup("Ban User");
_banUserPopupOpen = true;
}
if (!_showModalBanUser) _banUserPopupOpen = false;
if (ImGui.BeginPopupModal("Ban User", ref _showModalBanUser, UiSharedService.PopupWindowFlags))
{
UiSharedService.TextWrapped("User " + (entry.UserAliasOrUID) + " will be banned and removed from this Syncshell.");
ImGui.InputTextWithHint("##banreason", "Ban Reason", ref _banReason, 255);
if (ImGui.Button("Ban User"))
{
ImGui.CloseCurrentPopup();
var reason = _banReason;
_ = ApiController.GroupBanUser(entry, reason);
_banReason = string.Empty;
}
UiSharedService.TextWrapped("The reason will be displayed in the banlist. The current server-side alias if present (Vanity ID) will automatically be attached to the reason.");
UiSharedService.SetScaledWindowSize(300);
ImGui.EndPopup();
}
}
}

View File

@@ -3,7 +3,6 @@ using Dalamud.Interface.Components;
using ImGuiNET;
using MareSynchronos.API.Data.Extensions;
using MareSynchronos.MareConfiguration;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.UI.Handlers;
using MareSynchronos.WebAPI;
@@ -12,58 +11,31 @@ namespace MareSynchronos.UI.Components;
public class PairGroupsUi
{
private readonly ApiController _apiController;
private readonly Action<Pair> _clientRenderFn;
private readonly MareConfigService _mareConfig;
private readonly SelectPairForGroupUi _selectGroupForPairUi;
private readonly TagHandler _tagHandler;
public PairGroupsUi(MareConfigService mareConfig, TagHandler tagHandler, Action<Pair> clientRenderFn, ApiController apiController, SelectPairForGroupUi selectGroupForPairUi)
public PairGroupsUi(MareConfigService mareConfig, TagHandler tagHandler, ApiController apiController, SelectPairForGroupUi selectGroupForPairUi)
{
_clientRenderFn = clientRenderFn;
_mareConfig = mareConfig;
_tagHandler = tagHandler;
_apiController = apiController;
_selectGroupForPairUi = selectGroupForPairUi;
}
public void Draw(List<Pair> visibleUsers, List<Pair> onlineUsers, List<Pair> offlineUsers)
public void Draw<T>(List<T> visibleUsers, List<T> onlineUsers, List<T> offlineUsers) where T : DrawPairBase
{
// Only render those tags that actually have pairs in them, otherwise
// we can end up with a bunch of useless pair groups
var tagsWithPairsInThem = _tagHandler.GetAllTagsSorted();
var allUsers = visibleUsers.Concat(onlineUsers).Concat(offlineUsers).ToList();
if (_mareConfig.Current.ShowVisibleUsersSeparately)
if (typeof(T) == typeof(DrawUserPair))
{
UiSharedService.DrawWithID("$group-VisibleCustomTag", () => DrawCategory(TagHandler.CustomVisibleTag, visibleUsers, allUsers));
DrawUserPairs(tagsWithPairsInThem, allUsers.Cast<DrawUserPair>().ToList(), visibleUsers.Cast<DrawUserPair>(), onlineUsers.Cast<DrawUserPair>(), offlineUsers.Cast<DrawUserPair>());
}
foreach (var tag in tagsWithPairsInThem)
{
if (_mareConfig.Current.ShowOfflineUsersSeparately)
{
UiSharedService.DrawWithID($"group-{tag}", () => DrawCategory(tag, onlineUsers, allUsers, visibleUsers));
}
else
{
UiSharedService.DrawWithID($"group-{tag}", () => DrawCategory(tag, onlineUsers.Concat(offlineUsers).ToList(), allUsers, visibleUsers));
}
}
if (_mareConfig.Current.ShowOfflineUsersSeparately)
{
UiSharedService.DrawWithID($"group-OnlineCustomTag", () => DrawCategory(TagHandler.CustomOnlineTag,
onlineUsers.Where(u => !_tagHandler.HasAnyTag(u.UserPair!)).ToList(), allUsers));
UiSharedService.DrawWithID($"group-OfflineCustomTag", () => DrawCategory(TagHandler.CustomOfflineTag,
offlineUsers.Where(u => u.UserPair!.OtherPermissions.IsPaired()).ToList(), allUsers));
}
else
{
UiSharedService.DrawWithID($"group-OnlineCustomTag", () => DrawCategory(TagHandler.CustomOnlineTag,
onlineUsers.Concat(offlineUsers).Where(u => u.UserPair!.OtherPermissions.IsPaired() && !_tagHandler.HasAnyTag(u.UserPair!)).ToList(), allUsers));
}
UiSharedService.DrawWithID($"group-UnpairedCustomTag", () => DrawCategory(TagHandler.CustomUnpairedTag,
offlineUsers.Where(u => !u.UserPair!.OtherPermissions.IsPaired()).ToList(), allUsers));
}
private void DrawButtons(string tag, List<Pair> availablePairsInThisTag)
private void DrawButtons(string tag, List<DrawUserPair> availablePairsInThisTag)
{
var allArePaused = availablePairsInThisTag.All(pair => pair.UserPair!.OwnPermissions.IsPaused());
var pauseButton = allArePaused ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
@@ -114,9 +86,9 @@ public class PairGroupsUi
}
}
private void DrawCategory(string tag, List<Pair> onlineUsers, List<Pair> allUsers, List<Pair>? visibleUsers = null)
private void DrawCategory(string tag, IEnumerable<DrawPairBase> onlineUsers, IEnumerable<DrawPairBase> allUsers, IEnumerable<DrawPairBase>? visibleUsers = null)
{
List<Pair> usersInThisTag;
IEnumerable<DrawPairBase> usersInThisTag;
HashSet<string>? otherUidsTaggedWithTag = null;
bool isSpecialTag = false;
int visibleInThisTag = 0;
@@ -129,16 +101,21 @@ public class PairGroupsUi
{
otherUidsTaggedWithTag = _tagHandler.GetOtherUidsForTag(tag);
usersInThisTag = onlineUsers
.Where(pair => otherUidsTaggedWithTag.Contains(pair.UserData.UID))
.Where(pair => otherUidsTaggedWithTag.Contains(pair.UID))
.ToList();
visibleInThisTag = visibleUsers?.Count(p => otherUidsTaggedWithTag.Contains(p.UserData.UID)) ?? 0;
visibleInThisTag = visibleUsers?.Count(p => otherUidsTaggedWithTag.Contains(p.UID)) ?? 0;
}
if (isSpecialTag && !usersInThisTag.Any()) return;
DrawName(tag, isSpecialTag, visibleInThisTag, usersInThisTag.Count, otherUidsTaggedWithTag?.Count);
DrawName(tag, isSpecialTag, visibleInThisTag, usersInThisTag.Count(), otherUidsTaggedWithTag?.Count);
if (!isSpecialTag)
UiSharedService.DrawWithID($"group-{tag}-buttons", () => DrawButtons(tag, allUsers.Where(p => otherUidsTaggedWithTag!.Contains(p.UserData.UID)).ToList()));
{
if (onlineUsers.First() is DrawUserPair)
{
UiSharedService.DrawWithID($"group-{tag}-buttons", () => DrawButtons(tag, allUsers.Cast<DrawUserPair>().Where(p => otherUidsTaggedWithTag!.Contains(p.UID)).ToList()));
}
}
if (!_tagHandler.IsTagOpen(tag)) return;
@@ -201,31 +178,66 @@ public class PairGroupsUi
}
}
private void DrawPairs(string tag, List<Pair> availablePairsInThisCategory)
private void DrawPairs(string tag, IEnumerable<DrawPairBase> availablePairsInThisCategory)
{
// These are all the OtherUIDs that are tagged with this tag
availablePairsInThisCategory
.ForEach(pair => UiSharedService.DrawWithID($"tag-{tag}-pair-${pair.UserData.UID}", () => _clientRenderFn(pair)));
foreach (var pair in availablePairsInThisCategory)
{
UiSharedService.DrawWithID($"tag-{tag}-pair-${pair.UID}", () => pair.DrawPairedClient());
}
ImGui.Separator();
}
private void PauseRemainingPairs(List<Pair> availablePairs)
private void DrawUserPairs(List<string> tagsWithPairsInThem, List<DrawUserPair> allUsers, IEnumerable<DrawUserPair> visibleUsers, IEnumerable<DrawUserPair> onlineUsers, IEnumerable<DrawUserPair> offlineUsers)
{
if (_mareConfig.Current.ShowVisibleUsersSeparately)
{
UiSharedService.DrawWithID("$group-VisibleCustomTag", () => DrawCategory(TagHandler.CustomVisibleTag, visibleUsers, allUsers));
}
foreach (var tag in tagsWithPairsInThem)
{
if (_mareConfig.Current.ShowOfflineUsersSeparately)
{
UiSharedService.DrawWithID($"group-{tag}", () => DrawCategory(tag, onlineUsers, allUsers, visibleUsers));
}
else
{
UiSharedService.DrawWithID($"group-{tag}", () => DrawCategory(tag, onlineUsers.Concat(offlineUsers).ToList(), allUsers, visibleUsers));
}
}
if (_mareConfig.Current.ShowOfflineUsersSeparately)
{
UiSharedService.DrawWithID($"group-OnlineCustomTag", () => DrawCategory(TagHandler.CustomOnlineTag,
onlineUsers.Where(u => !_tagHandler.HasAnyTag(u.UID)).ToList(), allUsers));
UiSharedService.DrawWithID($"group-OfflineCustomTag", () => DrawCategory(TagHandler.CustomOfflineTag,
offlineUsers.Where(u => u.UserPair!.OtherPermissions.IsPaired()).ToList(), allUsers));
}
else
{
UiSharedService.DrawWithID($"group-OnlineCustomTag", () => DrawCategory(TagHandler.CustomOnlineTag,
onlineUsers.Concat(offlineUsers).Where(u => u.UserPair!.OtherPermissions.IsPaired() && !_tagHandler.HasAnyTag(u.UID)).ToList(), allUsers));
}
UiSharedService.DrawWithID($"group-UnpairedCustomTag", () => DrawCategory(TagHandler.CustomUnpairedTag,
offlineUsers.Where(u => !u.UserPair!.OtherPermissions.IsPaired()).ToList(), allUsers));
}
private void PauseRemainingPairs(List<DrawUserPair> availablePairs)
{
foreach (var pairToPause in availablePairs.Where(pair => !pair.UserPair!.OwnPermissions.IsPaused()))
{
var perm = pairToPause.UserPair!.OwnPermissions;
perm.SetPaused(paused: true);
_ = _apiController.UserSetPairPermissions(new(pairToPause.UserData, perm));
_ = _apiController.UserSetPairPermissions(new(new(pairToPause.UID), perm));
}
}
private void ResumeAllPairs(List<Pair> availablePairs)
private void ResumeAllPairs(List<DrawUserPair> availablePairs)
{
foreach (var pairToPause in availablePairs)
{
var perm = pairToPause.UserPair!.OwnPermissions;
perm.SetPaused(paused: false);
_ = _apiController.UserSetPairPermissions(new(pairToPause.UserData, perm));
_ = _apiController.UserSetPairPermissions(new(new(pairToPause.UID), perm));
}
}

View File

@@ -11,6 +11,7 @@ namespace MareSynchronos.UI.Components;
public class SelectGroupForPairUi
{
private readonly TagHandler _tagHandler;
private readonly UidDisplayHandler _uidDisplayHandler;
/// <summary>
/// The group UI is always open for a specific pair. This defines which pair the UI is open for.
@@ -28,21 +29,22 @@ public class SelectGroupForPairUi
/// </summary>
private string _tagNameToAdd = "";
public SelectGroupForPairUi(TagHandler tagHandler)
public SelectGroupForPairUi(TagHandler tagHandler, UidDisplayHandler uidDisplayHandler)
{
_show = false;
_pair = null;
_tagHandler = tagHandler;
_uidDisplayHandler = uidDisplayHandler;
}
public void Draw(Dictionary<string, bool> showUidForEntry)
public void Draw()
{
if (_pair == null)
{
return;
}
var name = PairName(showUidForEntry, _pair);
var name = PairName(_pair);
var popupName = $"Choose Groups for {name}";
// Is the popup supposed to show but did not open yet? Open it
if (_show)
@@ -93,30 +95,19 @@ public class SelectGroupForPairUi
_show = true;
}
private static string PairName(Dictionary<string, bool> showUidForEntry, Pair pair)
{
showUidForEntry.TryGetValue(pair.UserData.UID, out var showUidInsteadOfName);
var playerText = pair.GetNote();
if (showUidInsteadOfName || string.IsNullOrEmpty(playerText))
{
playerText = pair.UserData.AliasOrUID;
}
return playerText;
}
private void DrawGroupName(Pair pair, string name)
{
var hasTagBefore = _tagHandler.HasTag(pair.UserPair!, name);
var hasTagBefore = _tagHandler.HasTag(pair.UserData.UID, name);
var hasTag = hasTagBefore;
if (ImGui.Checkbox(name, ref hasTag))
{
if (hasTag)
{
_tagHandler.AddTagToPairedUid(pair.UserPair!, name);
_tagHandler.AddTagToPairedUid(pair.UserData.UID, name);
}
else
{
_tagHandler.RemoveTagFromPairedUid(pair.UserPair!, name);
_tagHandler.RemoveTagFromPairedUid(pair.UserData.UID, name);
}
}
}
@@ -128,7 +119,7 @@ public class SelectGroupForPairUi
_tagHandler.AddTag(_tagNameToAdd);
if (_pair != null)
{
_tagHandler.AddTagToPairedUid(_pair.UserPair!, _tagNameToAdd);
_tagHandler.AddTagToPairedUid(_pair.UserData.UID, _tagNameToAdd);
}
_tagNameToAdd = string.Empty;
}
@@ -137,4 +128,9 @@ public class SelectGroupForPairUi
_tagNameToAdd = string.Empty;
}
}
private string PairName(Pair pair)
{
return _uidDisplayHandler.GetPlayerText(pair).text;
}
}

View File

@@ -9,18 +9,20 @@ namespace MareSynchronos.UI.Components;
public class SelectPairForGroupUi
{
private readonly TagHandler _tagHandler;
private readonly UidDisplayHandler _uidDisplayHandler;
private string _filter = string.Empty;
private bool _opened = false;
private HashSet<string> _peopleInGroup = new(StringComparer.Ordinal);
private bool _show = false;
private string _tag = string.Empty;
public SelectPairForGroupUi(TagHandler tagHandler)
public SelectPairForGroupUi(TagHandler tagHandler, UidDisplayHandler uidDisplayHandler)
{
_tagHandler = tagHandler;
_uidDisplayHandler = uidDisplayHandler;
}
public void Draw(List<Pair> pairs, Dictionary<string, bool> showUidForEntry)
public void Draw(List<Pair> pairs)
{
var workHeight = ImGui.GetMainViewport().WorkSize.Y / ImGuiHelpers.GlobalScale;
var minSize = new Vector2(300, workHeight < 400 ? workHeight : 400) * ImGuiHelpers.GlobalScale;
@@ -47,21 +49,21 @@ public class SelectPairForGroupUi
UiSharedService.FontText($"Select users for group {_tag}", UiBuilder.DefaultFont);
ImGui.InputTextWithHint("##filter", "Filter", ref _filter, 255, ImGuiInputTextFlags.None);
foreach (var item in pairs
.Where(p => string.IsNullOrEmpty(_filter) || PairName(showUidForEntry, p).Contains(_filter, StringComparison.OrdinalIgnoreCase))
.OrderBy(p => PairName(showUidForEntry, p), StringComparer.OrdinalIgnoreCase)
.Where(p => string.IsNullOrEmpty(_filter) || PairName(p).Contains(_filter, StringComparison.OrdinalIgnoreCase))
.OrderBy(p => PairName(p), StringComparer.OrdinalIgnoreCase)
.ToList())
{
var isInGroup = _peopleInGroup.Contains(item.UserData.UID);
if (ImGui.Checkbox(PairName(showUidForEntry, item), ref isInGroup))
if (ImGui.Checkbox(PairName(item), ref isInGroup))
{
if (isInGroup)
{
_tagHandler.AddTagToPairedUid(item.UserPair!, _tag);
_tagHandler.AddTagToPairedUid(item.UserData.UID, _tag);
_peopleInGroup.Add(item.UserData.UID);
}
else
{
_tagHandler.RemoveTagFromPairedUid(item.UserPair!, _tag);
_tagHandler.RemoveTagFromPairedUid(item.UserData.UID, _tag);
_peopleInGroup.Remove(item.UserData.UID);
}
}
@@ -82,14 +84,8 @@ public class SelectPairForGroupUi
_show = true;
}
private static string PairName(Dictionary<string, bool> showUidForEntry, Pair pair)
private string PairName(Pair pair)
{
showUidForEntry.TryGetValue(pair.UserData.UID, out var showUidInsteadOfName);
var playerText = pair.GetNote();
if (showUidInsteadOfName || string.IsNullOrEmpty(playerText))
{
playerText = pair.UserData.AliasOrUID;
}
return playerText;
return _uidDisplayHandler.GetPlayerText(pair).text;
}
}

View File

@@ -46,7 +46,7 @@ public class GposeUi : WindowMediatorSubscriberBase
_fileDialogManager.OpenFileDialog("Pick MCDF file", ".mcdf", (success, paths) =>
{
if (!success) return;
if (paths.FirstOrDefault() is not { } path) return;
if (paths.FirstOrDefault() is not string path) return;
_configService.Current.ExportFolder = Path.GetDirectoryName(path) ?? string.Empty;
_configService.Save();

View File

@@ -21,9 +21,9 @@ public class TagHandler
_serverConfigurationManager.AddTag(tag);
}
public void AddTagToPairedUid(UserPairDto pair, string tagName)
public void AddTagToPairedUid(string uid, string tagName)
{
_serverConfigurationManager.AddTagForUid(pair.User.UID, tagName);
_serverConfigurationManager.AddTagForUid(uid, tagName);
}
public List<string> GetAllTagsSorted()
@@ -38,14 +38,14 @@ public class TagHandler
return _serverConfigurationManager.GetUidsForTag(tag);
}
public bool HasAnyTag(UserPairDto pair)
public bool HasAnyTag(string uid)
{
return _serverConfigurationManager.HasTags(pair.User.UID);
return _serverConfigurationManager.HasTags(uid);
}
public bool HasTag(UserPairDto pair, string tagName)
public bool HasTag(string uid, string tagName)
{
return _serverConfigurationManager.ContainsTag(pair.User.UID, tagName);
return _serverConfigurationManager.ContainsTag(uid, tagName);
}
/// <summary>
@@ -64,9 +64,9 @@ public class TagHandler
_serverConfigurationManager.RemoveTag(tag);
}
public void RemoveTagFromPairedUid(UserPairDto pair, string tagName)
public void RemoveTagFromPairedUid(string uid, string tagName)
{
_serverConfigurationManager.RemoveTagForUid(pair.User.UID, tagName);
_serverConfigurationManager.RemoveTagForUid(uid, tagName);
}
public void SetTagOpen(string tag, bool open)

View File

@@ -0,0 +1,117 @@
using Dalamud.Interface;
using ImGuiNET;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.Services.ServerConfiguration;
using MareSynchronos.MareConfiguration;
namespace MareSynchronos.UI.Handlers;
public class UidDisplayHandler
{
private readonly MareConfigService _mareConfigService;
private readonly PairManager _pairManager;
private readonly ServerConfigurationManager _serverManager;
private readonly Dictionary<string, bool> _showUidForEntry = new(StringComparer.Ordinal);
private string _editNickEntry = string.Empty;
private string _editUserComment = string.Empty;
public UidDisplayHandler(PairManager pairManager, ServerConfigurationManager serverManager, MareConfigService mareConfigService)
{
_pairManager = pairManager;
_serverManager = serverManager;
_mareConfigService = mareConfigService;
}
public void DrawPairText(Pair entry, float textPosX, float originalY, Func<float> editBoxWidth)
{
ImGui.SameLine(textPosX);
(bool textIsUid, string playerText) = GetPlayerText(entry);
if (!string.Equals(_editNickEntry, entry.UserData.UID, StringComparison.Ordinal))
{
ImGui.SetCursorPosY(originalY);
if (textIsUid) ImGui.PushFont(UiBuilder.MonoFont);
ImGui.TextUnformatted(playerText);
if (textIsUid) ImGui.PopFont();
UiSharedService.AttachToolTip("Left click to switch between UID display and nick" + Environment.NewLine +
"Right click to change nick for " + entry.UserData.UID);
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
{
var prevState = textIsUid;
if (_showUidForEntry.ContainsKey(entry.UserData.UID))
{
prevState = _showUidForEntry[entry.UserData.UID];
}
_showUidForEntry[entry.UserData.UID] = !prevState;
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
var pair = _pairManager.DirectPairs.Find(p => string.Equals(p.UserData.UID, _editNickEntry, StringComparison.Ordinal));
pair?.SetNote(_editUserComment);
_editUserComment = entry.GetNote() ?? string.Empty;
_editNickEntry = entry.UserData.UID;
}
}
else
{
ImGui.SetCursorPosY(originalY);
ImGui.SetNextItemWidth(editBoxWidth.Invoke());
if (ImGui.InputTextWithHint("", "Nick/Notes", ref _editUserComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
{
_serverManager.SetNoteForUid(entry.UserData.UID, _editUserComment);
_serverManager.SaveNotes();
_editNickEntry = string.Empty;
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
_editNickEntry = string.Empty;
}
UiSharedService.AttachToolTip("Hit ENTER to save\nRight click to cancel");
}
}
public (bool isUid, string text) GetPlayerText(Pair pair)
{
var textIsUid = true;
bool showUidInsteadOfName = ShowUidInsteadOfName(pair);
string? playerText = _serverManager.GetNoteForUid(pair.UserData.UID);
if (!showUidInsteadOfName && playerText != null)
{
if (string.IsNullOrEmpty(playerText))
{
playerText = pair.UserData.UID;
}
else
{
textIsUid = false;
}
}
else
{
playerText = pair.UserData.UID;
}
if (_mareConfigService.Current.ShowCharacterNameInsteadOfNotesForVisible && pair.IsVisible && !showUidInsteadOfName)
{
playerText = pair.PlayerName;
textIsUid = false;
}
return (textIsUid, playerText!);
}
internal void Clear()
{
_editNickEntry = string.Empty;
_editUserComment = string.Empty;
}
private bool ShowUidInsteadOfName(Pair pair)
{
_showUidForEntry.TryGetValue(pair.UserData.UID, out var showUidInsteadOfName);
return showUidInsteadOfName;
}
}