343 lines
18 KiB
C#
343 lines
18 KiB
C#
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Interface;
|
|
using Dalamud.Interface.Colors;
|
|
using Dalamud.Interface.Utility;
|
|
using Dalamud.Interface.Utility.Raii;
|
|
using MareSynchronos.API.Data.Extensions;
|
|
using MareSynchronos.API.Dto.User;
|
|
using MareSynchronos.Localization;
|
|
using MareSynchronos.PlayerData.Pairs;
|
|
using MareSynchronos.Services;
|
|
using MareSynchronos.Services.Mediator;
|
|
using MareSynchronos.UI.Handlers;
|
|
using MareSynchronos.WebAPI;
|
|
using System.Numerics;
|
|
using System.Globalization;
|
|
using System;
|
|
|
|
namespace MareSynchronos.UI.Components;
|
|
|
|
public class DrawUserPair : DrawPairBase
|
|
{
|
|
private static readonly Vector4 Violet = new(0.63f, 0.25f, 1f, 1f);
|
|
protected readonly MareMediator _mediator;
|
|
private readonly SelectGroupForPairUi _selectGroupForPairUi;
|
|
private readonly CharaDataManager _charaDataManager;
|
|
|
|
private static string L(string key, string fallback, params object[] args)
|
|
{
|
|
var safeArgs = args ?? Array.Empty<object>();
|
|
return LocalizationService.Instance?.GetString(key, fallback, safeArgs)
|
|
?? string.Format(CultureInfo.CurrentCulture, fallback, safeArgs);
|
|
}
|
|
|
|
public DrawUserPair(string id, Pair entry, UidDisplayHandler displayHandler, ApiController apiController,
|
|
MareMediator mareMediator, SelectGroupForPairUi selectGroupForPairUi,
|
|
UiSharedService uiSharedService, CharaDataManager charaDataManager)
|
|
: base(id, entry, apiController, displayHandler, uiSharedService)
|
|
{
|
|
if (_pair.UserPair == null) throw new ArgumentException("Pair must be UserPair", nameof(entry));
|
|
_pair = entry;
|
|
_selectGroupForPairUi = selectGroupForPairUi;
|
|
_mediator = mareMediator;
|
|
_charaDataManager = charaDataManager;
|
|
}
|
|
|
|
public bool IsOnline => _pair.IsOnline;
|
|
public bool IsVisible => _pair.IsVisible;
|
|
public UserPairDto UserPair => _pair.UserPair!;
|
|
|
|
protected override void DrawLeftSide(float textPosY, float originalY)
|
|
{
|
|
var online = _pair.IsOnline;
|
|
var offlineGrey = ImGuiColors.DalamudGrey3;
|
|
|
|
ImGui.SetCursorPosY(textPosY);
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
UiSharedService.ColorText(FontAwesomeIcon.Moon.ToIconString(), online ? Violet : offlineGrey);
|
|
ImGui.PopFont();
|
|
UiSharedService.AttachToolTip(online
|
|
? L("UserPair.Status.Online", "User is online")
|
|
: L("UserPair.Status.Offline", "User is offline"));
|
|
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(L("UserPair.Tooltip.NotAddedBack", "{0} has not added you back", _pair.UserData.AliasOrUID));
|
|
}
|
|
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(L("UserPair.Tooltip.Paused", "Pairing with {0} is paused", _pair.UserData.AliasOrUID));
|
|
}
|
|
if (_pair is { IsOnline: true, IsVisible: true })
|
|
{
|
|
ImGui.SameLine();
|
|
ImGui.SetCursorPosY(textPosY);
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
UiSharedService.ColorText(FontAwesomeIcon.Eye.ToIconString(), Violet);
|
|
if (ImGui.IsItemClicked())
|
|
{
|
|
_mediator.Publish(new TargetPairMessage(_pair));
|
|
}
|
|
ImGui.PopFont();
|
|
var visibleTooltip = L("UserPair.Tooltip.Visible", "{0} is visible: {1}\nClick to target this player", _pair.UserData.AliasOrUID, _pair.PlayerName!);
|
|
if (_pair.LastAppliedDataBytes >= 0)
|
|
{
|
|
visibleTooltip += UiSharedService.TooltipSeparator;
|
|
visibleTooltip += (!_pair.IsVisible ? L("UserPair.Tooltip.Visible.LastPrefix", "(Last) ") : string.Empty)
|
|
+ L("UserPair.Tooltip.Visible.ModsInfo", "Mods Info") + Environment.NewLine;
|
|
visibleTooltip += L("UserPair.Tooltip.Visible.FilesSize", "Files Size: {0}", UiSharedService.ByteToString(_pair.LastAppliedDataBytes, true));
|
|
if (_pair.LastAppliedApproximateVRAMBytes >= 0)
|
|
{
|
|
visibleTooltip += Environment.NewLine + L("UserPair.Tooltip.Visible.Vram", "Approx. VRAM Usage: {0}", UiSharedService.ByteToString(_pair.LastAppliedApproximateVRAMBytes, true));
|
|
}
|
|
if (_pair.LastAppliedDataTris >= 0)
|
|
{
|
|
var trisValue = _pair.LastAppliedDataTris > 1000
|
|
? (_pair.LastAppliedDataTris / 1000d).ToString("0.0'k'", CultureInfo.CurrentCulture)
|
|
: _pair.LastAppliedDataTris.ToString(CultureInfo.CurrentCulture);
|
|
visibleTooltip += Environment.NewLine + L("UserPair.Tooltip.Visible.Tris", "Triangle Count (excl. Vanilla): {0}", trisValue);
|
|
}
|
|
}
|
|
|
|
UiSharedService.AttachToolTip(visibleTooltip);
|
|
}
|
|
}
|
|
|
|
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 rightSidePos = windowEndX - barButtonSize.X;
|
|
|
|
// Flyout Menu
|
|
ImGui.SameLine(rightSidePos);
|
|
ImGui.SetCursorPosY(originalY);
|
|
|
|
if (_uiSharedService.IconButton(FontAwesomeIcon.Bars))
|
|
{
|
|
ImGui.OpenPopup("User Flyout Menu");
|
|
}
|
|
if (ImGui.BeginPopup("User Flyout Menu"))
|
|
{
|
|
using (ImRaii.PushId($"buttons-{_pair.UserData.UID}")) DrawPairedClientMenu(_pair);
|
|
ImGui.EndPopup();
|
|
}
|
|
|
|
// Pause (mutual pairs only)
|
|
if (_pair.UserPair!.OwnPermissions.IsPaired() && _pair.UserPair!.OtherPermissions.IsPaired())
|
|
{
|
|
rightSidePos -= pauseIconSize.X + spacingX;
|
|
ImGui.SameLine(rightSidePos);
|
|
ImGui.SetCursorPosY(originalY);
|
|
if (_uiSharedService.IconButton(pauseIcon))
|
|
{
|
|
var perm = _pair.UserPair!.OwnPermissions;
|
|
perm.SetPaused(!perm.IsPaused());
|
|
_ = _apiController.UserSetPairPermissions(new(_pair.UserData, perm));
|
|
}
|
|
UiSharedService.AttachToolTip(!_pair.UserPair!.OwnPermissions.IsPaused()
|
|
? L("UserPair.Tooltip.Pause", "Pause pairing with {0}", entryUID)
|
|
: L("UserPair.Tooltip.Resume", "Resume pairing with {0}", entryUID));
|
|
|
|
|
|
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);
|
|
if (individualSoundsDisabled || individualAnimDisabled || individualVFXDisabled)
|
|
{
|
|
var icon = FontAwesomeIcon.ExclamationTriangle;
|
|
var iconwidth = _uiSharedService.GetIconButtonSize(icon);
|
|
|
|
rightSidePos -= iconwidth.X + spacingX / 2f;
|
|
ImGui.SameLine(rightSidePos);
|
|
|
|
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudYellow);
|
|
_uiSharedService.IconText(icon);
|
|
ImGui.PopStyleColor();
|
|
if (ImGui.IsItemHovered())
|
|
{
|
|
ImGui.BeginTooltip();
|
|
|
|
ImGui.TextUnformatted(L("UserPair.Tooltip.Permission.Header", "Individual user permissions"));
|
|
|
|
if (individualSoundsDisabled)
|
|
{
|
|
var userSoundsText = L("UserPair.Tooltip.Permission.Sound", "Sound sync disabled with {0}", _pair.UserData.AliasOrUID);
|
|
_uiSharedService.IconText(FontAwesomeIcon.VolumeOff);
|
|
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
|
ImGui.TextUnformatted(userSoundsText);
|
|
ImGui.NewLine();
|
|
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
|
var youStatus = _pair.UserPair!.OwnPermissions.IsDisableSounds()
|
|
? L("UserPair.Tooltip.Permission.State.Disabled", "Disabled")
|
|
: L("UserPair.Tooltip.Permission.State.Enabled", "Enabled");
|
|
var theyStatus = _pair.UserPair!.OtherPermissions.IsDisableSounds()
|
|
? L("UserPair.Tooltip.Permission.State.Disabled", "Disabled")
|
|
: L("UserPair.Tooltip.Permission.State.Enabled", "Enabled");
|
|
ImGui.TextUnformatted(L("UserPair.Tooltip.Permission.Status", "You: {0}, They: {1}", youStatus, theyStatus));
|
|
}
|
|
|
|
if (individualAnimDisabled)
|
|
{
|
|
var userAnimText = L("UserPair.Tooltip.Permission.Animation", "Animation sync disabled with {0}", _pair.UserData.AliasOrUID);
|
|
_uiSharedService.IconText(FontAwesomeIcon.Stop);
|
|
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
|
ImGui.TextUnformatted(userAnimText);
|
|
ImGui.NewLine();
|
|
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
|
var youStatus = _pair.UserPair!.OwnPermissions.IsDisableAnimations()
|
|
? L("UserPair.Tooltip.Permission.State.Disabled", "Disabled")
|
|
: L("UserPair.Tooltip.Permission.State.Enabled", "Enabled");
|
|
var theyStatus = _pair.UserPair!.OtherPermissions.IsDisableAnimations()
|
|
? L("UserPair.Tooltip.Permission.State.Disabled", "Disabled")
|
|
: L("UserPair.Tooltip.Permission.State.Enabled", "Enabled");
|
|
ImGui.TextUnformatted(L("UserPair.Tooltip.Permission.Status", "You: {0}, They: {1}", youStatus, theyStatus));
|
|
}
|
|
|
|
if (individualVFXDisabled)
|
|
{
|
|
var userVFXText = L("UserPair.Tooltip.Permission.Vfx", "VFX sync disabled with {0}", _pair.UserData.AliasOrUID);
|
|
_uiSharedService.IconText(FontAwesomeIcon.Circle);
|
|
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
|
ImGui.TextUnformatted(userVFXText);
|
|
ImGui.NewLine();
|
|
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
|
var youStatus = _pair.UserPair!.OwnPermissions.IsDisableVFX()
|
|
? L("UserPair.Tooltip.Permission.State.Disabled", "Disabled")
|
|
: L("UserPair.Tooltip.Permission.State.Enabled", "Enabled");
|
|
var theyStatus = _pair.UserPair!.OtherPermissions.IsDisableVFX()
|
|
? L("UserPair.Tooltip.Permission.State.Disabled", "Disabled")
|
|
: L("UserPair.Tooltip.Permission.State.Enabled", "Enabled");
|
|
ImGui.TextUnformatted(L("UserPair.Tooltip.Permission.Status", "You: {0}, They: {1}", youStatus, theyStatus));
|
|
}
|
|
|
|
ImGui.EndTooltip();
|
|
}
|
|
}
|
|
}
|
|
if (_charaDataManager.SharedWithYouData.TryGetValue(_pair.UserData, out var sharedData))
|
|
{
|
|
var icon = FontAwesomeIcon.Running;
|
|
var iconwidth = _uiSharedService.GetIconButtonSize(icon);
|
|
rightSidePos -= iconwidth.X + spacingX / 2f;
|
|
ImGui.SameLine(rightSidePos);
|
|
_uiSharedService.IconText(icon);
|
|
|
|
UiSharedService.AttachToolTip(L("UserPair.Tooltip.SharedData", "This user has shared {0} Character Data Sets with you.", sharedData.Count)
|
|
+ UiSharedService.TooltipSeparator
|
|
+ L("UserPair.Tooltip.SharedData.OpenHub", "Click to open the Character Data Hub and show the entries."));
|
|
|
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
|
{
|
|
_mediator.Publish(new OpenCharaDataHubWithFilterMessage(_pair.UserData));
|
|
}
|
|
}
|
|
|
|
return rightSidePos - spacingX;
|
|
}
|
|
|
|
private void DrawPairedClientMenu(Pair entry)
|
|
{
|
|
if (entry.IsVisible)
|
|
{
|
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.Eye, L("UserPair.Menu.Target", "Target player")))
|
|
{
|
|
_mediator.Publish(new TargetPairMessage(entry));
|
|
ImGui.CloseCurrentPopup();
|
|
}
|
|
}
|
|
if (!entry.IsPaused)
|
|
{
|
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.User, L("UserPair.Menu.OpenProfile", "Open Profile")))
|
|
{
|
|
_displayHandler.OpenProfile(entry);
|
|
ImGui.CloseCurrentPopup();
|
|
}
|
|
UiSharedService.AttachToolTip(L("UserPair.Menu.OpenProfile.Tooltip", "Opens the profile for this user in a new window"));
|
|
}
|
|
if (entry.IsVisible)
|
|
{
|
|
#if DEBUG
|
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.PersonCircleQuestion, L("UserPair.Menu.OpenAnalysis", "Open Analysis")))
|
|
{
|
|
_displayHandler.OpenAnalysis(_pair);
|
|
ImGui.CloseCurrentPopup();
|
|
}
|
|
#endif
|
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.Sync, L("UserPair.Menu.ReloadData", "Reload last data")))
|
|
{
|
|
entry.ApplyLastReceivedData(forced: true);
|
|
ImGui.CloseCurrentPopup();
|
|
}
|
|
UiSharedService.AttachToolTip(L("UserPair.Menu.ReloadData.Tooltip", "This reapplies the last received character data to this character"));
|
|
}
|
|
|
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.PlayCircle, L("UserPair.Menu.CyclePause", "Cycle pause state")))
|
|
{
|
|
_ = _apiController.CyclePause(entry.UserData);
|
|
ImGui.CloseCurrentPopup();
|
|
}
|
|
var entryUID = entry.UserData.AliasOrUID;
|
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.Folder, L("UserPair.Menu.PairGroups", "Pair Groups")))
|
|
{
|
|
_selectGroupForPairUi.Open(entry);
|
|
}
|
|
UiSharedService.AttachToolTip(L("UserPair.Menu.PairGroups.Tooltip", "Choose pair groups for {0}", entryUID));
|
|
|
|
var isDisableSounds = entry.UserPair!.OwnPermissions.IsDisableSounds();
|
|
string disableSoundsText = isDisableSounds
|
|
? L("UserPair.Menu.EnableSoundSync", "Enable sound sync")
|
|
: L("UserPair.Menu.DisableSoundSync", "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
|
|
? L("UserPair.Menu.EnableAnimationSync", "Enable animation sync")
|
|
: L("UserPair.Menu.DisableAnimationSync", "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));
|
|
}
|
|
|
|
var isDisableVFX = entry.UserPair!.OwnPermissions.IsDisableVFX();
|
|
string disableVFXText = isDisableVFX
|
|
? L("UserPair.Menu.EnableVfxSync", "Enable VFX sync")
|
|
: L("UserPair.Menu.DisableVfxSync", "Disable VFX sync");
|
|
var disableVFXIcon = isDisableVFX ? FontAwesomeIcon.Sun : FontAwesomeIcon.Circle;
|
|
if (_uiSharedService.IconTextButton(disableVFXIcon, disableVFXText))
|
|
{
|
|
var permissions = entry.UserPair.OwnPermissions;
|
|
permissions.SetDisableVFX(!isDisableVFX);
|
|
_ = _apiController.UserSetPairPermissions(new UserPermissionsDto(entry.UserData, permissions));
|
|
}
|
|
|
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.Trash, L("UserPair.Menu.Unpair", "Unpair Permanently")) && UiSharedService.CtrlPressed())
|
|
{
|
|
_ = _apiController.UserRemovePair(new(entry.UserData));
|
|
}
|
|
UiSharedService.AttachToolTip(L("UserPair.Menu.Unpair.Tooltip", "Hold CTRL and click to unpair permanently from {0}", entryUID));
|
|
}
|
|
}
|