378 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			378 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 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;
 | |
| using MareSynchronos.Services.Mediator;
 | |
| using Dalamud.Interface.Utility;
 | |
| using MareSynchronos.UI.Components.Popup;
 | |
| using MareSynchronos.Services;
 | |
| 
 | |
| namespace MareSynchronos.UI.Components;
 | |
| 
 | |
| public class DrawGroupPair : DrawPairBase
 | |
| {
 | |
|     protected readonly MareMediator _mediator;
 | |
|     private readonly GroupPairFullInfoDto _fullInfoDto;
 | |
|     private readonly GroupFullInfoDto _group;
 | |
|     private readonly CharaDataManager _charaDataManager;
 | |
| 
 | |
|     public DrawGroupPair(string id, Pair entry, ApiController apiController,
 | |
|         MareMediator mareMediator, GroupFullInfoDto group, GroupPairFullInfoDto fullInfoDto,
 | |
|         UidDisplayHandler handler, UiSharedService uiSharedService, CharaDataManager charaDataManager)
 | |
|         : base(id, entry, apiController, handler, uiSharedService)
 | |
|     {
 | |
|         _group = group;
 | |
|         _fullInfoDto = fullInfoDto;
 | |
|         _mediator = mareMediator;
 | |
|         _charaDataManager = charaDataManager;
 | |
|     }
 | |
| 
 | |
|     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 + Environment.NewLine + "Click to target this player";
 | |
| 
 | |
|         ImGui.SameLine();
 | |
|         ImGui.SetCursorPosY(textPosY);
 | |
|         ImGui.PushFont(UiBuilder.IconFont);
 | |
|         UiSharedService.ColorText(presenceIcon.ToIconString(), presenceColor);
 | |
|         ImGui.PopFont();
 | |
|         if (_pair.IsVisible)
 | |
|         {
 | |
|             if (ImGui.IsItemClicked())
 | |
|             {
 | |
|                 _mediator.Publish(new TargetPairMessage(_pair));
 | |
|             }
 | |
|             if (_pair.LastAppliedDataBytes >= 0)
 | |
|             {
 | |
|                 presenceText += UiSharedService.TooltipSeparator;
 | |
|                 presenceText += ((!_pair.IsVisible) ? "(Last) " : string.Empty) + "Mods Info" + Environment.NewLine;
 | |
|                 presenceText += "Files Size: " + UiSharedService.ByteToString(_pair.LastAppliedDataBytes, true);
 | |
|                 if (_pair.LastAppliedApproximateVRAMBytes >= 0)
 | |
|                 {
 | |
|                     presenceText += Environment.NewLine + "Approx. VRAM Usage: " + UiSharedService.ByteToString(_pair.LastAppliedApproximateVRAMBytes, true);
 | |
|                 }
 | |
|                 if (_pair.LastAppliedDataTris >= 0)
 | |
|                 {
 | |
|                     presenceText += Environment.NewLine + "Triangle Count (excl. Vanilla): "
 | |
|                         + (_pair.LastAppliedDataTris > 1000 ? (_pair.LastAppliedDataTris / 1000d).ToString("0.0'k'") : _pair.LastAppliedDataTris);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         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 vfxDisabled = _fullInfoDto.GroupUserPermissions.IsDisableVFX();
 | |
|         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 individualVFXDisabled = (_pair.UserPair?.OwnPermissions.IsDisableVFX() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableVFX() ?? false);
 | |
| 
 | |
|         bool showShared = _charaDataManager.SharedWithYouData.TryGetValue(_pair.UserData, out var sharedData);
 | |
|         bool showInfo = (individualAnimDisabled || individualSoundsDisabled || animDisabled || soundsDisabled);
 | |
|         bool showPlus = _pair.UserPair == null;
 | |
|         bool showBars = (userIsOwner || (userIsModerator && !entryIsMod && !entryIsOwner)) || !_pair.IsPaused;
 | |
| 
 | |
|         var spacing = ImGui.GetStyle().ItemSpacing.X;
 | |
|         var permIcon = (individualAnimDisabled || individualSoundsDisabled || individualVFXDisabled) ? FontAwesomeIcon.ExclamationTriangle
 | |
|             : ((soundsDisabled || animDisabled || vfxDisabled) ? FontAwesomeIcon.InfoCircle : FontAwesomeIcon.None);
 | |
|         var runningIconWidth = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.Running).X;
 | |
|         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
 | |
|             - (showShared ? (runningIconWidth + spacing) : 0)
 | |
|             - (showInfo ? (infoIconWidth + spacing) : 0)
 | |
|             - (showPlus ? (plusButtonWidth + spacing) : 0)
 | |
|             - (showBars ? (barButtonWidth + spacing) : 0);
 | |
| 
 | |
|         ImGui.SameLine(pos);
 | |
| 
 | |
|         if (showShared)
 | |
|         {
 | |
|             _uiSharedService.IconText(FontAwesomeIcon.Running);
 | |
| 
 | |
|             UiSharedService.AttachToolTip($"This user has shared {sharedData!.Count} Character Data Sets with you." + UiSharedService.TooltipSeparator
 | |
|                 + "Click to open the Character Data Hub and show the entries.");
 | |
| 
 | |
|             if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
 | |
|             {
 | |
|                 _mediator.Publish(new OpenCharaDataHubWithFilterMessage(_pair.UserData));
 | |
|             }
 | |
|             ImGui.SameLine();
 | |
|         }
 | |
| 
 | |
|         if (individualAnimDisabled || individualSoundsDisabled)
 | |
|         {
 | |
|             ImGui.SetCursorPosY(textPosY);
 | |
|             ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudYellow);
 | |
|             _uiSharedService.IconText(permIcon);
 | |
|             ImGui.PopStyleColor();
 | |
|             if (ImGui.IsItemHovered())
 | |
|             {
 | |
|                 ImGui.BeginTooltip();
 | |
| 
 | |
|                 ImGui.TextUnformatted("Individual User permissions");
 | |
| 
 | |
|                 if (individualSoundsDisabled)
 | |
|                 {
 | |
|                     var userSoundsText = "Sound sync disabled with " + _pair.UserData.AliasOrUID;
 | |
|                     _uiSharedService.IconText(FontAwesomeIcon.VolumeOff);
 | |
|                     ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
 | |
|                     ImGui.TextUnformatted(userSoundsText);
 | |
|                     ImGui.NewLine();
 | |
|                     ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
 | |
|                     ImGui.TextUnformatted("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.IconText(FontAwesomeIcon.Stop);
 | |
|                     ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
 | |
|                     ImGui.TextUnformatted(userAnimText);
 | |
|                     ImGui.NewLine();
 | |
|                     ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
 | |
|                     ImGui.TextUnformatted("You: " + (_pair.UserPair!.OwnPermissions.IsDisableAnimations() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableAnimations() ? "Disabled" : "Enabled"));
 | |
|                 }
 | |
| 
 | |
|                 if (individualVFXDisabled)
 | |
|                 {
 | |
|                     var userVFXText = "VFX sync disabled with " + _pair.UserData.AliasOrUID;
 | |
|                     _uiSharedService.IconText(FontAwesomeIcon.Circle);
 | |
|                     ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
 | |
|                     ImGui.TextUnformatted(userVFXText);
 | |
|                     ImGui.NewLine();
 | |
|                     ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
 | |
|                     ImGui.TextUnformatted("You: " + (_pair.UserPair!.OwnPermissions.IsDisableVFX() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableVFX() ? "Disabled" : "Enabled"));
 | |
|                 }
 | |
| 
 | |
|                 ImGui.EndTooltip();
 | |
|             }
 | |
|             ImGui.SameLine();
 | |
|         }
 | |
|         else if ((animDisabled || soundsDisabled))
 | |
|         {
 | |
|             ImGui.SetCursorPosY(textPosY);
 | |
|             _uiSharedService.IconText(permIcon);
 | |
|             if (ImGui.IsItemHovered())
 | |
|             {
 | |
|                 ImGui.BeginTooltip();
 | |
| 
 | |
|                 ImGui.TextUnformatted("Syncshell User permissions");
 | |
| 
 | |
|                 if (soundsDisabled)
 | |
|                 {
 | |
|                     var userSoundsText = "Sound sync disabled by " + _pair.UserData.AliasOrUID;
 | |
|                     _uiSharedService.IconText(FontAwesomeIcon.VolumeOff);
 | |
|                     ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
 | |
|                     ImGui.TextUnformatted(userSoundsText);
 | |
|                 }
 | |
| 
 | |
|                 if (animDisabled)
 | |
|                 {
 | |
|                     var userAnimText = "Animation sync disabled by " + _pair.UserData.AliasOrUID;
 | |
|                     _uiSharedService.IconText(FontAwesomeIcon.Stop);
 | |
|                     ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
 | |
|                     ImGui.TextUnformatted(userAnimText);
 | |
|                 }
 | |
| 
 | |
|                 if (vfxDisabled)
 | |
|                 {
 | |
|                     var userVFXText = "VFX sync disabled by " + _pair.UserData.AliasOrUID;
 | |
|                     _uiSharedService.IconText(FontAwesomeIcon.Circle);
 | |
|                     ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
 | |
|                     ImGui.TextUnformatted(userVFXText);
 | |
|                 }
 | |
| 
 | |
|                 ImGui.EndTooltip();
 | |
|             }
 | |
|             ImGui.SameLine();
 | |
|         }
 | |
| 
 | |
|         if (showPlus)
 | |
|         {
 | |
|             ImGui.SetCursorPosY(originalY);
 | |
| 
 | |
|             if (_uiSharedService.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 (_uiSharedService.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"))
 | |
|                 {
 | |
|                     ImGui.CloseCurrentPopup();
 | |
|                     _mediator.Publish(new OpenBanUserPopupMessage(_pair, _group));
 | |
|                 }
 | |
|                 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.");
 | |
|             }
 | |
| 
 | |
|             if (userIsOwner || (userIsModerator && !(entryIsMod || entryIsOwner)))
 | |
|                 ImGui.Separator();
 | |
| 
 | |
|             if (_pair.IsVisible)
 | |
|             {
 | |
|                 if (_uiSharedService.IconTextButton(FontAwesomeIcon.Eye, "Target player"))
 | |
|                 {
 | |
|                     _mediator.Publish(new TargetPairMessage(_pair));
 | |
|                     ImGui.CloseCurrentPopup();
 | |
|                 }
 | |
|             }
 | |
|             if (!_pair.IsPaused)
 | |
|             {
 | |
|                 if (_uiSharedService.IconTextButton(FontAwesomeIcon.User, "Open Profile"))
 | |
|                 {
 | |
|                     _displayHandler.OpenProfile(_pair);
 | |
|                     ImGui.CloseCurrentPopup();
 | |
|                 }
 | |
|             }
 | |
|             if (_pair.IsVisible)
 | |
|             {
 | |
| #if DEBUG
 | |
|                 if (_uiSharedService.IconTextButton(FontAwesomeIcon.PersonCircleQuestion, "Open Analysis"))
 | |
|                 {
 | |
|                     _displayHandler.OpenAnalysis(_pair);
 | |
|                     ImGui.CloseCurrentPopup();
 | |
|                 }
 | |
| #endif
 | |
|                 if (_uiSharedService.IconTextButton(FontAwesomeIcon.Sync, "Reload last data"))
 | |
|                 {
 | |
|                     _pair.ApplyLastReceivedData(forced: true);
 | |
|                     ImGui.CloseCurrentPopup();
 | |
|                 }
 | |
|                 UiSharedService.AttachToolTip("This reapplies the last received character data to this character");
 | |
|             }
 | |
|             ImGui.EndPopup();
 | |
|         }
 | |
| 
 | |
|         return pos - spacing;
 | |
|     }
 | |
| } | 
