Client rework for API change and paradigm shift (#39)
* most of the groups refactoring on client * register OnMethods for group stuff * start implementing client (still pretty broken) * finish implementing new api first iteration * idk rework everything for pair shit (still WIP); goal is to remove PairedClients and GroupPairClients from ApiController * move everything to PairManager, remove dictionaries from APiController * remove admin stuff from client, cleanup * adjust reconnection handling, add new settings, todo still to remove access from old stuff that's marked obsolete from config * add back adding servers, fix intro ui * fix obsolete calls * adjust config namespace * add UI for setting animation/sound permissions to syncshells * add ConfigurationService to hot reload config on change from external * move transient data cache to configuration * add deleting service to ui * fix saving of transient resources * fix group pair user assignments * halt scanner when penumbra inactive, add visible/online/offline split to individual pairs and tags * add presence to syncshell ui * move fullpause from config to server config * fixes in code style * more codestyle * show info icon on player in shells, don't show icon when no changes from default state are made, add online notifs * fixes to intro UI --------- Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com>
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Reflection;
|
||||
using Dalamud.Interface;
|
||||
@@ -11,7 +8,12 @@ using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.API.Dto.User;
|
||||
using MareSynchronos.Delegates;
|
||||
using MareSynchronos.Managers;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.Models;
|
||||
using MareSynchronos.UI.Components;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
using MareSynchronos.Utils;
|
||||
@@ -22,7 +24,9 @@ namespace MareSynchronos.UI;
|
||||
public class CompactUi : Window, IDisposable
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private readonly Configuration _configuration;
|
||||
private readonly PairManager _pairManager;
|
||||
private readonly ServerConfigurationManager _serverManager;
|
||||
private readonly ConfigurationService _configService;
|
||||
private readonly TagHandler _tagHandler;
|
||||
public readonly Dictionary<string, bool> ShowUidForEntry = new(StringComparer.Ordinal);
|
||||
private readonly UiShared _uiShared;
|
||||
@@ -37,14 +41,14 @@ public class CompactUi : Window, IDisposable
|
||||
private readonly Stopwatch _timeout = new();
|
||||
private bool _buttonState;
|
||||
|
||||
public float TransferPartHeight = 0;
|
||||
public float _windowContentWidth = 0;
|
||||
private bool _showModalForUserAddition = false;
|
||||
private bool _wasOpen = false;
|
||||
public float TransferPartHeight;
|
||||
public float WindowContentWidth;
|
||||
private bool _showModalForUserAddition;
|
||||
private bool _wasOpen;
|
||||
|
||||
private bool showSyncShells = false;
|
||||
private GroupPanel groupPanel;
|
||||
private ClientPairDto? _lastAddedUser;
|
||||
private bool _showSyncShells;
|
||||
private readonly GroupPanel _groupPanel;
|
||||
private UserPairDto? _lastAddedUser;
|
||||
private string _lastAddedUserComment = string.Empty;
|
||||
|
||||
private readonly SelectGroupForPairUi _selectGroupForPairUi;
|
||||
@@ -52,7 +56,8 @@ public class CompactUi : Window, IDisposable
|
||||
private readonly PairGroupsUi _pairGroupsUi;
|
||||
|
||||
public CompactUi(WindowSystem windowSystem,
|
||||
UiShared uiShared, Configuration configuration, ApiController apiController) : base("###MareSynchronosMainUI")
|
||||
UiShared uiShared, ConfigurationService configService, ApiController apiController, PairManager pairManager,
|
||||
ServerConfigurationManager serverManager) : base("###MareSynchronosMainUI")
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
@@ -77,13 +82,15 @@ public class CompactUi : Window, IDisposable
|
||||
|
||||
_windowSystem = windowSystem;
|
||||
_uiShared = uiShared;
|
||||
_configuration = configuration;
|
||||
_configService = configService;
|
||||
_apiController = apiController;
|
||||
_tagHandler = new(_configuration);
|
||||
_pairManager = pairManager;
|
||||
_serverManager = serverManager;
|
||||
_tagHandler = new(_serverManager);
|
||||
|
||||
groupPanel = new(this, uiShared, configuration, apiController);
|
||||
_selectGroupForPairUi = new(_tagHandler, configuration);
|
||||
_selectPairsForGroupUi = new(_tagHandler, configuration);
|
||||
_groupPanel = new(this, uiShared, _pairManager, _serverManager);
|
||||
_selectGroupForPairUi = new(_tagHandler);
|
||||
_selectPairsForGroupUi = new(_tagHandler);
|
||||
_pairGroupsUi = new(_tagHandler, DrawPairedClient, apiController, _selectPairsForGroupUi);
|
||||
|
||||
_uiShared.GposeStart += UiShared_GposeStart;
|
||||
@@ -109,7 +116,7 @@ public class CompactUi : Window, IDisposable
|
||||
IsOpen = false;
|
||||
}
|
||||
|
||||
public event SwitchUi? OpenSettingsUi;
|
||||
public event VoidDelegate? OpenSettingsUi;
|
||||
public void Dispose()
|
||||
{
|
||||
Logger.Verbose("Disposing " + nameof(CompactUi));
|
||||
@@ -120,14 +127,14 @@ public class CompactUi : Window, IDisposable
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
_windowContentWidth = UiShared.GetWindowContentRegionWidth();
|
||||
WindowContentWidth = UiShared.GetWindowContentRegionWidth();
|
||||
UiShared.DrawWithID("header", DrawUIDHeader);
|
||||
ImGui.Separator();
|
||||
UiShared.DrawWithID("serverstatus", DrawServerStatus);
|
||||
|
||||
if (_apiController.ServerState is ServerState.Connected)
|
||||
{
|
||||
var hasShownSyncShells = showSyncShells;
|
||||
var hasShownSyncShells = _showSyncShells;
|
||||
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (!hasShownSyncShells)
|
||||
@@ -136,7 +143,7 @@ public class CompactUi : Window, IDisposable
|
||||
}
|
||||
if (ImGui.Button(FontAwesomeIcon.User.ToIconString(), new Vector2((UiShared.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X) / 2, 30 * ImGuiHelpers.GlobalScale)))
|
||||
{
|
||||
showSyncShells = false;
|
||||
_showSyncShells = false;
|
||||
}
|
||||
if (!hasShownSyncShells)
|
||||
{
|
||||
@@ -154,7 +161,7 @@ public class CompactUi : Window, IDisposable
|
||||
}
|
||||
if (ImGui.Button(FontAwesomeIcon.UserFriends.ToIconString(), new Vector2((UiShared.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X) / 2, 30 * ImGuiHelpers.GlobalScale)))
|
||||
{
|
||||
showSyncShells = true;
|
||||
_showSyncShells = true;
|
||||
}
|
||||
if (hasShownSyncShells)
|
||||
{
|
||||
@@ -171,17 +178,17 @@ public class CompactUi : Window, IDisposable
|
||||
}
|
||||
else
|
||||
{
|
||||
UiShared.DrawWithID("syncshells", groupPanel.DrawSyncshells);
|
||||
UiShared.DrawWithID("syncshells", _groupPanel.DrawSyncshells);
|
||||
|
||||
}
|
||||
ImGui.Separator();
|
||||
UiShared.DrawWithID("transfers", DrawTransfers);
|
||||
TransferPartHeight = ImGui.GetCursorPosY() - TransferPartHeight;
|
||||
UiShared.DrawWithID("group-user-popup", () => _selectPairsForGroupUi.Draw(_apiController.PairedClients, ShowUidForEntry));
|
||||
UiShared.DrawWithID("group-user-popup", () => _selectPairsForGroupUi.Draw(_pairManager.DirectPairs, ShowUidForEntry));
|
||||
UiShared.DrawWithID("grouping-popup", () => _selectGroupForPairUi.Draw(ShowUidForEntry));
|
||||
}
|
||||
|
||||
if (_configuration.OpenPopupOnAdd && _apiController.LastAddedUser != null)
|
||||
if (_configService.Current.OpenPopupOnAdd && _apiController.LastAddedUser != null)
|
||||
{
|
||||
_lastAddedUser = _apiController.LastAddedUser;
|
||||
_apiController.LastAddedUser = null;
|
||||
@@ -198,15 +205,14 @@ public class CompactUi : Window, IDisposable
|
||||
}
|
||||
else
|
||||
{
|
||||
var uid = string.IsNullOrEmpty(_lastAddedUser!.VanityUID) ? _lastAddedUser.OtherUID : _lastAddedUser.VanityUID;
|
||||
UiShared.TextWrapped($"You have successfully added {uid}. Set a local note for the user in the field below:");
|
||||
ImGui.InputTextWithHint("##noteforuser", $"Note for {uid}", ref _lastAddedUserComment, 100);
|
||||
UiShared.TextWrapped($"You have successfully added {_lastAddedUser.User.AliasOrUID}. Set a local note for the user in the field below:");
|
||||
ImGui.InputTextWithHint("##noteforuser", $"Note for {_lastAddedUser.User.AliasOrUID}", ref _lastAddedUserComment, 100);
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Save, "Save Note"))
|
||||
{
|
||||
_configuration.SetCurrentServerUidComment(_lastAddedUser.OtherUID, _lastAddedUserComment);
|
||||
_serverManager.CurrentServer!.UidServerComments[_lastAddedUser.User.UID] = _lastAddedUserComment;
|
||||
_serverManager.Save();
|
||||
_lastAddedUser = null;
|
||||
_lastAddedUserComment = string.Empty;
|
||||
_configuration.Save();
|
||||
_showModalForUserAddition = false;
|
||||
}
|
||||
}
|
||||
@@ -221,21 +227,27 @@ public class CompactUi : Window, IDisposable
|
||||
EditUserComment = string.Empty;
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
private void DrawAddPair()
|
||||
{
|
||||
var buttonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Plus);
|
||||
ImGui.SetNextItemWidth(UiShared.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X - buttonSize.X);
|
||||
ImGui.InputTextWithHint("##otheruid", "Other players UID/Alias", ref _pairToAdd, 20);
|
||||
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X);
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
|
||||
var canAdd = !_pairManager.DirectPairs.Any(p => string.Equals(p.UserData.UID, _pairToAdd, StringComparison.Ordinal) || string.Equals(p.UserData.Alias, _pairToAdd, StringComparison.Ordinal));
|
||||
if (!canAdd)
|
||||
{
|
||||
if (_apiController.PairedClients.All(w => !string.Equals(w.OtherUID, _pairToAdd, StringComparison.Ordinal)))
|
||||
ImGuiComponents.DisabledButton(FontAwesomeIcon.Plus);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
|
||||
{
|
||||
_ = _apiController.UserAddPair(_pairToAdd);
|
||||
_ = _apiController.UserAddPair(new(new(_pairToAdd)));
|
||||
_pairToAdd = string.Empty;
|
||||
}
|
||||
UiShared.AttachToolTip("Pair with " + (_pairToAdd.IsNullOrEmpty() ? "other user" : _pairToAdd));
|
||||
}
|
||||
UiShared.AttachToolTip("Pair with " + (_pairToAdd.IsNullOrEmpty() ? "other user" : _pairToAdd));
|
||||
|
||||
ImGuiHelpers.ScaledDummy(2);
|
||||
}
|
||||
@@ -244,12 +256,12 @@ public class CompactUi : Window, IDisposable
|
||||
{
|
||||
var buttonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.ArrowUp);
|
||||
var playButtonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Play);
|
||||
if (!_configuration.ReverseUserSort)
|
||||
if (!_configService.Current.ReverseUserSort)
|
||||
{
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.ArrowDown))
|
||||
{
|
||||
_configuration.ReverseUserSort = true;
|
||||
_configuration.Save();
|
||||
_configService.Current.ReverseUserSort = true;
|
||||
_configService.Save();
|
||||
}
|
||||
UiShared.AttachToolTip("Sort by name descending");
|
||||
}
|
||||
@@ -257,28 +269,30 @@ public class CompactUi : Window, IDisposable
|
||||
{
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.ArrowUp))
|
||||
{
|
||||
_configuration.ReverseUserSort = false;
|
||||
_configuration.Save();
|
||||
_configService.Current.ReverseUserSort = false;
|
||||
_configService.Save();
|
||||
}
|
||||
UiShared.AttachToolTip("Sort by name ascending");
|
||||
}
|
||||
ImGui.SameLine();
|
||||
|
||||
var users = GetFilteredUsers().ToList();
|
||||
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.SetNextItemWidth(WindowContentWidth - buttonSize.X - spacing);
|
||||
ImGui.InputTextWithHint("##filter", "Filter for UID/notes", ref _characterOrCommentFilter, 255);
|
||||
|
||||
if (userCount == 0) return;
|
||||
ImGui.SameLine();
|
||||
|
||||
var pausedUsers = users.Where(u => u.IsPaused).ToList();
|
||||
var resumedUsers = users.Where(u => !u.IsPaused).ToList();
|
||||
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)
|
||||
{
|
||||
@@ -306,10 +320,11 @@ public class CompactUi : Window, IDisposable
|
||||
{
|
||||
if (UiShared.CtrlPressed())
|
||||
{
|
||||
Logger.Debug(users.Count.ToString());
|
||||
foreach (var entry in users)
|
||||
{
|
||||
_ = _apiController.UserChangePairPauseStatus(entry.OtherUID, !entry.IsPaused);
|
||||
var perm = entry.UserPair!.OwnPermissions;
|
||||
perm.SetPaused(!perm.IsPaused());
|
||||
_ = _apiController.UserSetPairPermissions(new UserPermissionsDto(entry.UserData, perm));
|
||||
}
|
||||
|
||||
_timeout.Start();
|
||||
@@ -326,49 +341,72 @@ public class CompactUi : Window, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPairedClient(ClientPairDto entry)
|
||||
private void DrawPairedClient(Pair entry)
|
||||
{
|
||||
var pauseIcon = entry.IsPaused ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
|
||||
if (entry.UserPair == null) return;
|
||||
|
||||
var pauseIcon = entry.UserPair!.OwnPermissions.IsPaused() ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
|
||||
var pauseIconSize = UiShared.GetIconButtonSize(pauseIcon);
|
||||
var barButtonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Bars);
|
||||
var entryUID = string.IsNullOrEmpty(entry.VanityUID) ? entry.OtherUID : entry.VanityUID;
|
||||
var entryUID = entry.UserData.AliasOrUID;
|
||||
var textSize = ImGui.CalcTextSize(entryUID);
|
||||
var originalY = ImGui.GetCursorPosY();
|
||||
var buttonSizes = pauseIconSize.Y + barButtonSize.Y;
|
||||
var spacingX = ImGui.GetStyle().ItemSpacing.X;
|
||||
var windowEndX = ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth();
|
||||
|
||||
|
||||
var textPos = originalY + pauseIconSize.Y / 2 - textSize.Y / 2;
|
||||
ImGui.SetCursorPosY(textPos);
|
||||
if (!entry.IsSynced)
|
||||
FontAwesomeIcon presenceIcon;
|
||||
FontAwesomeIcon connectionIcon;
|
||||
string connectionText = string.Empty;
|
||||
string presenceText = string.Empty;
|
||||
Vector4 presenceColor;
|
||||
Vector4 connectionColor;
|
||||
if (!(entry.UserPair!.OwnPermissions.IsPaired() && entry.UserPair!.OtherPermissions.IsPaired()))
|
||||
{
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
UiShared.ColorText(FontAwesomeIcon.ArrowUp.ToIconString(), ImGuiColors.DalamudRed);
|
||||
ImGui.PopFont();
|
||||
|
||||
UiShared.AttachToolTip(entryUID + " has not added you back");
|
||||
connectionIcon = FontAwesomeIcon.ArrowUp;
|
||||
connectionText = entryUID + " has not added you back";
|
||||
connectionColor = ImGuiColors.DalamudRed;
|
||||
presenceIcon = FontAwesomeIcon.Question;
|
||||
presenceColor = ImGuiColors.DalamudGrey;
|
||||
presenceText = entryUID + " online status is unknown (not paired)";
|
||||
}
|
||||
else if (entry.IsPaused || entry.IsPausedFromOthers)
|
||||
else if (entry.UserPair!.OwnPermissions.IsPaused() || entry.UserPair!.OtherPermissions.IsPaused())
|
||||
{
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
UiShared.ColorText(FontAwesomeIcon.PauseCircle.ToIconString(), ImGuiColors.DalamudYellow);
|
||||
ImGui.PopFont();
|
||||
|
||||
UiShared.AttachToolTip("Pairing status with " + entryUID + " is paused");
|
||||
connectionIcon = FontAwesomeIcon.PauseCircle;
|
||||
connectionText = "Pairing status with " + entryUID + " is paused";
|
||||
connectionColor = ImGuiColors.DalamudYellow;
|
||||
presenceIcon = FontAwesomeIcon.Question;
|
||||
presenceColor = ImGuiColors.DalamudGrey;
|
||||
presenceText = entryUID + " online status is unknown (paused)";
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
UiShared.ColorText(FontAwesomeIcon.Check.ToIconString(), ImGuiColors.ParsedGreen);
|
||||
ImGui.PopFont();
|
||||
|
||||
UiShared.AttachToolTip("You are paired with " + entryUID);
|
||||
connectionIcon = FontAwesomeIcon.Check;
|
||||
connectionText = "You are paired with " + entryUID;
|
||||
connectionColor = ImGuiColors.ParsedGreen;
|
||||
presenceIcon = entry.IsVisible ? FontAwesomeIcon.Eye : (entry.IsOnline ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink);
|
||||
presenceColor = (entry.IsOnline || entry.IsVisible) ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
||||
presenceText = entryUID + " is offline";
|
||||
if (entry.IsOnline && !entry.IsVisible) presenceText = entryUID + " is online";
|
||||
else if (entry.IsOnline && entry.IsVisible) presenceText = entryUID + " is visible: " + entry.PlayerName;
|
||||
}
|
||||
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
UiShared.ColorText(connectionIcon.ToIconString(), connectionColor);
|
||||
ImGui.PopFont();
|
||||
UiShared.AttachToolTip(connectionText);
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosY(textPos);
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
UiShared.ColorText(presenceIcon.ToIconString(), presenceColor);
|
||||
ImGui.PopFont();
|
||||
UiShared.AttachToolTip(presenceText);
|
||||
|
||||
var textIsUid = true;
|
||||
ShowUidForEntry.TryGetValue(entry.OtherUID, out var showUidInsteadOfName);
|
||||
if (!showUidInsteadOfName && _configuration.GetCurrentServerUidComments().TryGetValue(entry.OtherUID, out var playerText))
|
||||
ShowUidForEntry.TryGetValue(entry.UserPair!.User.UID, out var showUidInsteadOfName);
|
||||
if (!showUidInsteadOfName && _serverManager.CurrentServer!.UidServerComments.TryGetValue(entry.UserPair!.User.UID, out var playerText))
|
||||
{
|
||||
if (string.IsNullOrEmpty(playerText))
|
||||
{
|
||||
@@ -385,7 +423,7 @@ public class CompactUi : Window, IDisposable
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (!string.Equals(EditNickEntry, entry.OtherUID, StringComparison.Ordinal))
|
||||
if (!string.Equals(EditNickEntry, entry.UserData.UID, StringComparison.Ordinal))
|
||||
{
|
||||
ImGui.SetCursorPosY(textPos);
|
||||
if (textIsUid) ImGui.PushFont(UiBuilder.MonoFont);
|
||||
@@ -396,22 +434,20 @@ public class CompactUi : Window, IDisposable
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||
{
|
||||
var prevState = textIsUid;
|
||||
if (ShowUidForEntry.ContainsKey(entry.OtherUID))
|
||||
if (ShowUidForEntry.ContainsKey(entry.UserPair!.User.UID))
|
||||
{
|
||||
prevState = ShowUidForEntry[entry.OtherUID];
|
||||
prevState = ShowUidForEntry[entry.UserPair!.User.UID];
|
||||
}
|
||||
|
||||
ShowUidForEntry[entry.OtherUID] = !prevState;
|
||||
ShowUidForEntry[entry.UserPair!.User.UID] = !prevState;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
_configuration.SetCurrentServerUidComment(EditNickEntry, EditUserComment);
|
||||
_configuration.Save();
|
||||
EditUserComment = _configuration.GetCurrentServerUidComments().ContainsKey(entry.OtherUID)
|
||||
? _configuration.GetCurrentServerUidComments()[entry.OtherUID]
|
||||
: string.Empty;
|
||||
EditNickEntry = entry.OtherUID;
|
||||
entry.SetNote(EditUserComment);
|
||||
_configService.Save();
|
||||
EditUserComment = entry.GetNote() ?? string.Empty;
|
||||
EditNickEntry = entry.UserPair!.User.UID;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -421,8 +457,8 @@ public class CompactUi : Window, IDisposable
|
||||
ImGui.SetNextItemWidth(UiShared.GetWindowContentRegionWidth() - ImGui.GetCursorPosX() - buttonSizes - ImGui.GetStyle().ItemSpacing.X * 2);
|
||||
if (ImGui.InputTextWithHint("", "Nick/Notes", ref EditUserComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
|
||||
{
|
||||
_configuration.SetCurrentServerUidComment(entry.OtherUID, EditUserComment);
|
||||
_configuration.Save();
|
||||
_serverManager.CurrentServer!.UidServerComments[entry.UserPair!.User.UID] = EditUserComment;
|
||||
_serverManager.Save();
|
||||
EditNickEntry = string.Empty;
|
||||
}
|
||||
|
||||
@@ -434,15 +470,17 @@ public class CompactUi : Window, IDisposable
|
||||
}
|
||||
|
||||
// Pause Button
|
||||
if (entry.IsSynced)
|
||||
if (entry.UserPair!.OwnPermissions.IsPaired() && entry.UserPair!.OtherPermissions.IsPaired())
|
||||
{
|
||||
ImGui.SameLine(windowEndX - barButtonSize.X - spacingX - pauseIconSize.X);
|
||||
ImGui.SetCursorPosY(originalY);
|
||||
if (ImGuiComponents.IconButton(pauseIcon))
|
||||
{
|
||||
_ = _apiController.UserChangePairPauseStatus(entry.OtherUID, !entry.IsPaused);
|
||||
var perm = entry.UserPair!.OwnPermissions;
|
||||
perm.SetPaused(!perm.IsPaused());
|
||||
_ = _apiController.UserSetPairPermissions(new(entry.UserData, perm));
|
||||
}
|
||||
UiShared.AttachToolTip(!entry.IsPaused
|
||||
UiShared.AttachToolTip(!entry.UserPair!.OwnPermissions.IsPaused()
|
||||
? "Pause pairing with " + entryUID
|
||||
: "Resume pairing with " + entryUID);
|
||||
}
|
||||
@@ -457,14 +495,14 @@ public class CompactUi : Window, IDisposable
|
||||
}
|
||||
if (ImGui.BeginPopup("User Flyout Menu"))
|
||||
{
|
||||
UiShared.DrawWithID($"buttons-{entry.OtherUID}", () => DrawPairedClientMenu(entry));
|
||||
UiShared.DrawWithID($"buttons-{entry.UserPair!.User.UID}", () => DrawPairedClientMenu(entry));
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPairedClientMenu(ClientPairDto entry)
|
||||
private void DrawPairedClientMenu(Pair entry)
|
||||
{
|
||||
var entryUID = string.IsNullOrEmpty(entry.VanityUID) ? entry.OtherUID : entry.VanityUID;
|
||||
var entryUID = entry.UserData.AliasOrUID;
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Folder, "Pair Groups"))
|
||||
{
|
||||
_selectGroupForPairUi.Open(entry);
|
||||
@@ -475,7 +513,7 @@ public class CompactUi : Window, IDisposable
|
||||
{
|
||||
if (UiShared.CtrlPressed())
|
||||
{
|
||||
_ = _apiController.UserRemovePair(entry.OtherUID);
|
||||
_ = _apiController.UserRemovePair(new(entry.UserData));
|
||||
}
|
||||
}
|
||||
UiShared.AttachToolTip("Hold CTRL and click to unpair permanently from " + entryUID);
|
||||
@@ -496,32 +534,65 @@ public class CompactUi : Window, IDisposable
|
||||
: (ImGui.GetWindowContentRegionMax().Y - ImGui.GetWindowContentRegionMin().Y) - TransferPartHeight - ImGui.GetCursorPosY();
|
||||
var users = GetFilteredUsers();
|
||||
|
||||
users = users.OrderBy(u => _configuration.GetCurrentServerUidComments().ContainsKey(u.OtherUID) ? _configuration.GetCurrentServerUidComments()[u.OtherUID] : !string.IsNullOrEmpty(u.VanityUID) ? u.VanityUID : u.OtherUID);
|
||||
if (_configuration.ReverseUserSort) users = users.Reverse();
|
||||
ImGui.BeginChild("list", new Vector2(WindowContentWidth, ySize), border: false);
|
||||
var visibleUsers = users.Where(u => u.IsVisible && u.UserPair!.OtherPermissions.IsPaired()).OrderBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase).ToList();
|
||||
var onlineUsers = users.Where(u => u.IsOnline && !u.IsVisible && u.UserPair!.OtherPermissions.IsPaired()).OrderBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase).ToList();
|
||||
var offlineUsers = users.Where(u => !u.IsOnline && !u.IsVisible || !u.UserPair!.OtherPermissions.IsPaired()).OrderBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase).ToList();
|
||||
|
||||
ImGui.BeginChild("list", new Vector2(_windowContentWidth, ySize), false);
|
||||
var allAvailablePairs = users.ToList();
|
||||
var pairsWithoutTags = allAvailablePairs.Where(pair => !_tagHandler.HasAnyTag(pair));
|
||||
_pairGroupsUi.Draw(allAvailablePairs);
|
||||
foreach (var entry in pairsWithoutTags)
|
||||
if (_configService.Current.ReverseUserSort)
|
||||
{
|
||||
UiShared.DrawWithID(entry.OtherUID, () => DrawPairedClient(entry));
|
||||
visibleUsers.Reverse();
|
||||
onlineUsers.Reverse();
|
||||
offlineUsers.Reverse();
|
||||
}
|
||||
|
||||
_pairGroupsUi.Draw(visibleUsers, onlineUsers, offlineUsers);
|
||||
|
||||
visibleUsers = visibleUsers.Where(pair => !_tagHandler.HasAnyTag(pair.UserPair!)).ToList();
|
||||
onlineUsers = onlineUsers.Where(pair => !_tagHandler.HasAnyTag(pair.UserPair!)).ToList();
|
||||
offlineUsers = offlineUsers.Where(pair => !_tagHandler.HasAnyTag(pair.UserPair!)).ToList();
|
||||
|
||||
if (visibleUsers.Any())
|
||||
{
|
||||
ImGui.Text("Visible");
|
||||
ImGui.Separator();
|
||||
foreach (var entry in visibleUsers)
|
||||
{
|
||||
UiShared.DrawWithID(entry.UserData.UID, () => DrawPairedClient(entry));
|
||||
}
|
||||
}
|
||||
|
||||
if (onlineUsers.Any())
|
||||
{
|
||||
ImGui.Text("Online");
|
||||
ImGui.Separator();
|
||||
foreach (var entry in onlineUsers)
|
||||
{
|
||||
UiShared.DrawWithID(entry.UserData.UID, () => DrawPairedClient(entry));
|
||||
}
|
||||
}
|
||||
|
||||
if (offlineUsers.Any())
|
||||
{
|
||||
ImGui.Text("Offline/Unknown");
|
||||
ImGui.Separator();
|
||||
foreach (var entry in offlineUsers)
|
||||
{
|
||||
UiShared.DrawWithID(entry.UserData.UID, () => DrawPairedClient(entry));
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndChild();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private IEnumerable<ClientPairDto> GetFilteredUsers()
|
||||
private List<Pair> GetFilteredUsers()
|
||||
{
|
||||
return _apiController.PairedClients.Where(p =>
|
||||
return _pairManager.DirectPairs.Where(p =>
|
||||
{
|
||||
if (_characterOrCommentFilter.IsNullOrEmpty()) return true;
|
||||
_configuration.GetCurrentServerUidComments().TryGetValue(p.OtherUID, out var comment);
|
||||
var uid = p.VanityUID.IsNullOrEmpty() ? p.OtherUID : p.VanityUID;
|
||||
return uid.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ||
|
||||
(comment?.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ?? false);
|
||||
});
|
||||
return p.UserData.AliasOrUID.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ||
|
||||
(p.GetNote()?.Contains(_characterOrCommentFilter, StringComparison.OrdinalIgnoreCase) ?? false);
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
private void DrawServerStatus()
|
||||
@@ -565,18 +636,18 @@ public class CompactUi : Window, IDisposable
|
||||
{
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((userSize.Y + textSize.Y) / 2 + shardTextSize.Y) / 2 - ImGui.GetStyle().ItemSpacing.Y + buttonSize.Y / 2);
|
||||
}
|
||||
var color = UiShared.GetBoolColor(!_configuration.FullPause);
|
||||
var connectedIcon = !_configuration.FullPause ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink;
|
||||
var color = UiShared.GetBoolColor(!_serverManager.CurrentServer!.FullPause);
|
||||
var connectedIcon = !_serverManager.CurrentServer.FullPause ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink;
|
||||
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, color);
|
||||
if (ImGuiComponents.IconButton(connectedIcon))
|
||||
{
|
||||
_configuration.FullPause = !_configuration.FullPause;
|
||||
_configuration.Save();
|
||||
_serverManager.CurrentServer.FullPause = !_serverManager.CurrentServer.FullPause;
|
||||
_serverManager.Save();
|
||||
_ = _apiController.CreateConnections();
|
||||
}
|
||||
ImGui.PopStyleColor();
|
||||
UiShared.AttachToolTip(!_configuration.FullPause ? "Disconnect from " + _apiController.ServerDictionary[_configuration.ApiUri] : "Connect to " + _apiController.ServerDictionary[_configuration.ApiUri]);
|
||||
UiShared.AttachToolTip(!_serverManager.CurrentServer.FullPause ? "Disconnect from " + _serverManager.CurrentServer.ServerName : "Connect to " + _serverManager.CurrentServer.ServerName);
|
||||
}
|
||||
|
||||
private void DrawTransfers()
|
||||
@@ -598,7 +669,7 @@ public class CompactUi : Window, IDisposable
|
||||
ImGui.Text($"{doneUploads}/{totalUploads}");
|
||||
var uploadText = $"({UiShared.ByteToString(totalUploaded)}/{UiShared.ByteToString(totalToUpload)})";
|
||||
var textSize = ImGui.CalcTextSize(uploadText);
|
||||
ImGui.SameLine(_windowContentWidth - textSize.X);
|
||||
ImGui.SameLine(WindowContentWidth - textSize.X);
|
||||
ImGui.Text(uploadText);
|
||||
}
|
||||
else
|
||||
@@ -623,7 +694,7 @@ public class CompactUi : Window, IDisposable
|
||||
var downloadText =
|
||||
$"({UiShared.ByteToString(totalDownloaded)}/{UiShared.ByteToString(totalToDownload)})";
|
||||
var textSize = ImGui.CalcTextSize(downloadText);
|
||||
ImGui.SameLine(_windowContentWidth - textSize.X);
|
||||
ImGui.SameLine(WindowContentWidth - textSize.X);
|
||||
ImGui.Text(downloadText);
|
||||
}
|
||||
else
|
||||
@@ -688,6 +759,8 @@ public class CompactUi : Window, IDisposable
|
||||
{
|
||||
return _apiController.ServerState switch
|
||||
{
|
||||
ServerState.Connecting => "Attempting to connect to the server.",
|
||||
ServerState.Reconnecting => "Connection to server interrupted, attempting to reconnect to the server.",
|
||||
ServerState.Disconnected => "You are currently disconnected from the Mare Synchronos server.",
|
||||
ServerState.Unauthorized => "Server Response: " + _apiController.AuthFailureMessage,
|
||||
ServerState.Offline => "Your selected Mare Synchronos server is currently offline.",
|
||||
@@ -695,6 +768,7 @@ public class CompactUi : Window, IDisposable
|
||||
"Your plugin or the server you are connecting to is out of date. Please update your plugin now. If you already did so, contact the server provider to update their server to the latest version.",
|
||||
ServerState.RateLimited => "You are rate limited for (re)connecting too often. Disconnect, wait 10 minutes and try again.",
|
||||
ServerState.Connected => string.Empty,
|
||||
ServerState.NoSecretKey => "You have no secret key set for this current character. Open the settings and set a secret key. You can reuse one secret key for different characters.",
|
||||
_ => string.Empty
|
||||
};
|
||||
}
|
||||
@@ -703,12 +777,15 @@ public class CompactUi : Window, IDisposable
|
||||
{
|
||||
return _apiController.ServerState switch
|
||||
{
|
||||
ServerState.Connecting => ImGuiColors.DalamudYellow,
|
||||
ServerState.Reconnecting => ImGuiColors.DalamudRed,
|
||||
ServerState.Connected => ImGuiColors.ParsedGreen,
|
||||
ServerState.Disconnected => ImGuiColors.DalamudYellow,
|
||||
ServerState.Unauthorized => ImGuiColors.DalamudRed,
|
||||
ServerState.VersionMisMatch => ImGuiColors.DalamudRed,
|
||||
ServerState.Offline => ImGuiColors.DalamudRed,
|
||||
ServerState.RateLimited => ImGuiColors.DalamudYellow,
|
||||
ServerState.NoSecretKey => ImGuiColors.DalamudYellow,
|
||||
_ => ImGuiColors.DalamudRed
|
||||
};
|
||||
}
|
||||
@@ -717,11 +794,14 @@ public class CompactUi : Window, IDisposable
|
||||
{
|
||||
return _apiController.ServerState switch
|
||||
{
|
||||
ServerState.Reconnecting => "Reconnecting",
|
||||
ServerState.Connecting => "Connecting",
|
||||
ServerState.Disconnected => "Disconnected",
|
||||
ServerState.Unauthorized => "Unauthorized",
|
||||
ServerState.VersionMisMatch => "Version mismatch",
|
||||
ServerState.Offline => "Unavailable",
|
||||
ServerState.RateLimited => "Rate Limited",
|
||||
ServerState.NoSecretKey => "No Secret Key",
|
||||
ServerState.Connected => _apiController.UID,
|
||||
_ => string.Empty
|
||||
};
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Components;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.Models;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
using MareSynchronos.WebAPI;
|
||||
|
||||
@@ -12,12 +10,12 @@ namespace MareSynchronos.UI.Components
|
||||
{
|
||||
public class PairGroupsUi
|
||||
{
|
||||
private readonly Action<ClientPairDto> _clientRenderFn;
|
||||
private readonly Action<Pair> _clientRenderFn;
|
||||
private readonly TagHandler _tagHandler;
|
||||
private readonly ApiController _apiController;
|
||||
private readonly SelectPairForGroupUi _selectGroupForPairUi;
|
||||
|
||||
public PairGroupsUi(TagHandler tagHandler, Action<ClientPairDto> clientRenderFn, ApiController apiController, SelectPairForGroupUi selectGroupForPairUi)
|
||||
public PairGroupsUi(TagHandler tagHandler, Action<Pair> clientRenderFn, ApiController apiController, SelectPairForGroupUi selectGroupForPairUi)
|
||||
{
|
||||
_clientRenderFn = clientRenderFn;
|
||||
_tagHandler = tagHandler;
|
||||
@@ -25,30 +23,57 @@ namespace MareSynchronos.UI.Components
|
||||
_selectGroupForPairUi = selectGroupForPairUi;
|
||||
}
|
||||
|
||||
public void Draw(List<ClientPairDto> availablePairs)
|
||||
public void Draw(List<Pair> visibleUsers, List<Pair> onlineUsers, List<Pair> offlineUsers)
|
||||
{
|
||||
// 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();
|
||||
foreach (var tag in tagsWithPairsInThem)
|
||||
{
|
||||
UiShared.DrawWithID($"group-{tag}", () => DrawCategory(tag, availablePairs));
|
||||
UiShared.DrawWithID($"group-{tag}", () => DrawCategory(tag, visibleUsers, onlineUsers, offlineUsers));
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawCategory(string tag, List<ClientPairDto> availablePairs)
|
||||
public void DrawCategory(string tag, List<Pair> visibleUsers, List<Pair> onlineUsers, List<Pair> offlineUsers)
|
||||
{
|
||||
var otherUidsTaggedWithTag = _tagHandler.GetOtherUidsForTag(tag);
|
||||
var availablePairsInThisTag = availablePairs
|
||||
.Where(pair => otherUidsTaggedWithTag.Contains(pair.OtherUID))
|
||||
var visiblePairsInThisTag = visibleUsers
|
||||
.Where(pair => otherUidsTaggedWithTag.Contains(pair.UserData.UID))
|
||||
.ToList();
|
||||
if (availablePairsInThisTag.Any())
|
||||
var onlinePairsInThisTag = onlineUsers
|
||||
.Where(pair => otherUidsTaggedWithTag.Contains(pair.UserData.UID))
|
||||
.ToList();
|
||||
var offlinePairsInThisTag = offlineUsers
|
||||
.Where(pair => otherUidsTaggedWithTag.Contains(pair.UserData.UID))
|
||||
.ToList();
|
||||
if (visiblePairsInThisTag.Any() || onlinePairsInThisTag.Any() || offlinePairsInThisTag.Any())
|
||||
{
|
||||
DrawName(tag);
|
||||
UiShared.DrawWithID($"group-{tag}-buttons", () => DrawButtons(tag, availablePairsInThisTag));
|
||||
UiShared.DrawWithID($"group-{tag}-buttons", () => DrawButtons(tag, visiblePairsInThisTag));
|
||||
if (_tagHandler.IsTagOpen(tag))
|
||||
{
|
||||
DrawPairs(tag, availablePairsInThisTag);
|
||||
ImGui.Indent(20);
|
||||
if (visiblePairsInThisTag.Any())
|
||||
{
|
||||
ImGui.Text("Visible");
|
||||
ImGui.Separator();
|
||||
DrawPairs(tag, visiblePairsInThisTag);
|
||||
}
|
||||
|
||||
if (onlinePairsInThisTag.Any())
|
||||
{
|
||||
ImGui.Text("Online");
|
||||
ImGui.Separator();
|
||||
DrawPairs(tag, onlinePairsInThisTag);
|
||||
}
|
||||
|
||||
if (offlinePairsInThisTag.Any())
|
||||
{
|
||||
ImGui.Text("Offline/Unknown");
|
||||
ImGui.Separator();
|
||||
DrawPairs(tag, offlinePairsInThisTag);
|
||||
}
|
||||
ImGui.Unindent(20);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,9 +97,9 @@ namespace MareSynchronos.UI.Components
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawButtons(string tag, List<ClientPairDto> availablePairsInThisTag)
|
||||
private void DrawButtons(string tag, List<Pair> availablePairsInThisTag)
|
||||
{
|
||||
var allArePaused = availablePairsInThisTag.All(pair => pair.IsPaused);
|
||||
var allArePaused = availablePairsInThisTag.All(pair => pair.UserPair!.OwnPermissions.IsPaused());
|
||||
var pauseButton = allArePaused ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
|
||||
var flyoutMenuX = UiShared.GetIconButtonSize(FontAwesomeIcon.Bars).X;
|
||||
var pauseButtonX = UiShared.GetIconButtonSize(pauseButton).X;
|
||||
@@ -142,43 +167,37 @@ namespace MareSynchronos.UI.Components
|
||||
UiShared.AttachToolTip($"Delete Group {tag} (Will not delete the pairs)" + Environment.NewLine + "Hold CTRL to delete");
|
||||
}
|
||||
|
||||
private void DrawPairs(string tag, List<ClientPairDto> availablePairsInThisCategory)
|
||||
private void DrawPairs(string tag, List<Pair> availablePairsInThisCategory)
|
||||
{
|
||||
ImGui.Separator();
|
||||
// These are all the OtherUIDs that are tagged with this tag
|
||||
availablePairsInThisCategory
|
||||
.ForEach(pair => UiShared.DrawWithID($"tag-{tag}-pair-${pair.OtherUID}", () => DrawPair(pair)));
|
||||
.ForEach(pair => UiShared.DrawWithID($"tag-{tag}-pair-${pair.UserData.UID}", () => _clientRenderFn(pair)));
|
||||
ImGui.Separator();
|
||||
}
|
||||
|
||||
private void DrawPair(ClientPairDto pair)
|
||||
{
|
||||
// This is probably just dumb. Somehow, just setting the cursor position to the icon lenght
|
||||
// does not really push the child rendering further. So we'll just add two whitespaces and call it a day?
|
||||
UiShared.FontText(" ", UiBuilder.DefaultFont);
|
||||
ImGui.SameLine();
|
||||
_clientRenderFn(pair);
|
||||
}
|
||||
|
||||
private void ToggleTagOpen(string tag)
|
||||
{
|
||||
bool open = !_tagHandler.IsTagOpen(tag);
|
||||
_tagHandler.SetTagOpen(tag, open);
|
||||
}
|
||||
|
||||
private void PauseRemainingPairs(List<ClientPairDto> availablePairs)
|
||||
private void PauseRemainingPairs(List<Pair> availablePairs)
|
||||
{
|
||||
foreach (var pairToPause in availablePairs.Where(pair => !pair.IsPaused))
|
||||
foreach (var pairToPause in availablePairs.Where(pair => !pair.UserPair!.OwnPermissions.IsPaused()))
|
||||
{
|
||||
_ = _apiController.UserChangePairPauseStatus(pairToPause.OtherUID, paused: true);
|
||||
var perm = pairToPause.UserPair!.OwnPermissions;
|
||||
perm.SetPaused(paused: true);
|
||||
_ = _apiController.UserSetPairPermissions(new(pairToPause.UserData, perm));
|
||||
}
|
||||
}
|
||||
|
||||
private void ResumeAllPairs(List<ClientPairDto> availablePairs)
|
||||
private void ResumeAllPairs(List<Pair> availablePairs)
|
||||
{
|
||||
foreach (var pairToPause in availablePairs)
|
||||
{
|
||||
_ = _apiController.UserChangePairPauseStatus(pairToPause.OtherUID, paused: false);
|
||||
var perm = pairToPause.UserPair!.OwnPermissions;
|
||||
perm.SetPaused(paused: false);
|
||||
_ = _apiController.UserSetPairPermissions(new(pairToPause.UserData, perm));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API;
|
||||
using MareSynchronos.Models;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
@@ -20,7 +19,7 @@ public class SelectGroupForPairUi
|
||||
/// The group UI is always open for a specific pair. This defines which pair the UI is open for.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private ClientPairDto? _pair;
|
||||
private Pair? _pair;
|
||||
|
||||
/// <summary>
|
||||
/// For the add category option, this stores the currently typed in tag name
|
||||
@@ -28,17 +27,15 @@ public class SelectGroupForPairUi
|
||||
private string _tagNameToAdd = "";
|
||||
|
||||
private readonly TagHandler _tagHandler;
|
||||
private readonly Configuration _configuration;
|
||||
|
||||
public SelectGroupForPairUi(TagHandler tagHandler, Configuration configuration)
|
||||
public SelectGroupForPairUi(TagHandler tagHandler)
|
||||
{
|
||||
_show = false;
|
||||
_pair = null;
|
||||
_tagHandler = tagHandler;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
public void Open(ClientPairDto pair)
|
||||
public void Open(Pair pair)
|
||||
{
|
||||
_pair = pair;
|
||||
// Using "_show" here to de-couple the opening of the popup
|
||||
@@ -56,7 +53,7 @@ public class SelectGroupForPairUi
|
||||
return;
|
||||
}
|
||||
|
||||
var name = PairName(showUidForEntry, _pair.OtherUID, _pair.VanityUID);
|
||||
var name = PairName(showUidForEntry, _pair);
|
||||
var popupName = $"Choose Groups for {name}";
|
||||
// Is the popup supposed to show but did not open yet? Open it
|
||||
if (_show)
|
||||
@@ -76,7 +73,7 @@ public class SelectGroupForPairUi
|
||||
{
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
UiShared.DrawWithID($"groups-pair-{_pair.OtherUID}-{tag}", () => DrawGroupName(_pair, tag));
|
||||
UiShared.DrawWithID($"groups-pair-{_pair.UserData.UID}-{tag}", () => DrawGroupName(_pair, tag));
|
||||
}
|
||||
ImGui.EndChild();
|
||||
}
|
||||
@@ -99,19 +96,19 @@ public class SelectGroupForPairUi
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawGroupName(ClientPairDto pair, string name)
|
||||
private void DrawGroupName(Pair pair, string name)
|
||||
{
|
||||
var hasTagBefore = _tagHandler.HasTag(pair, name);
|
||||
var hasTagBefore = _tagHandler.HasTag(pair.UserPair!, name);
|
||||
var hasTag = hasTagBefore;
|
||||
if (ImGui.Checkbox(name, ref hasTag))
|
||||
{
|
||||
if (hasTag)
|
||||
{
|
||||
_tagHandler.AddTagToPairedUid(pair, name);
|
||||
_tagHandler.AddTagToPairedUid(pair.UserPair!, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tagHandler.RemoveTagFromPairedUid(pair, name);
|
||||
_tagHandler.RemoveTagFromPairedUid(pair.UserPair!, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,19 +120,19 @@ public class SelectGroupForPairUi
|
||||
_tagHandler.AddTag(_tagNameToAdd);
|
||||
if (_pair != null)
|
||||
{
|
||||
_tagHandler.AddTagToPairedUid(_pair, _tagNameToAdd);
|
||||
_tagHandler.AddTagToPairedUid(_pair.UserPair!, _tagNameToAdd);
|
||||
}
|
||||
_tagNameToAdd = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private string PairName(Dictionary<string, bool> showUidForEntry, string otherUid, string vanityUid)
|
||||
private string PairName(Dictionary<string, bool> showUidForEntry, Pair pair)
|
||||
{
|
||||
showUidForEntry.TryGetValue(otherUid, out var showUidInsteadOfName);
|
||||
_configuration.GetCurrentServerUidComments().TryGetValue(otherUid, out var playerText);
|
||||
showUidForEntry.TryGetValue(pair.UserData.UID, out var showUidInsteadOfName);
|
||||
var playerText = pair.GetNote();
|
||||
if (showUidInsteadOfName || string.IsNullOrEmpty(playerText))
|
||||
{
|
||||
playerText = string.IsNullOrEmpty(vanityUid) ? otherUid : vanityUid;
|
||||
playerText = pair.UserData.AliasOrUID;
|
||||
}
|
||||
return playerText;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using FFXIVClientStructs.FFXIV.Common.Math;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API;
|
||||
using MareSynchronos.Models;
|
||||
using MareSynchronos.UI.Handlers;
|
||||
|
||||
namespace MareSynchronos.UI.Components;
|
||||
@@ -12,16 +10,14 @@ public class SelectPairForGroupUi
|
||||
{
|
||||
private bool _show = false;
|
||||
private bool _opened = false;
|
||||
private HashSet<string> _peopleInGroup = new(System.StringComparer.Ordinal);
|
||||
private HashSet<string> _peopleInGroup = new(StringComparer.Ordinal);
|
||||
private string _tag = string.Empty;
|
||||
private readonly TagHandler _tagHandler;
|
||||
private readonly Configuration _configuration;
|
||||
private string _filter = string.Empty;
|
||||
|
||||
public SelectPairForGroupUi(TagHandler tagHandler, Configuration configuration)
|
||||
public SelectPairForGroupUi(TagHandler tagHandler)
|
||||
{
|
||||
_tagHandler = tagHandler;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
public void Open(string tag)
|
||||
@@ -31,7 +27,7 @@ public class SelectPairForGroupUi
|
||||
_show = true;
|
||||
}
|
||||
|
||||
public void Draw(List<ClientPairDto> pairs, Dictionary<string, bool> showUidForEntry)
|
||||
public void Draw(List<Pair> pairs, Dictionary<string, bool> showUidForEntry)
|
||||
{
|
||||
var workHeight = ImGui.GetMainViewport().WorkSize.Y / ImGuiHelpers.GlobalScale;
|
||||
var minSize = new Vector2(300, workHeight < 400 ? workHeight : 400) * ImGuiHelpers.GlobalScale;
|
||||
@@ -57,21 +53,21 @@ public class SelectPairForGroupUi
|
||||
{
|
||||
UiShared.FontText($"Select users for group {_tag}", UiBuilder.DefaultFont);
|
||||
ImGui.InputTextWithHint("##filter", "Filter", ref _filter, 255, ImGuiInputTextFlags.None);
|
||||
foreach (var item in pairs.OrderBy(p => PairName(showUidForEntry, p.OtherUID, p.VanityUID), System.StringComparer.OrdinalIgnoreCase)
|
||||
.Where(p => string.IsNullOrEmpty(_filter) || PairName(showUidForEntry, p.OtherUID, p.VanityUID).Contains(_filter, System.StringComparison.OrdinalIgnoreCase)).ToList())
|
||||
foreach (var item in pairs.OrderBy(p => PairName(showUidForEntry, p), StringComparer.OrdinalIgnoreCase)
|
||||
.Where(p => string.IsNullOrEmpty(_filter) || PairName(showUidForEntry, p).Contains(_filter, StringComparison.OrdinalIgnoreCase)).ToList())
|
||||
{
|
||||
var isInGroup = _peopleInGroup.Contains(item.OtherUID);
|
||||
if (ImGui.Checkbox(PairName(showUidForEntry, item.OtherUID, item.VanityUID), ref isInGroup))
|
||||
var isInGroup = _peopleInGroup.Contains(item.UserData.UID);
|
||||
if (ImGui.Checkbox(PairName(showUidForEntry, item), ref isInGroup))
|
||||
{
|
||||
if (isInGroup)
|
||||
{
|
||||
_tagHandler.AddTagToPairedUid(item, _tag);
|
||||
_peopleInGroup.Add(item.OtherUID);
|
||||
_tagHandler.AddTagToPairedUid(item.UserPair!, _tag);
|
||||
_peopleInGroup.Add(item.UserData.UID);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tagHandler.RemoveTagFromPairedUid(item, _tag);
|
||||
_peopleInGroup.Remove(item.OtherUID);
|
||||
_tagHandler.RemoveTagFromPairedUid(item.UserPair!, _tag);
|
||||
_peopleInGroup.Remove(item.UserData.UID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,13 +80,13 @@ public class SelectPairForGroupUi
|
||||
}
|
||||
}
|
||||
|
||||
private string PairName(Dictionary<string, bool> showUidForEntry, string otherUid, string vanityUid)
|
||||
private string PairName(Dictionary<string, bool> showUidForEntry, Pair pair)
|
||||
{
|
||||
showUidForEntry.TryGetValue(otherUid, out var showUidInsteadOfName);
|
||||
_configuration.GetCurrentServerUidComments().TryGetValue(otherUid, out var playerText);
|
||||
showUidForEntry.TryGetValue(pair.UserData.UID, out var showUidInsteadOfName);
|
||||
var playerText = pair.GetNote();
|
||||
if (showUidInsteadOfName || string.IsNullOrEmpty(playerText))
|
||||
{
|
||||
playerText = string.IsNullOrEmpty(vanityUid) ? otherUid : vanityUid;
|
||||
playerText = pair.UserData.AliasOrUID;
|
||||
}
|
||||
return playerText;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.Utils;
|
||||
using MareSynchronos.WebAPI;
|
||||
|
||||
@@ -11,7 +10,7 @@ namespace MareSynchronos.UI;
|
||||
public class DownloadUi : Window, IDisposable
|
||||
{
|
||||
private readonly WindowSystem _windowSystem;
|
||||
private readonly Configuration _pluginConfiguration;
|
||||
private readonly ConfigurationService _configService;
|
||||
private readonly ApiController _apiController;
|
||||
private readonly UiShared _uiShared;
|
||||
private bool _wasOpen = false;
|
||||
@@ -22,18 +21,18 @@ public class DownloadUi : Window, IDisposable
|
||||
_windowSystem.RemoveWindow(this);
|
||||
}
|
||||
|
||||
public DownloadUi(WindowSystem windowSystem, Configuration pluginConfiguration, ApiController apiController, UiShared uiShared) : base("Mare Synchronos Downloads")
|
||||
public DownloadUi(WindowSystem windowSystem, ConfigurationService configService, ApiController apiController, UiShared uiShared) : base("Mare Synchronos Downloads")
|
||||
{
|
||||
Logger.Verbose("Creating " + nameof(DownloadUi));
|
||||
_windowSystem = windowSystem;
|
||||
_pluginConfiguration = pluginConfiguration;
|
||||
_configService = configService;
|
||||
_apiController = apiController;
|
||||
_uiShared = uiShared;
|
||||
|
||||
SizeConstraints = new WindowSizeConstraints()
|
||||
{
|
||||
MaximumSize = new Vector2(300, 90),
|
||||
MinimumSize = new Vector2(300, 90)
|
||||
MinimumSize = new Vector2(300, 90),
|
||||
};
|
||||
|
||||
Flags |= ImGuiWindowFlags.NoMove;
|
||||
@@ -79,7 +78,7 @@ public class DownloadUi : Window, IDisposable
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
if (!_pluginConfiguration.ShowTransferWindow) return;
|
||||
if (!_configService.Current.ShowTransferWindow) return;
|
||||
if (!_apiController.IsDownloading && !_apiController.IsUploading) return;
|
||||
|
||||
var drawList = ImGui.GetWindowDrawList();
|
||||
|
||||
@@ -4,9 +4,8 @@ using Dalamud.Interface.ImGuiFileDialog;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.Export;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.Utils;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MareSynchronos.UI;
|
||||
|
||||
@@ -16,15 +15,16 @@ public class GposeUi : Window, IDisposable
|
||||
private readonly MareCharaFileManager _mareCharaFileManager;
|
||||
private readonly DalamudUtil _dalamudUtil;
|
||||
private readonly FileDialogManager _fileDialogManager;
|
||||
private readonly Configuration _configuration;
|
||||
private readonly ConfigurationService _configService;
|
||||
|
||||
public GposeUi(WindowSystem windowSystem, MareCharaFileManager mareCharaFileManager, DalamudUtil dalamudUtil, FileDialogManager fileDialogManager, Configuration configuration) : base("Mare Synchronos Gpose Import UI###MareSynchronosGposeUI")
|
||||
public GposeUi(WindowSystem windowSystem, MareCharaFileManager mareCharaFileManager,
|
||||
DalamudUtil dalamudUtil, FileDialogManager fileDialogManager, ConfigurationService configService) : base("Mare Synchronos Gpose Import UI###MareSynchronosGposeUI")
|
||||
{
|
||||
_windowSystem = windowSystem;
|
||||
_mareCharaFileManager = mareCharaFileManager;
|
||||
_dalamudUtil = dalamudUtil;
|
||||
_fileDialogManager = fileDialogManager;
|
||||
_configuration = configuration;
|
||||
_configService = configService;
|
||||
_dalamudUtil.GposeStart += StartGpose;
|
||||
_dalamudUtil.GposeEnd += EndGpose;
|
||||
IsOpen = _dalamudUtil.IsInGpose;
|
||||
@@ -40,7 +40,7 @@ public class GposeUi : Window, IDisposable
|
||||
|
||||
private void StartGpose()
|
||||
{
|
||||
IsOpen = _configuration.OpenGposeImportOnGposeStart;
|
||||
IsOpen = _configService.Current.OpenGposeImportOnGposeStart;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -3,24 +3,27 @@ using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.API;
|
||||
using MareSynchronos.WebAPI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
using MareSynchronos.API.Data;
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronos.API.Dto.User;
|
||||
using MareSynchronos.API.Data.Enum;
|
||||
using MareSynchronos.API.Data.Extensions;
|
||||
using MareSynchronos.Managers;
|
||||
using MareSynchronos.Models;
|
||||
using MareSynchronos.API.Data.Comparer;
|
||||
|
||||
namespace MareSynchronos.UI
|
||||
{
|
||||
internal class GroupPanel
|
||||
{
|
||||
private readonly CompactUi _mainUi;
|
||||
private UiShared _uiShared;
|
||||
private Configuration _configuration;
|
||||
private ApiController _apiController;
|
||||
|
||||
private readonly UiShared _uiShared;
|
||||
private ApiController ApiController => _uiShared.ApiController;
|
||||
private readonly PairManager _pairManager;
|
||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||
private readonly Dictionary<string, bool> _showGidForEntry = new(StringComparer.Ordinal);
|
||||
private string _editGroupEntry = string.Empty;
|
||||
private string _editGroupComment = string.Empty;
|
||||
@@ -38,8 +41,8 @@ namespace MareSynchronos.UI
|
||||
private bool _isPasswordValid;
|
||||
private bool _errorGroupJoin;
|
||||
private bool _errorGroupCreate = false;
|
||||
private GroupCreatedDto? _lastCreatedGroup = null;
|
||||
private readonly Dictionary<string, bool> ExpandedGroupState = new(StringComparer.Ordinal);
|
||||
private GroupPasswordDto? _lastCreatedGroup = null;
|
||||
private readonly Dictionary<string, bool> _expandedGroupState = new(StringComparer.Ordinal);
|
||||
private List<BannedGroupUserDto> _bannedUsers = new();
|
||||
private List<string> _bulkOneTimeInvites = new();
|
||||
private bool _modalBanListOpened;
|
||||
@@ -48,12 +51,12 @@ namespace MareSynchronos.UI
|
||||
private bool _modalChangePwOpened;
|
||||
private int _bulkInviteCount = 10;
|
||||
|
||||
public GroupPanel(CompactUi mainUi, UiShared uiShared, Configuration configuration, ApiController apiController)
|
||||
public GroupPanel(CompactUi mainUi, UiShared uiShared, PairManager pairManager, ServerConfigurationManager serverConfigurationManager)
|
||||
{
|
||||
_mainUi = mainUi;
|
||||
_uiShared = uiShared;
|
||||
_configuration = configuration;
|
||||
_apiController = apiController;
|
||||
_pairManager = pairManager;
|
||||
_serverConfigurationManager = serverConfigurationManager;
|
||||
}
|
||||
|
||||
public void DrawSyncshells()
|
||||
@@ -70,12 +73,13 @@ namespace MareSynchronos.UI
|
||||
ImGui.InputTextWithHint("##syncshellid", "Syncshell GID/Alias (leave empty to create)", ref _syncShellToJoin, 20);
|
||||
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X);
|
||||
|
||||
bool userCanJoinMoreGroups = _apiController.Groups.Count < _apiController.ServerInfo.MaxGroupsJoinedByUser;
|
||||
bool userCanCreateMoreGroups = _apiController.Groups.Count(u => string.Equals(u.OwnedBy, _apiController.UID, StringComparison.Ordinal)) < _apiController.ServerInfo.MaxGroupsCreatedByUser;
|
||||
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;
|
||||
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
|
||||
{
|
||||
if (_apiController.Groups.All(w => !string.Equals(w.GID, _syncShellToJoin, StringComparison.Ordinal)) && !string.IsNullOrEmpty(_syncShellToJoin))
|
||||
if (_pairManager.GroupPairs.All(w => !string.Equals(w.Key.Group.GID, _syncShellToJoin, StringComparison.Ordinal) && !string.Equals(w.Key.Group.Alias, _syncShellToJoin, StringComparison.Ordinal))
|
||||
&& !string.IsNullOrEmpty(_syncShellToJoin))
|
||||
{
|
||||
if (userCanJoinMoreGroups)
|
||||
{
|
||||
@@ -96,8 +100,8 @@ namespace MareSynchronos.UI
|
||||
}
|
||||
}
|
||||
UiShared.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"));
|
||||
? (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 (ImGui.BeginPopupModal("Enter Syncshell Password", ref _showModalEnterPassword, UiShared.PopupWindowFlags))
|
||||
{
|
||||
@@ -108,15 +112,15 @@ namespace MareSynchronos.UI
|
||||
ImGui.InputTextWithHint("##password", _syncShellToJoin + " Password", ref _syncShellPassword, 255, ImGuiInputTextFlags.Password);
|
||||
if (_errorGroupJoin)
|
||||
{
|
||||
UiShared.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.",
|
||||
UiShared.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(shell, pw).Result;
|
||||
_errorGroupJoin = !ApiController.GroupJoin(new(new GroupData(shell), pw)).Result;
|
||||
if (!_errorGroupJoin)
|
||||
{
|
||||
_syncShellToJoin = string.Empty;
|
||||
@@ -136,7 +140,7 @@ namespace MareSynchronos.UI
|
||||
{
|
||||
try
|
||||
{
|
||||
_lastCreatedGroup = _apiController.GroupCreate().Result;
|
||||
_lastCreatedGroup = ApiController.GroupCreate().Result;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -149,7 +153,7 @@ namespace MareSynchronos.UI
|
||||
{
|
||||
ImGui.Separator();
|
||||
_errorGroupCreate = false;
|
||||
ImGui.TextUnformatted("Syncshell ID: " + _lastCreatedGroup.GID);
|
||||
ImGui.TextUnformatted("Syncshell ID: " + _lastCreatedGroup.Group.GID);
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Syncshell Password: " + _lastCreatedGroup.Password);
|
||||
ImGui.SameLine();
|
||||
@@ -178,22 +182,21 @@ namespace MareSynchronos.UI
|
||||
var ySize = _mainUi.TransferPartHeight == 0
|
||||
? 1
|
||||
: (ImGui.GetWindowContentRegionMax().Y - ImGui.GetWindowContentRegionMin().Y) - _mainUi.TransferPartHeight - ImGui.GetCursorPosY();
|
||||
ImGui.BeginChild("list", new Vector2(_mainUi._windowContentWidth, ySize), false);
|
||||
foreach (var entry in _apiController.Groups.OrderBy(g => string.IsNullOrEmpty(g.Alias) ? g.GID : g.Alias).ToList())
|
||||
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())
|
||||
{
|
||||
UiShared.DrawWithID(entry.GID, () => DrawSyncshell(entry));
|
||||
UiShared.DrawWithID(entry.Key.Group.GID, () => DrawSyncshell(entry.Key, entry.Value));
|
||||
}
|
||||
ImGui.EndChild();
|
||||
}
|
||||
|
||||
private void DrawSyncshell(GroupDto group)
|
||||
private void DrawSyncshell(GroupFullInfoDto groupDto, List<Pair> pairsInGroup)
|
||||
{
|
||||
var name = group.Alias ?? group.GID;
|
||||
var pairsInGroup = _apiController.GroupPairedClients.Where(p => string.Equals(p.GroupGID, group.GID, StringComparison.Ordinal)).ToList();
|
||||
if (!ExpandedGroupState.TryGetValue(group.GID, out bool isExpanded))
|
||||
var name = groupDto.Group.Alias ?? groupDto.GID;
|
||||
if (!_expandedGroupState.TryGetValue(groupDto.GID, out bool isExpanded))
|
||||
{
|
||||
isExpanded = false;
|
||||
ExpandedGroupState.Add(group.GID, isExpanded);
|
||||
_expandedGroupState.Add(groupDto.GID, isExpanded);
|
||||
}
|
||||
var icon = isExpanded ? FontAwesomeIcon.CaretSquareDown : FontAwesomeIcon.CaretSquareRight;
|
||||
var collapseButton = UiShared.GetIconButtonSize(icon);
|
||||
@@ -201,22 +204,23 @@ namespace MareSynchronos.UI
|
||||
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0, 0, 0, 0));
|
||||
if (ImGuiComponents.IconButton(icon))
|
||||
{
|
||||
ExpandedGroupState[group.GID] = !ExpandedGroupState[group.GID];
|
||||
_expandedGroupState[groupDto.GID] = !_expandedGroupState[groupDto.GID];
|
||||
}
|
||||
ImGui.PopStyleColor(2);
|
||||
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + collapseButton.X);
|
||||
var pauseIcon = (group.IsPaused ?? false) ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
|
||||
var pauseIcon = groupDto.GroupUserPermissions.IsPaused() ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
|
||||
if (ImGuiComponents.IconButton(pauseIcon))
|
||||
{
|
||||
_ = _apiController.GroupChangePauseState(group.GID, !group.IsPaused ?? false);
|
||||
var userPerm = groupDto.GroupUserPermissions ^ GroupUserPermissions.Paused;
|
||||
_ = ApiController.GroupChangeIndividualPermissionState(new GroupPairUserPermissionDto(groupDto.Group, new UserData(ApiController.UID), userPerm));
|
||||
}
|
||||
UiShared.AttachToolTip(((group.IsPaused ?? false) ? "Resume" : "Pause") + " pairing with all users in this Syncshell");
|
||||
UiShared.AttachToolTip((groupDto.GroupUserPermissions.IsPaused() ? "Resume" : "Pause") + " pairing with all users in this Syncshell");
|
||||
ImGui.SameLine();
|
||||
|
||||
var groupName = string.IsNullOrEmpty(group.Alias) ? group.GID : group.Alias;
|
||||
var textIsGid = true;
|
||||
string groupName = groupDto.GroupAliasOrGID;
|
||||
|
||||
if (string.Equals(group.OwnedBy, _apiController.UID, StringComparison.Ordinal))
|
||||
if (string.Equals(groupDto.OwnerUID, ApiController.UID, StringComparison.Ordinal))
|
||||
{
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
ImGui.Text(FontAwesomeIcon.Crown.ToIconString());
|
||||
@@ -224,7 +228,7 @@ namespace MareSynchronos.UI
|
||||
UiShared.AttachToolTip("You are the owner of Syncshell " + groupName);
|
||||
ImGui.SameLine();
|
||||
}
|
||||
else if (group.IsModerator ?? false)
|
||||
else if (groupDto.GroupUserInfo.IsModerator())
|
||||
{
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
ImGui.Text(FontAwesomeIcon.UserShield.ToIconString());
|
||||
@@ -233,8 +237,8 @@ namespace MareSynchronos.UI
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
_showGidForEntry.TryGetValue(group.GID, out var showGidInsteadOfName);
|
||||
if (!showGidInsteadOfName && _configuration.GetCurrentServerGidComments().TryGetValue(group.GID, out var groupComment))
|
||||
_showGidForEntry.TryGetValue(groupDto.GID, out var showGidInsteadOfName);
|
||||
if (!showGidInsteadOfName && _serverConfigurationManager.CurrentServer!.GidServerComments.TryGetValue(groupDto.GID, out var groupComment))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(groupComment))
|
||||
{
|
||||
@@ -243,33 +247,31 @@ namespace MareSynchronos.UI
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.Equals(_editGroupEntry, group.GID, StringComparison.Ordinal))
|
||||
if (!string.Equals(_editGroupEntry, groupDto.GID, StringComparison.Ordinal))
|
||||
{
|
||||
if (textIsGid) ImGui.PushFont(UiBuilder.MonoFont);
|
||||
ImGui.TextUnformatted(groupName);
|
||||
if (textIsGid) ImGui.PopFont();
|
||||
UiShared.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: " + group.OwnedBy);
|
||||
+ "Users: " + (pairsInGroup.Count + 1) + ", Owner: " + groupDto.OwnerAliasOrUID);
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||
{
|
||||
var prevState = textIsGid;
|
||||
if (_showGidForEntry.ContainsKey(group.GID))
|
||||
if (_showGidForEntry.ContainsKey(groupDto.GID))
|
||||
{
|
||||
prevState = _showGidForEntry[group.GID];
|
||||
prevState = _showGidForEntry[groupDto.GID];
|
||||
}
|
||||
|
||||
_showGidForEntry[group.GID] = !prevState;
|
||||
_showGidForEntry[groupDto.GID] = !prevState;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
_configuration.SetCurrentServerGidComment(_editGroupEntry, _editGroupComment);
|
||||
_configuration.Save();
|
||||
_editGroupComment = _configuration.GetCurrentServerGidComments().ContainsKey(group.GID)
|
||||
? _configuration.GetCurrentServerGidComments()[group.GID]
|
||||
: string.Empty;
|
||||
_editGroupEntry = group.GID;
|
||||
_serverConfigurationManager.CurrentServer!.GidServerComments[_editGroupEntry] = _editGroupComment;
|
||||
_serverConfigurationManager.Save();
|
||||
_editGroupComment = _serverConfigurationManager.CurrentServer!.GidServerComments.TryGetValue(groupDto.GID, out string? value) ? value : string.Empty;
|
||||
_editGroupEntry = groupDto.GID;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -278,8 +280,8 @@ namespace MareSynchronos.UI
|
||||
ImGui.SetNextItemWidth(UiShared.GetWindowContentRegionWidth() - ImGui.GetCursorPosX() - buttonSizes - ImGui.GetStyle().ItemSpacing.X * 2);
|
||||
if (ImGui.InputTextWithHint("", "Comment/Notes", ref _editGroupComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
|
||||
{
|
||||
_configuration.SetCurrentServerGidComment(group.GID, _editGroupComment);
|
||||
_configuration.Save();
|
||||
_serverConfigurationManager.CurrentServer!.GidServerComments[groupDto.GID] = _editGroupComment;
|
||||
_serverConfigurationManager.Save();
|
||||
_editGroupEntry = string.Empty;
|
||||
}
|
||||
|
||||
@@ -290,26 +292,27 @@ namespace MareSynchronos.UI
|
||||
UiShared.AttachToolTip("Hit ENTER to save\nRight click to cancel");
|
||||
}
|
||||
|
||||
UiShared.DrawWithID(group.GID + "settings", () => DrawSyncShellButtons(group, name));
|
||||
UiShared.DrawWithID(groupDto.GID + "settings", () => DrawSyncShellButtons(groupDto, pairsInGroup));
|
||||
|
||||
if (_showModalBanList && !_modalBanListOpened)
|
||||
{
|
||||
_modalBanListOpened = true;
|
||||
ImGui.OpenPopup("Manage Banlist for " + group.GID);
|
||||
ImGui.OpenPopup("Manage Banlist for " + groupDto.GID);
|
||||
}
|
||||
|
||||
if (!_showModalBanList) _modalBanListOpened = false;
|
||||
|
||||
if (ImGui.BeginPopupModal("Manage Banlist for " + group.GID, ref _showModalBanList, UiShared.PopupWindowFlags))
|
||||
if (ImGui.BeginPopupModal("Manage Banlist for " + groupDto.GID, ref _showModalBanList, UiShared.PopupWindowFlags))
|
||||
{
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Retweet, "Refresh Banlist from Server"))
|
||||
{
|
||||
_bannedUsers = _apiController.GroupGetBannedUsers(group.GID).Result;
|
||||
_bannedUsers = ApiController.GroupGetBannedUsers(groupDto).Result;
|
||||
}
|
||||
|
||||
if (ImGui.BeginTable("bannedusertable" + group.GID, 5, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingStretchProp | ImGuiTableFlags.ScrollY))
|
||||
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);
|
||||
@@ -322,6 +325,8 @@ namespace MareSynchronos.UI
|
||||
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));
|
||||
@@ -330,7 +335,7 @@ namespace MareSynchronos.UI
|
||||
ImGui.TableNextColumn();
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Check, "Unban"))
|
||||
{
|
||||
_ = _apiController.GroupUnbanUser(group.GID, bannedUser.UID);
|
||||
_ = ApiController.GroupUnbanUser(bannedUser);
|
||||
_bannedUsers.RemoveAll(b => string.Equals(b.UID, bannedUser.UID, StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
@@ -349,7 +354,6 @@ namespace MareSynchronos.UI
|
||||
|
||||
if (!_showModalChangePassword) _modalChangePwOpened = false;
|
||||
|
||||
|
||||
if (ImGui.BeginPopupModal("Change Syncshell Password", ref _showModalChangePassword, UiShared.PopupWindowFlags))
|
||||
{
|
||||
UiShared.TextWrapped("Enter the new Syncshell password for Syncshell " + name + " here.");
|
||||
@@ -359,7 +363,7 @@ namespace MareSynchronos.UI
|
||||
if (ImGui.Button("Change password"))
|
||||
{
|
||||
var pw = _newSyncShellPassword;
|
||||
_isPasswordValid = _apiController.GroupChangePassword(group.GID, pw).Result;
|
||||
_isPasswordValid = ApiController.GroupChangePassword(new(groupDto.Group, pw)).Result;
|
||||
_newSyncShellPassword = string.Empty;
|
||||
if (_isPasswordValid) _showModalChangePassword = false;
|
||||
}
|
||||
@@ -392,7 +396,7 @@ namespace MareSynchronos.UI
|
||||
ImGui.SliderInt("Amount##bulkinvites", ref _bulkInviteCount, 1, 100);
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.MailBulk, "Create invites"))
|
||||
{
|
||||
_bulkOneTimeInvites = _apiController.GroupCreateTempInvite(group.GID, _bulkInviteCount).Result;
|
||||
_bulkOneTimeInvites = ApiController.GroupCreateTempInvite(groupDto, _bulkInviteCount).Result;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -409,22 +413,55 @@ namespace MareSynchronos.UI
|
||||
}
|
||||
|
||||
ImGui.Indent(collapseButton.X);
|
||||
if (ExpandedGroupState[group.GID])
|
||||
if (_expandedGroupState[groupDto.GID])
|
||||
{
|
||||
pairsInGroup = pairsInGroup.OrderBy(p => string.Equals(p.UserUID, group.OwnedBy, StringComparison.Ordinal) ? 0 : 1)
|
||||
.ThenBy(p => p.IsModerator ?? false ? 0 : 1)
|
||||
.ThenBy(p => p.IsPinned ?? false ? 0 : 1)
|
||||
.ThenBy(p => p.UserAlias ?? p.UserUID).ToList();
|
||||
ImGui.Indent(ImGui.GetStyle().ItemSpacing.X / 2);
|
||||
ImGui.Separator();
|
||||
foreach (var pair in pairsInGroup)
|
||||
{
|
||||
UiShared.DrawWithID(group.GID + pair.UserUID, () => DrawSyncshellPairedClient(pair,
|
||||
group.OwnedBy!,
|
||||
string.Equals(group.OwnedBy, _apiController.UID, StringComparison.Ordinal),
|
||||
group.IsModerator ?? false,
|
||||
group?.IsPaused ?? false));
|
||||
var visibleUsers = pairsInGroup.Where(u => u.IsVisible).OrderBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase).ToList();
|
||||
var onlineUsers = pairsInGroup.Where(u => u.IsOnline && !u.IsVisible).OrderBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase).ToList();
|
||||
var offlineUsers = pairsInGroup.Where(u => !u.IsOnline && !u.IsVisible).OrderBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase).ToList();
|
||||
|
||||
if (visibleUsers.Any())
|
||||
{
|
||||
ImGui.Text("Visible");
|
||||
ImGui.Separator();
|
||||
foreach (var entry in visibleUsers)
|
||||
{
|
||||
UiShared.DrawWithID(groupDto.GID + entry.UserData.UID, () => DrawSyncshellPairedClient(
|
||||
entry,
|
||||
entry.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
|
||||
groupDto.OwnerUID,
|
||||
string.Equals(groupDto.OwnerUID, ApiController.UID, StringComparison.Ordinal),
|
||||
groupDto.GroupUserInfo.IsModerator()));
|
||||
}
|
||||
}
|
||||
|
||||
if (onlineUsers.Any())
|
||||
{
|
||||
ImGui.Text("Online");
|
||||
ImGui.Separator();
|
||||
foreach (var entry in onlineUsers)
|
||||
{
|
||||
UiShared.DrawWithID(groupDto.GID + entry.UserData.UID, () => DrawSyncshellPairedClient(
|
||||
entry,
|
||||
entry.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
|
||||
groupDto.OwnerUID,
|
||||
string.Equals(groupDto.OwnerUID, ApiController.UID, StringComparison.Ordinal),
|
||||
groupDto.GroupUserInfo.IsModerator()));
|
||||
}
|
||||
}
|
||||
|
||||
if (offlineUsers.Any())
|
||||
{
|
||||
ImGui.Text("Offline/Unknown");
|
||||
ImGui.Separator();
|
||||
foreach (var entry in offlineUsers)
|
||||
{
|
||||
UiShared.DrawWithID(groupDto.GID + entry.UserData.UID, () => DrawSyncshellPairedClient(
|
||||
entry,
|
||||
entry.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value,
|
||||
groupDto.OwnerUID,
|
||||
string.Equals(groupDto.OwnerUID, ApiController.UID, StringComparison.Ordinal),
|
||||
groupDto.GroupUserInfo.IsModerator()));
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
@@ -433,21 +470,97 @@ namespace MareSynchronos.UI
|
||||
ImGui.Unindent(collapseButton.X);
|
||||
}
|
||||
|
||||
private void DrawSyncShellButtons(GroupDto entry, string name)
|
||||
private void DrawSyncShellButtons(GroupFullInfoDto groupDto, List<Pair> groupPairs)
|
||||
{
|
||||
bool invitesEnabled = entry.InvitesEnabled ?? true;
|
||||
var lockedIcon = invitesEnabled ? FontAwesomeIcon.LockOpen : FontAwesomeIcon.Lock;
|
||||
var iconSize = UiShared.GetIconSize(lockedIcon);
|
||||
var diffLockUnlockIcons = invitesEnabled ? 0 : (UiShared.GetIconSize(FontAwesomeIcon.LockOpen).X - iconSize.X) / 2;
|
||||
var barbuttonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Bars);
|
||||
var isOwner = string.Equals(entry.OwnedBy, _apiController.UID, StringComparison.Ordinal);
|
||||
var infoIcon = FontAwesomeIcon.InfoCircle;
|
||||
|
||||
bool invitesEnabled = !groupDto.GroupPermissions.IsDisableInvites();
|
||||
var soundsDisabled = groupDto.GroupPermissions.IsDisableSounds();
|
||||
var animDisabled = groupDto.GroupPermissions.IsDisableAnimations();
|
||||
|
||||
var userSoundsDisabled = groupDto.GroupUserPermissions.IsDisableSounds();
|
||||
var userAnimDisabled = groupDto.GroupUserPermissions.IsDisableAnimations();
|
||||
|
||||
bool showInfoIcon = !invitesEnabled || soundsDisabled || animDisabled || userSoundsDisabled || userAnimDisabled;
|
||||
|
||||
var lockedIcon = invitesEnabled ? FontAwesomeIcon.LockOpen : FontAwesomeIcon.Lock;
|
||||
var animIcon = animDisabled ? FontAwesomeIcon.Stop : FontAwesomeIcon.Running;
|
||||
var soundsIcon = soundsDisabled ? FontAwesomeIcon.VolumeOff : FontAwesomeIcon.VolumeUp;
|
||||
var userAnimIcon = userAnimDisabled ? FontAwesomeIcon.Stop : FontAwesomeIcon.Running;
|
||||
var userSoundsIcon = userSoundsDisabled ? FontAwesomeIcon.VolumeOff : FontAwesomeIcon.VolumeUp;
|
||||
|
||||
var iconSize = UiShared.GetIconSize(infoIcon);
|
||||
var diffLockUnlockIcons = showInfoIcon ? (UiShared.GetIconSize(infoIcon).X - iconSize.X) / 2 : 0;
|
||||
var barbuttonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Bars);
|
||||
var isOwner = string.Equals(groupDto.OwnerUID, ApiController.UID, StringComparison.Ordinal);
|
||||
|
||||
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - barbuttonSize.X - (showInfoIcon ? iconSize.X : 0) - diffLockUnlockIcons - (showInfoIcon ? ImGui.GetStyle().ItemSpacing.X : 0));
|
||||
if (showInfoIcon)
|
||||
{
|
||||
UiShared.FontText(infoIcon.ToIconString(), UiBuilder.IconFont);
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
if (!invitesEnabled || soundsDisabled || animDisabled)
|
||||
{
|
||||
ImGui.Text("Syncshell permissions");
|
||||
|
||||
if (!invitesEnabled)
|
||||
{
|
||||
var lockedText = "Syncshell is closed for joining";
|
||||
UiShared.FontText(lockedIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(lockedText);
|
||||
}
|
||||
|
||||
if (soundsDisabled)
|
||||
{
|
||||
var soundsText = "Sound sync disabled through owner";
|
||||
UiShared.FontText(soundsIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(soundsText);
|
||||
}
|
||||
|
||||
if (animDisabled)
|
||||
{
|
||||
var animText = "Animation sync disabled through owner";
|
||||
UiShared.FontText(animIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(animText);
|
||||
}
|
||||
}
|
||||
|
||||
if (userSoundsDisabled || userAnimDisabled)
|
||||
{
|
||||
if (!invitesEnabled || soundsDisabled || animDisabled)
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.Text("Your permissions");
|
||||
|
||||
if (userSoundsDisabled)
|
||||
{
|
||||
var userSoundsText = "Sound sync disabled through you";
|
||||
UiShared.FontText(userSoundsIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(userSoundsText);
|
||||
}
|
||||
|
||||
if (userAnimDisabled)
|
||||
{
|
||||
var userAnimText = "Animation sync disabled through you";
|
||||
UiShared.FontText(userAnimIcon.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(userAnimText);
|
||||
}
|
||||
|
||||
if (!invitesEnabled || soundsDisabled || animDisabled)
|
||||
UiShared.TextWrapped("Note that syncshell permissions for disabling take precedence over your own set permissions");
|
||||
}
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - barbuttonSize.X - iconSize.X - diffLockUnlockIcons - ImGui.GetStyle().ItemSpacing.X);
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
ImGui.Text(lockedIcon.ToIconString());
|
||||
ImGui.PopFont();
|
||||
UiShared.AttachToolTip(invitesEnabled ? "Syncshell is open for new joiners" : "Syncshell is closed for new joiners");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + diffLockUnlockIcons);
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars))
|
||||
{
|
||||
@@ -460,35 +573,65 @@ namespace MareSynchronos.UI
|
||||
{
|
||||
if (UiShared.CtrlPressed())
|
||||
{
|
||||
_ = _apiController.GroupLeave(entry.GID);
|
||||
_ = ApiController.GroupLeave(groupDto);
|
||||
}
|
||||
}
|
||||
UiShared.AttachToolTip("Hold CTRL and click to leave this Syncshell" + (!string.Equals(entry.OwnedBy, _apiController.UID, StringComparison.Ordinal) ? string.Empty : Environment.NewLine
|
||||
+ "WARNING: This action is irreverisble" + Environment.NewLine + "Leaving an owned Syncshell will transfer the ownership to a random person in the Syncshell."));
|
||||
UiShared.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 (UiShared.IconTextButton(FontAwesomeIcon.Copy, "Copy ID"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
ImGui.SetClipboardText(string.IsNullOrEmpty(entry.Alias) ? entry.GID : entry.Alias);
|
||||
ImGui.SetClipboardText(groupDto.GroupAliasOrGID);
|
||||
}
|
||||
UiShared.AttachToolTip("Copy Syncshell ID to Clipboard");
|
||||
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.StickyNote, "Copy Notes"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
ImGui.SetClipboardText(_uiShared.GetNotes(entry.GID));
|
||||
ImGui.SetClipboardText(UiShared.GetNotes(groupPairs));
|
||||
}
|
||||
UiShared.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 (isOwner || (entry.IsModerator ?? false))
|
||||
|
||||
var soundsText = userSoundsDisabled ? "Enable sound sync" : "Disable sound sync";
|
||||
if (UiShared.IconTextButton(userSoundsIcon, soundsText))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var perm = groupDto.GroupUserPermissions;
|
||||
perm.SetDisableSounds(!perm.IsDisableSounds());
|
||||
_ = ApiController.GroupChangeIndividualPermissionState(new(groupDto.Group, new UserData(ApiController.UID), perm));
|
||||
}
|
||||
UiShared.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 (UiShared.IconTextButton(userAnimIcon, animText))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var perm = groupDto.GroupUserPermissions;
|
||||
perm.SetDisableAnimations(!perm.IsDisableAnimations());
|
||||
_ = ApiController.GroupChangeIndividualPermissionState(new(groupDto.Group, new UserData(ApiController.UID), perm));
|
||||
}
|
||||
UiShared.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.");
|
||||
|
||||
if (isOwner || groupDto.GroupUserInfo.IsModerator())
|
||||
{
|
||||
ImGui.Separator();
|
||||
|
||||
var changedToIcon = !invitesEnabled ? FontAwesomeIcon.LockOpen : FontAwesomeIcon.Lock;
|
||||
var changedToIcon = invitesEnabled ? FontAwesomeIcon.LockOpen : FontAwesomeIcon.Lock;
|
||||
if (UiShared.IconTextButton(changedToIcon, invitesEnabled ? "Lock Syncshell" : "Unlock Syncshell"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = _apiController.GroupChangeInviteState(entry.GID, !entry.InvitesEnabled ?? true);
|
||||
var groupPerm = groupDto.GroupPermissions;
|
||||
groupPerm.SetDisableInvites(invitesEnabled);
|
||||
_ = ApiController.GroupChangeGroupPermissionState(new GroupPermissionDto(groupDto.Group, groupPerm));
|
||||
}
|
||||
UiShared.AttachToolTip("Change Syncshell joining permissions" + Environment.NewLine + "Syncshell is currently " + (invitesEnabled ? "open" : "closed") + " for people to join");
|
||||
|
||||
@@ -508,16 +651,40 @@ namespace MareSynchronos.UI
|
||||
if (UiShared.CtrlPressed())
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = _apiController.GroupClear(entry.GID);
|
||||
_ = ApiController.GroupClear(groupDto);
|
||||
}
|
||||
}
|
||||
UiShared.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 (UiShared.IconTextButton(soundsIcon, groupSoundsText))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var perm = groupDto.GroupPermissions;
|
||||
perm.SetDisableSounds(!perm.IsDisableSounds());
|
||||
_ = ApiController.GroupChangeGroupPermissionState(new(groupDto.Group, perm));
|
||||
}
|
||||
UiShared.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 (UiShared.IconTextButton(animIcon, groupAnimText))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var perm = groupDto.GroupPermissions;
|
||||
perm.SetDisableAnimations(!perm.IsDisableAnimations());
|
||||
_ = ApiController.GroupChangeGroupPermissionState(new(groupDto.Group, perm));
|
||||
}
|
||||
UiShared.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.");
|
||||
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Envelope, "Single one-time invite"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
ImGui.SetClipboardText(_apiController.GroupCreateTempInvite(entry.GID, 1).Result.FirstOrDefault() ?? string.Empty);
|
||||
ImGui.SetClipboardText(ApiController.GroupCreateTempInvite(groupDto, 1).Result.FirstOrDefault() ?? string.Empty);
|
||||
}
|
||||
UiShared.AttachToolTip("Creates a single-use password for joining the syncshell which is valid for 24h and copies it to the clipboard.");
|
||||
|
||||
@@ -533,7 +700,7 @@ namespace MareSynchronos.UI
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_showModalBanList = true;
|
||||
_bannedUsers = _apiController.GroupGetBannedUsers(entry.GID).Result;
|
||||
_bannedUsers = ApiController.GroupGetBannedUsers(groupDto).Result;
|
||||
}
|
||||
|
||||
if (isOwner)
|
||||
@@ -543,7 +710,7 @@ namespace MareSynchronos.UI
|
||||
if (UiShared.CtrlPressed() && UiShared.ShiftPressed())
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = _apiController.GroupDelete(entry.GID);
|
||||
_ = ApiController.GroupDelete(groupDto);
|
||||
}
|
||||
}
|
||||
UiShared.AttachToolTip("Hold CTRL and Shift and click to delete this Syncshell." + Environment.NewLine + "WARNING: this action is irreversible.");
|
||||
@@ -554,20 +721,32 @@ namespace MareSynchronos.UI
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSyncshellPairedClient(GroupPairDto entry, string ownerUid, bool isOwner, bool isModerator, bool isPausedByYou)
|
||||
private void DrawSyncshellPairedClient(Pair pair, GroupPairFullInfoDto entry, string ownerUid, bool isOwner, bool isModerator)
|
||||
{
|
||||
var plusButtonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Plus);
|
||||
var barButtonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Bars);
|
||||
var entryUID = string.IsNullOrEmpty(entry.UserAlias) ? entry.UserUID : entry.UserAlias;
|
||||
var entryUID = entry.UserAliasOrUID;
|
||||
var textSize = ImGui.CalcTextSize(entryUID);
|
||||
var originalY = ImGui.GetCursorPosY();
|
||||
var userIsMod = entry.IsModerator ?? false;
|
||||
var userIsMod = entry.GroupPairStatusInfo.IsModerator();
|
||||
var userIsOwner = string.Equals(entryUID, ownerUid, StringComparison.Ordinal);
|
||||
var isPinned = entry.GroupPairStatusInfo.IsPinned();
|
||||
var isPaused = pair.IsPaused;
|
||||
var presenceIcon = pair.IsVisible ? FontAwesomeIcon.Eye : (pair.IsOnline ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink);
|
||||
var presenceColor = (pair.IsOnline || pair.IsVisible) ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
||||
var presenceText = entryUID + " is offline";
|
||||
|
||||
var soundsDisabled = entry.GroupUserPermissions.IsDisableSounds();
|
||||
var animDisabled = entry.GroupUserPermissions.IsDisableAnimations();
|
||||
|
||||
var textPos = originalY + barButtonSize.Y / 2 - textSize.Y / 2;
|
||||
ImGui.SetCursorPosY(textPos);
|
||||
if (isPausedByYou || (entry.IsPaused ?? false))
|
||||
if (pair.IsPaused)
|
||||
{
|
||||
presenceIcon = FontAwesomeIcon.Question;
|
||||
presenceColor = ImGuiColors.DalamudGrey;
|
||||
presenceText = entryUID + " online status is unknown (paused)";
|
||||
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
UiShared.ColorText(FontAwesomeIcon.PauseCircle.ToIconString(), ImGuiColors.DalamudYellow);
|
||||
ImGui.PopFont();
|
||||
@@ -583,6 +762,16 @@ namespace MareSynchronos.UI
|
||||
UiShared.AttachToolTip("You are paired with " + entryUID);
|
||||
}
|
||||
|
||||
if (pair.IsOnline && !pair.IsVisible) presenceText = entryUID + " is online";
|
||||
else if (pair.IsOnline && pair.IsVisible) presenceText = entryUID + " is visible: " + pair.PlayerName;
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosY(textPos);
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
UiShared.ColorText(presenceIcon.ToIconString(), presenceColor);
|
||||
ImGui.PopFont();
|
||||
UiShared.AttachToolTip(presenceText);
|
||||
|
||||
if (userIsOwner)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
@@ -601,7 +790,7 @@ namespace MareSynchronos.UI
|
||||
ImGui.PopFont();
|
||||
UiShared.AttachToolTip("User is moderator of this Syncshell");
|
||||
}
|
||||
else if (entry.IsPinned ?? false)
|
||||
else if (isPinned)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosY(textPos);
|
||||
@@ -612,8 +801,8 @@ namespace MareSynchronos.UI
|
||||
}
|
||||
|
||||
var textIsUid = true;
|
||||
_mainUi.ShowUidForEntry.TryGetValue(entry.UserUID, out var showUidInsteadOfName);
|
||||
if (!showUidInsteadOfName && _configuration.GetCurrentServerUidComments().TryGetValue(entry.UserUID, out var playerText))
|
||||
_mainUi.ShowUidForEntry.TryGetValue(entry.UID, out var showUidInsteadOfName);
|
||||
if (!showUidInsteadOfName && _serverConfigurationManager.CurrentServer!.UidServerComments.TryGetValue(entry.UID, out var playerText))
|
||||
{
|
||||
if (string.IsNullOrEmpty(playerText))
|
||||
{
|
||||
@@ -628,11 +817,11 @@ namespace MareSynchronos.UI
|
||||
{
|
||||
playerText = entryUID;
|
||||
}
|
||||
|
||||
bool plusButtonShown = !_apiController.PairedClients.Any(p => string.Equals(p.OtherUID, entry.UserUID, StringComparison.Ordinal));
|
||||
|
||||
bool plusButtonShown = !_pairManager.DirectPairs.Any(p => string.Equals(p.UserData.UID, entry.UID, StringComparison.Ordinal));
|
||||
|
||||
ImGui.SameLine();
|
||||
if (!string.Equals(_mainUi.EditNickEntry, entry.UserUID, StringComparison.Ordinal))
|
||||
if (!string.Equals(_mainUi.EditNickEntry, entry.UID, StringComparison.Ordinal))
|
||||
{
|
||||
ImGui.SetCursorPosY(textPos);
|
||||
if (textIsUid) ImGui.PushFont(UiBuilder.MonoFont);
|
||||
@@ -643,22 +832,20 @@ namespace MareSynchronos.UI
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||
{
|
||||
var prevState = textIsUid;
|
||||
if (_mainUi.ShowUidForEntry.ContainsKey(entry.UserUID))
|
||||
if (_mainUi.ShowUidForEntry.ContainsKey(entry.UID))
|
||||
{
|
||||
prevState = _mainUi.ShowUidForEntry[entry.UserUID];
|
||||
prevState = _mainUi.ShowUidForEntry[entry.UID];
|
||||
}
|
||||
|
||||
_mainUi.ShowUidForEntry[entry.UserUID] = !prevState;
|
||||
_mainUi.ShowUidForEntry[entry.UID] = !prevState;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
_configuration.SetCurrentServerUidComment(_mainUi.EditNickEntry, _mainUi.EditUserComment);
|
||||
_configuration.Save();
|
||||
_mainUi.EditUserComment = _configuration.GetCurrentServerUidComments().ContainsKey(entry.UserUID)
|
||||
? _configuration.GetCurrentServerUidComments()[entry.UserUID]
|
||||
: string.Empty;
|
||||
_mainUi.EditNickEntry = entry.UserUID;
|
||||
_serverConfigurationManager.CurrentServer!.UidServerComments[_mainUi.EditNickEntry] = _mainUi.EditUserComment;
|
||||
_serverConfigurationManager.Save();
|
||||
_mainUi.EditUserComment = _serverConfigurationManager.CurrentServer.UidServerComments.TryGetValue(entry.UID, out string? value) ? value : string.Empty;
|
||||
_mainUi.EditNickEntry = entry.UID;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -670,8 +857,8 @@ namespace MareSynchronos.UI
|
||||
ImGui.SetNextItemWidth(UiShared.GetWindowContentRegionWidth() - ImGui.GetCursorPosX() - buttonSizes - ImGui.GetStyle().ItemSpacing.X * buttons);
|
||||
if (ImGui.InputTextWithHint("", "Nick/Notes", ref _mainUi.EditUserComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
|
||||
{
|
||||
_configuration.SetCurrentServerUidComment(entry.UserUID, _mainUi.EditUserComment);
|
||||
_configuration.Save();
|
||||
_serverConfigurationManager.CurrentServer!.UidServerComments[entry.UID] = _mainUi.EditUserComment;
|
||||
_serverConfigurationManager.Save();
|
||||
_mainUi.EditNickEntry = string.Empty;
|
||||
}
|
||||
|
||||
@@ -692,7 +879,7 @@ namespace MareSynchronos.UI
|
||||
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
|
||||
{
|
||||
_ = _apiController.UserAddPair(entry.UserUID);
|
||||
_ = ApiController.UserAddPair(new UserDto(entry.User));
|
||||
}
|
||||
UiShared.AttachToolTip("Pair with " + entryUID + " individually");
|
||||
}
|
||||
@@ -705,18 +892,64 @@ namespace MareSynchronos.UI
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars))
|
||||
{
|
||||
ImGui.OpenPopup("Popup");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((animDisabled || soundsDisabled) && pair.UserPair == null)
|
||||
{
|
||||
var infoIconPosDist = (plusButtonShown ? plusButtonSize.X + ImGui.GetStyle().ItemSpacing.X : 0)
|
||||
+ ((isOwner || (isModerator && !userIsMod && !userIsOwner)) ? barButtonSize.X + ImGui.GetStyle().ItemSpacing.X : 0);
|
||||
var icon = FontAwesomeIcon.InfoCircle;
|
||||
var iconwidth = UiShared.GetIconSize(icon);
|
||||
|
||||
ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - infoIconPosDist - iconwidth.X);
|
||||
ImGui.SetCursorPosY(originalY);
|
||||
|
||||
UiShared.FontText(icon.ToIconString(), UiBuilder.IconFont);
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
|
||||
|
||||
ImGui.Text("User permissions");
|
||||
|
||||
if (soundsDisabled)
|
||||
{
|
||||
var userSoundsText = "Sound sync disabled by " + pair.UserData.AliasOrUID;
|
||||
UiShared.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;
|
||||
UiShared.FontText(FontAwesomeIcon.Stop.ToIconString(), UiBuilder.IconFont);
|
||||
ImGui.SameLine(40 * ImGuiHelpers.GlobalScale);
|
||||
ImGui.Text(userAnimText);
|
||||
}
|
||||
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
if (!plusButtonShown && !(isOwner || (isModerator && !userIsMod && !userIsOwner)))
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.Dummy(barButtonSize with { X = 0 });
|
||||
}
|
||||
|
||||
if (ImGui.BeginPopup("Popup"))
|
||||
{
|
||||
if ((!entry.IsModerator ?? false) && !(userIsMod || userIsOwner))
|
||||
if ((!isModerator) && !(userIsMod || userIsOwner))
|
||||
{
|
||||
var pinText = (entry?.IsPinned ?? false) ? "Unpin user" : "Pin user";
|
||||
var pinText = isPinned ? "Unpin user" : "Pin user";
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Thumbtack, pinText))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = _apiController.GroupChangePinned(entry.GroupGID, entry.UserUID, !entry.IsPinned ?? false);
|
||||
var userInfo = entry.GroupPairStatusInfo ^ GroupUserInfo.IsPinned;
|
||||
_ = ApiController.GroupSetUserInfo(new GroupPairUserInfoDto(entry.Group, entry.User, userInfo));
|
||||
}
|
||||
UiShared.AttachToolTip("Pin this user to the Syncshell. Pinned users will not be deleted in case of a manually initiated Syncshell clean");
|
||||
|
||||
@@ -725,11 +958,11 @@ namespace MareSynchronos.UI
|
||||
if (UiShared.CtrlPressed())
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = _apiController.GroupRemoveUser(entry.GroupGID, entry.UserUID);
|
||||
_ = ApiController.GroupRemoveUser(entry);
|
||||
}
|
||||
}
|
||||
|
||||
UiShared.AttachToolTip("Hold CTRL and click to remove user " + (entry.UserAlias ?? entry.UserUID) + " from Syncshell");
|
||||
UiShared.AttachToolTip("Hold CTRL and click to remove user " + (entry.UserAliasOrUID) + " from Syncshell");
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.UserSlash, "Ban User"))
|
||||
{
|
||||
_showModalBanUser = true;
|
||||
@@ -740,36 +973,31 @@ namespace MareSynchronos.UI
|
||||
|
||||
if (isOwner)
|
||||
{
|
||||
string modText = (entry.IsModerator ?? false) ? "Demod user" : "Mod user";
|
||||
string modText = userIsMod ? "Demod user" : "Mod user";
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.UserShield, modText))
|
||||
{
|
||||
if (UiShared.CtrlPressed())
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = _apiController.GroupSetModerator(entry.GroupGID, entry.UserUID, !entry.IsModerator ?? false);
|
||||
var userInfo = entry.GroupPairStatusInfo ^ GroupUserInfo.IsModerator;
|
||||
_ = ApiController.GroupSetUserInfo(new GroupPairUserInfoDto(entry.Group, entry.User, userInfo));
|
||||
}
|
||||
}
|
||||
UiShared.AttachToolTip("Hold CTRL to change the moderator status for " + (entry.UserAlias ?? entry.UserUID) + Environment.NewLine +
|
||||
UiShared.AttachToolTip("Hold CTRL to change the moderator status for " + (entry.UserAliasOrUID) + Environment.NewLine +
|
||||
"Moderators can kick, ban/unban, pin/unpin users and clear the Syncshell.");
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Crown, "Transfer Ownership"))
|
||||
{
|
||||
if (UiShared.CtrlPressed() && UiShared.ShiftPressed())
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_ = _apiController.GroupChangeOwnership(entry.GroupGID, entry.UserUID);
|
||||
_ = ApiController.GroupChangeOwnership(entry);
|
||||
}
|
||||
}
|
||||
UiShared.AttachToolTip("Hold CTRL and SHIFT and click to transfer ownership of this Syncshell to " + (entry.UserAlias ?? entry.UserUID) + Environment.NewLine + "WARNING: This action is irreversible.");
|
||||
UiShared.AttachToolTip("Hold CTRL and SHIFT and click to transfer ownership of this Syncshell to " + (entry.UserAliasOrUID) + Environment.NewLine + "WARNING: This action is irreversible.");
|
||||
}
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
if (!plusButtonShown && !(isOwner || (isModerator && !userIsMod && !userIsOwner)))
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.Dummy(barButtonSize with { X = 0 });
|
||||
}
|
||||
|
||||
if (_showModalBanUser && !_banUserPopupOpen)
|
||||
{
|
||||
ImGui.OpenPopup("Ban User");
|
||||
@@ -780,13 +1008,13 @@ namespace MareSynchronos.UI
|
||||
|
||||
if (ImGui.BeginPopupModal("Ban User", ref _showModalBanUser, UiShared.PopupWindowFlags))
|
||||
{
|
||||
UiShared.TextWrapped("User " + (entry.UserAlias ?? entry.UserUID) + " will be banned and removed from this Syncshell.");
|
||||
UiShared.TextWrapped("User " + (entry.UserAliasOrUID) + " will be banned and removed from this Syncshell.");
|
||||
ImGui.InputTextWithHint("##banreason", "Ban Reason", ref _banReason, 255);
|
||||
if (ImGui.Button("Ban User"))
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
var reason = _banReason;
|
||||
_ = _apiController.GroupBanUser(entry.GroupGID, entry.UserUID, reason);
|
||||
_ = ApiController.GroupBanUser(entry, reason);
|
||||
_banReason = string.Empty;
|
||||
}
|
||||
UiShared.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.");
|
||||
|
||||
@@ -1,25 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MareSynchronos.API;
|
||||
using MareSynchronos.WebAPI;
|
||||
using MareSynchronos.API.Dto.User;
|
||||
using MareSynchronos.Managers;
|
||||
|
||||
namespace MareSynchronos.UI.Handlers
|
||||
{
|
||||
public class TagHandler
|
||||
{
|
||||
private readonly Configuration _configuration;
|
||||
private readonly ApiController _apiController;
|
||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||
|
||||
public TagHandler(Configuration configuration)
|
||||
public TagHandler(ServerConfigurationManager serverConfigurationManager)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_serverConfigurationManager = serverConfigurationManager;
|
||||
}
|
||||
|
||||
public void AddTag(string tag)
|
||||
{
|
||||
GetAvailableTagsForCurrentServer().Add(tag);
|
||||
_configuration.Save();
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
|
||||
public void RemoveTag(string tag)
|
||||
@@ -30,20 +26,20 @@ namespace MareSynchronos.UI.Handlers
|
||||
GetUidTagDictionaryForCurrentServer().Keys
|
||||
.ToList()
|
||||
.ForEach(otherUid => RemoveTagFromPairedUid(otherUid, tag));
|
||||
_configuration.Save();
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
|
||||
public void SetTagOpen(string tag, bool open)
|
||||
{
|
||||
if (open)
|
||||
{
|
||||
_configuration.OpenPairTags.Add(tag);
|
||||
_serverConfigurationManager.CurrentServer!.OpenPairTags.Add(tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
_configuration.OpenPairTags.Remove(tag);
|
||||
_serverConfigurationManager.CurrentServer!.OpenPairTags.Remove(tag);
|
||||
}
|
||||
_configuration.Save();
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -53,7 +49,7 @@ namespace MareSynchronos.UI.Handlers
|
||||
/// <returns>open true/false</returns>
|
||||
public bool IsTagOpen(string tag)
|
||||
{
|
||||
return _configuration.OpenPairTags.Contains(tag);
|
||||
return _serverConfigurationManager.CurrentServer!.OpenPairTags.Contains(tag);
|
||||
}
|
||||
|
||||
public List<string> GetAllTagsSorted()
|
||||
@@ -71,30 +67,30 @@ namespace MareSynchronos.UI.Handlers
|
||||
.ToHashSet(StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
public void AddTagToPairedUid(ClientPairDto pair, string tagName)
|
||||
public void AddTagToPairedUid(UserPairDto pair, string tagName)
|
||||
{
|
||||
var tagDictionary = GetUidTagDictionaryForCurrentServer();
|
||||
var tagsForPair = tagDictionary.GetValueOrDefault(pair.OtherUID, new List<string>());
|
||||
var tagsForPair = tagDictionary.GetValueOrDefault(pair.User.UID, new List<string>());
|
||||
tagsForPair.Add(tagName);
|
||||
tagDictionary[pair.OtherUID] = tagsForPair;
|
||||
_configuration.Save();
|
||||
tagDictionary[pair.User.UID] = tagsForPair;
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
|
||||
public void RemoveTagFromPairedUid(ClientPairDto pair, string tagName)
|
||||
public void RemoveTagFromPairedUid(UserPairDto pair, string tagName)
|
||||
{
|
||||
RemoveTagFromPairedUid(pair.OtherUID, tagName);
|
||||
_configuration.Save();
|
||||
RemoveTagFromPairedUid(pair.User.UID, tagName);
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
|
||||
public bool HasTag(ClientPairDto pair, string tagName)
|
||||
public bool HasTag(UserPairDto pair, string tagName)
|
||||
{
|
||||
var tagsForPair = GetUidTagDictionaryForCurrentServer().GetValueOrDefault(pair.OtherUID, new List<string>());
|
||||
var tagsForPair = GetUidTagDictionaryForCurrentServer().GetValueOrDefault(pair.User.UID, new List<string>());
|
||||
return tagsForPair.Contains(tagName, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
public bool HasAnyTag(ClientPairDto pair)
|
||||
public bool HasAnyTag(UserPairDto pair)
|
||||
{
|
||||
return GetUidTagDictionaryForCurrentServer().ContainsKey(pair.OtherUID);
|
||||
return GetUidTagDictionaryForCurrentServer().ContainsKey(pair.User.UID);
|
||||
}
|
||||
|
||||
private void RemoveTagFromPairedUid(string otherUid, string tagName)
|
||||
@@ -114,22 +110,12 @@ namespace MareSynchronos.UI.Handlers
|
||||
|
||||
private Dictionary<string, List<string>> GetUidTagDictionaryForCurrentServer()
|
||||
{
|
||||
if (!_configuration.UidServerPairedUserTags.ContainsKey(_configuration.ApiUri))
|
||||
{
|
||||
_configuration.UidServerPairedUserTags.Add(_configuration.ApiUri, new(StringComparer.Ordinal));
|
||||
}
|
||||
|
||||
return _configuration.UidServerPairedUserTags[_configuration.ApiUri];
|
||||
return _serverConfigurationManager.CurrentServer!.UidServerPairedUserTags;
|
||||
}
|
||||
|
||||
private HashSet<string> GetAvailableTagsForCurrentServer()
|
||||
{
|
||||
if (!_configuration.ServerAvailablePairTags.ContainsKey(_configuration.ApiUri))
|
||||
{
|
||||
_configuration.ServerAvailablePairTags.Add(_configuration.ApiUri, new(StringComparer.Ordinal));
|
||||
}
|
||||
|
||||
return _configuration.ServerAvailablePairTags[_configuration.ApiUri];
|
||||
return _serverConfigurationManager.CurrentServer!.ServerAvailablePairTags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Threading.Tasks;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
@@ -11,25 +6,30 @@ using MareSynchronos.Utils;
|
||||
using MareSynchronos.Localization;
|
||||
using Dalamud.Utility;
|
||||
using MareSynchronos.FileCache;
|
||||
using Dalamud.Interface;
|
||||
using MareSynchronos.Managers;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.Delegates;
|
||||
|
||||
namespace MareSynchronos.UI;
|
||||
|
||||
internal class IntroUi : Window, IDisposable
|
||||
{
|
||||
private readonly UiShared _uiShared;
|
||||
private readonly Configuration _pluginConfiguration;
|
||||
private readonly ConfigurationService _configService;
|
||||
private readonly PeriodicFileScanner _fileCacheManager;
|
||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||
private readonly WindowSystem _windowSystem;
|
||||
private bool _readFirstPage;
|
||||
|
||||
public event SwitchUi? SwitchToMainUi;
|
||||
public event VoidDelegate? SwitchToMainUi;
|
||||
|
||||
private string[] TosParagraphs;
|
||||
private string[]? _tosParagraphs;
|
||||
|
||||
private Task _timeoutTask;
|
||||
private string _timeoutLabel;
|
||||
private Task? _timeoutTask;
|
||||
private string _timeoutLabel = string.Empty;
|
||||
|
||||
private Dictionary<string, string> _languages = new(StringComparer.Ordinal) { { "English", "en" }, { "Deutsch", "de" }, { "Français", "fr" } };
|
||||
private readonly Dictionary<string, string> _languages = new(StringComparer.Ordinal) { { "English", "en" }, { "Deutsch", "de" }, { "Français", "fr" } };
|
||||
private int _currentLanguage;
|
||||
|
||||
public void Dispose()
|
||||
@@ -39,20 +39,22 @@ internal class IntroUi : Window, IDisposable
|
||||
_windowSystem.RemoveWindow(this);
|
||||
}
|
||||
|
||||
public IntroUi(WindowSystem windowSystem, UiShared uiShared, Configuration pluginConfiguration,
|
||||
PeriodicFileScanner fileCacheManager) : base("Mare Synchronos Setup")
|
||||
public IntroUi(WindowSystem windowSystem, UiShared uiShared, ConfigurationService configService,
|
||||
PeriodicFileScanner fileCacheManager, ServerConfigurationManager serverConfigurationManager) : base("Mare Synchronos Setup")
|
||||
{
|
||||
Logger.Verbose("Creating " + nameof(IntroUi));
|
||||
|
||||
_uiShared = uiShared;
|
||||
_pluginConfiguration = pluginConfiguration;
|
||||
_configService = configService;
|
||||
_fileCacheManager = fileCacheManager;
|
||||
_serverConfigurationManager = serverConfigurationManager;
|
||||
_windowSystem = windowSystem;
|
||||
IsOpen = false;
|
||||
|
||||
SizeConstraints = new WindowSizeConstraints()
|
||||
{
|
||||
MinimumSize = new Vector2(600, 400),
|
||||
MaximumSize = new Vector2(600, 2000)
|
||||
MaximumSize = new Vector2(600, 2000),
|
||||
};
|
||||
|
||||
GetToSLocalization();
|
||||
@@ -64,7 +66,7 @@ internal class IntroUi : Window, IDisposable
|
||||
{
|
||||
if (_uiShared.IsInGpose) return;
|
||||
|
||||
if (!_pluginConfiguration.AcceptedAgreement && !_readFirstPage)
|
||||
if (!_configService.Current.AcceptedAgreement && !_readFirstPage)
|
||||
{
|
||||
if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont);
|
||||
ImGui.TextUnformatted("Welcome to Mare Synchronos");
|
||||
@@ -87,13 +89,12 @@ internal class IntroUi : Window, IDisposable
|
||||
for (int i = 60; i > 0; i--)
|
||||
{
|
||||
_timeoutLabel = $"{Strings.ToS.ButtonWillBeAvailableIn} {i}s";
|
||||
Logger.Debug(_timeoutLabel);
|
||||
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (!_pluginConfiguration.AcceptedAgreement && _readFirstPage)
|
||||
else if (!_configService.Current.AcceptedAgreement && _readFirstPage)
|
||||
{
|
||||
if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont);
|
||||
var textSize = ImGui.CalcTextSize(Strings.ToS.LanguageLabel);
|
||||
@@ -124,20 +125,20 @@ internal class IntroUi : Window, IDisposable
|
||||
ImGui.Separator();
|
||||
|
||||
|
||||
UiShared.TextWrapped(TosParagraphs[0]);
|
||||
UiShared.TextWrapped(TosParagraphs[1]);
|
||||
UiShared.TextWrapped(TosParagraphs[2]);
|
||||
UiShared.TextWrapped(TosParagraphs[3]);
|
||||
UiShared.TextWrapped(TosParagraphs[4]);
|
||||
UiShared.TextWrapped(TosParagraphs[5]);
|
||||
UiShared.TextWrapped(_tosParagraphs![0]);
|
||||
UiShared.TextWrapped(_tosParagraphs![1]);
|
||||
UiShared.TextWrapped(_tosParagraphs![2]);
|
||||
UiShared.TextWrapped(_tosParagraphs![3]);
|
||||
UiShared.TextWrapped(_tosParagraphs![4]);
|
||||
UiShared.TextWrapped(_tosParagraphs![5]);
|
||||
|
||||
ImGui.Separator();
|
||||
if (_timeoutTask?.IsCompleted ?? true)
|
||||
{
|
||||
if (ImGui.Button(Strings.ToS.AgreeLabel + "##toSetup"))
|
||||
{
|
||||
_pluginConfiguration.AcceptedAgreement = true;
|
||||
_pluginConfiguration.Save();
|
||||
_configService.Current.AcceptedAgreement = true;
|
||||
_configService.Save();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -145,10 +146,10 @@ internal class IntroUi : Window, IDisposable
|
||||
UiShared.TextWrapped(_timeoutLabel);
|
||||
}
|
||||
}
|
||||
else if (_pluginConfiguration.AcceptedAgreement
|
||||
&& (string.IsNullOrEmpty(_pluginConfiguration.CacheFolder)
|
||||
|| _pluginConfiguration.InitialScanComplete == false
|
||||
|| !Directory.Exists(_pluginConfiguration.CacheFolder)))
|
||||
else if (_configService.Current.AcceptedAgreement
|
||||
&& (string.IsNullOrEmpty(_configService.Current.CacheFolder)
|
||||
|| _configService.Current.InitialScanComplete == false
|
||||
|| !Directory.Exists(_configService.Current.CacheFolder)))
|
||||
{
|
||||
if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont);
|
||||
ImGui.TextUnformatted("File Storage Setup");
|
||||
@@ -171,11 +172,11 @@ internal class IntroUi : Window, IDisposable
|
||||
_uiShared.DrawCacheDirectorySetting();
|
||||
}
|
||||
|
||||
if (!_fileCacheManager.IsScanRunning && !string.IsNullOrEmpty(_pluginConfiguration.CacheFolder) && _uiShared.HasValidPenumbraModPath && Directory.Exists(_pluginConfiguration.CacheFolder))
|
||||
if (!_fileCacheManager.IsScanRunning && !string.IsNullOrEmpty(_configService.Current.CacheFolder) && _uiShared.HasValidPenumbraModPath && Directory.Exists(_configService.Current.CacheFolder))
|
||||
{
|
||||
if (ImGui.Button("Start Scan##startScan"))
|
||||
{
|
||||
_fileCacheManager.InvokeScan(true);
|
||||
_fileCacheManager.InvokeScan(forced: true);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -204,7 +205,37 @@ internal class IntroUi : Window, IDisposable
|
||||
|
||||
UiShared.TextWrapped("Once you have received a secret key you can connect to the service using the tools provided below.");
|
||||
|
||||
_uiShared.DrawServiceSelection(() => { });
|
||||
var idx = _uiShared.DrawServiceSelection(selectOnChange: true);
|
||||
|
||||
var text = "Enter Secret Key";
|
||||
var buttonText = "Save";
|
||||
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.SameLine();
|
||||
ImGui.SetNextItemWidth(UiShared.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X - buttonWidth - textSize.X);
|
||||
ImGui.InputText("", ref _secretKey, 64);
|
||||
if (_secretKey.Length > 0 && _secretKey.Length != 64)
|
||||
{
|
||||
UiShared.ColorTextWrapped("Your secret key must be exactly 64 characters long. Don't enter your Lodestone auth here.", ImGuiColors.DalamudRed);
|
||||
}
|
||||
else if (_secretKey.Length == 64)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button(buttonText))
|
||||
{
|
||||
if (_serverConfigurationManager.CurrentServer == null) _serverConfigurationManager.SelectServer(0);
|
||||
_serverConfigurationManager.CurrentServer!.SecretKeys.Add(_serverConfigurationManager.CurrentServer.SecretKeys.Select(k => k.Key).LastOrDefault() + 1, new SecretKey()
|
||||
{
|
||||
FriendlyName = $"Secret Key added on Setup ({DateTime.Now:yyyy-MM-dd})",
|
||||
Key = _secretKey,
|
||||
});
|
||||
_serverConfigurationManager.AddCurrentCharacterToServer(addLastSecretKey: true);
|
||||
_secretKey = string.Empty;
|
||||
Task.Run(() => _uiShared.ApiController.CreateConnections(forceGetToken: true));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -222,6 +253,6 @@ internal class IntroUi : Window, IDisposable
|
||||
_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 = new[] { Strings.ToS.Paragraph1, Strings.ToS.Paragraph2, Strings.ToS.Paragraph3, Strings.ToS.Paragraph4, Strings.ToS.Paragraph5, Strings.ToS.Paragraph6 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,42 +3,40 @@ using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.WebAPI;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Threading.Tasks;
|
||||
using MareSynchronos.API;
|
||||
using MareSynchronos.Utils;
|
||||
using MareSynchronos.WebAPI.Utils;
|
||||
using Dalamud.Utility;
|
||||
using Newtonsoft.Json;
|
||||
using MareSynchronos.Export;
|
||||
using MareSynchronos.API.Data;
|
||||
using MareSynchronos.Managers;
|
||||
using MareSynchronos.API.Data.Comparer;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.Delegates;
|
||||
|
||||
namespace MareSynchronos.UI;
|
||||
|
||||
public delegate void SwitchUi();
|
||||
public class SettingsUi : Window, IDisposable
|
||||
{
|
||||
private readonly Configuration _configuration;
|
||||
private readonly ConfigurationService _configService;
|
||||
private readonly WindowSystem _windowSystem;
|
||||
private readonly ApiController _apiController;
|
||||
private ApiController ApiController => _uiShared.ApiController;
|
||||
private readonly MareCharaFileManager _mareCharaFileManager;
|
||||
private readonly PairManager _pairManager;
|
||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||
private readonly UiShared _uiShared;
|
||||
public CharacterCacheDto LastCreatedCharacterData { private get; set; }
|
||||
public CharacterData? LastCreatedCharacterData { private get; set; }
|
||||
|
||||
public event SwitchUi? SwitchToIntroUi;
|
||||
public event VoidDelegate? SwitchToIntroUi;
|
||||
private bool _overwriteExistingLabels = false;
|
||||
private bool? _notesSuccessfullyApplied = null;
|
||||
private string _lastTab = string.Empty;
|
||||
private bool _openPopupOnAddition;
|
||||
private bool _hideInfoMessages;
|
||||
private bool _disableOptionalPluginsWarnings;
|
||||
private bool _wasOpen = false;
|
||||
|
||||
public SettingsUi(WindowSystem windowSystem,
|
||||
UiShared uiShared, Configuration configuration, ApiController apiController,
|
||||
MareCharaFileManager mareCharaFileManager) : base("Mare Synchronos Settings")
|
||||
UiShared uiShared, ConfigurationService configService,
|
||||
MareCharaFileManager mareCharaFileManager, PairManager pairManager, ServerConfigurationManager serverConfigurationManager) : base("Mare Synchronos Settings")
|
||||
{
|
||||
Logger.Verbose("Creating " + nameof(SettingsUi));
|
||||
|
||||
@@ -48,27 +46,26 @@ public class SettingsUi : Window, IDisposable
|
||||
MaximumSize = new Vector2(800, 2000),
|
||||
};
|
||||
|
||||
_configuration = configuration;
|
||||
_configService = configService;
|
||||
_windowSystem = windowSystem;
|
||||
_apiController = apiController;
|
||||
_mareCharaFileManager = mareCharaFileManager;
|
||||
_pairManager = pairManager;
|
||||
_serverConfigurationManager = serverConfigurationManager;
|
||||
_uiShared = uiShared;
|
||||
_openPopupOnAddition = _configuration.OpenPopupOnAdd;
|
||||
_hideInfoMessages = _configuration.HideInfoMessages;
|
||||
_disableOptionalPluginsWarnings = _configuration.DisableOptionalPluginWarnings;
|
||||
|
||||
_uiShared.GposeStart += _uiShared_GposeStart;
|
||||
_uiShared.GposeEnd += _uiShared_GposeEnd;
|
||||
|
||||
_uiShared.GposeStart += UiShared_GposeStart;
|
||||
_uiShared.GposeEnd += UiShared_GposeEnd;
|
||||
|
||||
windowSystem.AddWindow(this);
|
||||
}
|
||||
|
||||
private void _uiShared_GposeEnd()
|
||||
private void UiShared_GposeEnd()
|
||||
{
|
||||
IsOpen = _wasOpen;
|
||||
}
|
||||
|
||||
private void _uiShared_GposeStart()
|
||||
private void UiShared_GposeStart()
|
||||
{
|
||||
_wasOpen = IsOpen;
|
||||
IsOpen = false;
|
||||
@@ -78,15 +75,15 @@ public class SettingsUi : Window, IDisposable
|
||||
{
|
||||
Logger.Verbose("Disposing " + nameof(SettingsUi));
|
||||
|
||||
_uiShared.GposeStart -= _uiShared_GposeStart;
|
||||
_uiShared.GposeEnd -= _uiShared_GposeEnd;
|
||||
_uiShared.GposeStart -= UiShared_GposeStart;
|
||||
_uiShared.GposeEnd -= UiShared_GposeEnd;
|
||||
|
||||
_windowSystem.RemoveWindow(this);
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
var pluginState = _uiShared.DrawOtherPluginState();
|
||||
_ = _uiShared.DrawOtherPluginState();
|
||||
|
||||
DrawSettingsContent();
|
||||
}
|
||||
@@ -116,7 +113,7 @@ public class SettingsUi : Window, IDisposable
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
if (_apiController.ServerState is ServerState.Connected)
|
||||
if (ApiController.ServerState is ServerState.Connected)
|
||||
{
|
||||
if (ImGui.BeginTabItem("Transfers"))
|
||||
{
|
||||
@@ -131,344 +128,29 @@ public class SettingsUi : Window, IDisposable
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui.BeginTabItem("User Administration"))
|
||||
if (ImGui.BeginTabItem("Service Settings"))
|
||||
{
|
||||
DrawUserAdministration(_apiController.IsConnected);
|
||||
DrawServerConfiguration();
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
if (_apiController.IsConnected && _apiController.IsModerator)
|
||||
if (ImGui.BeginTabItem("Debug"))
|
||||
{
|
||||
if (ImGui.BeginTabItem("Administration"))
|
||||
{
|
||||
DrawAdministration();
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
DrawDebug();
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
ImGui.EndTabBar();
|
||||
}
|
||||
}
|
||||
|
||||
private string _forbiddenFileHashEntry = string.Empty;
|
||||
private string _forbiddenFileHashForbiddenBy = string.Empty;
|
||||
private string _bannedUserHashEntry = string.Empty;
|
||||
private string _bannedUserReasonEntry = string.Empty;
|
||||
|
||||
private void DrawGeneral()
|
||||
private void DrawServerConfiguration()
|
||||
{
|
||||
if (!string.Equals(_lastTab, "General", StringComparison.OrdinalIgnoreCase))
|
||||
_lastTab = "Service Settings";
|
||||
if (ApiController.ServerAlive)
|
||||
{
|
||||
_notesSuccessfullyApplied = null;
|
||||
}
|
||||
UiShared.FontText("Service Actions", _uiShared.UidFont);
|
||||
|
||||
_lastTab = "General";
|
||||
UiShared.FontText("Notes", _uiShared.UidFont);
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.StickyNote, "Export all your user notes to clipboard"))
|
||||
{
|
||||
ImGui.SetClipboardText(_uiShared.GetNotes());
|
||||
}
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.FileImport, "Import notes from clipboard"))
|
||||
{
|
||||
_notesSuccessfullyApplied = null;
|
||||
var notes = ImGui.GetClipboardText();
|
||||
_notesSuccessfullyApplied = _uiShared.ApplyNotesFromClipboard(notes, _overwriteExistingLabels);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Checkbox("Overwrite existing notes", ref _overwriteExistingLabels);
|
||||
UiShared.DrawHelpText("If this option is selected all already existing notes for UIDs will be overwritten by the imported notes.");
|
||||
if (_notesSuccessfullyApplied.HasValue && _notesSuccessfullyApplied.Value)
|
||||
{
|
||||
UiShared.ColorTextWrapped("User Notes successfully imported", ImGuiColors.HealerGreen);
|
||||
}
|
||||
else if (_notesSuccessfullyApplied.HasValue && !_notesSuccessfullyApplied.Value)
|
||||
{
|
||||
UiShared.ColorTextWrapped("Attempt to import notes from clipboard failed. Check formatting and try again", ImGuiColors.DalamudRed);
|
||||
}
|
||||
if (ImGui.Checkbox("Open Notes Popup on user addition", ref _openPopupOnAddition))
|
||||
{
|
||||
_apiController.LastAddedUser = null;
|
||||
_configuration.OpenPopupOnAdd = _openPopupOnAddition;
|
||||
_configuration.Save();
|
||||
}
|
||||
UiShared.DrawHelpText("This will open a popup that allows you to set the notes for a user after successfully adding them to your individual pairs.");
|
||||
|
||||
ImGui.Separator();
|
||||
UiShared.FontText("Server Messages", _uiShared.UidFont);
|
||||
if (ImGui.Checkbox("Hide Server Info Messages", ref _hideInfoMessages))
|
||||
{
|
||||
_configuration.HideInfoMessages = _hideInfoMessages;
|
||||
_configuration.Save();
|
||||
}
|
||||
UiShared.DrawHelpText("Enabling this will not print any \"Info\" labeled messages into the game chat.");
|
||||
if (ImGui.Checkbox("Disable optional plugin warnings", ref _disableOptionalPluginsWarnings))
|
||||
{
|
||||
_configuration.DisableOptionalPluginWarnings = _disableOptionalPluginsWarnings;
|
||||
_configuration.Save();
|
||||
}
|
||||
UiShared.DrawHelpText("Enabling this will not print any \"Warning\" labeled messages for missing optional plugins Heels or Customize+ in the game chat.");
|
||||
}
|
||||
|
||||
private void DrawAdministration()
|
||||
{
|
||||
_lastTab = "Administration";
|
||||
if (ImGui.TreeNode("Forbidden Files Changes"))
|
||||
{
|
||||
if (ImGui.BeginTable("ForbiddenFilesTable", 3, ImGuiTableFlags.RowBg))
|
||||
{
|
||||
ImGui.TableSetupColumn("File Hash", ImGuiTableColumnFlags.None, 290);
|
||||
ImGui.TableSetupColumn("Forbidden By", ImGuiTableColumnFlags.None, 290);
|
||||
ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.None, 70);
|
||||
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
foreach (var forbiddenFile in _apiController.AdminForbiddenFiles)
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
ImGui.Text(forbiddenFile.Hash);
|
||||
ImGui.TableNextColumn();
|
||||
string by = forbiddenFile.ForbiddenBy;
|
||||
if (ImGui.InputText("##forbiddenBy" + forbiddenFile.Hash, ref by, 255))
|
||||
{
|
||||
forbiddenFile.ForbiddenBy = by;
|
||||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
if (_apiController.IsAdmin)
|
||||
{
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (ImGui.Button(
|
||||
FontAwesomeIcon.Upload.ToIconString() + "##updateFile" + forbiddenFile.Hash))
|
||||
{
|
||||
_ = _apiController.AdminUpdateOrAddForbiddenFile(forbiddenFile);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button(FontAwesomeIcon.Trash.ToIconString() + "##deleteFile" +
|
||||
forbiddenFile.Hash))
|
||||
{
|
||||
_ = _apiController.AdminDeleteForbiddenFile(forbiddenFile);
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (_apiController.IsAdmin)
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.InputText("##addFileHash", ref _forbiddenFileHashEntry, 255);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.InputText("##addForbiddenBy", ref _forbiddenFileHashForbiddenBy, 255);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (ImGui.Button(FontAwesomeIcon.Plus.ToIconString() + "##addForbiddenFile"))
|
||||
{
|
||||
_ = _apiController.AdminUpdateOrAddForbiddenFile(new ForbiddenFileDto()
|
||||
{
|
||||
ForbiddenBy = _forbiddenFileHashForbiddenBy,
|
||||
Hash = _forbiddenFileHashEntry
|
||||
});
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
ImGui.NextColumn();
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
if (ImGui.TreeNode("Banned Users"))
|
||||
{
|
||||
if (ImGui.BeginTable("BannedUsersTable", 3, ImGuiTableFlags.RowBg))
|
||||
{
|
||||
ImGui.TableSetupColumn("Character Hash", ImGuiTableColumnFlags.None, 290);
|
||||
ImGui.TableSetupColumn("Reason", ImGuiTableColumnFlags.None, 290);
|
||||
ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.None, 70);
|
||||
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
foreach (var bannedUser in _apiController.AdminBannedUsers)
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text(bannedUser.CharacterHash);
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
string reason = bannedUser.Reason;
|
||||
ImGuiInputTextFlags moderatorFlags = _apiController.IsModerator
|
||||
? ImGuiInputTextFlags.ReadOnly
|
||||
: ImGuiInputTextFlags.None;
|
||||
if (ImGui.InputText("##bannedReason" + bannedUser.CharacterHash, ref reason, 255,
|
||||
moderatorFlags))
|
||||
{
|
||||
bannedUser.Reason = reason;
|
||||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (_apiController.IsAdmin)
|
||||
{
|
||||
if (ImGui.Button(FontAwesomeIcon.Upload.ToIconString() + "##updateUser" +
|
||||
bannedUser.CharacterHash))
|
||||
{
|
||||
_ = _apiController.AdminUpdateOrAddBannedUser(bannedUser);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
if (ImGui.Button(FontAwesomeIcon.Trash.ToIconString() + "##deleteUser" +
|
||||
bannedUser.CharacterHash))
|
||||
{
|
||||
_ = _apiController.AdminDeleteBannedUser(bannedUser);
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.InputText("##addUserHash", ref _bannedUserHashEntry, 255);
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
if (_apiController.IsAdmin)
|
||||
{
|
||||
ImGui.InputText("##addUserReason", ref _bannedUserReasonEntry, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
_bannedUserReasonEntry = "Banned by " + _uiShared.PlayerName;
|
||||
ImGui.InputText("##addUserReason", ref _bannedUserReasonEntry, 255,
|
||||
ImGuiInputTextFlags.ReadOnly);
|
||||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (ImGui.Button(FontAwesomeIcon.Plus.ToIconString() + "##addForbiddenFile"))
|
||||
{
|
||||
_ = _apiController.AdminUpdateOrAddBannedUser(new BannedUserDto()
|
||||
{
|
||||
CharacterHash = _forbiddenFileHashForbiddenBy,
|
||||
Reason = _forbiddenFileHashEntry
|
||||
});
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
if (ImGui.TreeNode("Online Users"))
|
||||
{
|
||||
if (ImGui.Button("Refresh Online Users"))
|
||||
{
|
||||
_ = _apiController.RefreshOnlineUsers();
|
||||
}
|
||||
|
||||
if (ImGui.BeginTable("OnlineUsersTable", 3, ImGuiTableFlags.RowBg))
|
||||
{
|
||||
ImGui.TableSetupColumn("UID", ImGuiTableColumnFlags.None, 100);
|
||||
ImGui.TableSetupColumn("Character Hash", ImGuiTableColumnFlags.None, 300);
|
||||
ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.None, 70);
|
||||
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
foreach (var onlineUser in _apiController.AdminOnlineUsers)
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
string icon = onlineUser.IsModerator
|
||||
? FontAwesomeIcon.ChessKing.ToIconString()
|
||||
: onlineUser.IsAdmin
|
||||
? FontAwesomeIcon.Crown.ToIconString()
|
||||
: FontAwesomeIcon.User.ToIconString();
|
||||
ImGui.Text(icon);
|
||||
ImGui.PopFont();
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGui.Text(onlineUser.UID);
|
||||
ImGui.SameLine();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (ImGui.Button(FontAwesomeIcon.Copy.ToIconString() + "##onlineUserCopyUID" +
|
||||
onlineUser.CharacterNameHash))
|
||||
{
|
||||
ImGui.SetClipboardText(onlineUser.UID);
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
string charNameHash = onlineUser.CharacterNameHash;
|
||||
ImGui.InputText("##onlineUserHash" + onlineUser.CharacterNameHash, ref charNameHash, 255,
|
||||
ImGuiInputTextFlags.ReadOnly);
|
||||
ImGui.SameLine();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (ImGui.Button(FontAwesomeIcon.Copy.ToIconString() + "##onlineUserCopyHash" +
|
||||
onlineUser.CharacterNameHash))
|
||||
{
|
||||
ImGui.SetClipboardText(onlineUser.UID);
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (ImGui.Button(FontAwesomeIcon.SkullCrossbones.ToIconString() + "##onlineUserBan" +
|
||||
onlineUser.CharacterNameHash))
|
||||
{
|
||||
_ = _apiController.AdminUpdateOrAddBannedUser(new BannedUserDto
|
||||
{
|
||||
CharacterHash = onlineUser.CharacterNameHash,
|
||||
Reason = "Banned by " + _uiShared.PlayerName
|
||||
});
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if (!string.Equals(onlineUser.UID, _apiController.UID, StringComparison.Ordinal) && _apiController.IsAdmin)
|
||||
{
|
||||
if (!onlineUser.IsModerator)
|
||||
{
|
||||
if (ImGui.Button(FontAwesomeIcon.ChessKing.ToIconString() +
|
||||
"##onlineUserModerator" +
|
||||
onlineUser.CharacterNameHash))
|
||||
{
|
||||
_apiController.AdminChangeModeratorStatus(onlineUser.UID, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ImGui.Button(FontAwesomeIcon.User.ToIconString() +
|
||||
"##onlineUserNonModerator" +
|
||||
onlineUser.CharacterNameHash))
|
||||
{
|
||||
_apiController.AdminChangeModeratorStatus(onlineUser.UID, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
}
|
||||
ImGui.EndTable();
|
||||
}
|
||||
ImGui.TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _deleteFilesPopupModalShown = false;
|
||||
private bool _deleteAccountPopupModalShown = false;
|
||||
|
||||
private void DrawUserAdministration(bool serverAlive)
|
||||
{
|
||||
_lastTab = "UserAdministration";
|
||||
if (serverAlive)
|
||||
{
|
||||
if (ImGui.Button("Delete all my files"))
|
||||
{
|
||||
_deleteFilesPopupModalShown = true;
|
||||
@@ -490,7 +172,7 @@ public class SettingsUi : Window, IDisposable
|
||||
|
||||
if (ImGui.Button("Delete everything", new Vector2(buttonSize, 0)))
|
||||
{
|
||||
Task.Run(() => _apiController.FilesDeleteAll());
|
||||
Task.Run(() => ApiController.FilesDeleteAll());
|
||||
_deleteFilesPopupModalShown = false;
|
||||
}
|
||||
|
||||
@@ -504,7 +186,7 @@ public class SettingsUi : Window, IDisposable
|
||||
UiShared.SetScaledWindowSize(325);
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Delete account"))
|
||||
{
|
||||
_deleteAccountPopupModalShown = true;
|
||||
@@ -527,7 +209,7 @@ public class SettingsUi : Window, IDisposable
|
||||
|
||||
if (ImGui.Button("Delete account", new Vector2(buttonSize, 0)))
|
||||
{
|
||||
Task.Run(() => _apiController.UserDelete());
|
||||
Task.Run(() => ApiController.UserDelete());
|
||||
_deleteAccountPopupModalShown = false;
|
||||
SwitchToIntroUi?.Invoke();
|
||||
}
|
||||
@@ -542,37 +224,277 @@ public class SettingsUi : Window, IDisposable
|
||||
UiShared.SetScaledWindowSize(325);
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
ImGui.Separator();
|
||||
|
||||
}
|
||||
|
||||
if (!_configuration.FullPause)
|
||||
UiShared.FontText("Service & Character Settings", _uiShared.UidFont);
|
||||
|
||||
var idx = _uiShared.DrawServiceSelection();
|
||||
|
||||
ImGui.Dummy(new Vector2(10, 10));
|
||||
|
||||
var selectedServer = _serverConfigurationManager.GetServerByIndex(idx);
|
||||
if (selectedServer == _serverConfigurationManager.CurrentServer)
|
||||
{
|
||||
UiShared.ColorTextWrapped("Note: to change servers or your secret key you need to disconnect from your current Mare Synchronos server.", ImGuiColors.DalamudYellow);
|
||||
UiShared.ColorTextWrapped("For any changes to be applied to the current service you need to reconnect to the service.", ImGuiColors.DalamudYellow);
|
||||
}
|
||||
|
||||
var marePaused = _configuration.FullPause;
|
||||
|
||||
if (_configuration.HasValidSetup())
|
||||
if (ImGui.BeginTabBar("serverTabBar"))
|
||||
{
|
||||
if (ImGui.Checkbox("Disconnect Mare Synchronos", ref marePaused))
|
||||
if (ImGui.BeginTabItem("Character Management"))
|
||||
{
|
||||
_configuration.FullPause = marePaused;
|
||||
_configuration.Save();
|
||||
Task.Run(() => _apiController.CreateConnections(false));
|
||||
UiShared.ColorTextWrapped("Characters listed here will automatically connect to the selected Mare service with the settings as provided below." +
|
||||
" Make sure to enter the character names correctly or use the 'Add current character' button at the bottom.", ImGuiColors.DalamudYellow);
|
||||
int i = 0;
|
||||
foreach (var item in selectedServer.Authentications.ToList())
|
||||
{
|
||||
UiShared.DrawWithID("selectedChara" + i, () =>
|
||||
{
|
||||
var charaName = item.CharacterName;
|
||||
if (ImGui.InputText("Character Name", ref charaName, 64))
|
||||
{
|
||||
item.CharacterName = charaName;
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
var worldIdx = (ushort)item.WorldId;
|
||||
var data = _uiShared.WorldData;
|
||||
if (!data.TryGetValue(worldIdx, out string? worldPreview))
|
||||
{
|
||||
worldPreview = data.First().Value;
|
||||
}
|
||||
if (ImGui.BeginCombo("World", worldPreview))
|
||||
{
|
||||
foreach (var world in data)
|
||||
{
|
||||
bool isSelected = worldIdx == world.Key;
|
||||
if (ImGui.Selectable(world.Value, isSelected))
|
||||
{
|
||||
item.WorldId = world.Key;
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
}
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
var secretKeyIdx = item.SecretKeyIdx;
|
||||
var keys = selectedServer.SecretKeys;
|
||||
if (!keys.TryGetValue(secretKeyIdx, out var secretKey))
|
||||
{
|
||||
secretKey = new();
|
||||
}
|
||||
var friendlyName = secretKey.FriendlyName;
|
||||
if (ImGui.BeginCombo("Secret Key", friendlyName))
|
||||
{
|
||||
foreach (var kvp in keys)
|
||||
{
|
||||
bool isSelected = kvp.Key == secretKeyIdx;
|
||||
if (ImGui.Selectable(kvp.Value.FriendlyName, isSelected))
|
||||
{
|
||||
item.SecretKeyIdx = kvp.Key;
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
}
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Trash, "Delete Character"))
|
||||
{
|
||||
if (UiShared.CtrlPressed())
|
||||
_serverConfigurationManager.RemoveCharacterFromServer(idx, item);
|
||||
}
|
||||
UiShared.AttachToolTip("Hold CTRL to delete this entry.");
|
||||
|
||||
if (item != selectedServer.Authentications.LastOrDefault())
|
||||
ImGui.Separator();
|
||||
});
|
||||
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
if (!selectedServer.Authentications.Any(c => string.Equals(c.CharacterName, _uiShared.PlayerName, StringComparison.Ordinal)
|
||||
&& c.WorldId == _uiShared.WorldId))
|
||||
{
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.User, "Add current character"))
|
||||
{
|
||||
_serverConfigurationManager.AddCurrentCharacterToServer(idx);
|
||||
}
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Plus, "Add new character"))
|
||||
{
|
||||
_serverConfigurationManager.AddEmptyCharacterToServer(idx);
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
UiShared.DrawHelpText("Completely pauses the sync and clears your current data (not uploaded files) on the service.");
|
||||
if (ImGui.BeginTabItem("Secret Key Management"))
|
||||
{
|
||||
foreach (var item in selectedServer.SecretKeys.ToList())
|
||||
{
|
||||
UiShared.DrawWithID("key" + item.Key, () =>
|
||||
{
|
||||
var friendlyName = item.Value.FriendlyName;
|
||||
if (ImGui.InputText("Secret Key Display Name", ref friendlyName, 255))
|
||||
{
|
||||
item.Value.FriendlyName = friendlyName;
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
var key = item.Value.Key;
|
||||
if (ImGui.InputText("Secret Key", ref key, 64))
|
||||
{
|
||||
item.Value.Key = key;
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Trash, "Delete Secret Key"))
|
||||
{
|
||||
if (UiShared.CtrlPressed())
|
||||
{
|
||||
selectedServer.SecretKeys.Remove(item.Key);
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
}
|
||||
UiShared.AttachToolTip("Hold CTRL to delete this secret key entry");
|
||||
});
|
||||
|
||||
if (item.Key != selectedServer.SecretKeys.Keys.LastOrDefault())
|
||||
ImGui.Separator();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Plus, "Add new Secret Key"))
|
||||
{
|
||||
selectedServer.SecretKeys.Add(selectedServer.SecretKeys.Last().Key + 1, new SecretKey()
|
||||
{
|
||||
FriendlyName = "New Secret Key",
|
||||
});
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui.BeginTabItem("Service Settings"))
|
||||
{
|
||||
var serverUri = selectedServer.ServerUri;
|
||||
ImGui.InputText("Service URI", ref serverUri, 255, ImGuiInputTextFlags.ReadOnly);
|
||||
UiShared.DrawHelpText("You cannot edit the service URI. Add a new service if you need to edit the URI.");
|
||||
var serverName = selectedServer.ServerName;
|
||||
var isMain = string.Equals(serverName, ApiController.MainServer, StringComparison.OrdinalIgnoreCase);
|
||||
var flags = isMain ? ImGuiInputTextFlags.ReadOnly : ImGuiInputTextFlags.None;
|
||||
if (ImGui.InputText("Service Name", ref serverName, 255, flags))
|
||||
{
|
||||
selectedServer.ServerName = serverName;
|
||||
_serverConfigurationManager.Save();
|
||||
}
|
||||
if (isMain)
|
||||
{
|
||||
UiShared.DrawHelpText("You cannot edit the name of the main service.");
|
||||
}
|
||||
if (!isMain)
|
||||
{
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Trash, "Delete Service"))
|
||||
{
|
||||
if (UiShared.CtrlPressed())
|
||||
{
|
||||
_serverConfigurationManager.DeleteServer(selectedServer);
|
||||
}
|
||||
}
|
||||
UiShared.DrawHelpText("Hold CTRL to delete this service");
|
||||
}
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
ImGui.EndTabBar();
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
private void DrawGeneral()
|
||||
{
|
||||
if (!string.Equals(_lastTab, "General", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
UiShared.ColorText("You cannot reconnect without a valid account on the service.", ImGuiColors.DalamudYellow);
|
||||
_notesSuccessfullyApplied = null;
|
||||
}
|
||||
|
||||
if (marePaused)
|
||||
_lastTab = "General";
|
||||
UiShared.FontText("Notes", _uiShared.UidFont);
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.StickyNote, "Export all your user notes to clipboard"))
|
||||
{
|
||||
_uiShared.DrawServiceSelection(() => { });
|
||||
ImGui.SetClipboardText(UiShared.GetNotes(_pairManager.DirectPairs.UnionBy(_pairManager.GroupPairs.SelectMany(p => p.Value), p => p.UserData, UserDataComparer.Instance).ToList()));
|
||||
}
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.FileImport, "Import notes from clipboard"))
|
||||
{
|
||||
_notesSuccessfullyApplied = null;
|
||||
var notes = ImGui.GetClipboardText();
|
||||
_notesSuccessfullyApplied = _uiShared.ApplyNotesFromClipboard(notes, _overwriteExistingLabels);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Checkbox("Overwrite existing notes", ref _overwriteExistingLabels);
|
||||
UiShared.DrawHelpText("If this option is selected all already existing notes for UIDs will be overwritten by the imported notes.");
|
||||
if (_notesSuccessfullyApplied.HasValue && _notesSuccessfullyApplied.Value)
|
||||
{
|
||||
UiShared.ColorTextWrapped("User Notes successfully imported", ImGuiColors.HealerGreen);
|
||||
}
|
||||
else if (_notesSuccessfullyApplied.HasValue && !_notesSuccessfullyApplied.Value)
|
||||
{
|
||||
UiShared.ColorTextWrapped("Attempt to import notes from clipboard failed. Check formatting and try again", ImGuiColors.DalamudRed);
|
||||
}
|
||||
|
||||
var openPopupOnAddition = _configService.Current.OpenPopupOnAdd;
|
||||
var hideInfoMessages = _configService.Current.HideInfoMessages;
|
||||
var disableOptionalPluginWarnings = _configService.Current.DisableOptionalPluginWarnings;
|
||||
var onlineNotifs = _configService.Current.ShowOnlineNotifications;
|
||||
var onlineNotifsPairsOnly = _configService.Current.ShowOnlineNotificationsOnlyForIndividualPairs;
|
||||
|
||||
if (ImGui.Checkbox("Open Notes Popup on user addition", ref openPopupOnAddition))
|
||||
{
|
||||
ApiController.LastAddedUser = null;
|
||||
_configService.Current.OpenPopupOnAdd = openPopupOnAddition;
|
||||
_configService.Save();
|
||||
}
|
||||
UiShared.DrawHelpText("This will open a popup that allows you to set the notes for a user after successfully adding them to your individual pairs.");
|
||||
|
||||
ImGui.Separator();
|
||||
UiShared.FontText("Server Messages", _uiShared.UidFont);
|
||||
if (ImGui.Checkbox("Hide Server Info Messages", ref hideInfoMessages))
|
||||
{
|
||||
_configService.Current.HideInfoMessages = hideInfoMessages;
|
||||
_configService.Save();
|
||||
}
|
||||
UiShared.DrawHelpText("Enabling this will not print any \"Info\" labeled messages into the game chat.");
|
||||
if (ImGui.Checkbox("Disable optional plugin warnings", ref disableOptionalPluginWarnings))
|
||||
{
|
||||
_configService.Current.DisableOptionalPluginWarnings = disableOptionalPluginWarnings;
|
||||
_configService.Save();
|
||||
}
|
||||
UiShared.DrawHelpText("Enabling this will not print any \"Warning\" labeled messages for missing optional plugins Heels or Customize+ in the game chat.");
|
||||
if (ImGui.Checkbox("Enable online notifications", ref onlineNotifs))
|
||||
{
|
||||
_configService.Current.ShowOnlineNotifications = onlineNotifs;
|
||||
_configService.Save();
|
||||
}
|
||||
UiShared.DrawHelpText("Enabling this will show a small notification in the bottom right corner when pairs go online.");
|
||||
|
||||
if (!onlineNotifs) ImGui.BeginDisabled();
|
||||
if (ImGui.Checkbox("Notify only for individual pairs", ref onlineNotifsPairsOnly))
|
||||
{
|
||||
_configService.Current.ShowOnlineNotificationsOnlyForIndividualPairs = onlineNotifsPairsOnly;
|
||||
_configService.Save();
|
||||
}
|
||||
UiShared.DrawHelpText("Enabling this will only show online notifications for individual pairs.");
|
||||
if (!onlineNotifs) ImGui.EndDisabled();
|
||||
}
|
||||
|
||||
private bool _deleteFilesPopupModalShown = false;
|
||||
private bool _deleteAccountPopupModalShown = false;
|
||||
|
||||
private void DrawDebug()
|
||||
{
|
||||
_lastTab = "Debug";
|
||||
|
||||
UiShared.FontText("Debug", _uiShared.UidFont);
|
||||
|
||||
@@ -590,9 +512,6 @@ public class SettingsUi : Window, IDisposable
|
||||
UiShared.AttachToolTip("Use this when reporting mods being rejected from the server.");
|
||||
}
|
||||
|
||||
private string _charaFileSavePath = string.Empty;
|
||||
private string _charaFileLoadPath = string.Empty;
|
||||
|
||||
private void DrawBlockedTransfers()
|
||||
{
|
||||
_lastTab = "BlockedTransfers";
|
||||
@@ -609,7 +528,7 @@ public class SettingsUi : Window, IDisposable
|
||||
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
foreach (var item in _apiController.ForbiddenTransfers)
|
||||
foreach (var item in ApiController.ForbiddenTransfers)
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
if (item is UploadFileTransfer transfer)
|
||||
@@ -630,14 +549,14 @@ public class SettingsUi : Window, IDisposable
|
||||
private void DrawCurrentTransfers()
|
||||
{
|
||||
_lastTab = "Transfers";
|
||||
bool showTransferWindow = _configuration.ShowTransferWindow;
|
||||
bool showTransferWindow = _configService.Current.ShowTransferWindow;
|
||||
if (ImGui.Checkbox("Show separate Transfer window while transfers are active", ref showTransferWindow))
|
||||
{
|
||||
_configuration.ShowTransferWindow = showTransferWindow;
|
||||
_configuration.Save();
|
||||
_configService.Current.ShowTransferWindow = showTransferWindow;
|
||||
_configService.Save();
|
||||
}
|
||||
|
||||
if (_configuration.ShowTransferWindow)
|
||||
if (_configService.Current.ShowTransferWindow)
|
||||
{
|
||||
ImGui.Indent();
|
||||
bool editTransferWindowPosition = _uiShared.EditTrackerPosition;
|
||||
@@ -651,8 +570,8 @@ public class SettingsUi : Window, IDisposable
|
||||
if (ImGui.BeginTable("TransfersTable", 2))
|
||||
{
|
||||
ImGui.TableSetupColumn(
|
||||
$"Uploads ({UiShared.ByteToString(_apiController.CurrentUploads.Sum(a => a.Transferred))} / {UiShared.ByteToString(_apiController.CurrentUploads.Sum(a => a.Total))})");
|
||||
ImGui.TableSetupColumn($"Downloads ({UiShared.ByteToString(_apiController.CurrentDownloads.SelectMany(k => k.Value).ToList().Sum(a => a.Transferred))} / {UiShared.ByteToString(_apiController.CurrentDownloads.SelectMany(k => k.Value).ToList().Sum(a => a.Total))})");
|
||||
$"Uploads ({UiShared.ByteToString(ApiController.CurrentUploads.Sum(a => a.Transferred))} / {UiShared.ByteToString(ApiController.CurrentUploads.Sum(a => a.Total))})");
|
||||
ImGui.TableSetupColumn($"Downloads ({UiShared.ByteToString(ApiController.CurrentDownloads.SelectMany(k => k.Value).ToList().Sum(a => a.Transferred))} / {UiShared.ByteToString(ApiController.CurrentDownloads.SelectMany(k => k.Value).ToList().Sum(a => a.Total))})");
|
||||
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
@@ -663,7 +582,7 @@ public class SettingsUi : Window, IDisposable
|
||||
ImGui.TableSetupColumn("Uploaded");
|
||||
ImGui.TableSetupColumn("Size");
|
||||
ImGui.TableHeadersRow();
|
||||
foreach (var transfer in _apiController.CurrentUploads.ToArray())
|
||||
foreach (var transfer in ApiController.CurrentUploads.ToArray())
|
||||
{
|
||||
var color = UiShared.UploadColor((transfer.Transferred, transfer.Total));
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, color);
|
||||
@@ -687,7 +606,7 @@ public class SettingsUi : Window, IDisposable
|
||||
ImGui.TableSetupColumn("Downloaded");
|
||||
ImGui.TableSetupColumn("Size");
|
||||
ImGui.TableHeadersRow();
|
||||
foreach (var transfer in _apiController.CurrentDownloads.SelectMany(k => k.Value).ToArray())
|
||||
foreach (var transfer in ApiController.CurrentDownloads.SelectMany(k => k.Value).ToArray())
|
||||
{
|
||||
var color = UiShared.UploadColor((transfer.Transferred, transfer.Total));
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, color);
|
||||
@@ -761,11 +680,11 @@ public class SettingsUi : Window, IDisposable
|
||||
|
||||
ImGui.Unindent();
|
||||
}
|
||||
bool openInGpose = _configuration.OpenGposeImportOnGposeStart;
|
||||
bool openInGpose = _configService.Current.OpenGposeImportOnGposeStart;
|
||||
if (ImGui.Checkbox("Open MCDF import window when GPose loads", ref openInGpose))
|
||||
{
|
||||
_configuration.OpenGposeImportOnGposeStart = openInGpose;
|
||||
_configuration.Save();
|
||||
_configService.Current.OpenGposeImportOnGposeStart = openInGpose;
|
||||
_configService.Save();
|
||||
}
|
||||
UiShared.DrawHelpText("This will automatically open the import menu when loading into Gpose. If unchecked you can open the menu manually with /mare gpose");
|
||||
|
||||
@@ -788,7 +707,7 @@ public class SettingsUi : Window, IDisposable
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(_configuration.CacheFolder))
|
||||
foreach (var file in Directory.GetFiles(_configService.Current.CacheFolder))
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
|
||||
@@ -1,40 +1,44 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.ImGuiFileDialog;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using MareSynchronos.Delegates;
|
||||
using MareSynchronos.FileCache;
|
||||
using MareSynchronos.Localization;
|
||||
using MareSynchronos.Managers;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.Models;
|
||||
using MareSynchronos.Utils;
|
||||
using MareSynchronos.WebAPI;
|
||||
|
||||
namespace MareSynchronos.UI;
|
||||
|
||||
public class UiShared : IDisposable
|
||||
public partial class UiShared : IDisposable
|
||||
{
|
||||
[DllImport("user32")]
|
||||
public static extern short GetKeyState(int nVirtKey);
|
||||
[LibraryImport("user32")]
|
||||
internal static partial short GetKeyState(int nVirtKey);
|
||||
|
||||
private readonly IpcManager _ipcManager;
|
||||
private readonly ApiController _apiController;
|
||||
private readonly PeriodicFileScanner _cacheScanner;
|
||||
public readonly FileDialogManager FileDialogManager;
|
||||
private readonly Configuration _pluginConfiguration;
|
||||
private readonly ConfigurationService _configService;
|
||||
private readonly DalamudUtil _dalamudUtil;
|
||||
private readonly DalamudPluginInterface _pluginInterface;
|
||||
private readonly Dalamud.Localization _localization;
|
||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||
|
||||
public long FileCacheSize => _cacheScanner.FileCacheSize;
|
||||
public string PlayerName => _dalamudUtil.PlayerName;
|
||||
public uint WorldId => _dalamudUtil.WorldId;
|
||||
public Dictionary<ushort, string> WorldData => _dalamudUtil.WorldData.Value;
|
||||
public bool HasValidPenumbraModPath => !(_ipcManager.PenumbraModDirectory() ?? string.Empty).IsNullOrEmpty() && Directory.Exists(_ipcManager.PenumbraModDirectory());
|
||||
public bool EditTrackerPosition { get; set; }
|
||||
public ImFontPtr UidFont { get; private set; }
|
||||
@@ -45,38 +49,40 @@ public class UiShared : IDisposable
|
||||
public static bool CtrlPressed() => (GetKeyState(0xA2) & 0x8000) != 0 || (GetKeyState(0xA3) & 0x8000) != 0;
|
||||
public static bool ShiftPressed() => (GetKeyState(0xA1) & 0x8000) != 0 || (GetKeyState(0xA0) & 0x8000) != 0;
|
||||
|
||||
public static ImGuiWindowFlags PopupWindowFlags = ImGuiWindowFlags.NoResize |
|
||||
public static readonly ImGuiWindowFlags PopupWindowFlags = ImGuiWindowFlags.NoResize |
|
||||
ImGuiWindowFlags.NoScrollbar |
|
||||
ImGuiWindowFlags.NoScrollWithMouse;
|
||||
|
||||
public ApiController ApiController => _apiController;
|
||||
|
||||
public UiShared(IpcManager ipcManager, ApiController apiController, PeriodicFileScanner cacheScanner, FileDialogManager fileDialogManager,
|
||||
Configuration pluginConfiguration, DalamudUtil dalamudUtil, DalamudPluginInterface pluginInterface, Dalamud.Localization localization)
|
||||
ConfigurationService configService, DalamudUtil dalamudUtil, DalamudPluginInterface pluginInterface, Dalamud.Localization localization,
|
||||
ServerConfigurationManager serverManager)
|
||||
{
|
||||
_ipcManager = ipcManager;
|
||||
_apiController = apiController;
|
||||
_cacheScanner = cacheScanner;
|
||||
FileDialogManager = fileDialogManager;
|
||||
_pluginConfiguration = pluginConfiguration;
|
||||
_configService = configService;
|
||||
_dalamudUtil = dalamudUtil;
|
||||
_pluginInterface = pluginInterface;
|
||||
_localization = localization;
|
||||
_isDirectoryWritable = IsDirectoryWritable(_pluginConfiguration.CacheFolder);
|
||||
_serverConfigurationManager = serverManager;
|
||||
_isDirectoryWritable = IsDirectoryWritable(_configService.Current.CacheFolder);
|
||||
|
||||
_pluginInterface.UiBuilder.BuildFonts += BuildFont;
|
||||
_pluginInterface.UiBuilder.RebuildFonts();
|
||||
|
||||
_dalamudUtil.GposeStart += _dalamudUtil_GposeStart;
|
||||
_dalamudUtil.GposeEnd += _dalamudUtil_GposeEnd;
|
||||
_dalamudUtil.GposeStart += DalamudUtil_GposeStart;
|
||||
_dalamudUtil.GposeEnd += DalamudUtil_GposeEnd;
|
||||
}
|
||||
|
||||
private void _dalamudUtil_GposeEnd()
|
||||
private void DalamudUtil_GposeEnd()
|
||||
{
|
||||
GposeEnd?.Invoke();
|
||||
}
|
||||
|
||||
private void _dalamudUtil_GposeStart()
|
||||
private void DalamudUtil_GposeStart()
|
||||
{
|
||||
GposeStart?.Invoke();
|
||||
}
|
||||
@@ -141,13 +147,13 @@ public class UiShared : IDisposable
|
||||
|
||||
ImGui.SetWindowSize(new Vector2(x, y));
|
||||
}
|
||||
|
||||
|
||||
private static void CenterWindow(float width, float height, ImGuiCond cond = ImGuiCond.None)
|
||||
{
|
||||
var center = ImGui.GetMainViewport().GetCenter();
|
||||
ImGui.SetWindowPos(new Vector2(center.X - width / 2, center.Y - height / 2), cond);
|
||||
}
|
||||
|
||||
|
||||
public static void CenterNextWindow(float width, float height, ImGuiCond cond = ImGuiCond.None)
|
||||
{
|
||||
var center = ImGui.GetMainViewport().GetCenter();
|
||||
@@ -219,13 +225,13 @@ public class UiShared : IDisposable
|
||||
? "Collecting files"
|
||||
: $"Processing {_cacheScanner.CurrentFileProgress} / {_cacheScanner.TotalFiles} files");
|
||||
}
|
||||
else if (_pluginConfiguration.FileScanPaused)
|
||||
else if (_configService.Current.FileScanPaused)
|
||||
{
|
||||
ImGui.Text("File scanner is paused");
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Force Rescan##forcedrescan"))
|
||||
{
|
||||
_cacheScanner.InvokeScan(true);
|
||||
_cacheScanner.InvokeScan(forced: true);
|
||||
}
|
||||
}
|
||||
else if (_cacheScanner.haltScanLocks.Any(f => f.Value > 0))
|
||||
@@ -245,18 +251,15 @@ public class UiShared : IDisposable
|
||||
|
||||
public void PrintServerState()
|
||||
{
|
||||
var serverName = _apiController.ServerDictionary.ContainsKey(_pluginConfiguration.ApiUri)
|
||||
? _apiController.ServerDictionary[_pluginConfiguration.ApiUri]
|
||||
: _pluginConfiguration.ApiUri;
|
||||
if (_apiController.ServerState is ServerState.Connected)
|
||||
{
|
||||
ImGui.TextUnformatted("Service " + serverName + ":");
|
||||
ImGui.TextUnformatted("Service " + _serverConfigurationManager.CurrentServer!.ServerName + ":");
|
||||
ImGui.SameLine();
|
||||
ImGui.TextColored(ImGuiColors.ParsedGreen, "Available");
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted("(");
|
||||
ImGui.SameLine();
|
||||
ImGui.TextColored(ImGuiColors.ParsedGreen, _apiController.OnlineUsers.ToString());
|
||||
ImGui.TextColored(ImGuiColors.ParsedGreen, _apiController.OnlineUsers.ToString(CultureInfo.InvariantCulture));
|
||||
ImGui.SameLine();
|
||||
ImGui.Text("Users Online");
|
||||
ImGui.SameLine();
|
||||
@@ -345,17 +348,23 @@ public class UiShared : IDisposable
|
||||
return $"{dblSByte:0.00} {suffix[i]}";
|
||||
}
|
||||
|
||||
private int _serverSelectionIndex = 0;
|
||||
private int _serverSelectionIndex = -1;
|
||||
private string _customServerName = "";
|
||||
private string _customServerUri = "";
|
||||
private bool _enterSecretKey = false;
|
||||
private bool _cacheDirectoryHasOtherFilesThanCache = false;
|
||||
private bool _cacheDirectoryIsValidPath = true;
|
||||
|
||||
public void DrawServiceSelection(Action? callBackOnExit = null)
|
||||
public int DrawServiceSelection(bool selectOnChange = false)
|
||||
{
|
||||
string[] comboEntries = _apiController.ServerDictionary.Values.ToArray();
|
||||
_serverSelectionIndex = Array.IndexOf(_apiController.ServerDictionary.Keys.ToArray(), _pluginConfiguration.ApiUri);
|
||||
string[] comboEntries = _serverConfigurationManager.GetServerNames();
|
||||
|
||||
if (_serverSelectionIndex == -1)
|
||||
_serverSelectionIndex = Array.IndexOf(_serverConfigurationManager.GetServerApiUrls(), _serverConfigurationManager.CurrentApiUrl);
|
||||
for (int i = 0; i < comboEntries.Length; i++)
|
||||
{
|
||||
if (string.Equals(_serverConfigurationManager.CurrentServer?.ServerName, comboEntries[i], StringComparison.OrdinalIgnoreCase))
|
||||
comboEntries[i] += " [Current]";
|
||||
}
|
||||
if (ImGui.BeginCombo("Select Service", comboEntries[_serverSelectionIndex]))
|
||||
{
|
||||
for (int i = 0; i < comboEntries.Length; i++)
|
||||
@@ -363,9 +372,11 @@ public class UiShared : IDisposable
|
||||
bool isSelected = _serverSelectionIndex == i;
|
||||
if (ImGui.Selectable(comboEntries[i], isSelected))
|
||||
{
|
||||
_pluginConfiguration.ApiUri = _apiController.ServerDictionary.Single(k => string.Equals(k.Value, comboEntries[i], StringComparison.Ordinal)).Key;
|
||||
_pluginConfiguration.Save();
|
||||
_ = _apiController.CreateConnections();
|
||||
_serverSelectionIndex = i;
|
||||
if (selectOnChange)
|
||||
{
|
||||
_serverConfigurationManager.SelectServer(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (isSelected)
|
||||
@@ -377,113 +388,61 @@ public class UiShared : IDisposable
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
|
||||
if (_serverSelectionIndex != 0)
|
||||
if (_serverConfigurationManager.GetSecretKey(_serverSelectionIndex) != null)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (ImGui.Button(FontAwesomeIcon.Trash.ToIconString() + "##deleteService"))
|
||||
var text = "Connect";
|
||||
if (_serverSelectionIndex == _serverConfigurationManager.GetCurrentServerIndex()) text = "Reconnect";
|
||||
if (IconTextButton(FontAwesomeIcon.Link, text))
|
||||
{
|
||||
_pluginConfiguration.CustomServerList.Remove(_pluginConfiguration.ApiUri);
|
||||
_pluginConfiguration.ApiUri = _apiController.ServerDictionary.First().Key;
|
||||
_pluginConfiguration.Save();
|
||||
_serverConfigurationManager.SelectServer(_serverSelectionIndex);
|
||||
_ = _apiController.CreateConnections();
|
||||
}
|
||||
ImGui.PopFont();
|
||||
}
|
||||
|
||||
if (ImGui.TreeNode("Add Custom Service"))
|
||||
{
|
||||
ImGui.SetNextItemWidth(250);
|
||||
ImGui.InputText("Custom Service Name", ref _customServerName, 255);
|
||||
ImGui.InputText("Custom Service URI", ref _customServerUri, 255);
|
||||
ImGui.SetNextItemWidth(250);
|
||||
ImGui.InputText("Custom Service Address", ref _customServerUri, 255);
|
||||
if (ImGui.Button("Add Custom Service"))
|
||||
ImGui.InputText("Custom Service Name", ref _customServerName, 255);
|
||||
if (UiShared.IconTextButton(FontAwesomeIcon.Plus, "Add Custom Service"))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_customServerUri)
|
||||
&& !string.IsNullOrEmpty(_customServerName)
|
||||
&& !_pluginConfiguration.CustomServerList.ContainsValue(_customServerName)
|
||||
&& !_pluginConfiguration.CustomServerList.ContainsKey(_customServerUri))
|
||||
&& !string.IsNullOrEmpty(_customServerName))
|
||||
{
|
||||
_pluginConfiguration.CustomServerList[_customServerUri] = _customServerName;
|
||||
_customServerUri = string.Empty;
|
||||
_serverConfigurationManager.AddServer(new ServerStorage()
|
||||
{
|
||||
ServerName = _customServerName,
|
||||
ServerUri = _customServerUri,
|
||||
});
|
||||
_customServerName = string.Empty;
|
||||
_pluginConfiguration.Save();
|
||||
_customServerUri = string.Empty;
|
||||
_configService.Save();
|
||||
}
|
||||
}
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
PrintServerState();
|
||||
|
||||
if (!_apiController.ServerAlive && (_pluginConfiguration.ClientSecret.ContainsKey(_pluginConfiguration.ApiUri) && !_pluginConfiguration.ClientSecret[_pluginConfiguration.ApiUri].IsNullOrEmpty()))
|
||||
{
|
||||
ColorTextWrapped("You already have an account on this server.", ImGuiColors.DalamudYellow);
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Connect##connectToService"))
|
||||
{
|
||||
_pluginConfiguration.FullPause = false;
|
||||
_pluginConfiguration.Save();
|
||||
Task.Run(() => _apiController.CreateConnections(true));
|
||||
}
|
||||
}
|
||||
|
||||
string checkboxText = _pluginConfiguration.ClientSecret.ContainsKey(_pluginConfiguration.ApiUri)
|
||||
? "I want to switch accounts"
|
||||
: "I have an account";
|
||||
ImGui.Checkbox(checkboxText, ref _enterSecretKey);
|
||||
|
||||
if (_enterSecretKey)
|
||||
{
|
||||
if (_pluginConfiguration.ClientSecret.ContainsKey(_pluginConfiguration.ApiUri))
|
||||
{
|
||||
ColorTextWrapped("A secret key was previously set for this service. Entering a new secret key will overwrite the one set prior.", ImGuiColors.DalamudYellow);
|
||||
}
|
||||
|
||||
var text = "Enter Secret Key";
|
||||
var buttonText = "Save";
|
||||
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.SameLine();
|
||||
ImGui.SetNextItemWidth(GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X - buttonWidth - textSize.X);
|
||||
ImGui.InputText("", ref _secretKey, 64);
|
||||
if (_secretKey.Length > 0 && _secretKey.Length != 64)
|
||||
{
|
||||
ColorTextWrapped("Your secret key must be exactly 64 characters long. Don't enter your Lodestone auth here.", ImGuiColors.DalamudRed);
|
||||
}
|
||||
else if (_secretKey.Length == 64)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button(buttonText))
|
||||
{
|
||||
_pluginConfiguration.ClientSecret[_pluginConfiguration.ApiUri] = _secretKey;
|
||||
_pluginConfiguration.Save();
|
||||
_secretKey = string.Empty;
|
||||
Task.Run(() => _apiController.CreateConnections(true));
|
||||
_enterSecretKey = false;
|
||||
callBackOnExit?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
return _serverSelectionIndex;
|
||||
}
|
||||
|
||||
private string _secretKey = "";
|
||||
|
||||
public static void OutlineTextWrapped(string text, Vector4 textcolor, Vector4 outlineColor, float dist = 3)
|
||||
{
|
||||
var cursorPos = ImGui.GetCursorPos();
|
||||
UiShared.ColorTextWrapped(text, outlineColor);
|
||||
ColorTextWrapped(text, outlineColor);
|
||||
ImGui.SetCursorPos(new(cursorPos.X, cursorPos.Y + dist));
|
||||
UiShared.ColorTextWrapped(text, outlineColor);
|
||||
ColorTextWrapped(text, outlineColor);
|
||||
ImGui.SetCursorPos(new(cursorPos.X + dist, cursorPos.Y));
|
||||
UiShared.ColorTextWrapped(text, outlineColor);
|
||||
ColorTextWrapped(text, outlineColor);
|
||||
ImGui.SetCursorPos(new(cursorPos.X + dist, cursorPos.Y + dist));
|
||||
UiShared.ColorTextWrapped(text, outlineColor);
|
||||
ColorTextWrapped(text, outlineColor);
|
||||
|
||||
ImGui.SetCursorPos(new(cursorPos.X + dist / 2, cursorPos.Y + dist / 2));
|
||||
UiShared.ColorTextWrapped(text, textcolor);
|
||||
ColorTextWrapped(text, textcolor);
|
||||
ImGui.SetCursorPos(new(cursorPos.X + dist / 2, cursorPos.Y + dist / 2));
|
||||
UiShared.ColorTextWrapped(text, textcolor);
|
||||
ColorTextWrapped(text, textcolor);
|
||||
}
|
||||
|
||||
public static void DrawHelpText(string helpText)
|
||||
@@ -507,7 +466,7 @@ public class UiShared : IDisposable
|
||||
public void DrawCacheDirectorySetting()
|
||||
{
|
||||
ColorTextWrapped("Note: The storage folder should be somewhere close to root (i.e. C:\\MareStorage) in a new empty folder. DO NOT point this to your game folder. DO NOT point this to your Penumbra folder.", ImGuiColors.DalamudYellow);
|
||||
var cacheDirectory = _pluginConfiguration.CacheFolder;
|
||||
var cacheDirectory = _configService.Current.CacheFolder;
|
||||
ImGui.InputText("Storage Folder##cache", ref cacheDirectory, 255, ImGuiInputTextFlags.ReadOnly);
|
||||
|
||||
ImGui.SameLine();
|
||||
@@ -531,8 +490,8 @@ public class UiShared : IDisposable
|
||||
&& !_cacheDirectoryHasOtherFilesThanCache
|
||||
&& _cacheDirectoryIsValidPath)
|
||||
{
|
||||
_pluginConfiguration.CacheFolder = path;
|
||||
_pluginConfiguration.Save();
|
||||
_configService.Current.CacheFolder = path;
|
||||
_configService.Save();
|
||||
_cacheScanner.StartScan();
|
||||
}
|
||||
});
|
||||
@@ -557,11 +516,11 @@ public class UiShared : IDisposable
|
||||
"Restrict yourself to latin letters (A-Z), underscores (_), dashes (-) and arabic numbers (0-9).", ImGuiColors.DalamudRed);
|
||||
}
|
||||
|
||||
float maxCacheSize = (float)_pluginConfiguration.MaxLocalCacheInGiB;
|
||||
float maxCacheSize = (float)_configService.Current.MaxLocalCacheInGiB;
|
||||
if (ImGui.SliderFloat("Maximum Storage Size in GiB", ref maxCacheSize, 1f, 200f, "%.2f GiB"))
|
||||
{
|
||||
_pluginConfiguration.MaxLocalCacheInGiB = maxCacheSize;
|
||||
_pluginConfiguration.Save();
|
||||
_configService.Current.MaxLocalCacheInGiB = maxCacheSize;
|
||||
_configService.Save();
|
||||
}
|
||||
DrawHelpText("The storage is automatically governed by Mare. It will clear itself automatically once it reaches the set capacity by removing the oldest unused files. You typically do not need to clear it yourself.");
|
||||
}
|
||||
@@ -569,19 +528,17 @@ public class UiShared : IDisposable
|
||||
private bool _isDirectoryWritable = false;
|
||||
private bool _isPenumbraDirectory = false;
|
||||
|
||||
public bool IsDirectoryWritable(string dirPath, bool throwIfFails = false)
|
||||
public static bool IsDirectoryWritable(string dirPath, bool throwIfFails = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream fs = File.Create(
|
||||
using FileStream fs = File.Create(
|
||||
Path.Combine(
|
||||
dirPath,
|
||||
Path.GetRandomFileName()
|
||||
),
|
||||
1,
|
||||
FileOptions.DeleteOnClose)
|
||||
)
|
||||
{ }
|
||||
FileOptions.DeleteOnClose);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
@@ -595,23 +552,23 @@ public class UiShared : IDisposable
|
||||
|
||||
public void RecalculateFileCacheSize()
|
||||
{
|
||||
_cacheScanner.InvokeScan(true);
|
||||
_cacheScanner.InvokeScan(forced: true);
|
||||
}
|
||||
|
||||
public void DrawTimeSpanBetweenScansSetting()
|
||||
{
|
||||
var timeSpan = _pluginConfiguration.TimeSpanBetweenScansInSeconds;
|
||||
var timeSpan = _configService.Current.TimeSpanBetweenScansInSeconds;
|
||||
if (ImGui.SliderInt("Seconds between scans##timespan", ref timeSpan, 20, 60))
|
||||
{
|
||||
_pluginConfiguration.TimeSpanBetweenScansInSeconds = timeSpan;
|
||||
_pluginConfiguration.Save();
|
||||
_configService.Current.TimeSpanBetweenScansInSeconds = timeSpan;
|
||||
_configService.Save();
|
||||
}
|
||||
DrawHelpText("This is the time in seconds between file scans. Increase it to reduce system load. A too high setting can cause issues when manually fumbling about in the cache or Penumbra mods folders.");
|
||||
var isPaused = _pluginConfiguration.FileScanPaused;
|
||||
var isPaused = _configService.Current.FileScanPaused;
|
||||
if (ImGui.Checkbox("Pause periodic file scan##filescanpause", ref isPaused))
|
||||
{
|
||||
_pluginConfiguration.FileScanPaused = isPaused;
|
||||
_pluginConfiguration.Save();
|
||||
_configService.Current.FileScanPaused = isPaused;
|
||||
_configService.Save();
|
||||
}
|
||||
DrawHelpText("This allows you to stop the periodic scans of your Penumbra and Mare cache directories. Use this to move the Mare cache and Penumbra mod folders around. If you enable this permanently, run a Force rescan after adding mods to Penumbra.");
|
||||
}
|
||||
@@ -653,24 +610,21 @@ public class UiShared : IDisposable
|
||||
return buttonClicked;
|
||||
}
|
||||
|
||||
private const string NotesStart = "##MARE_SYNCHRONOS_USER_NOTES_START##";
|
||||
private const string NotesEnd = "##MARE_SYNCHRONOS_USER_NOTES_END##";
|
||||
private const string _notesStart = "##MARE_SYNCHRONOS_USER_NOTES_START##";
|
||||
private const string _notesEnd = "##MARE_SYNCHRONOS_USER_NOTES_END##";
|
||||
|
||||
public string GetNotes(string? gid = null)
|
||||
public static string GetNotes(List<Pair> pairs)
|
||||
{
|
||||
var comments = _pluginConfiguration.GetCurrentServerUidComments();
|
||||
StringBuilder sb = new();
|
||||
sb.AppendLine(NotesStart);
|
||||
foreach (var userEntry in comments.Where(c => !string.IsNullOrEmpty(c.Key)))
|
||||
sb.AppendLine(_notesStart);
|
||||
foreach (var entry in pairs)
|
||||
{
|
||||
if (gid != null)
|
||||
{
|
||||
if (!ApiController.GroupPairedClients.Any(p => string.Equals(p.GroupGID, gid, StringComparison.Ordinal) && string.Equals(p.UserUID, userEntry.Key, StringComparison.Ordinal))) continue;
|
||||
}
|
||||
var note = entry.GetNote();
|
||||
if (note.IsNullOrEmpty()) continue;
|
||||
|
||||
sb.AppendLine(userEntry.Key + ":\"" + userEntry.Value + "\"");
|
||||
sb.AppendLine(entry.UserData.UID + ":\"" + entry.GetNote() + "\"");
|
||||
}
|
||||
sb.AppendLine(NotesEnd);
|
||||
sb.AppendLine(_notesEnd);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
@@ -680,14 +634,14 @@ public class UiShared : IDisposable
|
||||
var splitNotes = notes.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
var splitNotesStart = splitNotes.FirstOrDefault();
|
||||
var splitNotesEnd = splitNotes.LastOrDefault();
|
||||
if (!string.Equals(splitNotesStart, NotesStart) || !string.Equals(splitNotesEnd, NotesEnd))
|
||||
if (!string.Equals(splitNotesStart, _notesStart) || !string.Equals(splitNotesEnd, _notesEnd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
splitNotes.RemoveAll(n => string.Equals(n, NotesStart) || string.Equals(n, NotesEnd));
|
||||
splitNotes.RemoveAll(n => string.Equals(n, _notesStart) || string.Equals(n, _notesEnd));
|
||||
|
||||
var comments = _pluginConfiguration.GetCurrentServerUidComments();
|
||||
var comments = _serverConfigurationManager.CurrentServer!.UidServerComments;
|
||||
|
||||
foreach (var note in splitNotes)
|
||||
{
|
||||
@@ -697,7 +651,7 @@ public class UiShared : IDisposable
|
||||
var uid = splittedEntry[0];
|
||||
var comment = splittedEntry[1].Trim('"');
|
||||
if (comments.ContainsKey(uid) && !overwrite) continue;
|
||||
_pluginConfiguration.SetCurrentServerUidComment(uid, comment);
|
||||
_serverConfigurationManager.CurrentServer.UidServerComments[uid] = comment;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -705,7 +659,7 @@ public class UiShared : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
_pluginConfiguration.Save();
|
||||
_serverConfigurationManager.Save();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -713,7 +667,7 @@ public class UiShared : IDisposable
|
||||
public void Dispose()
|
||||
{
|
||||
_pluginInterface.UiBuilder.BuildFonts -= BuildFont;
|
||||
_dalamudUtil.GposeStart -= _dalamudUtil_GposeStart;
|
||||
_dalamudUtil.GposeEnd -= _dalamudUtil_GposeEnd;
|
||||
_dalamudUtil.GposeStart -= DalamudUtil_GposeStart;
|
||||
_dalamudUtil.GposeEnd -= DalamudUtil_GposeEnd;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user