Mare 0.9 (#65)
* add jwt expiry * start of 0.9 api impl * some stuff idk * some more impl * some cleanup * remove grouppair, add configuration, rework some pair drawing stuff * do some stuff * rework some ui * I don't even know anymore * add cancellationtoken * token bla * ui fixes etc * probably individual adding/removing now working fully as expected * add working report popup * I guess it's more syncshell shit or so * popup shit idk * work out most of the syncshell bullshit I guess * delete some old crap * are we actually getting closer to the end * update pair info stuff * more fixes/adjustments, idk * refactor some things * some rework * some more cleanup * cleanup * make menu buttons w i d e * better icon text buttons * add all syncshell folder and ordering fixes --------- Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com>
This commit is contained in:
@@ -1,16 +1,12 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Numerics;
|
||||
using System.Reflection;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.API.Dto.User;
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.PlayerData.Handlers;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
@@ -23,6 +19,10 @@ using MareSynchronos.WebAPI.Files;
|
||||
using MareSynchronos.WebAPI.Files.Models;
|
||||
using MareSynchronos.WebAPI.SignalR.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Globalization;
|
||||
using System.Numerics;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MareSynchronos.UI;
|
||||
|
||||
@@ -33,18 +33,16 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
private readonly ApiController _apiController;
|
||||
private readonly MareConfigService _configService;
|
||||
private readonly ConcurrentDictionary<GameObjectHandler, Dictionary<string, FileDownloadStatus>> _currentDownloads = new();
|
||||
private readonly DrawEntityFactory _drawEntityFactory;
|
||||
private readonly FileUploadManager _fileTransferManager;
|
||||
private readonly GroupPanel _groupPanel;
|
||||
private readonly PairGroupsUi _pairGroupsUi;
|
||||
private readonly PairManager _pairManager;
|
||||
private readonly SelectGroupForPairUi _selectGroupForPairUi;
|
||||
private readonly SelectPairForGroupUi _selectPairsForGroupUi;
|
||||
private readonly SelectTagForPairUi _selectGroupForPairUi;
|
||||
private readonly SelectPairForTagUi _selectPairsForGroupUi;
|
||||
private readonly ServerConfigurationManager _serverManager;
|
||||
private readonly Stopwatch _timeout = new();
|
||||
private readonly UidDisplayHandler _uidDisplayHandler;
|
||||
private readonly TagHandler _tagHandler;
|
||||
private readonly UiSharedService _uiShared;
|
||||
private bool _buttonState;
|
||||
private string _characterOrCommentFilter = string.Empty;
|
||||
private List<IDrawFolder> _drawFolders;
|
||||
private Pair? _lastAddedUser;
|
||||
private string _lastAddedUserComment = string.Empty;
|
||||
private Vector2 _lastPosition = Vector2.One;
|
||||
@@ -52,11 +50,12 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
private string _pairToAdd = string.Empty;
|
||||
private int _secretKeyIdx = -1;
|
||||
private bool _showModalForUserAddition;
|
||||
private bool _showSyncShells;
|
||||
private bool _wasOpen;
|
||||
|
||||
public CompactUi(ILogger<CompactUi> logger, UiSharedService uiShared, MareConfigService configService, ApiController apiController, PairManager pairManager,
|
||||
ServerConfigurationManager serverManager, MareMediator mediator, FileUploadManager fileTransferManager, UidDisplayHandler uidDisplayHandler) : base(logger, mediator, "###MareSynchronosMainUI")
|
||||
ServerConfigurationManager serverManager, MareMediator mediator, FileUploadManager fileTransferManager,
|
||||
TagHandler tagHandler, DrawEntityFactory drawEntityFactory, SelectTagForPairUi selectTagForPairUi, SelectPairForTagUi selectPairForTagUi)
|
||||
: base(logger, mediator, "###MareSynchronosMainUI")
|
||||
{
|
||||
_uiShared = uiShared;
|
||||
_configService = configService;
|
||||
@@ -64,13 +63,12 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
_pairManager = pairManager;
|
||||
_serverManager = serverManager;
|
||||
_fileTransferManager = fileTransferManager;
|
||||
_uidDisplayHandler = uidDisplayHandler;
|
||||
var tagHandler = new TagHandler(_serverManager);
|
||||
_tagHandler = tagHandler;
|
||||
_drawEntityFactory = drawEntityFactory;
|
||||
_selectGroupForPairUi = selectTagForPairUi;
|
||||
_selectPairsForGroupUi = selectPairForTagUi;
|
||||
|
||||
_groupPanel = new(this, uiShared, _pairManager, uidDisplayHandler, _serverManager);
|
||||
_selectGroupForPairUi = new(tagHandler, uidDisplayHandler);
|
||||
_selectPairsForGroupUi = new(tagHandler, uidDisplayHandler);
|
||||
_pairGroupsUi = new(configService, tagHandler, apiController, _selectPairsForGroupUi);
|
||||
_drawFolders = GetDrawFolders().ToList();
|
||||
|
||||
#if DEBUG
|
||||
string dev = "Dev Build";
|
||||
@@ -87,6 +85,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
Mediator.Subscribe<CutsceneEndMessage>(this, (_) => UiSharedService_GposeEnd());
|
||||
Mediator.Subscribe<DownloadStartedMessage>(this, (msg) => _currentDownloads[msg.DownloadId] = msg.DownloadStatus);
|
||||
Mediator.Subscribe<DownloadFinishedMessage>(this, (msg) => _currentDownloads.TryRemove(msg.DownloadId, out _));
|
||||
Mediator.Subscribe<RefreshUiMessage>(this, (msg) => _drawFolders = GetDrawFolders().ToList());
|
||||
|
||||
Flags |= ImGuiWindowFlags.NoDocking;
|
||||
|
||||
@@ -107,8 +106,11 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
var unsupported = "UNSUPPORTED VERSION";
|
||||
var uidTextSize = ImGui.CalcTextSize(unsupported);
|
||||
ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMax().X + ImGui.GetWindowContentRegionMin().X) / 2 - uidTextSize.X / 2);
|
||||
ImGui.TextColored(ImGuiColors.DalamudRed, unsupported);
|
||||
if (_uiShared.UidFontBuilt) ImGui.PopFont();
|
||||
using (ImRaii.PushFont(_uiShared.UidFont, _uiShared.UidFontBuilt))
|
||||
{
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextColored(ImGuiColors.DalamudRed, unsupported);
|
||||
}
|
||||
UiSharedService.ColorTextWrapped($"Your Mare Synchronos installation is out of date, the current version is {ver.Major}.{ver.Minor}.{ver.Build}. " +
|
||||
$"It is highly recommended to keep Mare Synchronos up to date. Open /xlplugins and update the plugin.", ImGuiColors.DalamudRed);
|
||||
}
|
||||
@@ -116,55 +118,12 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
UiSharedService.DrawWithID("header", DrawUIDHeader);
|
||||
ImGui.Separator();
|
||||
UiSharedService.DrawWithID("serverstatus", DrawServerStatus);
|
||||
ImGui.Separator();
|
||||
|
||||
if (_apiController.ServerState is ServerState.Connected)
|
||||
{
|
||||
var hasShownSyncShells = _showSyncShells;
|
||||
UiSharedService.DrawWithID("pairlist", DrawPairList);
|
||||
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (!hasShownSyncShells)
|
||||
{
|
||||
ImGui.PushStyleColor(ImGuiCol.Button, ImGui.GetStyle().Colors[(int)ImGuiCol.ButtonHovered]);
|
||||
}
|
||||
if (ImGui.Button(FontAwesomeIcon.User.ToIconString(), new Vector2((UiSharedService.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X) / 2, 30 * ImGuiHelpers.GlobalScale)))
|
||||
{
|
||||
_showSyncShells = false;
|
||||
}
|
||||
if (!hasShownSyncShells)
|
||||
{
|
||||
ImGui.PopStyleColor();
|
||||
}
|
||||
ImGui.PopFont();
|
||||
UiSharedService.AttachToolTip("Individual pairs");
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (hasShownSyncShells)
|
||||
{
|
||||
ImGui.PushStyleColor(ImGuiCol.Button, ImGui.GetStyle().Colors[(int)ImGuiCol.ButtonHovered]);
|
||||
}
|
||||
if (ImGui.Button(FontAwesomeIcon.UserFriends.ToIconString(), new Vector2((UiSharedService.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X) / 2, 30 * ImGuiHelpers.GlobalScale)))
|
||||
{
|
||||
_showSyncShells = true;
|
||||
}
|
||||
if (hasShownSyncShells)
|
||||
{
|
||||
ImGui.PopStyleColor();
|
||||
}
|
||||
ImGui.PopFont();
|
||||
|
||||
UiSharedService.AttachToolTip("Syncshells");
|
||||
|
||||
ImGui.Separator();
|
||||
if (!hasShownSyncShells)
|
||||
{
|
||||
UiSharedService.DrawWithID("pairlist", DrawPairList);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiSharedService.DrawWithID("syncshells", _groupPanel.DrawSyncshells);
|
||||
}
|
||||
ImGui.Separator();
|
||||
UiSharedService.DrawWithID("transfers", DrawTransfers);
|
||||
TransferPartHeight = ImGui.GetCursorPosY() - TransferPartHeight;
|
||||
@@ -213,12 +172,6 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnClose()
|
||||
{
|
||||
_uidDisplayHandler.Clear();
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
private void DrawAddCharacter()
|
||||
{
|
||||
ImGui.Dummy(new(10));
|
||||
@@ -237,7 +190,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
|
||||
_serverManager.Save();
|
||||
|
||||
_ = _apiController.CreateConnections(forceGetToken: true);
|
||||
_ = _apiController.CreateConnections();
|
||||
}
|
||||
|
||||
_uiShared.DrawCombo("Secret Key##addCharacterSecretKey", keys, (f) => f.Value.FriendlyName, (f) => _secretKeyIdx = f.Key);
|
||||
@@ -250,18 +203,15 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
|
||||
private void DrawAddPair()
|
||||
{
|
||||
var buttonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Plus);
|
||||
ImGui.SetNextItemWidth(UiSharedService.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X - buttonSize.X);
|
||||
var buttonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.UserPlus);
|
||||
var usersButtonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Users);
|
||||
ImGui.SetNextItemWidth(UiSharedService.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X - buttonSize.X - ImGui.GetStyle().ItemSpacing.X - usersButtonSize.X);
|
||||
ImGui.InputTextWithHint("##otheruid", "Other players UID/Alias", ref _pairToAdd, 20);
|
||||
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() - buttonSize.X);
|
||||
var canAdd = !_pairManager.DirectPairs.Any(p => string.Equals(p.UserData.UID, _pairToAdd, StringComparison.Ordinal) || string.Equals(p.UserData.Alias, _pairToAdd, StringComparison.Ordinal));
|
||||
if (!canAdd)
|
||||
ImGui.SameLine();
|
||||
var alreadyExisting = _pairManager.DirectPairs.Exists(p => string.Equals(p.UserData.UID, _pairToAdd, StringComparison.Ordinal) || string.Equals(p.UserData.Alias, _pairToAdd, StringComparison.Ordinal));
|
||||
using (ImRaii.Disabled(alreadyExisting || string.IsNullOrEmpty(_pairToAdd)))
|
||||
{
|
||||
ImGuiComponents.DisabledButton(FontAwesomeIcon.Plus);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.UserPlus))
|
||||
{
|
||||
_ = _apiController.UserAddPair(new(new(_pairToAdd)));
|
||||
_pairToAdd = string.Empty;
|
||||
@@ -269,95 +219,48 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
UiSharedService.AttachToolTip("Pair with " + (_pairToAdd.IsNullOrEmpty() ? "other user" : _pairToAdd));
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Users))
|
||||
{
|
||||
ImGui.OpenPopup("Syncshell Menu");
|
||||
}
|
||||
UiSharedService.AttachToolTip("Syncshell Menu");
|
||||
|
||||
if (ImGui.BeginPopup("Syncshell Menu"))
|
||||
{
|
||||
using (ImRaii.Disabled(_pairManager.GroupPairs.Select(k => k.Key).Distinct()
|
||||
.Count(g => string.Equals(g.OwnerUID, _apiController.UID, StringComparison.Ordinal)) >= _apiController.ServerInfo.MaxGroupsCreatedByUser))
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Plus, "Create new Syncshell", _syncshellMenuSize, true))
|
||||
{
|
||||
Mediator.Publish(new OpenCreateSyncshellPopupMessage());
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
using (ImRaii.Disabled(_pairManager.GroupPairs.Select(k => k.Key).Distinct().Count() >= _apiController.ServerInfo.MaxGroupsJoinedByUser))
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Users, "Join existing Syncshell", _syncshellMenuSize, true))
|
||||
{
|
||||
Mediator.Publish(new JoinSyncshellPopupMessage());
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
_syncshellMenuSize = ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X;
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(2);
|
||||
}
|
||||
|
||||
private float _syncshellMenuSize = 0;
|
||||
|
||||
private void DrawFilter()
|
||||
{
|
||||
var buttonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.ArrowUp);
|
||||
var playButtonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Play);
|
||||
if (!_configService.Current.ReverseUserSort)
|
||||
ImGui.SetNextItemWidth(WindowContentWidth);
|
||||
if (ImGui.InputTextWithHint("##filter", "Filter for UID/notes", ref _characterOrCommentFilter, 255))
|
||||
{
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.ArrowDown))
|
||||
{
|
||||
_configService.Current.ReverseUserSort = true;
|
||||
_configService.Save();
|
||||
}
|
||||
UiSharedService.AttachToolTip("Sort by name descending");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.ArrowUp))
|
||||
{
|
||||
_configService.Current.ReverseUserSort = false;
|
||||
_configService.Save();
|
||||
}
|
||||
UiSharedService.AttachToolTip("Sort by name ascending");
|
||||
}
|
||||
ImGui.SameLine();
|
||||
|
||||
var users = GetFilteredUsers();
|
||||
var userCount = users.Count;
|
||||
|
||||
var spacing = userCount > 0
|
||||
? playButtonSize.X + ImGui.GetStyle().ItemSpacing.X * 2
|
||||
: ImGui.GetStyle().ItemSpacing.X;
|
||||
|
||||
ImGui.SetNextItemWidth(WindowContentWidth - buttonSize.X - spacing);
|
||||
ImGui.InputTextWithHint("##filter", "Filter for UID/notes", ref _characterOrCommentFilter, 255);
|
||||
|
||||
if (userCount == 0) return;
|
||||
|
||||
var pausedUsers = users.Where(u => u.UserPair!.OwnPermissions.IsPaused() && u.UserPair.OtherPermissions.IsPaired()).ToList();
|
||||
var resumedUsers = users.Where(u => !u.UserPair!.OwnPermissions.IsPaused() && u.UserPair.OtherPermissions.IsPaired()).ToList();
|
||||
|
||||
if (!pausedUsers.Any() && !resumedUsers.Any()) return;
|
||||
ImGui.SameLine();
|
||||
|
||||
switch (_buttonState)
|
||||
{
|
||||
case true when !pausedUsers.Any():
|
||||
_buttonState = false;
|
||||
break;
|
||||
|
||||
case false when !resumedUsers.Any():
|
||||
_buttonState = true;
|
||||
break;
|
||||
|
||||
case true:
|
||||
users = pausedUsers;
|
||||
break;
|
||||
|
||||
case false:
|
||||
users = resumedUsers;
|
||||
break;
|
||||
}
|
||||
|
||||
var button = _buttonState ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
|
||||
|
||||
if (!_timeout.IsRunning || _timeout.ElapsedMilliseconds > 15000)
|
||||
{
|
||||
_timeout.Reset();
|
||||
|
||||
if (ImGuiComponents.IconButton(button) && UiSharedService.CtrlPressed())
|
||||
{
|
||||
foreach (var entry in users)
|
||||
{
|
||||
var perm = entry.UserPair!.OwnPermissions;
|
||||
perm.SetPaused(!perm.IsPaused());
|
||||
_ = _apiController.UserSetPairPermissions(new UserPermissionsDto(entry.UserData, perm));
|
||||
}
|
||||
|
||||
_timeout.Start();
|
||||
_buttonState = !_buttonState;
|
||||
}
|
||||
UiSharedService.AttachToolTip($"Hold Control to {(button == FontAwesomeIcon.Play ? "resume" : "pause")} pairing with {users.Count} out of {userCount} displayed users.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var availableAt = (15000 - _timeout.ElapsedMilliseconds) / 1000;
|
||||
ImGuiComponents.DisabledButton(button);
|
||||
UiSharedService.AttachToolTip($"Next execution is available at {availableAt} seconds");
|
||||
Mediator.Publish(new RefreshUiMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,24 +277,13 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
var ySize = TransferPartHeight == 0
|
||||
? 1
|
||||
: (ImGui.GetWindowContentRegionMax().Y - ImGui.GetWindowContentRegionMin().Y) - TransferPartHeight - ImGui.GetCursorPosY();
|
||||
var users = GetFilteredUsers()
|
||||
.OrderBy(
|
||||
u => _configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(u.PlayerName)
|
||||
? (_configService.Current.PreferNotesOverNamesForVisible ? u.GetNote() : u.PlayerName)
|
||||
: (u.GetNote() ?? u.UserData.AliasOrUID), StringComparer.OrdinalIgnoreCase).ToList();
|
||||
|
||||
if (_configService.Current.ReverseUserSort)
|
||||
{
|
||||
users.Reverse();
|
||||
}
|
||||
|
||||
var onlineUsers = users.Where(u => u.IsOnline || u.UserPair!.OwnPermissions.IsPaused()).Select(c => new DrawUserPair("Online" + c.UserData.UID, c, _uidDisplayHandler, _apiController, _selectGroupForPairUi)).ToList();
|
||||
var visibleUsers = users.Where(u => u.IsVisible).Select(c => new DrawUserPair("Visible" + c.UserData.UID, c, _uidDisplayHandler, _apiController, _selectGroupForPairUi)).ToList();
|
||||
var offlineUsers = users.Where(u => !u.IsOnline && !u.UserPair!.OwnPermissions.IsPaused()).Select(c => new DrawUserPair("Offline" + c.UserData.UID, c, _uidDisplayHandler, _apiController, _selectGroupForPairUi)).ToList();
|
||||
|
||||
ImGui.BeginChild("list", new Vector2(WindowContentWidth, ySize), border: false);
|
||||
|
||||
_pairGroupsUi.Draw(visibleUsers, onlineUsers, offlineUsers);
|
||||
foreach (var item in _drawFolders)
|
||||
{
|
||||
item.Draw();
|
||||
}
|
||||
|
||||
ImGui.EndChild();
|
||||
}
|
||||
@@ -417,7 +309,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
ImGui.TextColored(ImGuiColors.ParsedGreen, userCount);
|
||||
ImGui.SameLine();
|
||||
if (!printShard) ImGui.AlignTextToFramePadding();
|
||||
ImGui.Text("Users Online");
|
||||
ImGui.TextUnformatted("Users Online");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -474,7 +366,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
var currentUploads = _fileTransferManager.CurrentUploads.ToList();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
ImGui.Text(FontAwesomeIcon.Upload.ToIconString());
|
||||
ImGui.TextUnformatted(FontAwesomeIcon.Upload.ToIconString());
|
||||
ImGui.PopFont();
|
||||
ImGui.SameLine(35 * ImGuiHelpers.GlobalScale);
|
||||
|
||||
@@ -486,20 +378,20 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
var totalUploaded = currentUploads.Sum(c => c.Transferred);
|
||||
var totalToUpload = currentUploads.Sum(c => c.Total);
|
||||
|
||||
ImGui.Text($"{doneUploads}/{totalUploads}");
|
||||
ImGui.TextUnformatted($"{doneUploads}/{totalUploads}");
|
||||
var uploadText = $"({UiSharedService.ByteToString(totalUploaded)}/{UiSharedService.ByteToString(totalToUpload)})";
|
||||
var textSize = ImGui.CalcTextSize(uploadText);
|
||||
ImGui.SameLine(WindowContentWidth - textSize.X);
|
||||
ImGui.Text(uploadText);
|
||||
ImGui.TextUnformatted(uploadText);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text("No uploads in progress");
|
||||
ImGui.TextUnformatted("No uploads in progress");
|
||||
}
|
||||
|
||||
var currentDownloads = _currentDownloads.SelectMany(d => d.Value.Values).ToList();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
ImGui.Text(FontAwesomeIcon.Download.ToIconString());
|
||||
ImGui.TextUnformatted(FontAwesomeIcon.Download.ToIconString());
|
||||
ImGui.PopFont();
|
||||
ImGui.SameLine(35 * ImGuiHelpers.GlobalScale);
|
||||
|
||||
@@ -510,16 +402,16 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
var totalDownloaded = currentDownloads.Sum(c => c.TransferredBytes);
|
||||
var totalToDownload = currentDownloads.Sum(c => c.TotalBytes);
|
||||
|
||||
ImGui.Text($"{doneDownloads}/{totalDownloads}");
|
||||
ImGui.TextUnformatted($"{doneDownloads}/{totalDownloads}");
|
||||
var downloadText =
|
||||
$"({UiSharedService.ByteToString(totalDownloaded)}/{UiSharedService.ByteToString(totalToDownload)})";
|
||||
var textSize = ImGui.CalcTextSize(downloadText);
|
||||
ImGui.SameLine(WindowContentWidth - textSize.X);
|
||||
ImGui.Text(downloadText);
|
||||
ImGui.TextUnformatted(downloadText);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text("No downloads in progress");
|
||||
ImGui.TextUnformatted("No downloads in progress");
|
||||
}
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.PersonCircleQuestion, "Mare Character Data Analysis", WindowContentWidth))
|
||||
@@ -583,15 +475,119 @@ public class CompactUi : WindowMediatorSubscriberBase
|
||||
}
|
||||
}
|
||||
|
||||
private List<Pair> GetFilteredUsers()
|
||||
private IEnumerable<IDrawFolder> GetDrawFolders()
|
||||
{
|
||||
return _pairManager.DirectPairs.Where(p =>
|
||||
List<IDrawFolder> drawFolders = [];
|
||||
|
||||
var users = GetFilteredGroupUsers()
|
||||
.ToDictionary(g => g.Key, g => g.Value);
|
||||
|
||||
if (_configService.Current.ShowVisibleUsersSeparately)
|
||||
{
|
||||
var visibleUsers = users.Where(u => u.Key.IsVisible)
|
||||
.OrderBy(
|
||||
u => _configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(u.Key.PlayerName)
|
||||
? (_configService.Current.PreferNotesOverNamesForVisible ? u.Key.GetNote() : u.Key.PlayerName)
|
||||
: (u.Key.GetNote() ?? u.Key.UserData.AliasOrUID), StringComparer.OrdinalIgnoreCase)
|
||||
.ToDictionary(k => k.Key, k => k.Value);
|
||||
|
||||
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomVisibleTag, visibleUsers));
|
||||
}
|
||||
|
||||
List<IDrawFolder> groupFolders = new();
|
||||
foreach (var group in _pairManager.GroupPairs.Select(g => g.Key).OrderBy(g => g.GroupAliasOrGID, StringComparer.Ordinal))
|
||||
{
|
||||
var groupUsers2 = users.Where(v => v.Value.Exists(g => string.Equals(g.GID, group.GID, StringComparison.Ordinal))
|
||||
&& (v.Key.IsOnline || (!v.Key.IsOnline && !_configService.Current.ShowOfflineUsersSeparately)
|
||||
|| v.Key.UserPair.OwnPermissions.IsPaused()))
|
||||
.OrderByDescending(u => u.Key.IsOnline)
|
||||
.ThenBy(u =>
|
||||
{
|
||||
if (string.Equals(u.Key.UserData.UID, group.OwnerUID, StringComparison.Ordinal)) return 0;
|
||||
if (group.GroupPairUserInfos.TryGetValue(u.Key.UserData.UID, out var info))
|
||||
{
|
||||
if (info.IsModerator()) return 1;
|
||||
if (info.IsPinned()) return 2;
|
||||
}
|
||||
return u.Key.IsVisible ? 3 : 4;
|
||||
})
|
||||
.ThenBy(
|
||||
u => _configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(u.Key.PlayerName)
|
||||
? (_configService.Current.PreferNotesOverNamesForVisible ? u.Key.GetNote() : u.Key.PlayerName)
|
||||
: (u.Key.GetNote() ?? u.Key.UserData.AliasOrUID), StringComparer.Ordinal)
|
||||
.ToDictionary(k => k.Key, k => k.Value);
|
||||
|
||||
groupFolders.Add(_drawEntityFactory.CreateDrawGroupFolder(group, groupUsers2));
|
||||
}
|
||||
|
||||
if (_configService.Current.GroupUpSyncshells)
|
||||
drawFolders.Add(new DrawGroupedGroupFolder(groupFolders, _tagHandler));
|
||||
else
|
||||
drawFolders.AddRange(groupFolders);
|
||||
|
||||
var tags = _tagHandler.GetAllTagsSorted();
|
||||
HashSet<Pair> alreadyInTags = [];
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
var tagUsers = users.Where(u => u.Key.IsDirectlyPaired && !u.Key.IsOneSidedPair && _tagHandler.HasTag(u.Key.UserData.UID, tag)
|
||||
&& (u.Key.IsOnline || (!u.Key.IsOnline && !_configService.Current.ShowOfflineUsersSeparately)
|
||||
|| u.Key.UserPair.OwnPermissions.IsPaused()))
|
||||
.OrderByDescending(u => u.Key.IsVisible)
|
||||
.ThenByDescending(u => u.Key.IsOnline)
|
||||
.ThenBy(
|
||||
u => _configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(u.Key.PlayerName)
|
||||
? (_configService.Current.PreferNotesOverNamesForVisible ? u.Key.GetNote() : u.Key.PlayerName)
|
||||
: (u.Key.GetNote() ?? u.Key.UserData.AliasOrUID), StringComparer.OrdinalIgnoreCase)
|
||||
.ToDictionary(u => u.Key, u => u.Value);
|
||||
|
||||
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(tag, tagUsers.Select(u =>
|
||||
{
|
||||
alreadyInTags.Add(u.Key);
|
||||
return (u.Key, u.Value);
|
||||
}).ToDictionary(u => u.Key, u => u.Value)));
|
||||
}
|
||||
|
||||
var onlineDirectPairedUsersNotInTags = users.Where(u => u.Key.IsDirectlyPaired && !u.Key.IsOneSidedPair && !_tagHandler.HasAnyTag(u.Key.UserData.UID)
|
||||
&& (u.Key.IsOnline || (!u.Key.IsOnline && !_configService.Current.ShowOfflineUsersSeparately)
|
||||
|| u.Key.UserPair.OwnPermissions.IsPaused()))
|
||||
.OrderByDescending(u => u.Key.IsVisible)
|
||||
.ThenByDescending(u => u.Key.IsOnline)
|
||||
.ThenBy(
|
||||
u => _configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(u.Key.PlayerName)
|
||||
? (_configService.Current.PreferNotesOverNamesForVisible ? u.Key.GetNote() : u.Key.PlayerName)
|
||||
: (u.Key.GetNote() ?? u.Key.UserData.AliasOrUID), StringComparer.OrdinalIgnoreCase)
|
||||
.ToDictionary(u => u.Key, u => u.Value);
|
||||
|
||||
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder((_configService.Current.ShowOfflineUsersSeparately ? TagHandler.CustomOnlineTag : TagHandler.CustomAllTag),
|
||||
onlineDirectPairedUsersNotInTags));
|
||||
|
||||
if (_configService.Current.ShowOfflineUsersSeparately)
|
||||
{
|
||||
var offlineUsersEntries = users.Where(u => (!u.Key.IsOneSidedPair || u.Value.Any()) && !u.Key.IsOnline && !u.Key.UserPair.OwnPermissions.IsPaused()).OrderBy(
|
||||
u => _configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(u.Key.PlayerName)
|
||||
? (_configService.Current.PreferNotesOverNamesForVisible ? u.Key.GetNote() : u.Key.PlayerName)
|
||||
: (u.Key.GetNote() ?? u.Key.UserData.AliasOrUID), StringComparer.OrdinalIgnoreCase)
|
||||
.ToDictionary(u => u.Key, u => u.Value);
|
||||
|
||||
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineTag, offlineUsersEntries));
|
||||
}
|
||||
|
||||
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomUnpairedTag, users.Where(u => u.Key.IsOneSidedPair).ToDictionary(u => u.Key, u => u.Value)));
|
||||
|
||||
return drawFolders;
|
||||
}
|
||||
|
||||
private Dictionary<Pair, List<GroupFullInfoDto>> GetFilteredGroupUsers()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_characterOrCommentFilter)) return _pairManager.PairsWithGroups;
|
||||
|
||||
return _pairManager.PairsWithGroups.Where(p =>
|
||||
{
|
||||
if (_characterOrCommentFilter.IsNullOrEmpty()) return true;
|
||||
return p.UserData.AliasOrUID.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ||
|
||||
(p.GetNote()?.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ?? false) ||
|
||||
(p.PlayerName?.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ?? false);
|
||||
}).ToList();
|
||||
return p.Key.UserData.AliasOrUID.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ||
|
||||
(p.Key.GetNote()?.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ?? false) ||
|
||||
(p.Key.PlayerName?.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ?? false);
|
||||
}).ToDictionary(k => k.Key, k => k.Value);
|
||||
}
|
||||
|
||||
private string GetServerError()
|
||||
|
||||
116
MareSynchronos/UI/Components/DrawFolderBase.cs
Normal file
116
MareSynchronos/UI/Components/DrawFolderBase.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
|
||||
public abstract class DrawFolderBase : IDrawFolder
|
||||
{
|
||||
protected readonly IEnumerable<DrawUserPair> _drawPairs;
|
||||
protected readonly string _id;
|
||||
protected readonly TagHandler _tagHandler;
|
||||
private float _menuWidth = -1;
|
||||
protected DrawFolderBase(string id, IEnumerable<DrawUserPair> drawPairs, TagHandler tagHandler)
|
||||
{
|
||||
_id = id;
|
||||
_drawPairs = drawPairs;
|
||||
_tagHandler = tagHandler;
|
||||
}
|
||||
|
||||
protected abstract bool RenderIfEmpty { get; }
|
||||
protected abstract bool RenderMenu { get; }
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (!RenderIfEmpty && !_drawPairs.Any()) return;
|
||||
|
||||
using var id = ImRaii.PushId("folder_" + _id);
|
||||
var originalY = ImGui.GetCursorPosY();
|
||||
var pauseIconSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Bars);
|
||||
var textSize = ImGui.CalcTextSize(_id);
|
||||
var textPosY = originalY + pauseIconSize.Y / 2 - textSize.Y / 2;
|
||||
|
||||
// draw opener
|
||||
var icon = _tagHandler.IsTagOpen(_id) ? FontAwesomeIcon.CaretDown : FontAwesomeIcon.CaretRight;
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
UiSharedService.FontText(icon.ToIconString(), UiBuilder.IconFont);
|
||||
if (ImGui.IsItemClicked())
|
||||
{
|
||||
_tagHandler.SetTagOpen(_id, !_tagHandler.IsTagOpen(_id));
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
var leftSideEnd = DrawIcon(textPosY, originalY);
|
||||
|
||||
ImGui.SameLine();
|
||||
var rightSideStart = DrawRightSide(originalY);
|
||||
|
||||
// draw name
|
||||
ImGui.SameLine(leftSideEnd);
|
||||
DrawName(textPosY, rightSideStart - leftSideEnd);
|
||||
ImGui.Separator();
|
||||
|
||||
// if opened draw content
|
||||
if (_tagHandler.IsTagOpen(_id))
|
||||
{
|
||||
using var indent = ImRaii.PushIndent(20f);
|
||||
if (_drawPairs.Any())
|
||||
{
|
||||
foreach (var item in _drawPairs)
|
||||
{
|
||||
item.DrawPairedClient();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextUnformatted("No users (online)");
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract float DrawIcon(float textPosY, float originalY);
|
||||
|
||||
protected abstract void DrawMenu(float menuWidth);
|
||||
|
||||
protected abstract void DrawName(float originalY, float width);
|
||||
|
||||
protected abstract float DrawRightSide(float originalY, float currentRightSideX);
|
||||
|
||||
private float DrawRightSide(float originalY)
|
||||
{
|
||||
var barButtonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Bars);
|
||||
var spacingX = ImGui.GetStyle().ItemSpacing.X;
|
||||
var windowEndX = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth();
|
||||
|
||||
// Flyout Menu
|
||||
var rightSideStart = windowEndX - (RenderMenu ? (barButtonSize.X + spacingX) : spacingX);
|
||||
|
||||
if (RenderMenu)
|
||||
{
|
||||
ImGui.SameLine(windowEndX - barButtonSize.X);
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars))
|
||||
{
|
||||
ImGui.OpenPopup("User Flyout Menu");
|
||||
}
|
||||
if (ImGui.BeginPopup("User Flyout Menu"))
|
||||
{
|
||||
UiSharedService.DrawWithID($"buttons-{_id}", () =>
|
||||
{
|
||||
DrawMenu(_menuWidth);
|
||||
});
|
||||
_menuWidth = ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X;
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
else
|
||||
{
|
||||
_menuWidth = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return DrawRightSide(originalY, rightSideStart);
|
||||
}
|
||||
}
|
||||
236
MareSynchronos/UI/Components/DrawFolderGroup.cs
Normal file
236
MareSynchronos/UI/Components/DrawFolderGroup.cs
Normal file
@@ -0,0 +1,236 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
using MareSynchronos.WebAPI;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
|
||||
public class DrawFolderGroup : DrawFolderBase
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private readonly GroupFullInfoDto _groupFullInfoDto;
|
||||
private readonly IdDisplayHandler _idDisplayHandler;
|
||||
private readonly MareMediator _mareMediator;
|
||||
|
||||
public DrawFolderGroup(string id, GroupFullInfoDto groupFullInfoDto, ApiController apiController,
|
||||
IEnumerable<DrawUserPair> drawPairs, TagHandler tagHandler, IdDisplayHandler idDisplayHandler,
|
||||
MareMediator mareMediator) :
|
||||
base(id, drawPairs, tagHandler)
|
||||
{
|
||||
_groupFullInfoDto = groupFullInfoDto;
|
||||
_apiController = apiController;
|
||||
_idDisplayHandler = idDisplayHandler;
|
||||
_mareMediator = mareMediator;
|
||||
}
|
||||
|
||||
protected override bool RenderIfEmpty => true;
|
||||
protected override bool RenderMenu => true;
|
||||
private bool IsModerator => IsOwner || _groupFullInfoDto.GroupUserInfo.IsModerator();
|
||||
private bool IsOwner => string.Equals(_groupFullInfoDto.OwnerUID, _apiController.UID, StringComparison.Ordinal);
|
||||
private bool IsPinned => _groupFullInfoDto.GroupUserInfo.IsPinned();
|
||||
|
||||
protected override float DrawIcon(float textPosY, float originalY)
|
||||
{
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
ImGui.TextUnformatted(_groupFullInfoDto.GroupPermissions.IsDisableInvites() ? FontAwesomeIcon.Lock.ToIconString() : FontAwesomeIcon.Users.ToIconString());
|
||||
if (_groupFullInfoDto.GroupPermissions.IsDisableInvites())
|
||||
{
|
||||
UiSharedService.AttachToolTip("Syncshell " + _groupFullInfoDto.GroupAliasOrGID + " is closed for invites");
|
||||
}
|
||||
if (IsOwner)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
ImGui.TextUnformatted(FontAwesomeIcon.Crown.ToIconString());
|
||||
UiSharedService.AttachToolTip("You are the owner of " + _groupFullInfoDto.GroupAliasOrGID);
|
||||
}
|
||||
else if (IsModerator)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
ImGui.TextUnformatted(FontAwesomeIcon.UserShield.ToIconString());
|
||||
UiSharedService.AttachToolTip("You are a moderator in " + _groupFullInfoDto.GroupAliasOrGID);
|
||||
}
|
||||
else if (IsPinned)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
ImGui.TextUnformatted(FontAwesomeIcon.Thumbtack.ToIconString());
|
||||
UiSharedService.AttachToolTip("You are pinned in " + _groupFullInfoDto.GroupAliasOrGID);
|
||||
}
|
||||
ImGui.SameLine();
|
||||
return ImGui.GetCursorPosX();
|
||||
}
|
||||
|
||||
protected override void DrawMenu(float menuWidth)
|
||||
{
|
||||
ImGui.TextUnformatted("Syncshell Menu (" + _groupFullInfoDto.GroupAliasOrGID + ")");
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.TextUnformatted("General Syncshell Actions");
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Copy, "Copy ID", menuWidth, true))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
ImGui.SetClipboardText(_groupFullInfoDto.GroupAliasOrGID);
|
||||
}
|
||||
UiSharedService.AttachToolTip("Copy Syncshell ID to Clipboard");
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.StickyNote, "Copy Notes", menuWidth, true))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
ImGui.SetClipboardText(UiSharedService.GetNotes(_drawPairs.Select(k => k.Pair).ToList()));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Copies all your notes for all users in this Syncshell to the clipboard." + Environment.NewLine + "They can be imported via Settings -> Privacy -> Import Notes from Clipboard");
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.ArrowCircleLeft, "Leave Syncshell", menuWidth, true) && UiSharedService.CtrlPressed())
|
||||
{
|
||||
_ = _apiController.GroupLeave(_groupFullInfoDto);
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hold CTRL and click to leave this Syncshell" + (!string.Equals(_groupFullInfoDto.OwnerUID, _apiController.UID, StringComparison.Ordinal)
|
||||
? string.Empty : Environment.NewLine + "WARNING: This action is irreversible" + Environment.NewLine + "Leaving an owned Syncshell will transfer the ownership to a random person in the Syncshell."));
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.TextUnformatted("Permission Settings");
|
||||
var perm = _groupFullInfoDto.GroupUserPermissions;
|
||||
bool disableSounds = perm.IsDisableSounds();
|
||||
bool disableAnims = perm.IsDisableAnimations();
|
||||
bool disableVfx = perm.IsDisableVFX();
|
||||
|
||||
if ((_groupFullInfoDto.GroupPermissions.IsPreferDisableAnimations() != disableAnims
|
||||
|| _groupFullInfoDto.GroupPermissions.IsPreferDisableSounds() != disableSounds
|
||||
|| _groupFullInfoDto.GroupPermissions.IsPreferDisableVFX() != disableVfx)
|
||||
&& UiSharedService.IconTextButton(FontAwesomeIcon.Check, "Align with suggested permissions", menuWidth, true))
|
||||
{
|
||||
perm.SetDisableVFX(_groupFullInfoDto.GroupPermissions.IsPreferDisableVFX());
|
||||
perm.SetDisableSounds(_groupFullInfoDto.GroupPermissions.IsPreferDisableSounds());
|
||||
perm.SetDisableAnimations(_groupFullInfoDto.GroupPermissions.IsPreferDisableAnimations());
|
||||
_ = _apiController.GroupChangeIndividualPermissionState(new(_groupFullInfoDto.Group, new(_apiController.UID), perm));
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if (UiSharedService.IconTextButton(disableSounds ? FontAwesomeIcon.VolumeUp : FontAwesomeIcon.VolumeOff, disableSounds ? "Enable Sound Sync" : "Disable Sound Sync",
|
||||
menuWidth, true))
|
||||
{
|
||||
perm.SetDisableSounds(!disableSounds);
|
||||
_ = _apiController.GroupChangeIndividualPermissionState(new(_groupFullInfoDto.Group, new(_apiController.UID), perm));
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if (UiSharedService.IconTextButton(disableAnims ? FontAwesomeIcon.Running : FontAwesomeIcon.Stop, disableAnims ? "Enable Animation Sync" : "Disable Animation Sync",
|
||||
menuWidth, true))
|
||||
{
|
||||
perm.SetDisableAnimations(!disableAnims);
|
||||
_ = _apiController.GroupChangeIndividualPermissionState(new(_groupFullInfoDto.Group, new(_apiController.UID), perm));
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if (UiSharedService.IconTextButton(disableVfx ? FontAwesomeIcon.Sun : FontAwesomeIcon.Circle, disableVfx ? "Enable VFX Sync" : "Disable VFX Sync",
|
||||
menuWidth, true))
|
||||
{
|
||||
perm.SetDisableVFX(!disableVfx);
|
||||
_ = _apiController.GroupChangeIndividualPermissionState(new(_groupFullInfoDto.Group, new(_apiController.UID), perm));
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if (IsModerator || IsOwner)
|
||||
{
|
||||
ImGui.Separator();
|
||||
ImGui.TextUnformatted("Syncshell Admin Functions");
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Cog, "Open Admin Panel", menuWidth, true))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_mareMediator.Publish(new OpenSyncshellAdminPanelPopupMessage(_groupFullInfoDto));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DrawName(float originalY, float width)
|
||||
{
|
||||
_idDisplayHandler.DrawGroupText(_id, _groupFullInfoDto, ImGui.GetCursorPosX(), originalY, () => width);
|
||||
}
|
||||
|
||||
protected override float DrawRightSide(float originalY, float currentRightSideX)
|
||||
{
|
||||
var spacingX = ImGui.GetStyle().ItemSpacing.X;
|
||||
|
||||
FontAwesomeIcon pauseIcon = _groupFullInfoDto.GroupUserPermissions.IsPaused() ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
|
||||
var pauseButtonSize = UiSharedService.GetIconButtonSize(pauseIcon);
|
||||
|
||||
var folderIcon = FontAwesomeIcon.UsersCog;
|
||||
var userCogButtonSize = UiSharedService.GetIconSize(folderIcon);
|
||||
|
||||
var individualSoundsDisabled = _groupFullInfoDto.GroupUserPermissions.IsDisableSounds();
|
||||
var individualAnimDisabled = _groupFullInfoDto.GroupUserPermissions.IsDisableAnimations();
|
||||
var individualVFXDisabled = _groupFullInfoDto.GroupUserPermissions.IsDisableVFX();
|
||||
|
||||
var infoIconPosDist = currentRightSideX - pauseButtonSize.X - spacingX;
|
||||
|
||||
ImGui.SameLine(infoIconPosDist - userCogButtonSize.X);
|
||||
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudYellow,
|
||||
_groupFullInfoDto.GroupPermissions.IsPreferDisableAnimations() != individualAnimDisabled
|
||||
|| _groupFullInfoDto.GroupPermissions.IsPreferDisableSounds() != individualSoundsDisabled
|
||||
|| _groupFullInfoDto.GroupPermissions.IsPreferDisableVFX() != individualVFXDisabled))
|
||||
UiSharedService.FontText(folderIcon.ToIconString(), UiBuilder.IconFont);
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
|
||||
ImGui.TextUnformatted("Syncshell Permissions");
|
||||
ImGui.Dummy(new(2f));
|
||||
|
||||
UiSharedService.BooleanToColoredIcon(!individualSoundsDisabled, inline: false);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.TextUnformatted("Sound Sync");
|
||||
|
||||
UiSharedService.BooleanToColoredIcon(!individualAnimDisabled, inline: false);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.TextUnformatted("Animation Sync");
|
||||
|
||||
UiSharedService.BooleanToColoredIcon(!individualVFXDisabled, inline: false);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.TextUnformatted("VFX Sync");
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.Dummy(new(2f));
|
||||
ImGui.TextUnformatted("Suggested Permissions");
|
||||
ImGui.Dummy(new(2f));
|
||||
|
||||
UiSharedService.BooleanToColoredIcon(!_groupFullInfoDto.GroupPermissions.IsPreferDisableSounds(), inline: false);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.TextUnformatted("Sound Sync");
|
||||
|
||||
UiSharedService.BooleanToColoredIcon(!_groupFullInfoDto.GroupPermissions.IsPreferDisableAnimations(), inline: false);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.TextUnformatted("Animation Sync");
|
||||
|
||||
UiSharedService.BooleanToColoredIcon(!_groupFullInfoDto.GroupPermissions.IsPreferDisableVFX(), inline: false);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.TextUnformatted("VFX Sync");
|
||||
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGuiComponents.IconButton(pauseIcon))
|
||||
{
|
||||
var perm = _groupFullInfoDto.GroupUserPermissions;
|
||||
perm.SetPaused(!perm.IsPaused());
|
||||
_ = _apiController.GroupChangeIndividualPermissionState(new GroupPairUserPermissionDto(_groupFullInfoDto.Group, new(_apiController.UID), perm));
|
||||
}
|
||||
return currentRightSideX;
|
||||
}
|
||||
}
|
||||
156
MareSynchronos/UI/Components/DrawFolderTag.cs
Normal file
156
MareSynchronos/UI/Components/DrawFolderTag.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
using MareSynchronos.WebAPI;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
|
||||
public class DrawFolderTag : DrawFolderBase
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private readonly SelectPairForTagUi _selectPairForTagUi;
|
||||
|
||||
public DrawFolderTag(string id, IEnumerable<DrawUserPair> drawPairs, TagHandler tagHandler, ApiController apiController, SelectPairForTagUi selectPairForTagUi)
|
||||
: base(id, drawPairs, tagHandler)
|
||||
{
|
||||
_apiController = apiController;
|
||||
_selectPairForTagUi = selectPairForTagUi;
|
||||
}
|
||||
|
||||
protected override bool RenderIfEmpty => _id switch
|
||||
{
|
||||
TagHandler.CustomUnpairedTag => false,
|
||||
TagHandler.CustomOnlineTag => false,
|
||||
TagHandler.CustomOfflineTag => false,
|
||||
TagHandler.CustomVisibleTag => false,
|
||||
TagHandler.CustomAllTag => true,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
protected override bool RenderMenu => _id switch
|
||||
{
|
||||
TagHandler.CustomUnpairedTag => false,
|
||||
TagHandler.CustomOnlineTag => false,
|
||||
TagHandler.CustomOfflineTag => false,
|
||||
TagHandler.CustomVisibleTag => false,
|
||||
TagHandler.CustomAllTag => false,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
private bool RenderPause => _id switch
|
||||
{
|
||||
TagHandler.CustomUnpairedTag => false,
|
||||
TagHandler.CustomOnlineTag => false,
|
||||
TagHandler.CustomOfflineTag => false,
|
||||
TagHandler.CustomVisibleTag => false,
|
||||
TagHandler.CustomAllTag => false,
|
||||
_ => true,
|
||||
} && _drawPairs.Any();
|
||||
|
||||
protected override float DrawIcon(float textPosY, float originalY)
|
||||
{
|
||||
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
||||
var icon = _id switch
|
||||
{
|
||||
TagHandler.CustomUnpairedTag => FontAwesomeIcon.ArrowsLeftRight.ToIconString(),
|
||||
TagHandler.CustomOnlineTag => FontAwesomeIcon.Link.ToIconString(),
|
||||
TagHandler.CustomOfflineTag => FontAwesomeIcon.Unlink.ToIconString(),
|
||||
TagHandler.CustomVisibleTag => FontAwesomeIcon.Eye.ToIconString(),
|
||||
TagHandler.CustomAllTag => FontAwesomeIcon.User.ToIconString(),
|
||||
_ => FontAwesomeIcon.Folder.ToIconString()
|
||||
};
|
||||
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
ImGui.TextUnformatted(icon);
|
||||
ImGui.SameLine();
|
||||
return ImGui.GetCursorPosX();
|
||||
}
|
||||
|
||||
protected override void DrawMenu(float menuWidth)
|
||||
{
|
||||
ImGui.TextUnformatted("Group Menu");
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Users, "Select Pairs", menuWidth, true))
|
||||
{
|
||||
_selectPairForTagUi.Open(_id);
|
||||
}
|
||||
UiSharedService.AttachToolTip("Select Individual Pairs for this Pair Group");
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Delete Pair Group", menuWidth, true) && UiSharedService.CtrlPressed())
|
||||
{
|
||||
_tagHandler.RemoveTag(_id);
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hold CTRL to remove this Group permanently." + Environment.NewLine +
|
||||
"Note: this will not unpair with users in this Group.");
|
||||
}
|
||||
|
||||
protected override void DrawName(float originalY, float width)
|
||||
{
|
||||
ImGui.SetCursorPosY(originalY);
|
||||
string name = _id switch
|
||||
{
|
||||
TagHandler.CustomUnpairedTag => "One-sided Individual Pairs",
|
||||
TagHandler.CustomOnlineTag => "Online / Paused by you",
|
||||
TagHandler.CustomOfflineTag => "Offline / Paused by other",
|
||||
TagHandler.CustomVisibleTag => "Visible",
|
||||
TagHandler.CustomAllTag => "Users",
|
||||
_ => _id
|
||||
};
|
||||
|
||||
ImGui.TextUnformatted(name);
|
||||
}
|
||||
|
||||
protected override float DrawRightSide(float originalY, float currentRightSideX)
|
||||
{
|
||||
if (!RenderPause) return currentRightSideX;
|
||||
|
||||
var allArePaused = _drawPairs.All(pair => pair.UserPair!.OwnPermissions.IsPaused());
|
||||
var pauseButton = allArePaused ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
|
||||
var pauseButtonX = UiSharedService.GetIconButtonSize(pauseButton).X;
|
||||
|
||||
var buttonPauseOffset = currentRightSideX - pauseButtonX;
|
||||
ImGui.SameLine(buttonPauseOffset);
|
||||
if (ImGuiComponents.IconButton(pauseButton))
|
||||
{
|
||||
if (allArePaused)
|
||||
{
|
||||
ResumeAllPairs(_drawPairs);
|
||||
}
|
||||
else
|
||||
{
|
||||
PauseRemainingPairs(_drawPairs);
|
||||
}
|
||||
}
|
||||
if (allArePaused)
|
||||
{
|
||||
UiSharedService.AttachToolTip($"Resume pairing with all pairs in {_id}");
|
||||
}
|
||||
else
|
||||
{
|
||||
UiSharedService.AttachToolTip($"Pause pairing with all pairs in {_id}");
|
||||
}
|
||||
|
||||
return currentRightSideX;
|
||||
}
|
||||
|
||||
private void PauseRemainingPairs(IEnumerable<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(new(pairToPause.UID), perm));
|
||||
}
|
||||
}
|
||||
|
||||
private void ResumeAllPairs(IEnumerable<DrawUserPair> availablePairs)
|
||||
{
|
||||
foreach (var pairToPause in availablePairs)
|
||||
{
|
||||
var perm = pairToPause.UserPair!.OwnPermissions;
|
||||
perm.SetPaused(paused: false);
|
||||
_ = _apiController.UserSetPairPermissions(new(new(pairToPause.UID), perm));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,336 +0,0 @@
|
||||
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 Dalamud.Interface.Utility;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
|
||||
public class DrawGroupPair : DrawPairBase
|
||||
{
|
||||
private static string _banReason = string.Empty;
|
||||
private static bool _banUserPopupOpen;
|
||||
private static bool _showModalBanUser;
|
||||
private readonly GroupPairFullInfoDto _fullInfoDto;
|
||||
private readonly GroupFullInfoDto _group;
|
||||
|
||||
public DrawGroupPair(string id, Pair entry, ApiController apiController, GroupFullInfoDto group, GroupPairFullInfoDto fullInfoDto, UidDisplayHandler handler) : base(id, entry, apiController, handler)
|
||||
{
|
||||
_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 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 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 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"));
|
||||
}
|
||||
|
||||
if (individualVFXDisabled)
|
||||
{
|
||||
var userVFXText = "VFX sync disabled with " + _pair.UserData.AliasOrUID;
|
||||
UiSharedService.FontText(FontAwesomeIcon.Circle.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(userVFXText);
|
||||
ImGui.NewLine();
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text("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.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);
|
||||
}
|
||||
|
||||
if (vfxDisabled)
|
||||
{
|
||||
var userVFXText = "VFX sync disabled by " + _pair.UserData.AliasOrUID;
|
||||
UiSharedService.FontText(FontAwesomeIcon.Circle.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(userVFXText);
|
||||
}
|
||||
|
||||
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.Separator();
|
||||
if (!_pair.IsPaused)
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.User, "Open Profile"))
|
||||
{
|
||||
_displayHandler.OpenProfile(_pair);
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
UiSharedService.AttachToolTip("Opens the profile for this user in a new window");
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.ExclamationTriangle, "Report Mare Profile"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_showModalReport = true;
|
||||
}
|
||||
UiSharedService.AttachToolTip("Report this users Mare Profile to the administrative team");
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
49
MareSynchronos/UI/Components/DrawGroupedGroupFolder.cs
Normal file
49
MareSynchronos/UI/Components/DrawGroupedGroupFolder.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
|
||||
public class DrawGroupedGroupFolder : IDrawFolder
|
||||
{
|
||||
private readonly IEnumerable<IDrawFolder> _groups;
|
||||
private readonly TagHandler _tagHandler;
|
||||
|
||||
public DrawGroupedGroupFolder(IEnumerable<IDrawFolder> groups, TagHandler tagHandler)
|
||||
{
|
||||
_groups = groups;
|
||||
_tagHandler = tagHandler;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (!_groups.Any()) return;
|
||||
|
||||
string _id = "__folder_syncshells";
|
||||
using var id = ImRaii.PushId(_id);
|
||||
|
||||
var icon = _tagHandler.IsTagOpen(_id) ? FontAwesomeIcon.CaretDown : FontAwesomeIcon.CaretRight;
|
||||
UiSharedService.FontText(icon.ToIconString(), UiBuilder.IconFont);
|
||||
if (ImGui.IsItemClicked())
|
||||
{
|
||||
_tagHandler.SetTagOpen(_id, !_tagHandler.IsTagOpen(_id));
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
ImGui.TextUnformatted(FontAwesomeIcon.UsersRectangle.ToIconString());
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted("All Syncshells");
|
||||
ImGui.Separator();
|
||||
|
||||
if (_tagHandler.IsTagOpen(_id))
|
||||
{
|
||||
using var indent = ImRaii.PushIndent(20f);
|
||||
foreach (var entry in _groups)
|
||||
{
|
||||
entry.Draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
using MareSynchronos.WebAPI;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
|
||||
public abstract class DrawPairBase
|
||||
{
|
||||
protected static bool _showModalReport = false;
|
||||
protected readonly ApiController _apiController;
|
||||
protected readonly UidDisplayHandler _displayHandler;
|
||||
protected Pair _pair;
|
||||
private static bool _reportPopupOpen = false;
|
||||
private static string _reportReason = string.Empty;
|
||||
private readonly string _id;
|
||||
|
||||
protected DrawPairBase(string id, Pair entry, ApiController apiController, UidDisplayHandler uIDDisplayHandler)
|
||||
{
|
||||
_id = id;
|
||||
_pair = entry;
|
||||
_apiController = apiController;
|
||||
_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);
|
||||
|
||||
if (_showModalReport && !_reportPopupOpen)
|
||||
{
|
||||
ImGui.OpenPopup("Report Profile");
|
||||
_reportPopupOpen = true;
|
||||
}
|
||||
|
||||
if (!_showModalReport) _reportPopupOpen = false;
|
||||
|
||||
if (ImGui.BeginPopupModal("Report Profile", ref _showModalReport, UiSharedService.PopupWindowFlags))
|
||||
{
|
||||
UiSharedService.TextWrapped("Report " + (_pair.UserData.AliasOrUID) + " Mare Profile");
|
||||
ImGui.InputTextMultiline("##reportReason", ref _reportReason, 500, new System.Numerics.Vector2(500 - ImGui.GetStyle().ItemSpacing.X * 2, 200));
|
||||
UiSharedService.TextWrapped($"Note: Sending a report will disable the offending profile globally.{Environment.NewLine}" +
|
||||
$"The report will be sent to the team of your currently connected Mare Synchronos Service.{Environment.NewLine}" +
|
||||
$"The report will include your user and your contact info (Discord User).{Environment.NewLine}" +
|
||||
$"Depending on the severity of the offense the users Mare profile or account can be permanently disabled or banned.");
|
||||
UiSharedService.ColorTextWrapped("Report spam and wrong reports will not be tolerated and can lead to permanent account suspension.", ImGuiColors.DalamudRed);
|
||||
if (string.IsNullOrEmpty(_reportReason)) ImGui.BeginDisabled();
|
||||
if (ImGui.Button("Send Report"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var reason = _reportReason;
|
||||
_ = _apiController.UserReportProfile(new(_pair.UserData, reason));
|
||||
_reportReason = string.Empty;
|
||||
_showModalReport = false;
|
||||
_reportPopupOpen = false;
|
||||
}
|
||||
if (string.IsNullOrEmpty(_reportReason)) ImGui.EndDisabled();
|
||||
UiSharedService.SetScaledWindowSize(500);
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
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(_id, _pair, leftSide, originalY, () => rightSide - leftSide);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +1,298 @@
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface;
|
||||
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;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronos.API.Dto.User;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using MareSynchronos.Services.ServerConfiguration;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
using MareSynchronos.WebAPI;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
|
||||
public class DrawUserPair : DrawPairBase
|
||||
public class DrawUserPair
|
||||
{
|
||||
private readonly SelectGroupForPairUi _selectGroupForPairUi;
|
||||
protected readonly ApiController _apiController;
|
||||
protected readonly IdDisplayHandler _displayHandler;
|
||||
protected readonly MareMediator _mediator;
|
||||
protected readonly List<GroupFullInfoDto> _syncedGroups;
|
||||
protected Pair _pair;
|
||||
private readonly string _id;
|
||||
private readonly SelectTagForPairUi _selectTagForPairUi;
|
||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||
private float _menuRenderWidth = -1;
|
||||
|
||||
public DrawUserPair(string id, Pair entry, UidDisplayHandler displayHandler, ApiController apiController, SelectGroupForPairUi selectGroupForPairUi) : base(id, entry, apiController, displayHandler)
|
||||
public DrawUserPair(string id, Pair entry, List<GroupFullInfoDto> syncedGroups,
|
||||
ApiController apiController, IdDisplayHandler uIDDisplayHandler,
|
||||
MareMediator mareMediator, SelectTagForPairUi selectTagForPairUi,
|
||||
ServerConfigurationManager serverConfigurationManager)
|
||||
{
|
||||
if (_pair.UserPair == null) throw new ArgumentException("Pair must be UserPair", nameof(entry));
|
||||
_id = id;
|
||||
_pair = entry;
|
||||
_selectGroupForPairUi = selectGroupForPairUi;
|
||||
_syncedGroups = syncedGroups;
|
||||
_apiController = apiController;
|
||||
_displayHandler = uIDDisplayHandler;
|
||||
_mediator = mareMediator;
|
||||
_selectTagForPairUi = selectTagForPairUi;
|
||||
_serverConfigurationManager = serverConfigurationManager;
|
||||
}
|
||||
|
||||
public bool IsOnline => _pair.IsOnline;
|
||||
public bool IsVisible => _pair.IsVisible;
|
||||
public UserPairDto UserPair => _pair.UserPair!;
|
||||
public Pair Pair => _pair;
|
||||
public string UID => _pair.UserData.UID;
|
||||
public UserFullPairDto UserPair => _pair.UserPair!;
|
||||
|
||||
protected override void DrawLeftSide(float textPosY, float originalY)
|
||||
public void DrawPairedClient()
|
||||
{
|
||||
FontAwesomeIcon connectionIcon;
|
||||
Vector4 connectionColor;
|
||||
string connectionText;
|
||||
if (!(_pair.UserPair!.OwnPermissions.IsPaired() && _pair.UserPair!.OtherPermissions.IsPaired()))
|
||||
using var id = ImRaii.PushId(GetType() + _id);
|
||||
var originalY = ImGui.GetCursorPosY();
|
||||
var pauseIconSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Bars);
|
||||
var textSize = ImGui.CalcTextSize(_pair.UserData.AliasOrUID);
|
||||
|
||||
var textPosY = originalY + pauseIconSize.Y / 2 - textSize.Y / 2;
|
||||
DrawLeftSide(textPosY);
|
||||
ImGui.SameLine();
|
||||
var posX = ImGui.GetCursorPosX();
|
||||
var rightSide = DrawRightSide(originalY);
|
||||
DrawName(originalY, posX, rightSide);
|
||||
}
|
||||
|
||||
private void DrawCommonClientMenu()
|
||||
{
|
||||
if (!_pair.IsPaused)
|
||||
{
|
||||
connectionIcon = FontAwesomeIcon.ArrowUp;
|
||||
connectionText = _pair.UserData.AliasOrUID + " has not added you back";
|
||||
connectionColor = ImGuiColors.DalamudRed;
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.User, "Open Profile", _menuRenderWidth, true))
|
||||
{
|
||||
_displayHandler.OpenProfile(_pair);
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
UiSharedService.AttachToolTip("Opens the profile for this user in a new window");
|
||||
}
|
||||
else if (_pair.UserPair!.OwnPermissions.IsPaused() || _pair.UserPair!.OtherPermissions.IsPaused())
|
||||
if (_pair.IsVisible)
|
||||
{
|
||||
connectionIcon = FontAwesomeIcon.PauseCircle;
|
||||
connectionText = "Pairing status with " + _pair.UserData.AliasOrUID + " is paused";
|
||||
connectionColor = ImGuiColors.DalamudYellow;
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Sync, "Reload last data", _menuRenderWidth, true))
|
||||
{
|
||||
_pair.ApplyLastReceivedData(forced: true);
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
UiSharedService.AttachToolTip("This reapplies the last received character data to this character");
|
||||
}
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.PlayCircle, "Cycle pause state", _menuRenderWidth, true))
|
||||
{
|
||||
_ = _apiController.CyclePause(_pair.UserData);
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.TextUnformatted("Pair Permission Functions");
|
||||
var isSticky = _pair.UserPair!.OwnPermissions.IsSticky();
|
||||
string stickyText = isSticky ? "Disable Preferred Permissions" : "Enable Preferred Permissions";
|
||||
var stickyIcon = isSticky ? FontAwesomeIcon.ArrowCircleDown : FontAwesomeIcon.ArrowCircleUp;
|
||||
if (UiSharedService.IconTextButton(stickyIcon, stickyText, _menuRenderWidth, true))
|
||||
{
|
||||
var permissions = _pair.UserPair.OwnPermissions;
|
||||
permissions.SetSticky(!isSticky);
|
||||
_ = _apiController.UserSetPairPermissions(new(_pair.UserData, permissions));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Preferred permissions means that this pair will not" + Environment.NewLine + " be affected by any syncshell permission changes through you.");
|
||||
|
||||
string individualText = Environment.NewLine + Environment.NewLine + "Note: changing this permission will turn the permissions for this"
|
||||
+ Environment.NewLine + "user to preferred permissions. You can change this behavior"
|
||||
+ Environment.NewLine + "in the permission settings.";
|
||||
bool individual = !_pair.IsDirectlyPaired && _apiController.DefaultPermissions!.IndividualIsSticky;
|
||||
|
||||
var isDisableSounds = _pair.UserPair!.OwnPermissions.IsDisableSounds();
|
||||
string disableSoundsText = isDisableSounds ? "Enable sound sync" : "Disable sound sync";
|
||||
var disableSoundsIcon = isDisableSounds ? FontAwesomeIcon.VolumeUp : FontAwesomeIcon.VolumeMute;
|
||||
if (UiSharedService.IconTextButton(disableSoundsIcon, disableSoundsText, _menuRenderWidth, true))
|
||||
{
|
||||
var permissions = _pair.UserPair.OwnPermissions;
|
||||
permissions.SetDisableSounds(!isDisableSounds);
|
||||
_ = _apiController.UserSetPairPermissions(new UserPermissionsDto(_pair.UserData, permissions));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Changes sound sync permissions with this user." + (individual ? individualText : string.Empty));
|
||||
|
||||
var isDisableAnims = _pair.UserPair!.OwnPermissions.IsDisableAnimations();
|
||||
string disableAnimsText = isDisableAnims ? "Enable animation sync" : "Disable animation sync";
|
||||
var disableAnimsIcon = isDisableAnims ? FontAwesomeIcon.Running : FontAwesomeIcon.Stop;
|
||||
if (UiSharedService.IconTextButton(disableAnimsIcon, disableAnimsText, _menuRenderWidth, true))
|
||||
{
|
||||
var permissions = _pair.UserPair.OwnPermissions;
|
||||
permissions.SetDisableAnimations(!isDisableAnims);
|
||||
_ = _apiController.UserSetPairPermissions(new UserPermissionsDto(_pair.UserData, permissions));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Changes animation sync permissions with this user." + (individual ? individualText : string.Empty));
|
||||
|
||||
var isDisableVFX = _pair.UserPair!.OwnPermissions.IsDisableVFX();
|
||||
string disableVFXText = isDisableVFX ? "Enable VFX sync" : "Disable VFX sync";
|
||||
var disableVFXIcon = isDisableVFX ? FontAwesomeIcon.Sun : FontAwesomeIcon.Circle;
|
||||
if (UiSharedService.IconTextButton(disableVFXIcon, disableVFXText, _menuRenderWidth, true))
|
||||
{
|
||||
var permissions = _pair.UserPair.OwnPermissions;
|
||||
permissions.SetDisableVFX(!isDisableVFX);
|
||||
_ = _apiController.UserSetPairPermissions(new UserPermissionsDto(_pair.UserData, permissions));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Changes VFX sync permissions with this user." + (individual ? individualText : string.Empty));
|
||||
|
||||
if (!_pair.IsPaused)
|
||||
{
|
||||
ImGui.Separator();
|
||||
ImGui.TextUnformatted("Pair reporting");
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.ExclamationTriangle, "Report Mare Profile", _menuRenderWidth, true))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_mediator.Publish(new OpenReportPopupMessage(_pair));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Report this users Mare Profile to the administrative team.");
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawIndividualMenu()
|
||||
{
|
||||
ImGui.TextUnformatted("Individual Pair Functions");
|
||||
var entryUID = _pair.UserData.AliasOrUID;
|
||||
|
||||
if (_pair.IndividualPairStatus != API.Data.Enum.IndividualPairStatus.None)
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Folder, "Pair Groups", _menuRenderWidth, true))
|
||||
{
|
||||
_selectTagForPairUi.Open(_pair);
|
||||
}
|
||||
UiSharedService.AttachToolTip("Choose pair groups for " + entryUID);
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Unpair Permanently", _menuRenderWidth, true) && UiSharedService.CtrlPressed())
|
||||
{
|
||||
_ = _apiController.UserRemovePair(new(_pair.UserData));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hold CTRL and click to unpair permanently from " + entryUID);
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionIcon = FontAwesomeIcon.Check;
|
||||
connectionText = "You are paired with " + _pair.UserData.AliasOrUID;
|
||||
connectionColor = ImGuiColors.ParsedGreen;
|
||||
}
|
||||
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
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(textPosY);
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
UiSharedService.ColorText(FontAwesomeIcon.Eye.ToIconString(), ImGuiColors.ParsedGreen);
|
||||
ImGui.PopFont();
|
||||
UiSharedService.AttachToolTip(_pair.UserData.AliasOrUID + " is visible: " + _pair.PlayerName!);
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Plus, "Pair individually", _menuRenderWidth, true))
|
||||
{
|
||||
_ = _apiController.UserAddPair(new(_pair.UserData));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Pair individually with " + entryUID);
|
||||
}
|
||||
}
|
||||
|
||||
protected override float DrawRightSide(float textPosY, float originalY)
|
||||
private void DrawLeftSide(float textPosY)
|
||||
{
|
||||
string userPairText = string.Empty;
|
||||
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
|
||||
if (_pair.IsPaused)
|
||||
{
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
using var _ = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudYellow);
|
||||
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
||||
ImGui.TextUnformatted(FontAwesomeIcon.PauseCircle.ToIconString());
|
||||
userPairText = _pair.UserData.AliasOrUID + " is paused";
|
||||
}
|
||||
else if (!_pair.IsOnline)
|
||||
{
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
using var _ = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
|
||||
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
||||
ImGui.TextUnformatted(_pair.IndividualPairStatus == API.Data.Enum.IndividualPairStatus.Bidirectional
|
||||
? FontAwesomeIcon.User.ToIconString() : FontAwesomeIcon.Users.ToIconString());
|
||||
userPairText = _pair.UserData.AliasOrUID + " is offline";
|
||||
}
|
||||
else
|
||||
{
|
||||
using var _ = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.ParsedGreen);
|
||||
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
||||
ImGui.TextUnformatted(_pair.IndividualPairStatus == API.Data.Enum.IndividualPairStatus.Bidirectional
|
||||
? FontAwesomeIcon.User.ToIconString() : FontAwesomeIcon.Users.ToIconString());
|
||||
userPairText = _pair.UserData.AliasOrUID + " is online";
|
||||
}
|
||||
|
||||
if (_pair.IndividualPairStatus == API.Data.Enum.IndividualPairStatus.OneSided)
|
||||
{
|
||||
userPairText += UiSharedService.TooltipSeparator + "User has not added you back";
|
||||
}
|
||||
else if (_pair.IndividualPairStatus == API.Data.Enum.IndividualPairStatus.Bidirectional)
|
||||
{
|
||||
userPairText += UiSharedService.TooltipSeparator + "You are directly Paired";
|
||||
}
|
||||
|
||||
if (_syncedGroups.Any())
|
||||
{
|
||||
userPairText += UiSharedService.TooltipSeparator + string.Join(Environment.NewLine,
|
||||
_syncedGroups.Select(g =>
|
||||
{
|
||||
var groupNote = _serverConfigurationManager.GetNoteForGid(g.GID);
|
||||
var groupString = string.IsNullOrEmpty(groupNote) ? g.GroupAliasOrGID : $"{groupNote} ({g.GroupAliasOrGID})";
|
||||
return "Paired through " + groupString;
|
||||
}));
|
||||
}
|
||||
UiSharedService.AttachToolTip(userPairText);
|
||||
|
||||
if (_pair.UserPair.OwnPermissions.IsSticky())
|
||||
{
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
|
||||
using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing with { X = ImGui.GetStyle().ItemSpacing.X * 3 / 4f }))
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(FontAwesomeIcon.ArrowCircleUp.ToIconString());
|
||||
}
|
||||
|
||||
UiSharedService.AttachToolTip(_pair.UserData.AliasOrUID + " has preferred permissions enabled");
|
||||
}
|
||||
|
||||
if (_pair.IsVisible)
|
||||
{
|
||||
ImGui.SetCursorPosY(textPosY);
|
||||
using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing with { X = ImGui.GetStyle().ItemSpacing.X * 3 / 4f }))
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
{
|
||||
ImGui.SameLine();
|
||||
using var _ = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.ParsedGreen);
|
||||
ImGui.TextUnformatted(FontAwesomeIcon.Eye.ToIconString());
|
||||
}
|
||||
|
||||
UiSharedService.AttachToolTip("User is visible: " + _pair.PlayerName);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawName(float originalY, float leftSide, float rightSide)
|
||||
{
|
||||
_displayHandler.DrawPairText(_id, _pair, leftSide, originalY, () => rightSide - leftSide);
|
||||
}
|
||||
|
||||
private void DrawPairedClientMenu()
|
||||
{
|
||||
DrawIndividualMenu();
|
||||
|
||||
if (_syncedGroups.Any()) ImGui.Separator();
|
||||
foreach (var entry in _syncedGroups)
|
||||
{
|
||||
bool selfIsOwner = string.Equals(_apiController.UID, entry.Owner.UID, StringComparison.Ordinal);
|
||||
bool selfIsModerator = entry.GroupUserInfo.IsModerator();
|
||||
bool userIsModerator = entry.GroupPairUserInfos.TryGetValue(_pair.UserData.UID, out var modinfo) && modinfo.IsModerator();
|
||||
bool userIsPinned = entry.GroupPairUserInfos.TryGetValue(_pair.UserData.UID, out var info) && info.IsPinned();
|
||||
if (selfIsOwner || selfIsModerator)
|
||||
{
|
||||
var groupNote = _serverConfigurationManager.GetNoteForGid(entry.GID);
|
||||
var groupString = string.IsNullOrEmpty(groupNote) ? entry.GroupAliasOrGID : $"{groupNote} ({entry.GroupAliasOrGID})";
|
||||
|
||||
if (ImGui.BeginMenu(groupString + " Moderation Functions"))
|
||||
{
|
||||
DrawSyncshellMenu(entry, selfIsOwner, selfIsModerator, userIsPinned, userIsModerator);
|
||||
ImGui.EndMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float DrawRightSide(float originalY)
|
||||
{
|
||||
var pauseIcon = _pair.UserPair!.OwnPermissions.IsPaused() ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
|
||||
var pauseIconSize = UiSharedService.GetIconButtonSize(pauseIcon);
|
||||
@@ -76,8 +301,9 @@ public class DrawUserPair : DrawPairBase
|
||||
var spacingX = ImGui.GetStyle().ItemSpacing.X;
|
||||
var windowEndX = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth();
|
||||
var rightSideStart = 0f;
|
||||
float infoIconDist = 0f;
|
||||
|
||||
if (_pair.UserPair!.OwnPermissions.IsPaired() && _pair.UserPair!.OtherPermissions.IsPaired())
|
||||
if (_pair.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);
|
||||
@@ -86,75 +312,83 @@ public class DrawUserPair : DrawPairBase
|
||||
if (individualAnimDisabled || individualSoundsDisabled || individualVFXDisabled)
|
||||
{
|
||||
var infoIconPosDist = windowEndX - barButtonSize.X - spacingX - pauseIconSize.X - spacingX;
|
||||
var icon = FontAwesomeIcon.ExclamationTriangle;
|
||||
var icon = FontAwesomeIcon.InfoCircle;
|
||||
var iconwidth = UiSharedService.GetIconSize(icon);
|
||||
|
||||
rightSideStart = infoIconPosDist - iconwidth.X;
|
||||
infoIconDist = 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");
|
||||
ImGui.TextUnformatted("Individual User permissions");
|
||||
ImGui.Separator();
|
||||
|
||||
if (individualSoundsDisabled)
|
||||
{
|
||||
var userSoundsText = "Sound sync disabled with " + _pair.UserData.AliasOrUID;
|
||||
var userSoundsText = "Sound sync";
|
||||
UiSharedService.FontText(FontAwesomeIcon.VolumeOff.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(userSoundsText);
|
||||
ImGui.TextUnformatted(userSoundsText);
|
||||
ImGui.NewLine();
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text("You: " + (_pair.UserPair!.OwnPermissions.IsDisableSounds() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableSounds() ? "Disabled" : "Enabled"));
|
||||
ImGui.TextUnformatted("You");
|
||||
UiSharedService.BooleanToColoredIcon(!_pair.UserPair!.OwnPermissions.IsDisableSounds());
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted("They");
|
||||
UiSharedService.BooleanToColoredIcon(!_pair.UserPair!.OtherPermissions.IsDisableSounds());
|
||||
}
|
||||
|
||||
if (individualAnimDisabled)
|
||||
{
|
||||
var userAnimText = "Animation sync disabled with " + _pair.UserData.AliasOrUID;
|
||||
var userAnimText = "Animation sync";
|
||||
UiSharedService.FontText(FontAwesomeIcon.Stop.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(userAnimText);
|
||||
ImGui.TextUnformatted(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.TextUnformatted("You");
|
||||
UiSharedService.BooleanToColoredIcon(!_pair.UserPair!.OwnPermissions.IsDisableAnimations());
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted("They");
|
||||
UiSharedService.BooleanToColoredIcon(!_pair.UserPair!.OtherPermissions.IsDisableAnimations());
|
||||
}
|
||||
|
||||
if (individualVFXDisabled)
|
||||
{
|
||||
var userVFXText = "VFX sync disabled with " + _pair.UserData.AliasOrUID;
|
||||
var userVFXText = "VFX sync";
|
||||
UiSharedService.FontText(FontAwesomeIcon.Circle.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(userVFXText);
|
||||
ImGui.TextUnformatted(userVFXText);
|
||||
ImGui.NewLine();
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text("You: " + (_pair.UserPair!.OwnPermissions.IsDisableVFX() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableVFX() ? "Disabled" : "Enabled"));
|
||||
ImGui.TextUnformatted("You");
|
||||
UiSharedService.BooleanToColoredIcon(!_pair.UserPair!.OwnPermissions.IsDisableVFX());
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted("They");
|
||||
UiSharedService.BooleanToColoredIcon(!_pair.UserPair!.OtherPermissions.IsDisableVFX());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
rightSideStart = windowEndX - barButtonSize.X - spacingX * 3 - pauseIconSize.X - infoIconDist;
|
||||
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)
|
||||
{
|
||||
@@ -169,91 +403,90 @@ public class DrawUserPair : DrawPairBase
|
||||
}
|
||||
if (ImGui.BeginPopup("User Flyout Menu"))
|
||||
{
|
||||
UiSharedService.DrawWithID($"buttons-{_pair.UserData.UID}", () => DrawPairedClientMenu(_pair));
|
||||
UiSharedService.DrawWithID($"buttons-{_pair.UserData.UID}", () =>
|
||||
{
|
||||
ImGui.TextUnformatted("Common Pair Functions");
|
||||
DrawCommonClientMenu();
|
||||
ImGui.Separator();
|
||||
DrawPairedClientMenu();
|
||||
if (_menuRenderWidth <= 0)
|
||||
{
|
||||
_menuRenderWidth = ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X;
|
||||
}
|
||||
});
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
return rightSideStart;
|
||||
}
|
||||
|
||||
private void DrawPairedClientMenu(Pair entry)
|
||||
private void DrawSyncshellMenu(GroupFullInfoDto group, bool selfIsOwner, bool selfIsModerator, bool userIsPinned, bool userIsModerator)
|
||||
{
|
||||
if (!entry.IsPaused)
|
||||
if (selfIsOwner || ((selfIsModerator) && (!userIsModerator)))
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.User, "Open Profile"))
|
||||
{
|
||||
_displayHandler.OpenProfile(entry);
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
UiSharedService.AttachToolTip("Opens the profile for this user in a new window");
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.PlayCircle, "Cycle pause state"))
|
||||
{
|
||||
_ = _apiController.CyclePause(entry.UserData);
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
var isDisableVFX = entry.UserPair!.OwnPermissions.IsDisableVFX();
|
||||
string disableVFXText = isDisableVFX ? "Enable VFX sync" : "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, "Unpair Permanently") && UiSharedService.CtrlPressed())
|
||||
{
|
||||
_ = _apiController.UserRemovePair(new(entry.UserData));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hold CTRL and click to unpair permanently from " + entryUID);
|
||||
|
||||
ImGui.Separator();
|
||||
if (!entry.IsPaused)
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.ExclamationTriangle, "Report Mare Profile"))
|
||||
ImGui.TextUnformatted("Syncshell Moderator Functions");
|
||||
var pinText = userIsPinned ? "Unpin user" : "Pin user";
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Thumbtack, pinText, _menuRenderWidth, true))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_showModalReport = true;
|
||||
if (!group.GroupPairUserInfos.TryGetValue(_pair.UserData.UID, out var userinfo))
|
||||
{
|
||||
userinfo = API.Data.Enum.GroupPairUserInfo.IsPinned;
|
||||
}
|
||||
else
|
||||
{
|
||||
userinfo.SetPinned(!userinfo.IsPinned());
|
||||
}
|
||||
_ = _apiController.GroupSetUserInfo(new GroupPairUserInfoDto(group.Group, _pair.UserData, userinfo));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Report this users Mare Profile to the administrative team");
|
||||
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", _menuRenderWidth, true) && UiSharedService.CtrlPressed())
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = _apiController.GroupRemoveUser(new(group.Group, _pair.UserData));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hold CTRL and click to remove user " + (_pair.UserData.AliasOrUID) + " from Syncshell");
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.UserSlash, "Ban User", _menuRenderWidth, true))
|
||||
{
|
||||
_mediator.Publish(new OpenBanUserPopupMessage(_pair, group));
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
UiSharedService.AttachToolTip("Ban user from this Syncshell");
|
||||
|
||||
ImGui.Separator();
|
||||
}
|
||||
|
||||
if (selfIsOwner)
|
||||
{
|
||||
ImGui.TextUnformatted("Syncshell Owner Functions");
|
||||
string modText = userIsModerator ? "Demod user" : "Mod user";
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.UserShield, modText, _menuRenderWidth, true) && UiSharedService.CtrlPressed())
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
if (!group.GroupPairUserInfos.TryGetValue(_pair.UserData.UID, out var userinfo))
|
||||
{
|
||||
userinfo = API.Data.Enum.GroupPairUserInfo.IsModerator;
|
||||
}
|
||||
else
|
||||
{
|
||||
userinfo.SetModerator(!userinfo.IsModerator());
|
||||
}
|
||||
|
||||
_ = _apiController.GroupSetUserInfo(new GroupPairUserInfoDto(group.Group, _pair.UserData, userinfo));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hold CTRL to change the moderator status for " + (_pair.UserData.AliasOrUID) + Environment.NewLine +
|
||||
"Moderators can kick, ban/unban, pin/unpin users and clear the Syncshell.");
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Crown, "Transfer Ownership", _menuRenderWidth, true) && UiSharedService.CtrlPressed() && UiSharedService.ShiftPressed())
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = _apiController.GroupChangeOwnership(new(group.Group, _pair.UserData));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hold CTRL and SHIFT and click to transfer ownership of this Syncshell to "
|
||||
+ (_pair.UserData.AliasOrUID) + Environment.NewLine + "WARNING: This action is irreversible.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,765 +0,0 @@
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.WebAPI;
|
||||
using System.Numerics;
|
||||
using System.Globalization;
|
||||
using MareSynchronos.API.Data;
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronos.API.Data.Enum;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.API.Data.Comparer;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services.ServerConfiguration;
|
||||
using MareSynchronos.UI.Components;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
using Dalamud.Interface.Utility;
|
||||
|
||||
namespace MareSynchronos.UI;
|
||||
|
||||
internal sealed class GroupPanel
|
||||
{
|
||||
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 int _bulkInviteCount = 10;
|
||||
private List<string> _bulkOneTimeInvites = new();
|
||||
private string _editGroupComment = string.Empty;
|
||||
private string _editGroupEntry = string.Empty;
|
||||
private bool _errorGroupCreate = false;
|
||||
private bool _errorGroupJoin;
|
||||
private bool _isPasswordValid;
|
||||
private GroupPasswordDto? _lastCreatedGroup = null;
|
||||
private bool _modalBanListOpened;
|
||||
private bool _modalBulkOneTimeInvitesOpened;
|
||||
private bool _modalChangePwOpened;
|
||||
private string _newSyncShellPassword = string.Empty;
|
||||
private bool _showModalBanList = false;
|
||||
private bool _showModalBulkOneTimeInvites = false;
|
||||
private bool _showModalChangePassword;
|
||||
private bool _showModalCreateGroup;
|
||||
private bool _showModalEnterPassword;
|
||||
private string _syncShellPassword = string.Empty;
|
||||
private string _syncShellToJoin = string.Empty;
|
||||
|
||||
public GroupPanel(CompactUi mainUi, UiSharedService uiShared, PairManager pairManager, UidDisplayHandler uidDisplayHandler, ServerConfigurationManager serverConfigurationManager)
|
||||
{
|
||||
_mainUi = mainUi;
|
||||
_uiShared = uiShared;
|
||||
_pairManager = pairManager;
|
||||
_uidDisplayHandler = uidDisplayHandler;
|
||||
_serverConfigurationManager = serverConfigurationManager;
|
||||
}
|
||||
|
||||
private ApiController ApiController => _uiShared.ApiController;
|
||||
|
||||
public void DrawSyncshells()
|
||||
{
|
||||
UiSharedService.DrawWithID("addsyncshell", DrawAddSyncshell);
|
||||
UiSharedService.DrawWithID("syncshelllist", DrawSyncshellList);
|
||||
_mainUi.TransferPartHeight = ImGui.GetCursorPosY();
|
||||
}
|
||||
|
||||
private void DrawAddSyncshell()
|
||||
{
|
||||
var buttonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Plus);
|
||||
ImGui.SetNextItemWidth(UiSharedService.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X - buttonSize.X);
|
||||
ImGui.InputTextWithHint("##syncshellid", "Syncshell GID/Alias (leave empty to create)", ref _syncShellToJoin, 20);
|
||||
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() - buttonSize.X);
|
||||
|
||||
bool userCanJoinMoreGroups = _pairManager.GroupPairs.Count < ApiController.ServerInfo.MaxGroupsJoinedByUser;
|
||||
bool userCanCreateMoreGroups = _pairManager.GroupPairs.Count(u => string.Equals(u.Key.Owner.UID, ApiController.UID, StringComparison.Ordinal)) < ApiController.ServerInfo.MaxGroupsCreatedByUser;
|
||||
bool alreadyInGroup = _pairManager.GroupPairs.Select(p => p.Key).Any(p => string.Equals(p.Group.Alias, _syncShellToJoin, StringComparison.Ordinal)
|
||||
|| string.Equals(p.Group.GID, _syncShellToJoin, StringComparison.Ordinal));
|
||||
|
||||
if (alreadyInGroup) ImGui.BeginDisabled();
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_syncShellToJoin))
|
||||
{
|
||||
if (userCanJoinMoreGroups)
|
||||
{
|
||||
_errorGroupJoin = false;
|
||||
_showModalEnterPassword = true;
|
||||
ImGui.OpenPopup("Enter Syncshell Password");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (userCanCreateMoreGroups)
|
||||
{
|
||||
_lastCreatedGroup = null;
|
||||
_errorGroupCreate = false;
|
||||
_showModalCreateGroup = true;
|
||||
ImGui.OpenPopup("Create Syncshell");
|
||||
}
|
||||
}
|
||||
}
|
||||
UiSharedService.AttachToolTip(_syncShellToJoin.IsNullOrEmpty()
|
||||
? (userCanCreateMoreGroups ? "Create Syncshell" : $"You cannot create more than {ApiController.ServerInfo.MaxGroupsCreatedByUser} Syncshells")
|
||||
: (userCanJoinMoreGroups ? "Join Syncshell" + _syncShellToJoin : $"You cannot join more than {ApiController.ServerInfo.MaxGroupsJoinedByUser} Syncshells"));
|
||||
|
||||
if (alreadyInGroup) ImGui.EndDisabled();
|
||||
|
||||
if (ImGui.BeginPopupModal("Enter Syncshell Password", ref _showModalEnterPassword, UiSharedService.PopupWindowFlags))
|
||||
{
|
||||
UiSharedService.TextWrapped("Before joining any Syncshells please be aware that you will be automatically paired with everyone in the Syncshell.");
|
||||
ImGui.Separator();
|
||||
UiSharedService.TextWrapped("Enter the password for Syncshell " + _syncShellToJoin + ":");
|
||||
ImGui.SetNextItemWidth(-1);
|
||||
ImGui.InputTextWithHint("##password", _syncShellToJoin + " Password", ref _syncShellPassword, 255, ImGuiInputTextFlags.Password);
|
||||
if (_errorGroupJoin)
|
||||
{
|
||||
UiSharedService.ColorTextWrapped($"An error occured during joining of this Syncshell: you either have joined the maximum amount of Syncshells ({ApiController.ServerInfo.MaxGroupsJoinedByUser}), " +
|
||||
$"it does not exist, the password you entered is wrong, you already joined the Syncshell, the Syncshell is full ({ApiController.ServerInfo.MaxGroupUserCount} users) or the Syncshell has closed invites.",
|
||||
new Vector4(1, 0, 0, 1));
|
||||
}
|
||||
if (ImGui.Button("Join " + _syncShellToJoin))
|
||||
{
|
||||
var shell = _syncShellToJoin;
|
||||
var pw = _syncShellPassword;
|
||||
_errorGroupJoin = !ApiController.GroupJoin(new(new GroupData(shell), pw)).Result;
|
||||
if (!_errorGroupJoin)
|
||||
{
|
||||
_syncShellToJoin = string.Empty;
|
||||
_showModalEnterPassword = false;
|
||||
}
|
||||
_syncShellPassword = string.Empty;
|
||||
}
|
||||
UiSharedService.SetScaledWindowSize(290);
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
if (ImGui.BeginPopupModal("Create Syncshell", ref _showModalCreateGroup, UiSharedService.PopupWindowFlags))
|
||||
{
|
||||
UiSharedService.TextWrapped("Press the button below to create a new Syncshell.");
|
||||
ImGui.SetNextItemWidth(200);
|
||||
if (ImGui.Button("Create Syncshell"))
|
||||
{
|
||||
try
|
||||
{
|
||||
_lastCreatedGroup = ApiController.GroupCreate().Result;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_lastCreatedGroup = null;
|
||||
_errorGroupCreate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_lastCreatedGroup != null)
|
||||
{
|
||||
ImGui.Separator();
|
||||
_errorGroupCreate = false;
|
||||
ImGui.TextUnformatted("Syncshell ID: " + _lastCreatedGroup.Group.GID);
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Syncshell Password: " + _lastCreatedGroup.Password);
|
||||
ImGui.SameLine();
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Copy))
|
||||
{
|
||||
ImGui.SetClipboardText(_lastCreatedGroup.Password);
|
||||
}
|
||||
UiSharedService.TextWrapped("You can change the Syncshell password later at any time.");
|
||||
}
|
||||
|
||||
if (_errorGroupCreate)
|
||||
{
|
||||
UiSharedService.ColorTextWrapped("You are already owner of the maximum amount of Syncshells (3) or joined the maximum amount of Syncshells (6). Relinquish ownership of your own Syncshells to someone else or leave existing Syncshells.",
|
||||
new Vector4(1, 0, 0, 1));
|
||||
}
|
||||
|
||||
UiSharedService.SetScaledWindowSize(350);
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(2);
|
||||
}
|
||||
|
||||
private void DrawSyncshell(GroupFullInfoDto groupDto, List<Pair> pairsInGroup)
|
||||
{
|
||||
var name = groupDto.Group.Alias ?? groupDto.GID;
|
||||
if (!_expandedGroupState.TryGetValue(groupDto.GID, out bool isExpanded))
|
||||
{
|
||||
isExpanded = false;
|
||||
_expandedGroupState.Add(groupDto.GID, isExpanded);
|
||||
}
|
||||
var icon = isExpanded ? FontAwesomeIcon.CaretSquareDown : FontAwesomeIcon.CaretSquareRight;
|
||||
var collapseButton = UiSharedService.GetIconButtonSize(icon);
|
||||
ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0, 0, 0, 0));
|
||||
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0, 0, 0, 0));
|
||||
if (ImGuiComponents.IconButton(icon))
|
||||
{
|
||||
_expandedGroupState[groupDto.GID] = !_expandedGroupState[groupDto.GID];
|
||||
}
|
||||
ImGui.PopStyleColor(2);
|
||||
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + collapseButton.X);
|
||||
var pauseIcon = groupDto.GroupUserPermissions.IsPaused() ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
|
||||
if (ImGuiComponents.IconButton(pauseIcon))
|
||||
{
|
||||
var userPerm = groupDto.GroupUserPermissions ^ GroupUserPermissions.Paused;
|
||||
_ = ApiController.GroupChangeIndividualPermissionState(new GroupPairUserPermissionDto(groupDto.Group, new UserData(ApiController.UID), userPerm));
|
||||
}
|
||||
UiSharedService.AttachToolTip((groupDto.GroupUserPermissions.IsPaused() ? "Resume" : "Pause") + " pairing with all users in this Syncshell");
|
||||
ImGui.SameLine();
|
||||
|
||||
var textIsGid = true;
|
||||
string groupName = groupDto.GroupAliasOrGID;
|
||||
|
||||
if (string.Equals(groupDto.OwnerUID, ApiController.UID, StringComparison.Ordinal))
|
||||
{
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
ImGui.Text(FontAwesomeIcon.Crown.ToIconString());
|
||||
ImGui.PopFont();
|
||||
UiSharedService.AttachToolTip("You are the owner of Syncshell " + groupName);
|
||||
ImGui.SameLine();
|
||||
}
|
||||
else if (groupDto.GroupUserInfo.IsModerator())
|
||||
{
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
ImGui.Text(FontAwesomeIcon.UserShield.ToIconString());
|
||||
ImGui.PopFont();
|
||||
UiSharedService.AttachToolTip("You are a moderator of Syncshell " + groupName);
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
_showGidForEntry.TryGetValue(groupDto.GID, out var showGidInsteadOfName);
|
||||
var groupComment = _serverConfigurationManager.GetNoteForGid(groupDto.GID);
|
||||
if (!showGidInsteadOfName && !string.IsNullOrEmpty(groupComment))
|
||||
{
|
||||
groupName = groupComment;
|
||||
textIsGid = false;
|
||||
}
|
||||
|
||||
if (!string.Equals(_editGroupEntry, groupDto.GID, StringComparison.Ordinal))
|
||||
{
|
||||
if (textIsGid) ImGui.PushFont(UiBuilder.MonoFont);
|
||||
ImGui.TextUnformatted(groupName);
|
||||
if (textIsGid) ImGui.PopFont();
|
||||
UiSharedService.AttachToolTip("Left click to switch between GID display and comment" + Environment.NewLine +
|
||||
"Right click to change comment for " + groupName + Environment.NewLine + Environment.NewLine
|
||||
+ "Users: " + (pairsInGroup.Count + 1) + ", Owner: " + groupDto.OwnerAliasOrUID);
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||
{
|
||||
var prevState = textIsGid;
|
||||
if (_showGidForEntry.ContainsKey(groupDto.GID))
|
||||
{
|
||||
prevState = _showGidForEntry[groupDto.GID];
|
||||
}
|
||||
|
||||
_showGidForEntry[groupDto.GID] = !prevState;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
_serverConfigurationManager.SetNoteForGid(_editGroupEntry, _editGroupComment);
|
||||
_editGroupComment = _serverConfigurationManager.GetNoteForGid(groupDto.GID) ?? string.Empty;
|
||||
_editGroupEntry = groupDto.GID;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var buttonSizes = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Bars).X + UiSharedService.GetIconSize(FontAwesomeIcon.LockOpen).X;
|
||||
ImGui.SetNextItemWidth(UiSharedService.GetWindowContentRegionWidth() - ImGui.GetCursorPosX() - buttonSizes - ImGui.GetStyle().ItemSpacing.X * 2);
|
||||
if (ImGui.InputTextWithHint("", "Comment/Notes", ref _editGroupComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
|
||||
{
|
||||
_serverConfigurationManager.SetNoteForGid(groupDto.GID, _editGroupComment);
|
||||
_editGroupEntry = string.Empty;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
_editGroupEntry = string.Empty;
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hit ENTER to save\nRight click to cancel");
|
||||
}
|
||||
|
||||
UiSharedService.DrawWithID(groupDto.GID + "settings", () => DrawSyncShellButtons(groupDto, pairsInGroup));
|
||||
|
||||
if (_showModalBanList && !_modalBanListOpened)
|
||||
{
|
||||
_modalBanListOpened = true;
|
||||
ImGui.OpenPopup("Manage Banlist for " + groupDto.GID);
|
||||
}
|
||||
|
||||
if (!_showModalBanList) _modalBanListOpened = false;
|
||||
|
||||
if (ImGui.BeginPopupModal("Manage Banlist for " + groupDto.GID, ref _showModalBanList, UiSharedService.PopupWindowFlags))
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Retweet, "Refresh Banlist from Server"))
|
||||
{
|
||||
_bannedUsers = ApiController.GroupGetBannedUsers(groupDto).Result;
|
||||
}
|
||||
|
||||
if (ImGui.BeginTable("bannedusertable" + groupDto.GID, 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingStretchProp | ImGuiTableFlags.ScrollY))
|
||||
{
|
||||
ImGui.TableSetupColumn("UID", ImGuiTableColumnFlags.None, 1);
|
||||
ImGui.TableSetupColumn("Alias", ImGuiTableColumnFlags.None, 1);
|
||||
ImGui.TableSetupColumn("By", ImGuiTableColumnFlags.None, 1);
|
||||
ImGui.TableSetupColumn("Date", ImGuiTableColumnFlags.None, 2);
|
||||
ImGui.TableSetupColumn("Reason", ImGuiTableColumnFlags.None, 3);
|
||||
ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.None, 1);
|
||||
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
foreach (var bannedUser in _bannedUsers.ToList())
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(bannedUser.UID);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(bannedUser.UserAlias ?? string.Empty);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(bannedUser.BannedBy);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(bannedUser.BannedOn.ToLocalTime().ToString(CultureInfo.CurrentCulture));
|
||||
ImGui.TableNextColumn();
|
||||
UiSharedService.TextWrapped(bannedUser.Reason);
|
||||
ImGui.TableNextColumn();
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Check, "Unban#" + bannedUser.UID))
|
||||
{
|
||||
_ = ApiController.GroupUnbanUser(bannedUser);
|
||||
_bannedUsers.RemoveAll(b => string.Equals(b.UID, bannedUser.UID, StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
UiSharedService.SetScaledWindowSize(700, 300);
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
if (_showModalChangePassword && !_modalChangePwOpened)
|
||||
{
|
||||
_modalChangePwOpened = true;
|
||||
ImGui.OpenPopup("Change Syncshell Password");
|
||||
}
|
||||
|
||||
if (!_showModalChangePassword) _modalChangePwOpened = false;
|
||||
|
||||
if (ImGui.BeginPopupModal("Change Syncshell Password", ref _showModalChangePassword, UiSharedService.PopupWindowFlags))
|
||||
{
|
||||
UiSharedService.TextWrapped("Enter the new Syncshell password for Syncshell " + name + " here.");
|
||||
UiSharedService.TextWrapped("This action is irreversible");
|
||||
ImGui.SetNextItemWidth(-1);
|
||||
ImGui.InputTextWithHint("##changepw", "New password for " + name, ref _newSyncShellPassword, 255);
|
||||
if (ImGui.Button("Change password"))
|
||||
{
|
||||
var pw = _newSyncShellPassword;
|
||||
_isPasswordValid = ApiController.GroupChangePassword(new(groupDto.Group, pw)).Result;
|
||||
_newSyncShellPassword = string.Empty;
|
||||
if (_isPasswordValid) _showModalChangePassword = false;
|
||||
}
|
||||
|
||||
if (!_isPasswordValid)
|
||||
{
|
||||
UiSharedService.ColorTextWrapped("The selected password is too short. It must be at least 10 characters.", new Vector4(1, 0, 0, 1));
|
||||
}
|
||||
|
||||
UiSharedService.SetScaledWindowSize(290);
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
if (_showModalBulkOneTimeInvites && !_modalBulkOneTimeInvitesOpened)
|
||||
{
|
||||
_modalBulkOneTimeInvitesOpened = true;
|
||||
ImGui.OpenPopup("Create Bulk One-Time Invites");
|
||||
}
|
||||
|
||||
if (!_showModalBulkOneTimeInvites) _modalBulkOneTimeInvitesOpened = false;
|
||||
|
||||
if (ImGui.BeginPopupModal("Create Bulk One-Time Invites", ref _showModalBulkOneTimeInvites, UiSharedService.PopupWindowFlags))
|
||||
{
|
||||
UiSharedService.TextWrapped("This allows you to create up to 100 one-time invites at once for the Syncshell " + name + "." + Environment.NewLine
|
||||
+ "The invites are valid for 24h after creation and will automatically expire.");
|
||||
ImGui.Separator();
|
||||
if (_bulkOneTimeInvites.Count == 0)
|
||||
{
|
||||
ImGui.SetNextItemWidth(-1);
|
||||
ImGui.SliderInt("Amount##bulkinvites", ref _bulkInviteCount, 1, 100);
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.MailBulk, "Create invites"))
|
||||
{
|
||||
_bulkOneTimeInvites = ApiController.GroupCreateTempInvite(groupDto, _bulkInviteCount).Result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UiSharedService.TextWrapped("A total of " + _bulkOneTimeInvites.Count + " invites have been created.");
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Copy, "Copy invites to clipboard"))
|
||||
{
|
||||
ImGui.SetClipboardText(string.Join(Environment.NewLine, _bulkOneTimeInvites));
|
||||
}
|
||||
}
|
||||
|
||||
UiSharedService.SetScaledWindowSize(290);
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGui.Indent(collapseButton.X);
|
||||
if (_expandedGroupState[groupDto.GID])
|
||||
{
|
||||
var visibleUsers = pairsInGroup.Where(u => 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(groupDto.GID + c.UserData.UID, 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(groupDto.GID + c.UserData.UID, 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(groupDto.GID + c.UserData.UID, c, ApiController, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
|
||||
_uidDisplayHandler))
|
||||
.ToList();
|
||||
|
||||
if (visibleUsers.Any())
|
||||
{
|
||||
ImGui.Text("Visible");
|
||||
ImGui.Separator();
|
||||
foreach (var entry in visibleUsers)
|
||||
{
|
||||
UiSharedService.DrawWithID(groupDto.GID + entry.UID, () => entry.DrawPairedClient());
|
||||
}
|
||||
}
|
||||
|
||||
if (onlineUsers.Any())
|
||||
{
|
||||
ImGui.Text("Online");
|
||||
ImGui.Separator();
|
||||
foreach (var entry in onlineUsers)
|
||||
{
|
||||
UiSharedService.DrawWithID(groupDto.GID + entry.UID, () => entry.DrawPairedClient());
|
||||
}
|
||||
}
|
||||
|
||||
if (offlineUsers.Any())
|
||||
{
|
||||
ImGui.Text("Offline/Unknown");
|
||||
ImGui.Separator();
|
||||
foreach (var entry in offlineUsers)
|
||||
{
|
||||
UiSharedService.DrawWithID(groupDto.GID + entry.UID, () => entry.DrawPairedClient());
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Unindent(ImGui.GetStyle().ItemSpacing.X / 2);
|
||||
}
|
||||
ImGui.Unindent(collapseButton.X);
|
||||
}
|
||||
|
||||
private void DrawSyncShellButtons(GroupFullInfoDto groupDto, List<Pair> groupPairs)
|
||||
{
|
||||
var infoIcon = FontAwesomeIcon.InfoCircle;
|
||||
|
||||
bool invitesEnabled = !groupDto.GroupPermissions.IsDisableInvites();
|
||||
var soundsDisabled = groupDto.GroupPermissions.IsDisableSounds();
|
||||
var animDisabled = groupDto.GroupPermissions.IsDisableAnimations();
|
||||
var vfxDisabled = groupDto.GroupPermissions.IsDisableVFX();
|
||||
|
||||
var userSoundsDisabled = groupDto.GroupUserPermissions.IsDisableSounds();
|
||||
var userAnimDisabled = groupDto.GroupUserPermissions.IsDisableAnimations();
|
||||
var userVFXDisabled = groupDto.GroupUserPermissions.IsDisableVFX();
|
||||
|
||||
bool showInfoIcon = !invitesEnabled || soundsDisabled || animDisabled || vfxDisabled || userSoundsDisabled || userAnimDisabled || userVFXDisabled;
|
||||
|
||||
var lockedIcon = invitesEnabled ? FontAwesomeIcon.LockOpen : FontAwesomeIcon.Lock;
|
||||
var animIcon = animDisabled ? FontAwesomeIcon.Stop : FontAwesomeIcon.Running;
|
||||
var soundsIcon = soundsDisabled ? FontAwesomeIcon.VolumeOff : FontAwesomeIcon.VolumeUp;
|
||||
var vfxIcon = vfxDisabled ? FontAwesomeIcon.Circle : FontAwesomeIcon.Sun;
|
||||
var userAnimIcon = userAnimDisabled ? FontAwesomeIcon.Stop : FontAwesomeIcon.Running;
|
||||
var userSoundsIcon = userSoundsDisabled ? FontAwesomeIcon.VolumeOff : FontAwesomeIcon.VolumeUp;
|
||||
var userVFXIcon = userVFXDisabled ? FontAwesomeIcon.Circle : FontAwesomeIcon.Sun;
|
||||
|
||||
var iconSize = UiSharedService.GetIconSize(infoIcon);
|
||||
var diffLockUnlockIcons = showInfoIcon ? (UiSharedService.GetIconSize(infoIcon).X - iconSize.X) / 2 : 0;
|
||||
var barbuttonSize = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Bars);
|
||||
var isOwner = string.Equals(groupDto.OwnerUID, ApiController.UID, StringComparison.Ordinal);
|
||||
|
||||
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() - barbuttonSize.X - (showInfoIcon ? iconSize.X : 0) - diffLockUnlockIcons - (showInfoIcon ? ImGui.GetStyle().ItemSpacing.X : 0));
|
||||
if (showInfoIcon)
|
||||
{
|
||||
UiSharedService.FontText(infoIcon.ToIconString(), UiBuilder.IconFont);
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
if (!invitesEnabled || soundsDisabled || animDisabled || vfxDisabled)
|
||||
{
|
||||
ImGui.Text("Syncshell permissions");
|
||||
|
||||
if (!invitesEnabled)
|
||||
{
|
||||
var lockedText = "Syncshell is closed for joining";
|
||||
UiSharedService.FontText(lockedIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(lockedText);
|
||||
}
|
||||
|
||||
if (soundsDisabled)
|
||||
{
|
||||
var soundsText = "Sound sync disabled through owner";
|
||||
UiSharedService.FontText(soundsIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(soundsText);
|
||||
}
|
||||
|
||||
if (animDisabled)
|
||||
{
|
||||
var animText = "Animation sync disabled through owner";
|
||||
UiSharedService.FontText(animIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(animText);
|
||||
}
|
||||
|
||||
if (vfxDisabled)
|
||||
{
|
||||
var vfxText = "VFX sync disabled through owner";
|
||||
UiSharedService.FontText(vfxIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(vfxText);
|
||||
}
|
||||
}
|
||||
|
||||
if (userSoundsDisabled || userAnimDisabled || userVFXDisabled)
|
||||
{
|
||||
if (!invitesEnabled || soundsDisabled || animDisabled || vfxDisabled)
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.Text("Your permissions");
|
||||
|
||||
if (userSoundsDisabled)
|
||||
{
|
||||
var userSoundsText = "Sound sync disabled through you";
|
||||
UiSharedService.FontText(userSoundsIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(userSoundsText);
|
||||
}
|
||||
|
||||
if (userAnimDisabled)
|
||||
{
|
||||
var userAnimText = "Animation sync disabled through you";
|
||||
UiSharedService.FontText(userAnimIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(userAnimText);
|
||||
}
|
||||
|
||||
if (userVFXDisabled)
|
||||
{
|
||||
var userVFXText = "VFX sync disabled through you";
|
||||
UiSharedService.FontText(userVFXIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(userVFXText);
|
||||
}
|
||||
|
||||
if (!invitesEnabled || soundsDisabled || animDisabled || vfxDisabled)
|
||||
UiSharedService.TextWrapped("Note that syncshell permissions for disabling take precedence over your own set permissions");
|
||||
}
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + diffLockUnlockIcons);
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars))
|
||||
{
|
||||
ImGui.OpenPopup("ShellPopup");
|
||||
}
|
||||
|
||||
if (ImGui.BeginPopup("ShellPopup"))
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.ArrowCircleLeft, "Leave Syncshell") && UiSharedService.CtrlPressed())
|
||||
{
|
||||
_ = ApiController.GroupLeave(groupDto);
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hold CTRL and click to leave this Syncshell" + (!string.Equals(groupDto.OwnerUID, ApiController.UID, StringComparison.Ordinal) ? string.Empty : Environment.NewLine
|
||||
+ "WARNING: This action is irreversible" + Environment.NewLine + "Leaving an owned Syncshell will transfer the ownership to a random person in the Syncshell."));
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Copy, "Copy ID"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
ImGui.SetClipboardText(groupDto.GroupAliasOrGID);
|
||||
}
|
||||
UiSharedService.AttachToolTip("Copy Syncshell ID to Clipboard");
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.StickyNote, "Copy Notes"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
ImGui.SetClipboardText(UiSharedService.GetNotes(groupPairs));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Copies all your notes for all users in this Syncshell to the clipboard." + Environment.NewLine + "They can be imported via Settings -> Privacy -> Import Notes from Clipboard");
|
||||
|
||||
var soundsText = userSoundsDisabled ? "Enable sound sync" : "Disable sound sync";
|
||||
if (UiSharedService.IconTextButton(userSoundsIcon, soundsText))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var perm = groupDto.GroupUserPermissions;
|
||||
perm.SetDisableSounds(!perm.IsDisableSounds());
|
||||
_ = ApiController.GroupChangeIndividualPermissionState(new(groupDto.Group, new UserData(ApiController.UID), perm));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Sets your allowance for sound synchronization for users of this syncshell."
|
||||
+ Environment.NewLine + "Disabling the synchronization will stop applying sound modifications for users of this syncshell."
|
||||
+ Environment.NewLine + "Note: this setting can be forcefully overridden to 'disabled' through the syncshell owner."
|
||||
+ Environment.NewLine + "Note: this setting does not apply to individual pairs that are also in the syncshell.");
|
||||
|
||||
var animText = userAnimDisabled ? "Enable animations sync" : "Disable animations sync";
|
||||
if (UiSharedService.IconTextButton(userAnimIcon, animText))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var perm = groupDto.GroupUserPermissions;
|
||||
perm.SetDisableAnimations(!perm.IsDisableAnimations());
|
||||
_ = ApiController.GroupChangeIndividualPermissionState(new(groupDto.Group, new UserData(ApiController.UID), perm));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Sets your allowance for animations synchronization for users of this syncshell."
|
||||
+ Environment.NewLine + "Disabling the synchronization will stop applying animations modifications for users of this syncshell."
|
||||
+ Environment.NewLine + "Note: this setting might also affect sound synchronization"
|
||||
+ Environment.NewLine + "Note: this setting can be forcefully overridden to 'disabled' through the syncshell owner."
|
||||
+ Environment.NewLine + "Note: this setting does not apply to individual pairs that are also in the syncshell.");
|
||||
|
||||
var vfxText = userVFXDisabled ? "Enable VFX sync" : "Disable VFX sync";
|
||||
if (UiSharedService.IconTextButton(userVFXIcon, vfxText))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var perm = groupDto.GroupUserPermissions;
|
||||
perm.SetDisableVFX(!perm.IsDisableVFX());
|
||||
_ = ApiController.GroupChangeIndividualPermissionState(new(groupDto.Group, new UserData(ApiController.UID), perm));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Sets your allowance for VFX synchronization for users of this syncshell."
|
||||
+ Environment.NewLine + "Disabling the synchronization will stop applying VFX modifications for users of this syncshell."
|
||||
+ Environment.NewLine + "Note: this setting might also affect animation synchronization to some degree"
|
||||
+ Environment.NewLine + "Note: this setting can be forcefully overridden to 'disabled' through the syncshell owner."
|
||||
+ Environment.NewLine + "Note: this setting does not apply to individual pairs that are also in the syncshell.");
|
||||
|
||||
if (isOwner || groupDto.GroupUserInfo.IsModerator())
|
||||
{
|
||||
ImGui.Separator();
|
||||
|
||||
var changedToIcon = invitesEnabled ? FontAwesomeIcon.LockOpen : FontAwesomeIcon.Lock;
|
||||
if (UiSharedService.IconTextButton(changedToIcon, invitesEnabled ? "Lock Syncshell" : "Unlock Syncshell"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var groupPerm = groupDto.GroupPermissions;
|
||||
groupPerm.SetDisableInvites(invitesEnabled);
|
||||
_ = ApiController.GroupChangeGroupPermissionState(new GroupPermissionDto(groupDto.Group, groupPerm));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Change Syncshell joining permissions" + Environment.NewLine + "Syncshell is currently " + (invitesEnabled ? "open" : "closed") + " for people to join");
|
||||
|
||||
if (isOwner)
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Passport, "Change Password"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_isPasswordValid = true;
|
||||
_showModalChangePassword = true;
|
||||
}
|
||||
UiSharedService.AttachToolTip("Change Syncshell Password");
|
||||
}
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Broom, "Clear Syncshell") && UiSharedService.CtrlPressed())
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = ApiController.GroupClear(groupDto);
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hold CTRL and click to clear this Syncshell." + Environment.NewLine + "WARNING: this action is irreversible." + Environment.NewLine
|
||||
+ "Clearing the Syncshell will remove all not pinned users from it.");
|
||||
|
||||
var groupSoundsText = soundsDisabled ? "Enable syncshell sound sync" : "Disable syncshell sound sync";
|
||||
if (UiSharedService.IconTextButton(soundsIcon, groupSoundsText))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var perm = groupDto.GroupPermissions;
|
||||
perm.SetDisableSounds(!perm.IsDisableSounds());
|
||||
_ = ApiController.GroupChangeGroupPermissionState(new(groupDto.Group, perm));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Sets syncshell-wide allowance for sound synchronization for all users." + Environment.NewLine
|
||||
+ "Note: users that are individually paired with others in the syncshell will ignore this setting." + Environment.NewLine
|
||||
+ "Note: if the synchronization is enabled, users can individually override this setting to disabled.");
|
||||
|
||||
var groupAnimText = animDisabled ? "Enable syncshell animations sync" : "Disable syncshell animations sync";
|
||||
if (UiSharedService.IconTextButton(animIcon, groupAnimText))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var perm = groupDto.GroupPermissions;
|
||||
perm.SetDisableAnimations(!perm.IsDisableAnimations());
|
||||
_ = ApiController.GroupChangeGroupPermissionState(new(groupDto.Group, perm));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Sets syncshell-wide allowance for animations synchronization for all users." + Environment.NewLine
|
||||
+ "Note: users that are individually paired with others in the syncshell will ignore this setting." + Environment.NewLine
|
||||
+ "Note: if the synchronization is enabled, users can individually override this setting to disabled.");
|
||||
|
||||
var groupVFXText = vfxDisabled ? "Enable syncshell VFX sync" : "Disable syncshell VFX sync";
|
||||
if (UiSharedService.IconTextButton(vfxIcon, groupVFXText))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var perm = groupDto.GroupPermissions;
|
||||
perm.SetDisableVFX(!perm.IsDisableVFX());
|
||||
_ = ApiController.GroupChangeGroupPermissionState(new(groupDto.Group, perm));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Sets syncshell-wide allowance for VFX synchronization for all users." + Environment.NewLine
|
||||
+ "Note: users that are individually paired with others in the syncshell will ignore this setting." + Environment.NewLine
|
||||
+ "Note: if the synchronization is enabled, users can individually override this setting to disabled.");
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Envelope, "Single one-time invite"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
ImGui.SetClipboardText(ApiController.GroupCreateTempInvite(groupDto, 1).Result.FirstOrDefault() ?? string.Empty);
|
||||
}
|
||||
UiSharedService.AttachToolTip("Creates a single-use password for joining the syncshell which is valid for 24h and copies it to the clipboard.");
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.MailBulk, "Bulk one-time invites"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_showModalBulkOneTimeInvites = true;
|
||||
_bulkOneTimeInvites.Clear();
|
||||
}
|
||||
UiSharedService.AttachToolTip("Opens a dialog to create up to 100 single-use passwords for joining the syncshell.");
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Ban, "Manage Banlist"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_showModalBanList = true;
|
||||
_bannedUsers = ApiController.GroupGetBannedUsers(groupDto).Result;
|
||||
}
|
||||
|
||||
if (isOwner)
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Delete Syncshell") && UiSharedService.CtrlPressed() && UiSharedService.ShiftPressed())
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = ApiController.GroupDelete(groupDto);
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hold CTRL and Shift and click to delete this Syncshell." + Environment.NewLine + "WARNING: this action is irreversible.");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSyncshellList()
|
||||
{
|
||||
var ySize = _mainUi.TransferPartHeight == 0
|
||||
? 1
|
||||
: (ImGui.GetWindowContentRegionMax().Y - ImGui.GetWindowContentRegionMin().Y) - _mainUi.TransferPartHeight - ImGui.GetCursorPosY();
|
||||
ImGui.BeginChild("list", new Vector2(_mainUi.WindowContentWidth, ySize), border: false);
|
||||
foreach (var entry in _pairManager.GroupPairs.OrderBy(g => g.Key.Group.AliasOrGID, StringComparer.OrdinalIgnoreCase).ToList())
|
||||
{
|
||||
UiSharedService.DrawWithID(entry.Key.Group.GID, () => DrawSyncshell(entry.Key, entry.Value));
|
||||
}
|
||||
ImGui.EndChild();
|
||||
}
|
||||
}
|
||||
6
MareSynchronos/UI/Components/IDrawFolder.cs
Normal file
6
MareSynchronos/UI/Components/IDrawFolder.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace MareSynchronos.UI.Components;
|
||||
|
||||
public interface IDrawFolder
|
||||
{
|
||||
void Draw();
|
||||
}
|
||||
@@ -1,249 +0,0 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Components;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
using MareSynchronos.WebAPI;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
|
||||
public class PairGroupsUi
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private readonly MareConfigService _mareConfig;
|
||||
private readonly SelectPairForGroupUi _selectGroupForPairUi;
|
||||
private readonly TagHandler _tagHandler;
|
||||
|
||||
public PairGroupsUi(MareConfigService mareConfig, TagHandler tagHandler, ApiController apiController, SelectPairForGroupUi selectGroupForPairUi)
|
||||
{
|
||||
_mareConfig = mareConfig;
|
||||
_tagHandler = tagHandler;
|
||||
_apiController = apiController;
|
||||
_selectGroupForPairUi = selectGroupForPairUi;
|
||||
}
|
||||
|
||||
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 (typeof(T) == typeof(DrawUserPair))
|
||||
{
|
||||
DrawUserPairs(tagsWithPairsInThem, allUsers.Cast<DrawUserPair>().ToList(), visibleUsers.Cast<DrawUserPair>(), onlineUsers.Cast<DrawUserPair>(), offlineUsers.Cast<DrawUserPair>());
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawButtons(string tag, List<DrawUserPair> availablePairsInThisTag)
|
||||
{
|
||||
var allArePaused = availablePairsInThisTag.All(pair => pair.UserPair!.OwnPermissions.IsPaused());
|
||||
var pauseButton = allArePaused ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
|
||||
var flyoutMenuX = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Bars).X;
|
||||
var pauseButtonX = UiSharedService.GetIconButtonSize(pauseButton).X;
|
||||
var windowX = ImGui.GetWindowContentRegionMin().X;
|
||||
var windowWidth = UiSharedService.GetWindowContentRegionWidth();
|
||||
var spacingX = ImGui.GetStyle().ItemSpacing.X;
|
||||
|
||||
var buttonPauseOffset = windowX + windowWidth - flyoutMenuX - spacingX - pauseButtonX;
|
||||
ImGui.SameLine(buttonPauseOffset);
|
||||
if (ImGuiComponents.IconButton(pauseButton))
|
||||
{
|
||||
// If all of the currently visible pairs (after applying filters to the pairs)
|
||||
// are paused we display a resume button to resume all currently visible (after filters)
|
||||
// pairs. Otherwise, we just pause all the remaining pairs.
|
||||
if (allArePaused)
|
||||
{
|
||||
// If all are paused => resume all
|
||||
ResumeAllPairs(availablePairsInThisTag);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise pause all remaining
|
||||
PauseRemainingPairs(availablePairsInThisTag);
|
||||
}
|
||||
}
|
||||
if (allArePaused)
|
||||
{
|
||||
UiSharedService.AttachToolTip($"Resume pairing with all pairs in {tag}");
|
||||
}
|
||||
else
|
||||
{
|
||||
UiSharedService.AttachToolTip($"Pause pairing with all pairs in {tag}");
|
||||
}
|
||||
|
||||
var buttonDeleteOffset = windowX + windowWidth - flyoutMenuX;
|
||||
ImGui.SameLine(buttonDeleteOffset);
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars))
|
||||
{
|
||||
ImGui.OpenPopup("Group Flyout Menu");
|
||||
}
|
||||
|
||||
if (ImGui.BeginPopup("Group Flyout Menu"))
|
||||
{
|
||||
UiSharedService.DrawWithID($"buttons-{tag}", () => DrawGroupMenu(tag));
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCategory(string tag, IEnumerable<DrawPairBase> onlineUsers, IEnumerable<DrawPairBase> allUsers, IEnumerable<DrawPairBase>? visibleUsers = null)
|
||||
{
|
||||
IEnumerable<DrawPairBase> usersInThisTag;
|
||||
HashSet<string>? otherUidsTaggedWithTag = null;
|
||||
bool isSpecialTag = false;
|
||||
int visibleInThisTag = 0;
|
||||
if (tag is TagHandler.CustomOfflineTag or TagHandler.CustomOnlineTag or TagHandler.CustomVisibleTag or TagHandler.CustomUnpairedTag)
|
||||
{
|
||||
usersInThisTag = onlineUsers;
|
||||
isSpecialTag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
otherUidsTaggedWithTag = _tagHandler.GetOtherUidsForTag(tag);
|
||||
usersInThisTag = onlineUsers
|
||||
.Where(pair => otherUidsTaggedWithTag.Contains(pair.UID))
|
||||
.ToList();
|
||||
visibleInThisTag = visibleUsers?.Count(p => otherUidsTaggedWithTag.Contains(p.UID)) ?? 0;
|
||||
}
|
||||
|
||||
if (isSpecialTag && !usersInThisTag.Any()) return;
|
||||
|
||||
DrawName(tag, isSpecialTag, visibleInThisTag, usersInThisTag.Count(), otherUidsTaggedWithTag?.Count);
|
||||
if (!isSpecialTag)
|
||||
{
|
||||
if (onlineUsers.Any() && 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;
|
||||
|
||||
ImGui.Indent(20);
|
||||
DrawPairs(tag, usersInThisTag);
|
||||
ImGui.Unindent(20);
|
||||
}
|
||||
|
||||
private void DrawGroupMenu(string tag)
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Users, "Add people to " + tag))
|
||||
{
|
||||
_selectGroupForPairUi.Open(tag);
|
||||
}
|
||||
UiSharedService.AttachToolTip($"Add more users to Group {tag}");
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Delete " + tag) && UiSharedService.CtrlPressed())
|
||||
{
|
||||
_tagHandler.RemoveTag(tag);
|
||||
}
|
||||
UiSharedService.AttachToolTip($"Delete Group {tag} (Will not delete the pairs)" + Environment.NewLine + "Hold CTRL to delete");
|
||||
}
|
||||
|
||||
private void DrawName(string tag, bool isSpecialTag, int visible, int online, int? total)
|
||||
{
|
||||
string displayedName = tag switch
|
||||
{
|
||||
TagHandler.CustomUnpairedTag => "Unpaired",
|
||||
TagHandler.CustomOfflineTag => "Offline",
|
||||
TagHandler.CustomOnlineTag => _mareConfig.Current.ShowOfflineUsersSeparately ? "Online/Paused" : "Contacts",
|
||||
TagHandler.CustomVisibleTag => "Visible",
|
||||
_ => tag
|
||||
};
|
||||
|
||||
string resultFolderName = !isSpecialTag ? $"{displayedName} ({visible}/{online}/{total} Pairs)" : $"{displayedName} ({online} Pairs)";
|
||||
|
||||
// FontAwesomeIcon.CaretSquareDown : FontAwesomeIcon.CaretSquareRight
|
||||
var icon = _tagHandler.IsTagOpen(tag) ? FontAwesomeIcon.CaretSquareDown : FontAwesomeIcon.CaretSquareRight;
|
||||
UiSharedService.FontText(icon.ToIconString(), UiBuilder.IconFont);
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||
{
|
||||
ToggleTagOpen(tag);
|
||||
}
|
||||
ImGui.SameLine();
|
||||
UiSharedService.FontText(resultFolderName, UiBuilder.DefaultFont);
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||
{
|
||||
ToggleTagOpen(tag);
|
||||
}
|
||||
|
||||
if (!isSpecialTag && ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
ImGui.TextUnformatted($"Group {tag}");
|
||||
ImGui.Separator();
|
||||
ImGui.TextUnformatted($"{visible} Pairs visible");
|
||||
ImGui.TextUnformatted($"{online} Pairs online/paused");
|
||||
ImGui.TextUnformatted($"{total} Pairs total");
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPairs(string tag, IEnumerable<DrawPairBase> availablePairsInThisCategory)
|
||||
{
|
||||
// These are all the OtherUIDs that are tagged with this tag
|
||||
foreach (var pair in availablePairsInThisCategory)
|
||||
{
|
||||
UiSharedService.DrawWithID($"tag-{tag}-pair-${pair.UID}", () => pair.DrawPairedClient());
|
||||
}
|
||||
ImGui.Separator();
|
||||
}
|
||||
|
||||
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(new(pairToPause.UID), perm));
|
||||
}
|
||||
}
|
||||
|
||||
private void ResumeAllPairs(List<DrawUserPair> availablePairs)
|
||||
{
|
||||
foreach (var pairToPause in availablePairs)
|
||||
{
|
||||
var perm = pairToPause.UserPair!.OwnPermissions;
|
||||
perm.SetPaused(paused: false);
|
||||
_ = _apiController.UserSetPairPermissions(new(new(pairToPause.UID), perm));
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleTagOpen(string tag)
|
||||
{
|
||||
bool open = !_tagHandler.IsTagOpen(tag);
|
||||
_tagHandler.SetTagOpen(tag, open);
|
||||
}
|
||||
}
|
||||
46
MareSynchronos/UI/Components/Popup/BanUserPopupHandler.cs
Normal file
46
MareSynchronos/UI/Components/Popup/BanUserPopupHandler.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using MareSynchronos.WebAPI;
|
||||
using System.Numerics;
|
||||
|
||||
namespace MareSynchronos.UI.Components.Popup;
|
||||
|
||||
public class BanUserPopupHandler : IPopupHandler
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private string _banReason = string.Empty;
|
||||
private GroupFullInfoDto _group = null!;
|
||||
private Pair _reportedPair = null!;
|
||||
|
||||
public BanUserPopupHandler(ApiController apiController)
|
||||
{
|
||||
_apiController = apiController;
|
||||
}
|
||||
|
||||
public Vector2 PopupSize => new(500, 250);
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
UiSharedService.TextWrapped("User " + (_reportedPair.UserData.AliasOrUID) + " will be banned and removed from this Syncshell.");
|
||||
ImGui.InputTextWithHint("##banreason", "Ban Reason", ref _banReason, 255);
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.UserSlash, "Ban User"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var reason = _banReason;
|
||||
_ = _apiController.GroupBanUser(new GroupPairDto(_group.Group, _reportedPair.UserData), 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.");
|
||||
}
|
||||
|
||||
public void Open(OpenBanUserPopupMessage message)
|
||||
{
|
||||
_reportedPair = message.PairToBan;
|
||||
_group = message.GroupFullInfoDto;
|
||||
_banReason = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronos.WebAPI;
|
||||
using System.Numerics;
|
||||
|
||||
namespace MareSynchronos.UI.Components.Popup;
|
||||
|
||||
public class CreateSyncshellPopupHandler : IPopupHandler
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private readonly UiSharedService _uiSharedService;
|
||||
private bool _errorGroupCreate;
|
||||
private GroupJoinDto? _lastCreatedGroup;
|
||||
|
||||
public CreateSyncshellPopupHandler(ApiController apiController, UiSharedService uiSharedService)
|
||||
{
|
||||
_apiController = apiController;
|
||||
_uiSharedService = uiSharedService;
|
||||
}
|
||||
|
||||
public Vector2 PopupSize => new(500, 300);
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
using (ImRaii.PushFont(_uiSharedService.UidFont))
|
||||
ImGui.TextUnformatted("Create new Syncshell");
|
||||
|
||||
if (_lastCreatedGroup == null)
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Plus, "Create Syncshell"))
|
||||
{
|
||||
try
|
||||
{
|
||||
_lastCreatedGroup = _apiController.GroupCreate().Result;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_lastCreatedGroup = null;
|
||||
_errorGroupCreate = true;
|
||||
}
|
||||
}
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
if (_lastCreatedGroup == null)
|
||||
{
|
||||
UiSharedService.TextWrapped("Creating a new Syncshell with create it defaulting to your current preferred permissions for Syncshells." + Environment.NewLine +
|
||||
"- You can own up to " + _apiController.ServerInfo.MaxGroupsCreatedByUser + " Syncshells on this server." + Environment.NewLine +
|
||||
"- You can join up to " + _apiController.ServerInfo.MaxGroupsJoinedByUser + " Syncshells on this server (including your own)" + Environment.NewLine +
|
||||
"- Syncshells on this server can have a maximum of " + _apiController.ServerInfo.MaxGroupUserCount + " users");
|
||||
ImGui.Dummy(new(2f));
|
||||
ImGui.TextUnformatted("Your current Syncshell preferred permissions are:");
|
||||
ImGui.TextUnformatted("- Animations");
|
||||
UiSharedService.BooleanToColoredIcon(!_apiController.DefaultPermissions!.DisableGroupAnimations);
|
||||
ImGui.TextUnformatted("- Sounds");
|
||||
UiSharedService.BooleanToColoredIcon(!_apiController.DefaultPermissions!.DisableGroupSounds);
|
||||
ImGui.TextUnformatted("- VFX");
|
||||
UiSharedService.BooleanToColoredIcon(!_apiController.DefaultPermissions!.DisableGroupVFX);
|
||||
UiSharedService.TextWrapped("(Those preferred permissions can be changed anytime after Syncshell creation, your defaults can be changed anytime in the Mare Settings)");
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorGroupCreate = false;
|
||||
ImGui.TextUnformatted("Syncshell ID: " + _lastCreatedGroup.Group.GID);
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Syncshell Password: " + _lastCreatedGroup.Password);
|
||||
ImGui.SameLine();
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Copy))
|
||||
{
|
||||
ImGui.SetClipboardText(_lastCreatedGroup.Password);
|
||||
}
|
||||
UiSharedService.TextWrapped("You can change the Syncshell password later at any time.");
|
||||
ImGui.Separator();
|
||||
UiSharedService.TextWrapped("These settings were set based on your preferred syncshell permissions:");
|
||||
ImGui.Dummy(new(2f));
|
||||
UiSharedService.TextWrapped("Suggest Animation sync:");
|
||||
UiSharedService.BooleanToColoredIcon(!_lastCreatedGroup.GroupUserPreferredPermissions.IsDisableAnimations());
|
||||
UiSharedService.TextWrapped("Suggest Sounds sync:");
|
||||
UiSharedService.BooleanToColoredIcon(!_lastCreatedGroup.GroupUserPreferredPermissions.IsDisableSounds());
|
||||
UiSharedService.TextWrapped("Suggest VFX sync:");
|
||||
UiSharedService.BooleanToColoredIcon(!_lastCreatedGroup.GroupUserPreferredPermissions.IsDisableVFX());
|
||||
}
|
||||
|
||||
if (_errorGroupCreate)
|
||||
{
|
||||
UiSharedService.ColorTextWrapped("Something went wrong during creation of a new Syncshell", new Vector4(1, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
_lastCreatedGroup = null;
|
||||
}
|
||||
}
|
||||
10
MareSynchronos/UI/Components/Popup/IPopupHandler.cs
Normal file
10
MareSynchronos/UI/Components/Popup/IPopupHandler.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Numerics;
|
||||
|
||||
namespace MareSynchronos.UI.Components.Popup;
|
||||
|
||||
public interface IPopupHandler
|
||||
{
|
||||
Vector2 PopupSize { get; }
|
||||
|
||||
void DrawContent();
|
||||
}
|
||||
163
MareSynchronos/UI/Components/Popup/JoinSyncshellPopupHandler.cs
Normal file
163
MareSynchronos/UI/Components/Popup/JoinSyncshellPopupHandler.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Data.Enum;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.API.Dto;
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronos.Utils;
|
||||
using MareSynchronos.WebAPI;
|
||||
using System.Numerics;
|
||||
|
||||
namespace MareSynchronos.UI.Components.Popup;
|
||||
|
||||
internal class JoinSyncshellPopupHandler : IPopupHandler
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private readonly UiSharedService _uiSharedService;
|
||||
private string _desiredSyncshellToJoin = string.Empty;
|
||||
private GroupJoinInfoDto? _groupJoinInfo = null;
|
||||
private DefaultPermissionsDto _ownPermissions = null!;
|
||||
private string _previousPassword = string.Empty;
|
||||
private string _syncshellPassword = string.Empty;
|
||||
|
||||
public JoinSyncshellPopupHandler(UiSharedService uiSharedService, ApiController apiController)
|
||||
{
|
||||
_uiSharedService = uiSharedService;
|
||||
_apiController = apiController;
|
||||
}
|
||||
|
||||
public Vector2 PopupSize => new(700, 400);
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
using (ImRaii.PushFont(_uiSharedService.UidFont))
|
||||
ImGui.TextUnformatted((_groupJoinInfo == null || !_groupJoinInfo.Success) ? "Join Syncshell" : ("Finalize join Syncshell " + _groupJoinInfo.GroupAliasOrGID));
|
||||
ImGui.Separator();
|
||||
|
||||
if (_groupJoinInfo == null || !_groupJoinInfo.Success)
|
||||
{
|
||||
UiSharedService.TextWrapped("Here you can join existing Syncshells. " +
|
||||
"Please keep in mind that you cannot join more than " + _apiController.ServerInfo.MaxGroupsJoinedByUser + " syncshells on this server." + Environment.NewLine +
|
||||
"Joining a Syncshell will pair you implicitly with all existing users in the Syncshell." + Environment.NewLine +
|
||||
"All permissions to all users in the Syncshell will be set to the preferred Syncshell permissions on joining, excluding prior set preferred permissions.");
|
||||
ImGui.Separator();
|
||||
ImGui.TextUnformatted("Note: Syncshell ID and Password are case sensitive. MSS- is part of Syncshell IDs, unless using Vanity IDs.");
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Syncshell ID");
|
||||
ImGui.SameLine(200);
|
||||
ImGui.InputTextWithHint("##syncshellId", "Full Syncshell ID", ref _desiredSyncshellToJoin, 20);
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Syncshell Password");
|
||||
ImGui.SameLine(200);
|
||||
ImGui.InputTextWithHint("##syncshellpw", "Password", ref _syncshellPassword, 20, ImGuiInputTextFlags.Password);
|
||||
using (ImRaii.Disabled(string.IsNullOrEmpty(_desiredSyncshellToJoin) || string.IsNullOrEmpty(_syncshellPassword)))
|
||||
{
|
||||
if (UiSharedService.IconTextButton(Dalamud.Interface.FontAwesomeIcon.Plus, "Join Syncshell"))
|
||||
{
|
||||
_groupJoinInfo = _apiController.GroupJoin(new GroupPasswordDto(new API.Data.GroupData(_desiredSyncshellToJoin), _syncshellPassword)).Result;
|
||||
_previousPassword = _syncshellPassword;
|
||||
_syncshellPassword = string.Empty;
|
||||
}
|
||||
}
|
||||
if (_groupJoinInfo != null && !_groupJoinInfo.Success)
|
||||
{
|
||||
UiSharedService.ColorTextWrapped("Failed to join the Syncshell. This is due to one of following reasons:" + Environment.NewLine +
|
||||
"- The Syncshell does not exist or the password is incorrect" + Environment.NewLine +
|
||||
"- You are already in that Syncshell or are banned from that Syncshell" + Environment.NewLine +
|
||||
"- The Syncshell is at capacity or has invites disabled" + Environment.NewLine, ImGuiColors.DalamudYellow);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextUnformatted("You are about to join the Syncshell " + _groupJoinInfo.GroupAliasOrGID + " by " + _groupJoinInfo.OwnerAliasOrUID);
|
||||
ImGui.Dummy(new(2));
|
||||
ImGui.TextUnformatted("This Syncshell staff has set the following suggested Syncshell permissions:");
|
||||
ImGui.TextUnformatted("- Sounds ");
|
||||
UiSharedService.BooleanToColoredIcon(!_groupJoinInfo.GroupPermissions.IsPreferDisableSounds());
|
||||
ImGui.TextUnformatted("- Animations");
|
||||
UiSharedService.BooleanToColoredIcon(!_groupJoinInfo.GroupPermissions.IsPreferDisableAnimations());
|
||||
ImGui.TextUnformatted("- VFX");
|
||||
UiSharedService.BooleanToColoredIcon(!_groupJoinInfo.GroupPermissions.IsPreferDisableVFX());
|
||||
|
||||
if (_groupJoinInfo.GroupPermissions.IsPreferDisableSounds() != _ownPermissions.DisableGroupSounds
|
||||
|| _groupJoinInfo.GroupPermissions.IsPreferDisableVFX() != _ownPermissions.DisableGroupVFX
|
||||
|| _groupJoinInfo.GroupPermissions.IsPreferDisableAnimations() != _ownPermissions.DisableGroupAnimations)
|
||||
{
|
||||
ImGui.Dummy(new(2));
|
||||
UiSharedService.ColorText("Your current preferred default Syncshell permissions deviate from the suggested permissions:", ImGuiColors.DalamudYellow);
|
||||
if (_groupJoinInfo.GroupPermissions.IsPreferDisableSounds() != _ownPermissions.DisableGroupSounds)
|
||||
{
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("- Sounds");
|
||||
UiSharedService.BooleanToColoredIcon(!_ownPermissions.DisableGroupSounds);
|
||||
ImGui.SameLine(200);
|
||||
ImGui.TextUnformatted("Suggested");
|
||||
UiSharedService.BooleanToColoredIcon(!_groupJoinInfo.GroupPermissions.IsPreferDisableSounds());
|
||||
ImGui.SameLine();
|
||||
using var id = ImRaii.PushId("suggestedSounds");
|
||||
if (UiSharedService.IconTextButton(Dalamud.Interface.FontAwesomeIcon.ArrowRight, "Apply suggested"))
|
||||
{
|
||||
_ownPermissions.DisableGroupSounds = _groupJoinInfo.GroupPermissions.IsPreferDisableSounds();
|
||||
}
|
||||
}
|
||||
if (_groupJoinInfo.GroupPermissions.IsPreferDisableAnimations() != _ownPermissions.DisableGroupAnimations)
|
||||
{
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("- Animations");
|
||||
UiSharedService.BooleanToColoredIcon(!_ownPermissions.DisableGroupAnimations);
|
||||
ImGui.SameLine(200);
|
||||
ImGui.TextUnformatted("Suggested");
|
||||
UiSharedService.BooleanToColoredIcon(!_groupJoinInfo.GroupPermissions.IsPreferDisableAnimations());
|
||||
ImGui.SameLine();
|
||||
using var id = ImRaii.PushId("suggestedAnims");
|
||||
if (UiSharedService.IconTextButton(Dalamud.Interface.FontAwesomeIcon.ArrowRight, "Apply suggested"))
|
||||
{
|
||||
_ownPermissions.DisableGroupAnimations = _groupJoinInfo.GroupPermissions.IsPreferDisableAnimations();
|
||||
}
|
||||
}
|
||||
if (_groupJoinInfo.GroupPermissions.IsPreferDisableVFX() != _ownPermissions.DisableGroupVFX)
|
||||
{
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("- VFX");
|
||||
UiSharedService.BooleanToColoredIcon(!_ownPermissions.DisableGroupVFX);
|
||||
ImGui.SameLine(200);
|
||||
ImGui.TextUnformatted("Suggested");
|
||||
UiSharedService.BooleanToColoredIcon(!_groupJoinInfo.GroupPermissions.IsPreferDisableVFX());
|
||||
ImGui.SameLine();
|
||||
using var id = ImRaii.PushId("suggestedVfx");
|
||||
if (UiSharedService.IconTextButton(Dalamud.Interface.FontAwesomeIcon.ArrowRight, "Apply suggested"))
|
||||
{
|
||||
_ownPermissions.DisableGroupVFX = _groupJoinInfo.GroupPermissions.IsPreferDisableVFX();
|
||||
}
|
||||
}
|
||||
UiSharedService.TextWrapped("Note: you do not need to apply the suggested Syncshell permissions, they are solely suggestions by the staff of the Syncshell.");
|
||||
}
|
||||
else
|
||||
{
|
||||
UiSharedService.TextWrapped("Your default syncshell permissions on joining are in line with the suggested Syncshell permissions through the owner.");
|
||||
}
|
||||
ImGui.Dummy(new(2));
|
||||
if (UiSharedService.IconTextButton(Dalamud.Interface.FontAwesomeIcon.Plus, "Finalize and join " + _groupJoinInfo.GroupAliasOrGID))
|
||||
{
|
||||
GroupUserPreferredPermissions joinPermissions = GroupUserPreferredPermissions.NoneSet;
|
||||
joinPermissions.SetDisableSounds(_ownPermissions.DisableGroupSounds);
|
||||
joinPermissions.SetDisableAnimations(_ownPermissions.DisableGroupAnimations);
|
||||
joinPermissions.SetDisableVFX(_ownPermissions.DisableGroupVFX);
|
||||
_ = _apiController.GroupJoinFinalize(new GroupJoinDto(_groupJoinInfo.Group, _previousPassword, joinPermissions));
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
_desiredSyncshellToJoin = string.Empty;
|
||||
_syncshellPassword = string.Empty;
|
||||
_previousPassword = string.Empty;
|
||||
_groupJoinInfo = null;
|
||||
_ownPermissions = _apiController.DefaultPermissions.DeepClone()!;
|
||||
}
|
||||
}
|
||||
95
MareSynchronos/UI/Components/Popup/PopupHandler.cs
Normal file
95
MareSynchronos/UI/Components/Popup/PopupHandler.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Numerics;
|
||||
|
||||
namespace MareSynchronos.UI.Components.Popup;
|
||||
|
||||
public class PopupHandler : WindowMediatorSubscriberBase
|
||||
{
|
||||
protected bool _openPopup = false;
|
||||
private readonly HashSet<IPopupHandler> _handlers;
|
||||
private IPopupHandler? _currentHandler = null;
|
||||
|
||||
public PopupHandler(ILogger<PopupHandler> logger, MareMediator mediator, IEnumerable<IPopupHandler> popupHandlers)
|
||||
: base(logger, mediator, "MarePopupHandler")
|
||||
{
|
||||
Flags = ImGuiWindowFlags.NoBringToFrontOnFocus
|
||||
| ImGuiWindowFlags.NoDecoration
|
||||
| ImGuiWindowFlags.NoInputs
|
||||
| ImGuiWindowFlags.NoSavedSettings
|
||||
| ImGuiWindowFlags.NoBackground
|
||||
| ImGuiWindowFlags.NoMove
|
||||
| ImGuiWindowFlags.NoNav
|
||||
| ImGuiWindowFlags.NoTitleBar;
|
||||
IsOpen = true;
|
||||
|
||||
_handlers = popupHandlers.ToHashSet();
|
||||
|
||||
Mediator.Subscribe<OpenReportPopupMessage>(this, (msg) =>
|
||||
{
|
||||
_openPopup = true;
|
||||
_currentHandler = _handlers.OfType<ReportPopupHandler>().Single();
|
||||
((ReportPopupHandler)_currentHandler).Open(msg);
|
||||
IsOpen = true;
|
||||
});
|
||||
|
||||
Mediator.Subscribe<OpenCreateSyncshellPopupMessage>(this, (msg) =>
|
||||
{
|
||||
_openPopup = true;
|
||||
_currentHandler = _handlers.OfType<CreateSyncshellPopupHandler>().Single();
|
||||
((CreateSyncshellPopupHandler)_currentHandler).Open();
|
||||
IsOpen = true;
|
||||
});
|
||||
|
||||
Mediator.Subscribe<OpenBanUserPopupMessage>(this, (msg) =>
|
||||
{
|
||||
_openPopup = true;
|
||||
_currentHandler = _handlers.OfType<BanUserPopupHandler>().Single();
|
||||
((BanUserPopupHandler)_currentHandler).Open(msg);
|
||||
IsOpen = true;
|
||||
});
|
||||
|
||||
Mediator.Subscribe<JoinSyncshellPopupMessage>(this, (_) =>
|
||||
{
|
||||
_openPopup = true;
|
||||
_currentHandler = _handlers.OfType<JoinSyncshellPopupHandler>().Single();
|
||||
((JoinSyncshellPopupHandler)_currentHandler).Open();
|
||||
IsOpen = true;
|
||||
});
|
||||
|
||||
Mediator.Subscribe<OpenSyncshellAdminPanelPopupMessage>(this, (msg) =>
|
||||
{
|
||||
IsOpen = true;
|
||||
_openPopup = true;
|
||||
_currentHandler = _handlers.OfType<SyncshellAdminPopupHandler>().Single();
|
||||
((SyncshellAdminPopupHandler)_currentHandler).Open(msg.GroupInfo);
|
||||
IsOpen = true;
|
||||
});
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
if (_currentHandler == null) return;
|
||||
|
||||
if (_openPopup)
|
||||
{
|
||||
ImGui.OpenPopup(WindowName);
|
||||
_openPopup = false;
|
||||
}
|
||||
|
||||
var viewportSize = ImGui.GetWindowViewport().Size;
|
||||
ImGui.SetNextWindowSize(_currentHandler!.PopupSize);
|
||||
ImGui.SetNextWindowPos(viewportSize / 2, ImGuiCond.Always, new Vector2(0.5f));
|
||||
using var popup = ImRaii.Popup(WindowName, ImGuiWindowFlags.Modal);
|
||||
if (!popup) return;
|
||||
_currentHandler.DrawContent();
|
||||
ImGui.Separator();
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Times, "Close"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
57
MareSynchronos/UI/Components/Popup/ReportPopupHandler.cs
Normal file
57
MareSynchronos/UI/Components/Popup/ReportPopupHandler.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using MareSynchronos.WebAPI;
|
||||
using System.Numerics;
|
||||
|
||||
namespace MareSynchronos.UI.Components.Popup;
|
||||
|
||||
internal class ReportPopupHandler : IPopupHandler
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private readonly UiSharedService _uiSharedService;
|
||||
private Pair? _reportedPair;
|
||||
private string _reportReason = string.Empty;
|
||||
|
||||
public ReportPopupHandler(ApiController apiController, UiSharedService uiSharedService)
|
||||
{
|
||||
_apiController = apiController;
|
||||
_uiSharedService = uiSharedService;
|
||||
}
|
||||
|
||||
public Vector2 PopupSize => new(500, 500);
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
using (ImRaii.PushFont(_uiSharedService.UidFont))
|
||||
UiSharedService.TextWrapped("Report " + _reportedPair!.UserData.AliasOrUID + " Mare Profile");
|
||||
|
||||
ImGui.InputTextMultiline("##reportReason", ref _reportReason, 500, new Vector2(500 - ImGui.GetStyle().ItemSpacing.X * 2, 200));
|
||||
UiSharedService.TextWrapped($"Note: Sending a report will disable the offending profile globally.{Environment.NewLine}" +
|
||||
$"The report will be sent to the team of your currently connected Mare Synchronos Service.{Environment.NewLine}" +
|
||||
$"The report will include your user and your contact info (Discord User).{Environment.NewLine}" +
|
||||
$"Depending on the severity of the offense the users Mare profile or account can be permanently disabled or banned.");
|
||||
UiSharedService.ColorTextWrapped("Report spam and wrong reports will not be tolerated and can lead to permanent account suspension.", ImGuiColors.DalamudRed);
|
||||
UiSharedService.ColorTextWrapped("This is not for reporting misbehavior or Mare usage but solely for the actual profile. " +
|
||||
"Reports that are not solely for the profile will be ignored.", ImGuiColors.DalamudYellow);
|
||||
|
||||
using (ImRaii.Disabled(string.IsNullOrEmpty(_reportReason)))
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.ExclamationTriangle, "Send Report"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var reason = _reportReason;
|
||||
_ = _apiController.UserReportProfile(new(_reportedPair.UserData, reason));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Open(OpenReportPopupMessage msg)
|
||||
{
|
||||
_reportedPair = msg.PairToReport;
|
||||
_reportReason = string.Empty;
|
||||
}
|
||||
}
|
||||
234
MareSynchronos/UI/Components/Popup/SyncshellAdminPopupHandler.cs
Normal file
234
MareSynchronos/UI/Components/Popup/SyncshellAdminPopupHandler.cs
Normal file
@@ -0,0 +1,234 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.WebAPI;
|
||||
using System.Globalization;
|
||||
using System.Numerics;
|
||||
|
||||
namespace MareSynchronos.UI.Components.Popup;
|
||||
|
||||
internal class SyncshellAdminPopupHandler : IPopupHandler
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private readonly List<string> _oneTimeInvites = [];
|
||||
private readonly PairManager _pairManager;
|
||||
private readonly UiSharedService _uiSharedService;
|
||||
private List<BannedGroupUserDto> _bannedUsers = [];
|
||||
private GroupFullInfoDto _groupFullInfo = null!;
|
||||
private bool _isModerator = false;
|
||||
private bool _isOwner = false;
|
||||
private int _multiInvites = 30;
|
||||
private string _newPassword = string.Empty;
|
||||
private bool _pwChangeSuccess = true;
|
||||
|
||||
public SyncshellAdminPopupHandler(ApiController apiController, UiSharedService uiSharedService, PairManager pairManager)
|
||||
{
|
||||
_apiController = apiController;
|
||||
_uiSharedService = uiSharedService;
|
||||
_pairManager = pairManager;
|
||||
}
|
||||
|
||||
public Vector2 PopupSize => new(700, 500);
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
if (!_isModerator && !_isOwner) return;
|
||||
|
||||
_groupFullInfo = _pairManager.Groups[_groupFullInfo.Group];
|
||||
|
||||
using (ImRaii.PushFont(_uiSharedService.UidFont))
|
||||
ImGui.TextUnformatted(_groupFullInfo.GroupAliasOrGID + " Administrative Panel");
|
||||
|
||||
ImGui.Separator();
|
||||
var perm = _groupFullInfo.GroupPermissions;
|
||||
|
||||
var inviteNode = ImRaii.TreeNode("Invites");
|
||||
if (inviteNode)
|
||||
{
|
||||
bool isInvitesDisabled = perm.IsDisableInvites();
|
||||
|
||||
if (UiSharedService.IconTextButton(isInvitesDisabled ? FontAwesomeIcon.Unlock : FontAwesomeIcon.Lock,
|
||||
isInvitesDisabled ? "Unlock Syncshell" : "Lock Syncshell"))
|
||||
{
|
||||
perm.SetDisableInvites(!isInvitesDisabled);
|
||||
_ = _apiController.GroupChangeGroupPermissionState(new(_groupFullInfo.Group, perm));
|
||||
}
|
||||
|
||||
ImGui.Dummy(new(2f));
|
||||
|
||||
UiSharedService.TextWrapped("One-time invites work as single-use passwords. Use those if you do not want to distribute your Syncshell password.");
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Envelope, "Single one-time invite"))
|
||||
{
|
||||
ImGui.SetClipboardText(_apiController.GroupCreateTempInvite(new(_groupFullInfo.Group), 1).Result.FirstOrDefault() ?? string.Empty);
|
||||
}
|
||||
UiSharedService.AttachToolTip("Creates a single-use password for joining the syncshell which is valid for 24h and copies it to the clipboard.");
|
||||
ImGui.InputInt("##amountofinvites", ref _multiInvites);
|
||||
ImGui.SameLine();
|
||||
using (ImRaii.Disabled(_multiInvites <= 1 || _multiInvites > 100))
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Envelope, "Generate " + _multiInvites + " one-time invites"))
|
||||
{
|
||||
_oneTimeInvites.AddRange(_apiController.GroupCreateTempInvite(new(_groupFullInfo.Group), _multiInvites).Result);
|
||||
}
|
||||
}
|
||||
|
||||
if (_oneTimeInvites.Any())
|
||||
{
|
||||
var invites = string.Join(Environment.NewLine, _oneTimeInvites);
|
||||
ImGui.InputTextMultiline("Generated Multi Invites", ref invites, 5000, new(0, 0), ImGuiInputTextFlags.ReadOnly);
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Copy, "Copy Invites to clipboard"))
|
||||
{
|
||||
ImGui.SetClipboardText(invites);
|
||||
}
|
||||
}
|
||||
}
|
||||
inviteNode.Dispose();
|
||||
|
||||
var mgmtNode = ImRaii.TreeNode("User Management");
|
||||
if (mgmtNode)
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Broom, "Clear Syncshell"))
|
||||
{
|
||||
_ = _apiController.GroupClear(new(_groupFullInfo.Group));
|
||||
}
|
||||
UiSharedService.AttachToolTip("This will remove all non-pinned, non-moderator users from the Syncshell");
|
||||
|
||||
ImGui.Dummy(new(2f));
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Retweet, "Refresh Banlist from Server"))
|
||||
{
|
||||
_bannedUsers = _apiController.GroupGetBannedUsers(new GroupDto(_groupFullInfo.Group)).Result;
|
||||
}
|
||||
|
||||
if (ImGui.BeginTable("bannedusertable" + _groupFullInfo.GID, 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingStretchProp | ImGuiTableFlags.ScrollY))
|
||||
{
|
||||
ImGui.TableSetupColumn("UID", ImGuiTableColumnFlags.None, 1);
|
||||
ImGui.TableSetupColumn("Alias", ImGuiTableColumnFlags.None, 1);
|
||||
ImGui.TableSetupColumn("By", ImGuiTableColumnFlags.None, 1);
|
||||
ImGui.TableSetupColumn("Date", ImGuiTableColumnFlags.None, 2);
|
||||
ImGui.TableSetupColumn("Reason", ImGuiTableColumnFlags.None, 3);
|
||||
ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.None, 1);
|
||||
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
foreach (var bannedUser in _bannedUsers.ToList())
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(bannedUser.UID);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(bannedUser.UserAlias ?? string.Empty);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(bannedUser.BannedBy);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(bannedUser.BannedOn.ToLocalTime().ToString(CultureInfo.CurrentCulture));
|
||||
ImGui.TableNextColumn();
|
||||
UiSharedService.TextWrapped(bannedUser.Reason);
|
||||
ImGui.TableNextColumn();
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Check, "Unban#" + bannedUser.UID))
|
||||
{
|
||||
_ = _apiController.GroupUnbanUser(bannedUser);
|
||||
_bannedUsers.RemoveAll(b => string.Equals(b.UID, bannedUser.UID, StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
}
|
||||
mgmtNode.Dispose();
|
||||
|
||||
var permNode = ImRaii.TreeNode("Permissions");
|
||||
if (permNode)
|
||||
{
|
||||
bool isDisableAnimations = perm.IsPreferDisableAnimations();
|
||||
bool isDisableSounds = perm.IsPreferDisableSounds();
|
||||
bool isDisableVfx = perm.IsPreferDisableVFX();
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.Text("Suggest Sound Sync");
|
||||
UiSharedService.BooleanToColoredIcon(!isDisableSounds);
|
||||
ImGui.SameLine(230);
|
||||
if (UiSharedService.IconTextButton(isDisableSounds ? FontAwesomeIcon.VolumeUp : FontAwesomeIcon.VolumeMute,
|
||||
isDisableSounds ? "Suggest to enable sound sync" : "Suggest to disable sound sync"))
|
||||
{
|
||||
perm.SetPreferDisableSounds(!perm.IsPreferDisableSounds());
|
||||
_ = _apiController.GroupChangeGroupPermissionState(new(_groupFullInfo.Group, perm));
|
||||
}
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.Text("Suggest Animation Sync");
|
||||
UiSharedService.BooleanToColoredIcon(!isDisableAnimations);
|
||||
ImGui.SameLine(230);
|
||||
if (UiSharedService.IconTextButton(isDisableAnimations ? FontAwesomeIcon.Running : FontAwesomeIcon.Stop,
|
||||
isDisableAnimations ? "Suggest to enable animation sync" : "Suggest to disable animation sync"))
|
||||
{
|
||||
perm.SetPreferDisableAnimations(!perm.IsPreferDisableAnimations());
|
||||
_ = _apiController.GroupChangeGroupPermissionState(new(_groupFullInfo.Group, perm));
|
||||
}
|
||||
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.Text("Suggest VFX Sync");
|
||||
UiSharedService.BooleanToColoredIcon(!isDisableVfx);
|
||||
ImGui.SameLine(230);
|
||||
if (UiSharedService.IconTextButton(isDisableVfx ? FontAwesomeIcon.Sun : FontAwesomeIcon.Circle,
|
||||
isDisableVfx ? "Suggest to enable vfx sync" : "Suggest to disable vfx sync"))
|
||||
{
|
||||
perm.SetPreferDisableVFX(!perm.IsPreferDisableVFX());
|
||||
_ = _apiController.GroupChangeGroupPermissionState(new(_groupFullInfo.Group, perm));
|
||||
}
|
||||
|
||||
UiSharedService.TextWrapped("Note: those suggested permissions will be shown to users on joining the Syncshell.");
|
||||
}
|
||||
permNode.Dispose();
|
||||
|
||||
if (_isOwner)
|
||||
{
|
||||
var ownerNode = ImRaii.TreeNode("Owner Settings");
|
||||
if (ownerNode)
|
||||
{
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("New Password");
|
||||
ImGui.SameLine();
|
||||
ImGui.InputTextWithHint("##changepw", "Min 10 characters", ref _newPassword, 50);
|
||||
ImGui.SameLine();
|
||||
using (ImRaii.Disabled(_newPassword.Length < 10))
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Passport, "Change Password"))
|
||||
{
|
||||
_pwChangeSuccess = _apiController.GroupChangePassword(new GroupPasswordDto(_groupFullInfo.Group, _newPassword)).Result;
|
||||
_newPassword = string.Empty;
|
||||
}
|
||||
}
|
||||
UiSharedService.AttachToolTip("Password requires to be at least 10 characters long. This action is irreversible.");
|
||||
|
||||
if (!_pwChangeSuccess)
|
||||
{
|
||||
UiSharedService.ColorTextWrapped("Failed to change the password. Password requires to be at least 10 characters long.", ImGuiColors.DalamudYellow);
|
||||
}
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Delete Syncshell") && UiSharedService.CtrlPressed() && UiSharedService.ShiftPressed())
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = _apiController.GroupDelete(new(_groupFullInfo.Group));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hold CTRL and Shift and click to delete this Syncshell." + Environment.NewLine + "WARNING: this action is irreversible.");
|
||||
}
|
||||
ownerNode.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void Open(GroupFullInfoDto groupFullInfo)
|
||||
{
|
||||
_groupFullInfo = groupFullInfo;
|
||||
_isOwner = string.Equals(_groupFullInfo.OwnerUID, _apiController.UID, StringComparison.Ordinal);
|
||||
_isModerator = _groupFullInfo.GroupUserInfo.IsModerator();
|
||||
_newPassword = string.Empty;
|
||||
_bannedUsers.Clear();
|
||||
_oneTimeInvites.Clear();
|
||||
_multiInvites = 30;
|
||||
_pwChangeSuccess = true;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,24 @@
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
|
||||
using System.Numerics;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
|
||||
public class SelectPairForGroupUi
|
||||
public class SelectPairForTagUi
|
||||
{
|
||||
private readonly TagHandler _tagHandler;
|
||||
private readonly UidDisplayHandler _uidDisplayHandler;
|
||||
private readonly IdDisplayHandler _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, UidDisplayHandler uidDisplayHandler)
|
||||
public SelectPairForTagUi(TagHandler tagHandler, IdDisplayHandler uidDisplayHandler)
|
||||
{
|
||||
_tagHandler = tagHandler;
|
||||
_uidDisplayHandler = uidDisplayHandler;
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Utility;
|
||||
@@ -7,12 +6,14 @@ using ImGuiNET;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
|
||||
using System.Numerics;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
|
||||
public class SelectGroupForPairUi
|
||||
public class SelectTagForPairUi
|
||||
{
|
||||
private readonly TagHandler _tagHandler;
|
||||
private readonly UidDisplayHandler _uidDisplayHandler;
|
||||
private readonly IdDisplayHandler _uidDisplayHandler;
|
||||
|
||||
/// <summary>
|
||||
/// The group UI is always open for a specific pair. This defines which pair the UI is open for.
|
||||
@@ -30,7 +31,7 @@ public class SelectGroupForPairUi
|
||||
/// </summary>
|
||||
private string _tagNameToAdd = "";
|
||||
|
||||
public SelectGroupForPairUi(TagHandler tagHandler, UidDisplayHandler uidDisplayHandler)
|
||||
public SelectTagForPairUi(TagHandler tagHandler, IdDisplayHandler uidDisplayHandler)
|
||||
{
|
||||
_show = false;
|
||||
_pair = null;
|
||||
@@ -15,20 +15,20 @@ namespace MareSynchronos.UI;
|
||||
public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
private readonly CharacterAnalyzer _characterAnalyzer;
|
||||
private readonly IpcManager _ipcManager;
|
||||
private bool _hasUpdate = false;
|
||||
private Dictionary<ObjectKind, Dictionary<string, CharacterAnalyzer.FileDataEntry>>? _cachedAnalysis;
|
||||
private string _selectedHash = string.Empty;
|
||||
private ObjectKind _selectedObjectTab;
|
||||
private string _selectedFileTypeTab = string.Empty;
|
||||
private bool _enableBc7ConversionMode = false;
|
||||
private readonly Dictionary<string, string[]> _texturesToConvert = new(StringComparer.Ordinal);
|
||||
private Task? _conversionTask;
|
||||
private CancellationTokenSource _conversionCancellationTokenSource = new();
|
||||
private readonly Progress<(string, int)> _conversionProgress = new();
|
||||
private readonly IpcManager _ipcManager;
|
||||
private readonly Dictionary<string, string[]> _texturesToConvert = new(StringComparer.Ordinal);
|
||||
private Dictionary<ObjectKind, Dictionary<string, CharacterAnalyzer.FileDataEntry>>? _cachedAnalysis;
|
||||
private CancellationTokenSource _conversionCancellationTokenSource = new();
|
||||
private string _conversionCurrentFileName = string.Empty;
|
||||
private int _conversionCurrentFileProgress = 0;
|
||||
private Task? _conversionTask;
|
||||
private bool _enableBc7ConversionMode = false;
|
||||
private bool _hasUpdate = false;
|
||||
private bool _modalOpen = false;
|
||||
private string _selectedFileTypeTab = string.Empty;
|
||||
private string _selectedHash = string.Empty;
|
||||
private ObjectKind _selectedObjectTab;
|
||||
private bool _showModal = false;
|
||||
|
||||
public DataAnalysisUi(ILogger<DataAnalysisUi> logger, MareMediator mediator, CharacterAnalyzer characterAnalyzer, IpcManager ipcManager) : base(logger, mediator, "Mare Character Data Analysis")
|
||||
@@ -57,26 +57,6 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
_conversionProgress.ProgressChanged += ConversionProgress_ProgressChanged;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
_conversionProgress.ProgressChanged -= ConversionProgress_ProgressChanged;
|
||||
}
|
||||
|
||||
private void ConversionProgress_ProgressChanged(object? sender, (string, int) e)
|
||||
{
|
||||
_conversionCurrentFileName = e.Item1;
|
||||
_conversionCurrentFileProgress = e.Item2;
|
||||
}
|
||||
|
||||
public override void OnOpen()
|
||||
{
|
||||
_hasUpdate = true;
|
||||
_selectedHash = string.Empty;
|
||||
_enableBc7ConversionMode = false;
|
||||
_texturesToConvert.Clear();
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
if (_conversionTask != null && !_conversionTask.IsCompleted)
|
||||
@@ -84,7 +64,7 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
_showModal = true;
|
||||
if (ImGui.BeginPopupModal("BC7 Conversion in Progress"))
|
||||
{
|
||||
ImGui.Text("BC7 Conversion in progress: " + _conversionCurrentFileProgress + "/" + _texturesToConvert.Count);
|
||||
ImGui.TextUnformatted("BC7 Conversion in progress: " + _conversionCurrentFileProgress + "/" + _texturesToConvert.Count);
|
||||
UiSharedService.TextWrapped("Current file: " + _conversionCurrentFileName);
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.StopCircle, "Cancel conversion"))
|
||||
{
|
||||
@@ -141,14 +121,14 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
ImGuiColors.DalamudYellow);
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.PlayCircle, "Start analysis (missing entries)"))
|
||||
{
|
||||
_ = _characterAnalyzer.ComputeAnalysis(false);
|
||||
_ = _characterAnalyzer.ComputeAnalysis(print: false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.PlayCircle, "Start analysis (recalculate all entries)"))
|
||||
{
|
||||
_ = _characterAnalyzer.ComputeAnalysis(false, true);
|
||||
_ = _characterAnalyzer.ComputeAnalysis(print: false, recalculate: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,7 +246,7 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(UiSharedService.ByteToString(fileGroup.Sum(c => c.CompressedSize)));
|
||||
|
||||
if (_selectedFileTypeTab == "tex")
|
||||
if (string.Equals(_selectedFileTypeTab, "tex", StringComparison.Ordinal))
|
||||
{
|
||||
ImGui.Checkbox("Enable BC7 Conversion Mode", ref _enableBc7ConversionMode);
|
||||
if (_enableBc7ConversionMode)
|
||||
@@ -298,13 +278,13 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.Text("Selected file:");
|
||||
ImGui.TextUnformatted("Selected file:");
|
||||
ImGui.SameLine();
|
||||
UiSharedService.ColorText(_selectedHash, ImGuiColors.DalamudYellow);
|
||||
|
||||
if (_cachedAnalysis[_selectedObjectTab].ContainsKey(_selectedHash))
|
||||
if (_cachedAnalysis[_selectedObjectTab].TryGetValue(_selectedHash, out CharacterAnalyzer.FileDataEntry? item))
|
||||
{
|
||||
var filePaths = _cachedAnalysis[_selectedObjectTab][_selectedHash].FilePaths;
|
||||
var filePaths = item.FilePaths;
|
||||
ImGui.TextUnformatted("Local file path:");
|
||||
ImGui.SameLine();
|
||||
UiSharedService.TextWrapped(filePaths[0]);
|
||||
@@ -317,7 +297,7 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
UiSharedService.AttachToolTip(string.Join(Environment.NewLine, filePaths.Skip(1)));
|
||||
}
|
||||
|
||||
var gamepaths = _cachedAnalysis[_selectedObjectTab][_selectedHash].GamePaths;
|
||||
var gamepaths = item.GamePaths;
|
||||
ImGui.TextUnformatted("Used by game path:");
|
||||
ImGui.SameLine();
|
||||
UiSharedService.TextWrapped(gamepaths[0]);
|
||||
@@ -332,17 +312,38 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnOpen()
|
||||
{
|
||||
_hasUpdate = true;
|
||||
_selectedHash = string.Empty;
|
||||
_enableBc7ConversionMode = false;
|
||||
_texturesToConvert.Clear();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
_conversionProgress.ProgressChanged -= ConversionProgress_ProgressChanged;
|
||||
}
|
||||
|
||||
private void ConversionProgress_ProgressChanged(object? sender, (string, int) e)
|
||||
{
|
||||
_conversionCurrentFileName = e.Item1;
|
||||
_conversionCurrentFileProgress = e.Item2;
|
||||
}
|
||||
|
||||
private void DrawTable(IGrouping<string, CharacterAnalyzer.FileDataEntry> fileGroup)
|
||||
{
|
||||
using var table = ImRaii.Table("Analysis", fileGroup.Key == "tex" ? (_enableBc7ConversionMode ? 7 : 6) : 5, ImGuiTableFlags.Sortable | ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.SizingFixedFit,
|
||||
new Vector2(0, 300));
|
||||
using var table = ImRaii.Table("Analysis", string.Equals(fileGroup.Key, "tex", StringComparison.Ordinal) ?
|
||||
(_enableBc7ConversionMode ? 7 : 6) : 5, ImGuiTableFlags.Sortable | ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.SizingFixedFit,
|
||||
new Vector2(0, 300));
|
||||
if (!table.Success) return;
|
||||
ImGui.TableSetupColumn("Hash");
|
||||
ImGui.TableSetupColumn("Filepaths");
|
||||
ImGui.TableSetupColumn("Gamepaths");
|
||||
ImGui.TableSetupColumn("Original Size");
|
||||
ImGui.TableSetupColumn("Compressed Size");
|
||||
if (fileGroup.Key == "tex")
|
||||
if (string.Equals(fileGroup.Key, "tex", StringComparison.Ordinal))
|
||||
{
|
||||
ImGui.TableSetupColumn("Format");
|
||||
if (_enableBc7ConversionMode) ImGui.TableSetupColumn("Convert to BC7");
|
||||
@@ -375,9 +376,9 @@ new Vector2(0, 300));
|
||||
_cachedAnalysis![_selectedObjectTab] = _cachedAnalysis[_selectedObjectTab].OrderBy(k => k.Value.CompressedSize).ToDictionary(d => d.Key, d => d.Value, StringComparer.Ordinal);
|
||||
if (idx == 4 && sortSpecs.Specs.SortDirection == ImGuiSortDirection.Descending)
|
||||
_cachedAnalysis![_selectedObjectTab] = _cachedAnalysis[_selectedObjectTab].OrderByDescending(k => k.Value.CompressedSize).ToDictionary(d => d.Key, d => d.Value, StringComparer.Ordinal);
|
||||
if (fileGroup.Key == "tex" && idx == 5 && sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending)
|
||||
if (string.Equals(fileGroup.Key, "tex", StringComparison.Ordinal) && idx == 5 && sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending)
|
||||
_cachedAnalysis![_selectedObjectTab] = _cachedAnalysis[_selectedObjectTab].OrderBy(k => k.Value.Format).ToDictionary(d => d.Key, d => d.Value, StringComparer.Ordinal);
|
||||
if (fileGroup.Key == "tex" && idx == 5 && sortSpecs.Specs.SortDirection == ImGuiSortDirection.Descending)
|
||||
if (string.Equals(fileGroup.Key, "tex", StringComparison.Ordinal) && idx == 5 && sortSpecs.Specs.SortDirection == ImGuiSortDirection.Descending)
|
||||
_cachedAnalysis![_selectedObjectTab] = _cachedAnalysis[_selectedObjectTab].OrderByDescending(k => k.Value.Format).ToDictionary(d => d.Key, d => d.Value, StringComparer.Ordinal);
|
||||
|
||||
sortSpecs.SpecsDirty = false;
|
||||
@@ -385,7 +386,7 @@ new Vector2(0, 300));
|
||||
|
||||
foreach (var item in fileGroup)
|
||||
{
|
||||
using var text = ImRaii.PushColor(ImGuiCol.Text, new Vector4(0, 0, 0, 1), string.Equals(item.Hash, _selectedHash));
|
||||
using var text = ImRaii.PushColor(ImGuiCol.Text, new Vector4(0, 0, 0, 1), string.Equals(item.Hash, _selectedHash, StringComparison.Ordinal));
|
||||
using var text2 = ImRaii.PushColor(ImGuiCol.Text, new Vector4(1, 1, 1, 1), !item.IsComputed);
|
||||
ImGui.TableNextColumn();
|
||||
if (!item.IsComputed)
|
||||
@@ -412,7 +413,7 @@ new Vector2(0, 300));
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(UiSharedService.ByteToString(item.CompressedSize));
|
||||
if (ImGui.IsItemClicked()) _selectedHash = item.Hash;
|
||||
if (fileGroup.Key == "tex")
|
||||
if (string.Equals(fileGroup.Key, "tex", StringComparison.Ordinal))
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(item.Format.Value);
|
||||
@@ -420,9 +421,9 @@ new Vector2(0, 300));
|
||||
if (_enableBc7ConversionMode)
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
if (item.Format.Value == "BC7")
|
||||
if (string.Equals(item.Format.Value, "BC7", StringComparison.Ordinal))
|
||||
{
|
||||
ImGui.Text("");
|
||||
ImGui.TextUnformatted("");
|
||||
continue;
|
||||
}
|
||||
var filePath = item.FilePaths[0];
|
||||
@@ -442,4 +443,4 @@ new Vector2(0, 300));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
61
MareSynchronos/UI/DrawEntityFactory.cs
Normal file
61
MareSynchronos/UI/DrawEntityFactory.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using MareSynchronos.Services.ServerConfiguration;
|
||||
using MareSynchronos.UI.Components;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
using MareSynchronos.WebAPI;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MareSynchronos.UI;
|
||||
|
||||
public class DrawEntityFactory
|
||||
{
|
||||
private readonly ILogger<DrawEntityFactory> _logger;
|
||||
private readonly ApiController _apiController;
|
||||
private readonly MareMediator _mediator;
|
||||
private readonly SelectPairForTagUi _selectPairForTagUi;
|
||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||
private readonly SelectTagForPairUi _selectTagForPairUi;
|
||||
private readonly TagHandler _tagHandler;
|
||||
private readonly IdDisplayHandler _uidDisplayHandler;
|
||||
|
||||
public DrawEntityFactory(ILogger<DrawEntityFactory> logger, ApiController apiController, IdDisplayHandler uidDisplayHandler,
|
||||
SelectTagForPairUi selectTagForPairUi, MareMediator mediator,
|
||||
TagHandler tagHandler, SelectPairForTagUi selectPairForTagUi,
|
||||
ServerConfigurationManager serverConfigurationManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_apiController = apiController;
|
||||
_uidDisplayHandler = uidDisplayHandler;
|
||||
_selectTagForPairUi = selectTagForPairUi;
|
||||
_mediator = mediator;
|
||||
_tagHandler = tagHandler;
|
||||
_selectPairForTagUi = selectPairForTagUi;
|
||||
_serverConfigurationManager = serverConfigurationManager;
|
||||
}
|
||||
|
||||
public DrawFolderGroup CreateDrawGroupFolder(GroupFullInfoDto groupFullInfoDto, Dictionary<Pair, List<GroupFullInfoDto>> pairs)
|
||||
{
|
||||
_logger.LogTrace("Creating new DrawGroupFolder for {gid}", groupFullInfoDto.GID);
|
||||
return new DrawFolderGroup(groupFullInfoDto.Group.GID, groupFullInfoDto, _apiController,
|
||||
pairs.Select(p => CreateDrawPair(groupFullInfoDto.Group.GID + p.Key.UserData.UID, p.Key, p.Value)).ToList(),
|
||||
_tagHandler, _uidDisplayHandler, _mediator);
|
||||
}
|
||||
|
||||
public DrawFolderTag CreateDrawTagFolder(string tag, Dictionary<Pair, List<GroupFullInfoDto>> pairs)
|
||||
{
|
||||
_logger.LogTrace("Creating new DrawTagFolder for {tag}", tag);
|
||||
|
||||
return new(tag, pairs.Select(u => CreateDrawPair(tag, u.Key, u.Value)).ToList(),
|
||||
_tagHandler, _apiController, _selectPairForTagUi);
|
||||
}
|
||||
|
||||
public DrawUserPair CreateDrawPair(string id, Pair user, List<GroupFullInfoDto> groups)
|
||||
{
|
||||
_logger.LogTrace("Creating new DrawPair for {id}", id + user.UserData.UID);
|
||||
|
||||
return new DrawUserPair(id + user.UserData.UID, user, groups, _apiController, _uidDisplayHandler,
|
||||
_mediator, _selectTagForPairUi, _serverConfigurationManager);
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,11 @@ public sealed class DtrEntry : IDisposable, IHostedService
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private readonly CancellationTokenSource _cancellationTokenSource = new();
|
||||
private readonly ILogger<DtrEntry> _logger;
|
||||
private readonly IDtrBar _dtrBar;
|
||||
private readonly ConfigurationServiceBase<MareConfig> _configService;
|
||||
private readonly MareMediator _mareMediator;
|
||||
private readonly IDtrBar _dtrBar;
|
||||
private readonly Lazy<DtrBarEntry> _entry;
|
||||
private readonly ILogger<DtrEntry> _logger;
|
||||
private readonly MareMediator _mareMediator;
|
||||
private readonly PairManager _pairManager;
|
||||
private Task? _runTask;
|
||||
private string? _text;
|
||||
@@ -67,15 +67,6 @@ public sealed class DtrEntry : IDisposable, IHostedService
|
||||
}
|
||||
}
|
||||
|
||||
private DtrBarEntry CreateEntry()
|
||||
{
|
||||
_logger.LogTrace("Creating new DtrBar entry");
|
||||
var entry = _dtrBar.Get("Mare Synchronos");
|
||||
entry.OnClick = () => _mareMediator.Publish(new UiToggleMessage(typeof(CompactUi)));
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
private void Clear()
|
||||
{
|
||||
if (!_entry.IsValueCreated) return;
|
||||
@@ -85,6 +76,15 @@ public sealed class DtrEntry : IDisposable, IHostedService
|
||||
_entry.Value.Shown = false;
|
||||
}
|
||||
|
||||
private DtrBarEntry CreateEntry()
|
||||
{
|
||||
_logger.LogTrace("Creating new DtrBar entry");
|
||||
var entry = _dtrBar.Get("Mare Synchronos");
|
||||
entry.OnClick = () => _mareMediator.Publish(new UiToggleMessage(typeof(CompactUi)));
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
private async Task RunAsync()
|
||||
{
|
||||
while (!_cancellationTokenSource.IsCancellationRequested)
|
||||
|
||||
@@ -26,7 +26,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
||||
private string _descriptionText = string.Empty;
|
||||
private IDalamudTextureWrap? _pfpTextureWrap;
|
||||
private string _profileDescription = string.Empty;
|
||||
private byte[] _profileImage = Array.Empty<byte>();
|
||||
private byte[] _profileImage = [];
|
||||
private bool _showFileDialogError = false;
|
||||
private bool _wasOpen;
|
||||
|
||||
@@ -136,7 +136,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
||||
_fileDialogManager.OpenFileDialog("Select new Profile picture", ".png", (success, file) =>
|
||||
{
|
||||
if (!success) return;
|
||||
Task.Run(async () =>
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
var fileContent = File.ReadAllBytes(file);
|
||||
using MemoryStream ms = new(fileContent);
|
||||
@@ -155,7 +155,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
||||
}
|
||||
|
||||
_showFileDialogError = false;
|
||||
await _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), false, null, Convert.ToBase64String(fileContent), null))
|
||||
await _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, Convert.ToBase64String(fileContent), Description: null))
|
||||
.ConfigureAwait(false);
|
||||
});
|
||||
});
|
||||
@@ -164,7 +164,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
||||
ImGui.SameLine();
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Clear uploaded profile picture"))
|
||||
{
|
||||
_ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), false, null, "", null));
|
||||
_ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, "", Description: null));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Clear your currently uploaded profile picture");
|
||||
if (_showFileDialogError)
|
||||
@@ -174,7 +174,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
||||
var isNsfw = profile.IsNSFW;
|
||||
if (ImGui.Checkbox("Profile is NSFW", ref isNsfw))
|
||||
{
|
||||
_ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), false, isNsfw, null, null));
|
||||
_ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, isNsfw, ProfilePictureBase64: null, Description: null));
|
||||
}
|
||||
UiSharedService.DrawHelpText("If your profile description or image can be considered NSFW, toggle this to ON");
|
||||
var widthTextBox = 400;
|
||||
@@ -213,13 +213,13 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
||||
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Save, "Save Description"))
|
||||
{
|
||||
_ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), false, null, null, _descriptionText));
|
||||
_ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, ProfilePictureBase64: null, _descriptionText));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Sets your profile description text");
|
||||
ImGui.SameLine();
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Clear Description"))
|
||||
{
|
||||
_ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), false, null, null, ""));
|
||||
_ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, ProfilePictureBase64: null, ""));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Clears your profile description text");
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class GposeUi : WindowMediatorSubscriberBase
|
||||
_configService.Current.ExportFolder = Path.GetDirectoryName(path) ?? string.Empty;
|
||||
_configService.Save();
|
||||
|
||||
Task.Run(() => _mareCharaFileManager.LoadMareCharaFile(path));
|
||||
_ = Task.Run(() => _mareCharaFileManager.LoadMareCharaFile(path));
|
||||
}, 1, Directory.Exists(_configService.Current.ExportFolder) ? _configService.Current.ExportFolder : null);
|
||||
}
|
||||
UiSharedService.AttachToolTip("Applies it to the currently selected GPose actor");
|
||||
@@ -61,7 +61,7 @@ public class GposeUi : WindowMediatorSubscriberBase
|
||||
UiSharedService.TextWrapped("File Description: " + _mareCharaFileManager.LoadedCharaFile.CharaFileData.Description);
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Check, "Apply loaded MCDF"))
|
||||
{
|
||||
Task.Run(async () => await _mareCharaFileManager.ApplyMareCharaFile(_dalamudUtil.GposeTargetGameObject).ConfigureAwait(false));
|
||||
_ = Task.Run(async () => await _mareCharaFileManager.ApplyMareCharaFile(_dalamudUtil.GposeTargetGameObject).ConfigureAwait(false));
|
||||
}
|
||||
UiSharedService.AttachToolTip("Applies it to the currently selected GPose actor");
|
||||
UiSharedService.ColorTextWrapped("Warning: redrawing or changing the character will revert all applied mods.", ImGuiColors.DalamudYellow);
|
||||
|
||||
@@ -1,41 +1,96 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services.ServerConfiguration;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using ImGuiScene;
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using MareSynchronos.Services.ServerConfiguration;
|
||||
|
||||
namespace MareSynchronos.UI.Handlers;
|
||||
|
||||
public class UidDisplayHandler
|
||||
public class IdDisplayHandler
|
||||
{
|
||||
private readonly MareConfigService _mareConfigService;
|
||||
private readonly MareMediator _mediator;
|
||||
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;
|
||||
private readonly Dictionary<string, bool> _showIdForEntry = new(StringComparer.Ordinal);
|
||||
private string _editComment = string.Empty;
|
||||
private string _editEntry = string.Empty;
|
||||
private bool _editIsUid = false;
|
||||
private string _lastMouseOverUid = string.Empty;
|
||||
private bool _popupShown = false;
|
||||
private DateTime? _popupTime;
|
||||
private TextureWrap? _textureWrap;
|
||||
|
||||
public UidDisplayHandler(MareMediator mediator, PairManager pairManager,
|
||||
ServerConfigurationManager serverManager, MareConfigService mareConfigService)
|
||||
public IdDisplayHandler(MareMediator mediator, ServerConfigurationManager serverManager, MareConfigService mareConfigService)
|
||||
{
|
||||
_mediator = mediator;
|
||||
_pairManager = pairManager;
|
||||
_serverManager = serverManager;
|
||||
_mareConfigService = mareConfigService;
|
||||
}
|
||||
|
||||
public void DrawGroupText(string id, GroupFullInfoDto group, float textPosX, float originalY, Func<float> editBoxWidth)
|
||||
{
|
||||
ImGui.SameLine(textPosX);
|
||||
(bool textIsUid, string playerText) = GetGroupText(group);
|
||||
if (!string.Equals(_editEntry, group.GID, StringComparison.Ordinal))
|
||||
{
|
||||
ImGui.SetCursorPosY(originalY);
|
||||
using (ImRaii.PushFont(UiBuilder.MonoFont, textIsUid))
|
||||
ImGui.TextUnformatted(playerText);
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||
{
|
||||
var prevState = textIsUid;
|
||||
if (_showIdForEntry.ContainsKey(group.GID))
|
||||
{
|
||||
prevState = _showIdForEntry[group.GID];
|
||||
}
|
||||
_showIdForEntry[group.GID] = !prevState;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
if (_editIsUid)
|
||||
{
|
||||
_serverManager.SetNoteForUid(_editEntry, _editComment, save: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_serverManager.SetNoteForGid(_editEntry, _editComment, save: true);
|
||||
}
|
||||
|
||||
_editComment = _serverManager.GetNoteForGid(group.GID) ?? string.Empty;
|
||||
_editEntry = group.GID;
|
||||
_editIsUid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.SetCursorPosY(originalY);
|
||||
|
||||
ImGui.SetNextItemWidth(editBoxWidth.Invoke());
|
||||
if (ImGui.InputTextWithHint("", "Name/Notes", ref _editComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
|
||||
{
|
||||
_serverManager.SetNoteForGid(group.GID, _editComment, save: true);
|
||||
_editEntry = string.Empty;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
_editEntry = string.Empty;
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hit ENTER to save\nRight click to cancel");
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawPairText(string id, Pair pair, float textPosX, float originalY, Func<float> editBoxWidth)
|
||||
{
|
||||
ImGui.SameLine(textPosX);
|
||||
(bool textIsUid, string playerText) = GetPlayerText(pair);
|
||||
if (!string.Equals(_editNickEntry, pair.UserData.UID, StringComparison.Ordinal))
|
||||
if (!string.Equals(_editEntry, pair.UserData.UID, StringComparison.Ordinal))
|
||||
{
|
||||
ImGui.SetCursorPosY(originalY);
|
||||
if (textIsUid) ImGui.PushFont(UiBuilder.MonoFont);
|
||||
@@ -66,7 +121,7 @@ public class UidDisplayHandler
|
||||
{
|
||||
if (string.Equals(_lastMouseOverUid, id))
|
||||
{
|
||||
_mediator.Publish(new ProfilePopoutToggle(null));
|
||||
_mediator.Publish(new ProfilePopoutToggle(Pair: null));
|
||||
_lastMouseOverUid = string.Empty;
|
||||
_popupShown = false;
|
||||
_textureWrap?.Dispose();
|
||||
@@ -77,19 +132,27 @@ public class UidDisplayHandler
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||
{
|
||||
var prevState = textIsUid;
|
||||
if (_showUidForEntry.ContainsKey(pair.UserData.UID))
|
||||
if (_showIdForEntry.ContainsKey(pair.UserData.UID))
|
||||
{
|
||||
prevState = _showUidForEntry[pair.UserData.UID];
|
||||
prevState = _showIdForEntry[pair.UserData.UID];
|
||||
}
|
||||
_showUidForEntry[pair.UserData.UID] = !prevState;
|
||||
_showIdForEntry[pair.UserData.UID] = !prevState;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
var nickEntryPair = _pairManager.DirectPairs.Find(p => string.Equals(p.UserData.UID, _editNickEntry, StringComparison.Ordinal));
|
||||
nickEntryPair?.SetNote(_editUserComment);
|
||||
_editUserComment = pair.GetNote() ?? string.Empty;
|
||||
_editNickEntry = pair.UserData.UID;
|
||||
if (_editIsUid)
|
||||
{
|
||||
_serverManager.SetNoteForUid(_editEntry, _editComment, save: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_serverManager.SetNoteForGid(_editEntry, _editComment, save: true);
|
||||
}
|
||||
|
||||
_editComment = pair.GetNote() ?? string.Empty;
|
||||
_editEntry = pair.UserData.UID;
|
||||
_editIsUid = true;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Middle))
|
||||
@@ -102,21 +165,45 @@ public class UidDisplayHandler
|
||||
ImGui.SetCursorPosY(originalY);
|
||||
|
||||
ImGui.SetNextItemWidth(editBoxWidth.Invoke());
|
||||
if (ImGui.InputTextWithHint("", "Nick/Notes", ref _editUserComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
|
||||
if (ImGui.InputTextWithHint("", "Nick/Notes", ref _editComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
|
||||
{
|
||||
_serverManager.SetNoteForUid(pair.UserData.UID, _editUserComment);
|
||||
_serverManager.SetNoteForUid(pair.UserData.UID, _editComment);
|
||||
_serverManager.SaveNotes();
|
||||
_editNickEntry = string.Empty;
|
||||
_editEntry = string.Empty;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
_editNickEntry = string.Empty;
|
||||
_editEntry = string.Empty;
|
||||
}
|
||||
UiSharedService.AttachToolTip("Hit ENTER to save\nRight click to cancel");
|
||||
}
|
||||
}
|
||||
|
||||
public (bool isGid, string text) GetGroupText(GroupFullInfoDto group)
|
||||
{
|
||||
var textIsGid = true;
|
||||
bool showUidInsteadOfName = ShowGidInsteadOfName(group);
|
||||
string? groupText = _serverManager.GetNoteForGid(group.GID);
|
||||
if (!showUidInsteadOfName && groupText != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(groupText))
|
||||
{
|
||||
groupText = group.GroupAliasOrGID;
|
||||
}
|
||||
else
|
||||
{
|
||||
textIsGid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
groupText = group.GroupAliasOrGID;
|
||||
}
|
||||
|
||||
return (textIsGid, groupText!);
|
||||
}
|
||||
|
||||
public (bool isUid, string text) GetPlayerText(Pair pair)
|
||||
{
|
||||
var textIsUid = true;
|
||||
@@ -157,8 +244,8 @@ public class UidDisplayHandler
|
||||
|
||||
internal void Clear()
|
||||
{
|
||||
_editNickEntry = string.Empty;
|
||||
_editUserComment = string.Empty;
|
||||
_editEntry = string.Empty;
|
||||
_editComment = string.Empty;
|
||||
}
|
||||
|
||||
internal void OpenProfile(Pair entry)
|
||||
@@ -166,10 +253,17 @@ public class UidDisplayHandler
|
||||
_mediator.Publish(new ProfileOpenStandaloneMessage(entry));
|
||||
}
|
||||
|
||||
private bool ShowGidInsteadOfName(GroupFullInfoDto group)
|
||||
{
|
||||
_showIdForEntry.TryGetValue(group.GID, out var showidInsteadOfName);
|
||||
|
||||
return showidInsteadOfName;
|
||||
}
|
||||
|
||||
private bool ShowUidInsteadOfName(Pair pair)
|
||||
{
|
||||
_showUidForEntry.TryGetValue(pair.UserData.UID, out var showUidInsteadOfName);
|
||||
_showIdForEntry.TryGetValue(pair.UserData.UID, out var showidInsteadOfName);
|
||||
|
||||
return showUidInsteadOfName;
|
||||
return showidInsteadOfName;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace MareSynchronos.UI.Handlers;
|
||||
|
||||
public class TagHandler
|
||||
{
|
||||
public const string CustomAllTag = "Mare_All";
|
||||
public const string CustomOfflineTag = "Mare_Offline";
|
||||
public const string CustomOnlineTag = "Mare_Online";
|
||||
public const string CustomUnpairedTag = "Mare_Unpaired";
|
||||
@@ -27,9 +28,12 @@ public class TagHandler
|
||||
|
||||
public List<string> GetAllTagsSorted()
|
||||
{
|
||||
return _serverConfigurationManager.GetServerAvailablePairTags()
|
||||
.OrderBy(s => s, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
return
|
||||
[
|
||||
.. _serverConfigurationManager.GetServerAvailablePairTags()
|
||||
.OrderBy(s => s, StringComparer.OrdinalIgnoreCase)
|
||||
,
|
||||
];
|
||||
}
|
||||
|
||||
public HashSet<string> GetOtherUidsForTag(string tag)
|
||||
@@ -59,7 +63,6 @@ public class TagHandler
|
||||
|
||||
public void RemoveTag(string tag)
|
||||
{
|
||||
// First remove the tag from teh available pair tags
|
||||
_serverConfigurationManager.RemoveTag(tag);
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ public class IntroUi : WindowMediatorSubscriberBase
|
||||
var buttonWidth = _secretKey.Length != 64 ? 0 : ImGuiHelpers.GetButtonSize(buttonText).X + ImGui.GetStyle().ItemSpacing.X;
|
||||
var textSize = ImGui.CalcTextSize(text);
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.Text(text);
|
||||
ImGui.TextUnformatted(text);
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(UiSharedService.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X - buttonWidth - textSize.X);
|
||||
ImGui.InputText("", ref _secretKey, 64);
|
||||
@@ -235,7 +235,7 @@ public class IntroUi : WindowMediatorSubscriberBase
|
||||
});
|
||||
_serverConfigurationManager.AddCurrentCharacterToServer(addLastSecretKey: true);
|
||||
_secretKey = string.Empty;
|
||||
Task.Run(() => _uiShared.ApiController.CreateConnections(forceGetToken: true));
|
||||
_ = Task.Run(() => _uiShared.ApiController.CreateConnections());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,6 +253,6 @@ public class IntroUi : WindowMediatorSubscriberBase
|
||||
_uiShared.LoadLocalization(_languages.ElementAt(changeLanguageTo).Value);
|
||||
}
|
||||
|
||||
_tosParagraphs = new[] { Strings.ToS.Paragraph1, Strings.ToS.Paragraph2, Strings.ToS.Paragraph3, Strings.ToS.Paragraph4, Strings.ToS.Paragraph5, Strings.ToS.Paragraph6 };
|
||||
_tosParagraphs = [Strings.ToS.Paragraph1, Strings.ToS.Paragraph2, Strings.ToS.Paragraph3, Strings.ToS.Paragraph4, Strings.ToS.Paragraph5, Strings.ToS.Paragraph6];
|
||||
}
|
||||
}
|
||||
@@ -1,47 +1,49 @@
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Internal;
|
||||
|
||||
using Dalamud.Interface.Utility;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using MareSynchronos.Services.ServerConfiguration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Numerics;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Interface.Internal;
|
||||
|
||||
namespace MareSynchronos.UI;
|
||||
|
||||
public class PopoutProfileUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
private readonly MareProfileManager _mareProfileManager;
|
||||
private readonly PairManager _pairManager;
|
||||
private readonly ServerConfigurationManager _serverManager;
|
||||
private readonly UiSharedService _uiSharedService;
|
||||
private Vector2 _lastMainPos = Vector2.Zero;
|
||||
private Vector2 _lastMainSize = Vector2.Zero;
|
||||
private byte[] _lastProfilePicture = Array.Empty<byte>();
|
||||
private byte[] _lastSupporterPicture = Array.Empty<byte>();
|
||||
private byte[] _lastProfilePicture = [];
|
||||
private byte[] _lastSupporterPicture = [];
|
||||
private Pair? _pair;
|
||||
private IDalamudTextureWrap? _supporterTextureWrap;
|
||||
private IDalamudTextureWrap? _textureWrap;
|
||||
|
||||
public PopoutProfileUi(ILogger<PopoutProfileUi> logger, MareMediator mediator, UiSharedService uiBuilder,
|
||||
ServerConfigurationManager serverManager, MareConfigService mareConfigService,
|
||||
MareProfileManager mareProfileManager) : base(logger, mediator, "###MareSynchronosPopoutProfileUI")
|
||||
MareProfileManager mareProfileManager, PairManager pairManager) : base(logger, mediator, "###MareSynchronosPopoutProfileUI")
|
||||
{
|
||||
_uiSharedService = uiBuilder;
|
||||
_serverManager = serverManager;
|
||||
_mareProfileManager = mareProfileManager;
|
||||
|
||||
_pairManager = pairManager;
|
||||
Flags = ImGuiWindowFlags.NoDecoration;
|
||||
|
||||
Mediator.Subscribe<ProfilePopoutToggle>(this, (msg) =>
|
||||
{
|
||||
IsOpen = msg.Pair != null;
|
||||
_pair = msg.Pair;
|
||||
_lastProfilePicture = Array.Empty<byte>();
|
||||
_lastSupporterPicture = Array.Empty<byte>();
|
||||
_lastProfilePicture = [];
|
||||
_lastSupporterPicture = [];
|
||||
_textureWrap?.Dispose();
|
||||
_textureWrap = null;
|
||||
_supporterTextureWrap?.Dispose();
|
||||
@@ -54,7 +56,6 @@ public class PopoutProfileUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
var border = ImGui.GetStyle().WindowBorderSize;
|
||||
var padding = ImGui.GetStyle().WindowPadding;
|
||||
var spacing = ImGui.GetStyle().ItemSpacing;
|
||||
Size = new(256 + (padding.X * 2) + border, msg.Size.Y / ImGuiHelpers.GlobalScale);
|
||||
_lastMainSize = msg.Size;
|
||||
}
|
||||
@@ -65,7 +66,7 @@ public class PopoutProfileUi : WindowMediatorSubscriberBase
|
||||
}
|
||||
else
|
||||
{
|
||||
Position = new(mainPos.X - Size.Value.X * ImGuiHelpers.GlobalScale, mainPos.Y);
|
||||
Position = new(mainPos.X - Size!.Value.X * ImGuiHelpers.GlobalScale, mainPos.Y);
|
||||
}
|
||||
|
||||
if (msg.Position != Vector2.Zero)
|
||||
@@ -129,7 +130,7 @@ public class PopoutProfileUi : WindowMediatorSubscriberBase
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted($"({_pair.PlayerName})");
|
||||
}
|
||||
if (_pair.UserPair != null)
|
||||
if (_pair.UserPair.IndividualPairStatus == API.Data.Enum.IndividualPairStatus.Bidirectional)
|
||||
{
|
||||
ImGui.TextUnformatted("Directly paired");
|
||||
if (_pair.UserPair.OwnPermissions.IsPaused())
|
||||
@@ -143,13 +144,14 @@ public class PopoutProfileUi : WindowMediatorSubscriberBase
|
||||
UiSharedService.ColorText("They: paused", ImGuiColors.DalamudYellow);
|
||||
}
|
||||
}
|
||||
if (_pair.GroupPair.Any())
|
||||
if (_pair.UserPair.Groups.Any())
|
||||
{
|
||||
ImGui.TextUnformatted("Paired through Syncshells:");
|
||||
foreach (var groupPair in _pair.GroupPair.Select(k => k.Key))
|
||||
foreach (var group in _pair.UserPair.Groups)
|
||||
{
|
||||
var groupNote = _serverManager.GetNoteForGid(groupPair.GID);
|
||||
var groupString = string.IsNullOrEmpty(groupNote) ? groupPair.GroupAliasOrGID : $"{groupNote} ({groupPair.GroupAliasOrGID})";
|
||||
var groupNote = _serverManager.GetNoteForGid(group);
|
||||
var groupName = _pairManager.GroupPairs.First(f => string.Equals(f.Key.GID, group, StringComparison.Ordinal)).Key.GroupAliasOrGID;
|
||||
var groupString = string.IsNullOrEmpty(groupNote) ? groupName : $"{groupNote} ({groupName})";
|
||||
ImGui.TextUnformatted("- " + groupString);
|
||||
}
|
||||
}
|
||||
@@ -162,7 +164,7 @@ public class PopoutProfileUi : WindowMediatorSubscriberBase
|
||||
bool trimmed = textSize.Y > remaining;
|
||||
while (textSize.Y > remaining && descText.Contains(' '))
|
||||
{
|
||||
descText = descText.Substring(0, descText.LastIndexOf(' ')).TrimEnd();
|
||||
descText = descText[..descText.LastIndexOf(' ')].TrimEnd();
|
||||
textSize = ImGui.CalcTextSize(descText + $"...{Environment.NewLine}[Open Full Profile for complete description]", 256f * ImGuiHelpers.GlobalScale);
|
||||
}
|
||||
UiSharedService.TextWrapped(trimmed ? descText + $"...{Environment.NewLine}[Open Full Profile for complete description]" : mareProfile.Description);
|
||||
|
||||
@@ -1,36 +1,37 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.WebAPI;
|
||||
using System.Numerics;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Data;
|
||||
using MareSynchronos.API.Data.Comparer;
|
||||
using MareSynchronos.FileCache;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.MareConfiguration.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MareSynchronos.WebAPI.SignalR.Utils;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using System.Text.Json;
|
||||
using MareSynchronos.PlayerData.Export;
|
||||
using MareSynchronos.PlayerData.Handlers;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using MareSynchronos.Services.ServerConfiguration;
|
||||
using MareSynchronos.Services;
|
||||
using MareSynchronos.WebAPI;
|
||||
using MareSynchronos.WebAPI.Files;
|
||||
using MareSynchronos.WebAPI.Files.Models;
|
||||
using MareSynchronos.PlayerData.Handlers;
|
||||
using MareSynchronos.WebAPI.SignalR.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Concurrent;
|
||||
using MareSynchronos.FileCache;
|
||||
using System.Numerics;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace MareSynchronos.UI;
|
||||
|
||||
public class SettingsUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private readonly MareConfigService _configService;
|
||||
private readonly ConcurrentDictionary<GameObjectHandler, Dictionary<string, FileDownloadStatus>> _currentDownloads = new();
|
||||
private readonly FileCompactor _fileCompactor;
|
||||
private readonly FileUploadManager _fileTransferManager;
|
||||
private readonly FileTransferOrchestrator _fileTransferOrchestrator;
|
||||
private readonly FileCompactor _fileCompactor;
|
||||
private readonly MareCharaFileManager _mareCharaFileManager;
|
||||
private readonly PairManager _pairManager;
|
||||
private readonly PerformanceCollectorService _performanceCollector;
|
||||
@@ -53,7 +54,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
MareMediator mediator, PerformanceCollectorService performanceCollector,
|
||||
FileUploadManager fileTransferManager,
|
||||
FileTransferOrchestrator fileTransferOrchestrator,
|
||||
FileCompactor fileCompactor) : base(logger, mediator, "Mare Synchronos Settings")
|
||||
FileCompactor fileCompactor, ApiController apiController) : base(logger, mediator, "Mare Synchronos Settings")
|
||||
{
|
||||
_configService = configService;
|
||||
_mareCharaFileManager = mareCharaFileManager;
|
||||
@@ -62,6 +63,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
_performanceCollector = performanceCollector;
|
||||
_fileTransferManager = fileTransferManager;
|
||||
_fileTransferOrchestrator = fileTransferOrchestrator;
|
||||
_apiController = apiController;
|
||||
_fileCompactor = fileCompactor;
|
||||
_uiShared = uiShared;
|
||||
|
||||
@@ -117,14 +119,14 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
ImGui.TableNextColumn();
|
||||
if (item is UploadFileTransfer transfer)
|
||||
{
|
||||
ImGui.Text(transfer.LocalFile);
|
||||
ImGui.TextUnformatted(transfer.LocalFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text(item.Hash);
|
||||
ImGui.TextUnformatted(item.Hash);
|
||||
}
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(item.ForbiddenBy);
|
||||
ImGui.TextUnformatted(item.ForbiddenBy);
|
||||
}
|
||||
ImGui.EndTable();
|
||||
}
|
||||
@@ -248,11 +250,11 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
var color = UiSharedService.UploadColor((transfer.Transferred, transfer.Total));
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, color);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(transfer.Hash);
|
||||
ImGui.TextUnformatted(transfer.Hash);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(UiSharedService.ByteToString(transfer.Transferred));
|
||||
ImGui.TextUnformatted(UiSharedService.ByteToString(transfer.Transferred));
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(UiSharedService.ByteToString(transfer.Total));
|
||||
ImGui.TextUnformatted(UiSharedService.ByteToString(transfer.Total));
|
||||
ImGui.PopStyleColor();
|
||||
ImGui.TableNextRow();
|
||||
}
|
||||
@@ -276,14 +278,14 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
var color = UiSharedService.UploadColor((entry.Value.TransferredBytes, entry.Value.TotalBytes));
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(userName);
|
||||
ImGui.TextUnformatted(userName);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(entry.Key);
|
||||
ImGui.TextUnformatted(entry.Key);
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, color);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(entry.Value.TransferredFiles + "/" + entry.Value.TotalFiles);
|
||||
ImGui.TextUnformatted(entry.Value.TransferredFiles + "/" + entry.Value.TotalFiles);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(UiSharedService.ByteToString(entry.Value.TransferredBytes) + "/" + UiSharedService.ByteToString(entry.Value.TotalBytes));
|
||||
ImGui.TextUnformatted(UiSharedService.ByteToString(entry.Value.TransferredBytes) + "/" + UiSharedService.ByteToString(entry.Value.TotalBytes));
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.PopStyleColor();
|
||||
ImGui.TableNextRow();
|
||||
@@ -316,7 +318,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
foreach (var l in JsonSerializer.Serialize(LastCreatedCharacterData, new JsonSerializerOptions() { WriteIndented = true }).Split('\n'))
|
||||
{
|
||||
ImGui.Text($"{l}");
|
||||
ImGui.TextUnformatted($"{l}");
|
||||
}
|
||||
|
||||
ImGui.TreePop();
|
||||
@@ -436,7 +438,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
_uiShared.DrawFileScanState();
|
||||
_uiShared.DrawTimeSpanBetweenScansSetting();
|
||||
_uiShared.DrawCacheDirectorySetting();
|
||||
ImGui.Text($"Currently utilized local storage: {UiSharedService.ByteToString(_uiShared.FileCacheSize)}");
|
||||
ImGui.TextUnformatted($"Currently utilized local storage: {UiSharedService.ByteToString(_uiShared.FileCacheSize)}");
|
||||
bool isLinux = Util.IsWine();
|
||||
if (isLinux) ImGui.BeginDisabled();
|
||||
bool useFileCompactor = _configService.Current.UseCompactor;
|
||||
@@ -452,14 +454,14 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.FileArchive, "Compact all files in storage"))
|
||||
{
|
||||
_ = Task.Run(() => _fileCompactor.CompactStorage(true));
|
||||
_ = Task.Run(() => _fileCompactor.CompactStorage(compress: true));
|
||||
}
|
||||
UiSharedService.AttachToolTip("This will run compression on all files in your current Mare Storage." + Environment.NewLine
|
||||
+ "You do not need to run this manually if you keep the file compactor enabled.");
|
||||
ImGui.SameLine();
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.File, "Decompact all files in storage"))
|
||||
{
|
||||
_ = Task.Run(() => _fileCompactor.CompactStorage(false));
|
||||
_ = Task.Run(() => _fileCompactor.CompactStorage(compress: false));
|
||||
}
|
||||
UiSharedService.AttachToolTip("This will run decompression on all files in your current Mare Storage.");
|
||||
}
|
||||
@@ -470,11 +472,11 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
if (isLinux)
|
||||
{
|
||||
ImGui.EndDisabled();
|
||||
ImGui.Text("The file compactor is only available on Windows.");
|
||||
ImGui.TextUnformatted("The file compactor is only available on Windows.");
|
||||
}
|
||||
|
||||
ImGui.Dummy(new Vector2(10, 10));
|
||||
ImGui.Text("To clear the local storage accept the following disclaimer");
|
||||
ImGui.TextUnformatted("To clear the local storage accept the following disclaimer");
|
||||
ImGui.Indent();
|
||||
ImGui.Checkbox("##readClearCache", ref _readClearCache);
|
||||
ImGui.SameLine();
|
||||
@@ -557,6 +559,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
var enableRightClickMenu = _configService.Current.EnableRightClickMenus;
|
||||
var enableDtrEntry = _configService.Current.EnableDtrEntry;
|
||||
var preferNotesInsteadOfName = _configService.Current.PreferNotesOverNamesForVisible;
|
||||
var groupUpSyncshells = _configService.Current.GroupUpSyncshells;
|
||||
|
||||
if (ImGui.Checkbox("Enable Game Right Click Menu Entries", ref enableRightClickMenu))
|
||||
{
|
||||
@@ -576,6 +579,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
_configService.Current.ShowVisibleUsersSeparately = showVisibleSeparate;
|
||||
_configService.Save();
|
||||
Mediator.Publish(new RefreshUiMessage());
|
||||
}
|
||||
UiSharedService.DrawHelpText("This will show all currently visible users in a special 'Visible' group in the main UI.");
|
||||
|
||||
@@ -583,13 +587,23 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
_configService.Current.ShowOfflineUsersSeparately = showOfflineSeparate;
|
||||
_configService.Save();
|
||||
Mediator.Publish(new RefreshUiMessage());
|
||||
}
|
||||
UiSharedService.DrawHelpText("This will show all currently offline users in a special 'Offline' group in the main UI.");
|
||||
|
||||
if (ImGui.Checkbox("Group up all syncshells in one folder", ref groupUpSyncshells))
|
||||
{
|
||||
_configService.Current.GroupUpSyncshells = groupUpSyncshells;
|
||||
_configService.Save();
|
||||
Mediator.Publish(new RefreshUiMessage());
|
||||
}
|
||||
UiSharedService.DrawHelpText("This will group up all Syncshells in a special 'All Syncshells' folder in the main UI.");
|
||||
|
||||
if (ImGui.Checkbox("Show player name for visible players", ref showNameInsteadOfNotes))
|
||||
{
|
||||
_configService.Current.ShowCharacterNameInsteadOfNotesForVisible = showNameInsteadOfNotes;
|
||||
_configService.Save();
|
||||
Mediator.Publish(new RefreshUiMessage());
|
||||
}
|
||||
UiSharedService.DrawHelpText("This will show the character name instead of custom set note when a character is visible");
|
||||
|
||||
@@ -599,6 +613,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
_configService.Current.PreferNotesOverNamesForVisible = preferNotesInsteadOfName;
|
||||
_configService.Save();
|
||||
Mediator.Publish(new RefreshUiMessage());
|
||||
}
|
||||
UiSharedService.DrawHelpText("If you set a note for a player it will be shown instead of the player name");
|
||||
if (!_configService.Current.ShowCharacterNameInsteadOfNotesForVisible) ImGui.EndDisabled();
|
||||
@@ -728,7 +743,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
UiSharedService.TextWrapped(
|
||||
"All your own uploaded files on the service will be deleted.\nThis operation cannot be undone.");
|
||||
ImGui.Text("Are you sure you want to continue?");
|
||||
ImGui.TextUnformatted("Are you sure you want to continue?");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
@@ -737,7 +752,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
|
||||
if (ImGui.Button("Delete everything", new Vector2(buttonSize, 0)))
|
||||
{
|
||||
Task.Run(_fileTransferManager.DeleteAllFiles);
|
||||
_ = Task.Run(_fileTransferManager.DeleteAllFiles);
|
||||
_deleteFilesPopupModalShown = false;
|
||||
}
|
||||
|
||||
@@ -765,7 +780,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
UiSharedService.TextWrapped(
|
||||
"Your account and all associated files and data on the service will be deleted.");
|
||||
UiSharedService.TextWrapped("Your UID will be removed from all pairing lists.");
|
||||
ImGui.Text("Are you sure you want to continue?");
|
||||
ImGui.TextUnformatted("Are you sure you want to continue?");
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
@@ -774,7 +789,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
|
||||
if (ImGui.Button("Delete account", new Vector2(buttonSize, 0)))
|
||||
{
|
||||
Task.Run(ApiController.UserDelete);
|
||||
_ = Task.Run(ApiController.UserDelete);
|
||||
_deleteAccountPopupModalShown = false;
|
||||
Mediator.Publish(new SwitchToIntroUiMessage());
|
||||
}
|
||||
@@ -873,7 +888,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
if (!selectedServer.Authentications.Any(c => string.Equals(c.CharacterName, _uiShared.PlayerName, StringComparison.Ordinal)
|
||||
if (!selectedServer.Authentications.Exists(c => string.Equals(c.CharacterName, _uiShared.PlayerName, StringComparison.Ordinal)
|
||||
&& c.WorldId == _uiShared.WorldId))
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.User, "Add current character"))
|
||||
@@ -914,7 +929,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
item.Value.Key = key;
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
if (!selectedServer.Authentications.Any(p => p.SecretKeyIdx == item.Key))
|
||||
if (!selectedServer.Authentications.Exists(p => p.SecretKeyIdx == item.Key))
|
||||
{
|
||||
if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Delete Secret Key") && UiSharedService.CtrlPressed())
|
||||
{
|
||||
@@ -982,6 +997,84 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
}
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui.BeginTabItem("Permission Settings"))
|
||||
{
|
||||
UiSharedService.FontText("Default Permission Settings", _uiShared.UidFont);
|
||||
if (selectedServer == _serverConfigurationManager.CurrentServer && _apiController.IsConnected)
|
||||
{
|
||||
UiSharedService.TextWrapped("Note: The default permissions settings here are not applied retroactively to existing pairs or joined Syncshells.");
|
||||
UiSharedService.TextWrapped("Note: The default permissions settings here are sent and stored on the connected service.");
|
||||
ImGui.Dummy(new(5f));
|
||||
var perms = _apiController.DefaultPermissions!;
|
||||
bool individualIsSticky = perms.IndividualIsSticky;
|
||||
bool disableIndividualSounds = perms.DisableIndividualSounds;
|
||||
bool disableIndividualAnimations = perms.DisableIndividualAnimations;
|
||||
bool disableIndividualVFX = perms.DisableIndividualVFX;
|
||||
if (ImGui.Checkbox("Individually set permissions become preferred permissions", ref individualIsSticky))
|
||||
{
|
||||
perms.IndividualIsSticky = individualIsSticky;
|
||||
_ = _apiController.UserUpdateDefaultPermissions(perms);
|
||||
}
|
||||
UiSharedService.DrawHelpText("The preferred attribute means that the permissions to that user will never change through any of your permission changes to Syncshells " +
|
||||
"(i.e. if you have paused one specific user in a Syncshell and they become preferred permissions, then pause and unpause the same Syncshell, the user will remain paused - " +
|
||||
"if a user does not have preferred permissions, it will follow the permissions of the Syncshell and be unpaused)." + Environment.NewLine + Environment.NewLine +
|
||||
"This setting means:" + Environment.NewLine +
|
||||
" - All new individual pairs get their permissions defaulted to preferred permissions." + Environment.NewLine +
|
||||
" - All individually set permissions for any pair will also automatically become preferred permissions. This includes pairs in Syncshells." + Environment.NewLine + Environment.NewLine +
|
||||
"It is possible to remove or set the preferred permission state for any pair at any time." + Environment.NewLine + Environment.NewLine +
|
||||
"If unsure, leave this setting off.");
|
||||
ImGui.Dummy(new(3f));
|
||||
|
||||
if (ImGui.Checkbox("Disable individual pair sounds", ref disableIndividualSounds))
|
||||
{
|
||||
perms.DisableIndividualSounds = disableIndividualSounds;
|
||||
_ = _apiController.UserUpdateDefaultPermissions(perms);
|
||||
}
|
||||
UiSharedService.DrawHelpText("This setting will disable sound sync for all new individual pairs.");
|
||||
if (ImGui.Checkbox("Disable individual pair animations", ref disableIndividualAnimations))
|
||||
{
|
||||
perms.DisableIndividualAnimations = disableIndividualAnimations;
|
||||
_ = _apiController.UserUpdateDefaultPermissions(perms);
|
||||
}
|
||||
UiSharedService.DrawHelpText("This setting will disable animation sync for all new individual pairs.");
|
||||
if (ImGui.Checkbox("Disable individual pair VFX", ref disableIndividualVFX))
|
||||
{
|
||||
perms.DisableIndividualVFX = disableIndividualVFX;
|
||||
_ = _apiController.UserUpdateDefaultPermissions(perms);
|
||||
}
|
||||
UiSharedService.DrawHelpText("This setting will disable VFX sync for all new individual pairs.");
|
||||
ImGui.Dummy(new(5f));
|
||||
bool disableGroundSounds = perms.DisableGroupSounds;
|
||||
bool disableGroupAnimations = perms.DisableGroupAnimations;
|
||||
bool disableGroupVFX = perms.DisableGroupVFX;
|
||||
if (ImGui.Checkbox("Disable Syncshell pair sounds", ref disableGroundSounds))
|
||||
{
|
||||
perms.DisableGroupSounds = disableGroundSounds;
|
||||
_ = _apiController.UserUpdateDefaultPermissions(perms);
|
||||
}
|
||||
UiSharedService.DrawHelpText("This setting will disable sound sync for all non-sticky pairs in newly joined syncshells.");
|
||||
if (ImGui.Checkbox("Disable Syncshell pair animations", ref disableGroupAnimations))
|
||||
{
|
||||
perms.DisableGroupAnimations = disableGroupAnimations;
|
||||
_ = _apiController.UserUpdateDefaultPermissions(perms);
|
||||
}
|
||||
UiSharedService.DrawHelpText("This setting will disable animation sync for all non-sticky pairs in newly joined syncshells.");
|
||||
if (ImGui.Checkbox("Disable Syncshell pair VFX", ref disableGroupVFX))
|
||||
{
|
||||
perms.DisableGroupVFX = disableGroupVFX;
|
||||
_ = _apiController.UserUpdateDefaultPermissions(perms);
|
||||
}
|
||||
UiSharedService.DrawHelpText("This setting will disable VFX sync for all non-sticky pairs in newly joined syncshells.");
|
||||
}
|
||||
else
|
||||
{
|
||||
UiSharedService.ColorTextWrapped("Default Permission Settings unavailable for this service. " +
|
||||
"You need to connect to this service to change the default permissions since they are stored on the service.", ImGuiColors.DalamudYellow);
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
ImGui.EndTabBar();
|
||||
}
|
||||
}
|
||||
@@ -990,7 +1083,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
_uiShared.PrintServerState();
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.Text("Community and Support:");
|
||||
ImGui.TextUnformatted("Community and Support:");
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Mare Synchronos Discord"))
|
||||
{
|
||||
@@ -1043,4 +1136,4 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
_wasOpen = IsOpen;
|
||||
IsOpen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,39 @@
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Internal;
|
||||
|
||||
using Dalamud.Interface.Utility;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
using MareSynchronos.Services.ServerConfiguration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Numerics;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Interface.Internal;
|
||||
|
||||
namespace MareSynchronos.UI;
|
||||
|
||||
public class StandaloneProfileUi : WindowMediatorSubscriberBase
|
||||
{
|
||||
private readonly MareProfileManager _mareProfileManager;
|
||||
private readonly PairManager _pairManager;
|
||||
private readonly ServerConfigurationManager _serverManager;
|
||||
private readonly UiSharedService _uiSharedService;
|
||||
private bool _adjustedForScrollBars = false;
|
||||
private byte[] _lastProfilePicture = Array.Empty<byte>();
|
||||
private byte[] _lastSupporterPicture = Array.Empty<byte>();
|
||||
private byte[] _lastProfilePicture = [];
|
||||
private byte[] _lastSupporterPicture = [];
|
||||
private IDalamudTextureWrap? _supporterTextureWrap;
|
||||
private IDalamudTextureWrap? _textureWrap;
|
||||
|
||||
public StandaloneProfileUi(ILogger<StandaloneProfileUi> logger, MareMediator mediator, UiSharedService uiBuilder,
|
||||
ServerConfigurationManager serverManager, MareProfileManager mareProfileManager, Pair pair)
|
||||
ServerConfigurationManager serverManager, MareProfileManager mareProfileManager, PairManager pairManager, Pair pair)
|
||||
: base(logger, mediator, "Mare Profile of " + pair.UserData.AliasOrUID + "##MareSynchronosStandaloneProfileUI" + pair.UserData.AliasOrUID)
|
||||
{
|
||||
_uiSharedService = uiBuilder;
|
||||
_serverManager = serverManager;
|
||||
_mareProfileManager = mareProfileManager;
|
||||
Pair = pair;
|
||||
|
||||
_pairManager = pairManager;
|
||||
Flags = ImGuiWindowFlags.NoResize | ImGuiWindowFlags.AlwaysAutoResize;
|
||||
|
||||
var spacing = ImGui.GetStyle().ItemSpacing;
|
||||
@@ -88,12 +90,12 @@ public class StandaloneProfileUi : WindowMediatorSubscriberBase
|
||||
var descriptionChildHeight = rectMax.Y - pos.Y - rectMin.Y - spacing.Y * 2;
|
||||
if (descriptionTextSize.Y > descriptionChildHeight && !_adjustedForScrollBars)
|
||||
{
|
||||
Size = Size.Value with { X = Size.Value.X + ImGui.GetStyle().ScrollbarSize };
|
||||
Size = Size!.Value with { X = Size.Value.X + ImGui.GetStyle().ScrollbarSize };
|
||||
_adjustedForScrollBars = true;
|
||||
}
|
||||
else if (descriptionTextSize.Y < descriptionChildHeight && _adjustedForScrollBars)
|
||||
{
|
||||
Size = Size.Value with { X = Size.Value.X - ImGui.GetStyle().ScrollbarSize };
|
||||
Size = Size!.Value with { X = Size.Value.X - ImGui.GetStyle().ScrollbarSize };
|
||||
_adjustedForScrollBars = false;
|
||||
}
|
||||
var childFrame = ImGuiHelpers.ScaledVector2(256 + ImGui.GetStyle().WindowPadding.X + ImGui.GetStyle().WindowBorderSize, descriptionChildHeight);
|
||||
@@ -137,13 +139,15 @@ public class StandaloneProfileUi : WindowMediatorSubscriberBase
|
||||
UiSharedService.ColorText("They: paused", ImGuiColors.DalamudYellow);
|
||||
}
|
||||
}
|
||||
if (Pair.GroupPair.Any())
|
||||
|
||||
if (Pair.UserPair.Groups.Any())
|
||||
{
|
||||
ImGui.TextUnformatted("Paired through Syncshells:");
|
||||
foreach (var groupPair in Pair.GroupPair.Select(k => k.Key))
|
||||
foreach (var group in Pair.UserPair.Groups)
|
||||
{
|
||||
var groupNote = _serverManager.GetNoteForGid(groupPair.GID);
|
||||
var groupString = string.IsNullOrEmpty(groupNote) ? groupPair.GroupAliasOrGID : $"{groupNote} ({groupPair.GroupAliasOrGID})";
|
||||
var groupNote = _serverManager.GetNoteForGid(group);
|
||||
var groupName = _pairManager.GroupPairs.First(f => string.Equals(f.Key.GID, group, StringComparison.Ordinal)).Key.GroupAliasOrGID;
|
||||
var groupString = string.IsNullOrEmpty(groupNote) ? groupName : $"{groupNote} ({groupName})";
|
||||
ImGui.TextUnformatted("- " + groupString);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,17 +129,51 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
|
||||
public uint WorldId => _dalamudUtil.GetWorldId();
|
||||
|
||||
public const string TooltipSeparator = "--SEP--";
|
||||
|
||||
public static void AttachToolTip(string text)
|
||||
{
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip(text);
|
||||
ImGui.BeginTooltip();
|
||||
if (text.Contains(TooltipSeparator, StringComparison.Ordinal))
|
||||
{
|
||||
var splitText = text.Split(TooltipSeparator, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int i = 0; i < splitText.Length; i++)
|
||||
{
|
||||
ImGui.TextUnformatted(splitText[i]);
|
||||
if (i != splitText.Length - 1) ImGui.Separator();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextUnformatted(text);
|
||||
}
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
public static void BooleanToColoredIcon(bool value, bool inline = true)
|
||||
{
|
||||
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
||||
using var colorgreen = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.HealerGreen, value);
|
||||
using var colorred = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed, !value);
|
||||
|
||||
if (inline) ImGui.SameLine();
|
||||
|
||||
if (value)
|
||||
{
|
||||
ImGui.TextUnformatted(FontAwesomeIcon.Check.ToIconString());
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextUnformatted(FontAwesomeIcon.Times.ToIconString());
|
||||
}
|
||||
}
|
||||
|
||||
public static string ByteToString(long bytes, bool addSuffix = true)
|
||||
{
|
||||
string[] suffix = { "B", "KiB", "MiB", "GiB", "TiB" };
|
||||
string[] suffix = ["B", "KiB", "MiB", "GiB", "TiB"];
|
||||
int i;
|
||||
double dblSByte = bytes;
|
||||
for (i = 0; i < suffix.Length && bytes >= 1024; i++, bytes /= 1024)
|
||||
@@ -315,42 +349,55 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
return ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X;
|
||||
}
|
||||
|
||||
public static bool IconTextButton(FontAwesomeIcon icon, string text, float? width = null)
|
||||
public static bool IconTextButton(FontAwesomeIcon icon, string text, float? width = null, bool isInPopup = false)
|
||||
{
|
||||
var buttonClicked = false;
|
||||
var wasClicked = false;
|
||||
|
||||
var iconSize = GetIconSize(icon);
|
||||
var textSize = ImGui.CalcTextSize(text);
|
||||
var padding = ImGui.GetStyle().FramePadding;
|
||||
var spacing = ImGui.GetStyle().ItemSpacing;
|
||||
var cursor = ImGui.GetCursorPos();
|
||||
var drawList = ImGui.GetWindowDrawList();
|
||||
var pos = ImGui.GetWindowPos();
|
||||
|
||||
Vector2 buttonSize;
|
||||
var buttonSizeY = (iconSize.Y > textSize.Y ? iconSize.Y : textSize.Y) + padding.Y * 2;
|
||||
var buttonSizeY = textSize.Y + padding.Y * 2;
|
||||
var iconExtraSpacing = isInPopup ? padding.X * 2 : 0;
|
||||
|
||||
if (width == null)
|
||||
var iconXoffset = iconSize.X <= iconSize.Y ? (iconSize.Y - iconSize.X) / 2f : 0;
|
||||
var iconScaling = iconSize.X > iconSize.Y ? 1 / (iconSize.X / iconSize.Y) : 1;
|
||||
|
||||
if (width == null || width <= 0)
|
||||
{
|
||||
var buttonSizeX = iconSize.X + textSize.X + padding.X * 2 + spacing.X;
|
||||
buttonSize = new Vector2(buttonSizeX, buttonSizeY);
|
||||
var buttonSizeX = (iconScaling == 1 ? iconSize.Y : (iconSize.X * iconScaling))
|
||||
+ textSize.X + padding.X * 2 + spacing.X + (iconXoffset * 2);
|
||||
buttonSize = new Vector2(buttonSizeX + iconExtraSpacing, buttonSizeY);
|
||||
}
|
||||
else
|
||||
{
|
||||
buttonSize = new Vector2(width.Value, buttonSizeY);
|
||||
}
|
||||
|
||||
if (ImGui.Button("###" + icon.ToIconString() + text, buttonSize))
|
||||
using (ImRaii.PushColor(ImGuiCol.Button, ImGui.GetColorU32(ImGuiCol.PopupBg), isInPopup))
|
||||
{
|
||||
buttonClicked = true;
|
||||
if (ImGui.Button("###" + icon.ToIconString() + text, buttonSize))
|
||||
{
|
||||
wasClicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosX(ImGui.GetCursorPosX() - buttonSize.X - padding.X);
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
ImGui.Text(icon.ToIconString());
|
||||
ImGui.PopFont();
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(text);
|
||||
drawList.AddText(UiBuilder.IconFont, ImGui.GetFontSize() * iconScaling,
|
||||
new(pos.X + cursor.X + iconXoffset + padding.X,
|
||||
pos.Y + cursor.Y + (buttonSizeY - (iconSize.Y * iconScaling)) / 2f),
|
||||
ImGui.GetColorU32(ImGuiCol.Text), icon.ToIconString());
|
||||
|
||||
return buttonClicked;
|
||||
drawList.AddText(UiBuilder.DefaultFont, ImGui.GetFontSize(),
|
||||
new(pos.X + cursor.X + (padding.X) + spacing.X + (iconSize.X * iconScaling) + (iconXoffset * 2) + iconExtraSpacing,
|
||||
pos.Y + cursor.Y + ((buttonSizeY - textSize.Y) / 2f)),
|
||||
ImGui.GetColorU32(ImGuiCol.Text), text);
|
||||
|
||||
return wasClicked;
|
||||
}
|
||||
|
||||
public static bool IsDirectoryWritable(string dirPath, bool throwIfFails = false)
|
||||
@@ -571,14 +618,14 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
|
||||
public void DrawFileScanState()
|
||||
{
|
||||
ImGui.Text("File Scanner Status");
|
||||
ImGui.TextUnformatted("File Scanner Status");
|
||||
ImGui.SameLine();
|
||||
if (_cacheScanner.IsScanRunning)
|
||||
{
|
||||
ImGui.Text("Scan is running");
|
||||
ImGui.Text("Current Progress:");
|
||||
ImGui.TextUnformatted("Scan is running");
|
||||
ImGui.TextUnformatted("Current Progress:");
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(_cacheScanner.TotalFiles == 1
|
||||
ImGui.TextUnformatted(_cacheScanner.TotalFiles == 1
|
||||
? "Collecting files"
|
||||
: $"Processing {_cacheScanner.CurrentFileProgress}/{_cacheScanner.TotalFilesStorage} from storage ({_cacheScanner.TotalFiles} scanned in)");
|
||||
AttachToolTip("Note: it is possible to have more files in storage than scanned in, " +
|
||||
@@ -587,7 +634,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
}
|
||||
else if (_configService.Current.FileScanPaused)
|
||||
{
|
||||
ImGui.Text("File scanner is paused");
|
||||
ImGui.TextUnformatted("File scanner is paused");
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Force Rescan##forcedrescan"))
|
||||
{
|
||||
@@ -596,7 +643,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
}
|
||||
else if (_cacheScanner.HaltScanLocks.Any(f => f.Value > 0))
|
||||
{
|
||||
ImGui.Text("Halted (" + string.Join(", ", _cacheScanner.HaltScanLocks.Where(f => f.Value > 0).Select(locker => locker.Key + ": " + locker.Value + " halt requests")) + ")");
|
||||
ImGui.TextUnformatted("Halted (" + string.Join(", ", _cacheScanner.HaltScanLocks.Where(f => f.Value > 0).Select(locker => locker.Key + ": " + locker.Value + " halt requests")) + ")");
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Reset halt requests##clearlocks"))
|
||||
{
|
||||
@@ -605,7 +652,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text("Next scan in " + _cacheScanner.TimeUntilNextScan);
|
||||
ImGui.TextUnformatted("Next scan in " + _cacheScanner.TimeUntilNextScan);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,10 +666,10 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
var honorificColor = _honorificExists ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
||||
var check = FontAwesomeIcon.Check.ToIconString();
|
||||
var cross = FontAwesomeIcon.SquareXmark.ToIconString();
|
||||
ImGui.Text("Mandatory Plugins:");
|
||||
ImGui.TextUnformatted("Mandatory Plugins:");
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Text("Penumbra");
|
||||
ImGui.TextUnformatted("Penumbra");
|
||||
ImGui.SameLine();
|
||||
FontText(_penumbraExists ? check : cross, UiBuilder.IconFont, penumbraColor);
|
||||
ImGui.SameLine();
|
||||
@@ -630,16 +677,16 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Text("Glamourer");
|
||||
ImGui.TextUnformatted("Glamourer");
|
||||
ImGui.SameLine();
|
||||
FontText(_glamourerExists ? check : cross, UiBuilder.IconFont, glamourerColor);
|
||||
ImGui.SameLine();
|
||||
AttachToolTip($"Glamourer is " + (_glamourerExists ? "available and up to date." : "unavailable or not up to date."));
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGui.Text("Optional Plugins:");
|
||||
ImGui.TextUnformatted("Optional Plugins:");
|
||||
ImGui.SameLine();
|
||||
ImGui.Text("SimpleHeels");
|
||||
ImGui.TextUnformatted("SimpleHeels");
|
||||
ImGui.SameLine();
|
||||
FontText(_heelsExists ? check : cross, UiBuilder.IconFont, heelsColor);
|
||||
ImGui.SameLine();
|
||||
@@ -647,7 +694,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Text("Customize+");
|
||||
ImGui.TextUnformatted("Customize+");
|
||||
ImGui.SameLine();
|
||||
FontText(_customizePlusExists ? check : cross, UiBuilder.IconFont, customizeColor);
|
||||
ImGui.SameLine();
|
||||
@@ -655,7 +702,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Text("Palette+");
|
||||
ImGui.TextUnformatted("Palette+");
|
||||
ImGui.SameLine();
|
||||
FontText(_palettePlusExists ? check : cross, UiBuilder.IconFont, paletteColor);
|
||||
ImGui.SameLine();
|
||||
@@ -663,7 +710,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Text("Honorific");
|
||||
ImGui.TextUnformatted("Honorific");
|
||||
ImGui.SameLine();
|
||||
FontText(_honorificExists ? check : cross, UiBuilder.IconFont, honorificColor);
|
||||
ImGui.SameLine();
|
||||
@@ -792,9 +839,9 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||
ImGui.SameLine();
|
||||
ImGui.TextColored(ImGuiColors.ParsedGreen, _apiController.OnlineUsers.ToString(CultureInfo.InvariantCulture));
|
||||
ImGui.SameLine();
|
||||
ImGui.Text("Users Online");
|
||||
ImGui.TextUnformatted("Users Online");
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(")");
|
||||
ImGui.TextUnformatted(")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user