add banned user table, add privacy tab and notes copy/import functionality

This commit is contained in:
Stanley Dimant
2022-10-06 21:43:03 +02:00
parent 3fe6d430e3
commit 58ad7153d3
4 changed files with 183 additions and 35 deletions

View File

@@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Globalization;
namespace MareSynchronos.UI
{
@@ -30,6 +31,7 @@ namespace MareSynchronos.UI
private bool _showModalCreateGroup;
private bool _showModalChangePassword;
private bool _showModalBanUser;
private bool _showModalBanList;
private string _newSyncShellPassword = string.Empty;
private string _banReason = string.Empty;
private bool _isPasswordValid;
@@ -37,6 +39,7 @@ namespace MareSynchronos.UI
private bool _errorGroupCreate = false;
private GroupCreatedDto? _lastCreatedGroup = null;
private readonly Dictionary<string, bool> ExpandedGroupState = new(StringComparer.Ordinal);
private List<BannedGroupUserDto> _bannedUsers = new();
public GroupPanel(CompactUi mainUi, UiShared uiShared, Configuration configuration, ApiController apiController)
{
@@ -282,6 +285,7 @@ namespace MareSynchronos.UI
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));
@@ -330,23 +334,11 @@ namespace MareSynchronos.UI
}
UiShared.AttachToolTip("Copy Syncshell ID to Clipboard");
if (UiShared.IconTextButton(FontAwesomeIcon.UserSecret, "Copy Notes"))
if (UiShared.IconTextButton(FontAwesomeIcon.StickyNote, "Copy Notes"))
{
var entries = _apiController.GroupPairedClients.Where(p => string.Equals(p.GroupGID, entry.GID, StringComparison.Ordinal));
var comments = _configuration.GetCurrentServerUidComments();
StringBuilder sb = new();
sb.AppendLine("##MARE_SYNCHRONOS_USER_NOTES_START##");
foreach (var userEntry in entries)
{
if (comments.TryGetValue(userEntry.UserUID, out var comment))
{
sb.AppendLine(userEntry.UserUID + ":\"" + comment + "\"");
}
}
sb.AppendLine("##MARE_SYNCHRONOS_USER_NOTES_END##");
ImGui.SetClipboardText(sb.ToString());
ImGui.SetClipboardText(_uiShared.GetNotes(entry.GID));
}
UiShared.AttachToolTip("Copies all your notes for all users in this Syncshell to the clipboard");
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))
{
@@ -402,7 +394,51 @@ namespace MareSynchronos.UI
if (UiShared.IconTextButton(FontAwesomeIcon.Ban, "Manage Banlist"))
{
// todo: show banlist
_showModalBanList = true;
_bannedUsers = new();
ImGui.OpenPopup("Manage Banlist for " + entry.GID);
}
if (ImGui.BeginPopupModal("Manage Banlist for " + entry.GID, ref _showModalBanList))
{
ImGui.SetWindowSize(new Vector2(700, 300));
if (UiShared.IconTextButton(FontAwesomeIcon.Retweet, "Refresh Banlist from Server"))
{
_bannedUsers = _apiController.GetBannedUsersForGroup(entry.GID).Result;
}
if (ImGui.BeginTable("bannedusertable" + entry.GID, 5, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingStretchProp))
{
ImGui.TableSetupColumn("UID", ImGuiTableColumnFlags.None, 1);
ImGui.TableSetupColumn("By", ImGuiTableColumnFlags.None, 1);
ImGui.TableSetupColumn("Date", ImGuiTableColumnFlags.None, 2);
ImGui.TableSetupColumn("Reason", ImGuiTableColumnFlags.None, 3);
ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.None, 1);
ImGui.TableHeadersRow();
foreach (var bannedUser in _bannedUsers.ToList())
{
ImGui.TableNextColumn();
ImGui.TextUnformatted(bannedUser.UID);
ImGui.TableNextColumn();
ImGui.TextUnformatted(bannedUser.BannedBy);
ImGui.TableNextColumn();
ImGui.TextUnformatted(bannedUser.BannedOn.ToLocalTime().ToString(CultureInfo.CurrentCulture));
ImGui.TableNextColumn();
UiShared.TextWrapped(bannedUser.Reason);
ImGui.TableNextColumn();
if (UiShared.IconTextButton(FontAwesomeIcon.Check, "Unban"))
{
_ = _apiController.UnbanUserFromGroup(entry.GID, bannedUser.UID);
_bannedUsers.RemoveAll(b => string.Equals(b.UID, bannedUser.UID, StringComparison.Ordinal));
}
ImGui.TableNextColumn();
}
ImGui.EndTable();
}
ImGui.EndPopup();
}
if (isOwner)
@@ -422,7 +458,7 @@ namespace MareSynchronos.UI
}
}
private void DrawSyncshellPairedClient(GroupPairDto entry, bool isOwner, bool isModerator, bool isPausedByYou)
private void DrawSyncshellPairedClient(GroupPairDto entry, string ownerUid, bool isOwner, bool isModerator, bool isPausedByYou)
{
var plusButtonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Plus);
var barButtonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Bars);
@@ -579,27 +615,34 @@ namespace MareSynchronos.UI
_ = _apiController.SendRemoveUserFromGroup(entry.GroupGID, entry.UserUID);
}
}
UiShared.AttachToolTip("Hold CTRL and click to remove user " + (entry.UserAlias ?? entry.UserUID) + " from Syncshell");
if (UiShared.IconTextButton(FontAwesomeIcon.UserSlash, "Ban User"))
{
_showModalBanUser = true;
ImGui.OpenPopup("Ban User");
}
UiShared.AttachToolTip("Ban user from this Syncshell");
if (ImGui.BeginPopupModal("Ban User", ref _showModalBanUser))
var userIsMod = string.Equals(entry.UserUID, ownerUid, StringComparison.Ordinal);
var userIsOwner = string.Equals(entry.UserAlias, ownerUid, StringComparison.Ordinal);
if ((!entry.IsModerator ?? false) && !(userIsMod || userIsOwner))
{
ImGui.SetWindowSize(new Vector2(300, 200));
UiShared.TextWrapped("User " + (entry.UserAlias ?? entry.UserUID) + " will be banned and removed from this Syncshell.");
ImGui.InputTextWithHint("##banreason", "Ban Reason", ref _banReason, 255);
if (ImGui.Button("Ban User"))
UiShared.AttachToolTip("Hold CTRL and click to remove user " + (entry.UserAlias ?? entry.UserUID) + " from Syncshell");
if (UiShared.IconTextButton(FontAwesomeIcon.UserSlash, "Ban User"))
{
var reason = _banReason;
_ = _apiController.BanUserFromGroup(entry.GroupGID, entry.UserUID, reason);
_banReason = string.Empty;
_showModalBanUser = true;
ImGui.OpenPopup("Ban User");
}
UiShared.AttachToolTip("Ban user from this Syncshell");
if (ImGui.BeginPopupModal("Ban User", ref _showModalBanUser))
{
ImGui.SetWindowSize(new Vector2(300, 200));
UiShared.TextWrapped("User " + (entry.UserAlias ?? entry.UserUID) + " will be banned and removed from this Syncshell.");
ImGui.InputTextWithHint("##banreason", "Ban Reason", ref _banReason, 255);
if (ImGui.Button("Ban User"))
{
var reason = _banReason;
_ = _apiController.BanUserFromGroup(entry.GroupGID, entry.UserUID, 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.");
ImGui.EndPopup();
}
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.");
ImGui.EndPopup();
}
if (isOwner)

View File

@@ -24,6 +24,9 @@ public class SettingsUi : Window, IDisposable
private readonly ApiController _apiController;
private readonly UiShared _uiShared;
public event SwitchUi? SwitchToIntroUi;
private bool _overwriteExistingLabels = false;
private bool? _notesSuccessfullyApplied = null;
private string _lastTab = string.Empty;
public SettingsUi(WindowSystem windowSystem,
UiShared uiShared, Configuration configuration, ApiController apiController) : base("Mare Synchronos Settings")
@@ -97,6 +100,12 @@ public class SettingsUi : Window, IDisposable
ImGui.EndTabItem();
}
if (ImGui.BeginTabItem("Privacy"))
{
DrawPrivacy();
ImGui.EndTabItem();
}
if (_apiController.IsConnected && _apiController.IsModerator)
{
if (ImGui.BeginTabItem("Administration"))
@@ -115,8 +124,43 @@ public class SettingsUi : Window, IDisposable
private string _bannedUserHashEntry = string.Empty;
private string _bannedUserReasonEntry = string.Empty;
private void DrawPrivacy()
{
if (!string.Equals(_lastTab, "Privacy", StringComparison.OrdinalIgnoreCase))
{
_notesSuccessfullyApplied = null;
}
_lastTab = "Privacy";
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);
}
}
private void DrawAdministration()
{
_lastTab = "Administration";
if (ImGui.TreeNode("Forbidden Files Changes"))
{
if (ImGui.BeginTable("ForbiddenFilesTable", 3, ImGuiTableFlags.RowBg))
@@ -370,6 +414,7 @@ public class SettingsUi : Window, IDisposable
private void DrawUserAdministration(bool serverAlive)
{
_lastTab = "UserAdministration";
if (serverAlive)
{
if (ImGui.Button("Delete all my files"))
@@ -472,6 +517,7 @@ public class SettingsUi : Window, IDisposable
private void DrawBlockedTransfers()
{
_lastTab = "BlockedTransfers";
UiShared.ColorTextWrapped("Files that you attempted to upload or download that were forbidden to be transferred by their creators will appear here. " +
"If you see file paths from your drive here, then those files were not allowed to be uploaded. If you see hashes, those files were not allowed to be downloaded. " +
"Ask your paired friend to send you the mod in question through other means, acquire the mod yourself or pester the mod creator to allow it to be sent over Mare.",
@@ -505,6 +551,7 @@ public class SettingsUi : Window, IDisposable
private void DrawCurrentTransfers()
{
_lastTab = "Transfers";
bool showTransferWindow = _configuration.ShowTransferWindow;
if (ImGui.Checkbox("Show separate Transfer window while transfers are active", ref showTransferWindow))
{
@@ -585,6 +632,7 @@ public class SettingsUi : Window, IDisposable
private void DrawFileCacheSettings()
{
_lastTab = "FileCache";
_uiShared.DrawFileScanState();
_uiShared.DrawTimeSpanBetweenScansSetting();
_uiShared.DrawCacheDirectorySetting();

View File

@@ -589,6 +589,63 @@ public class UiShared : IDisposable
return buttonClicked;
}
private const string NotesStart = "##MARE_SYNCHRONOS_USER_NOTES_START##";
private const string NotesEnd = "##MARE_SYNCHRONOS_USER_NOTES_END##";
public string GetNotes(string? gid = null)
{
var comments = _pluginConfiguration.GetCurrentServerUidComments();
StringBuilder sb = new();
sb.AppendLine(NotesStart);
foreach (var userEntry in comments.Where(c => !string.IsNullOrEmpty(c.Key)))
{
if (gid != null)
{
if (!ApiController.GroupPairedClients.Any(p => string.Equals(p.GroupGID, gid, StringComparison.Ordinal) && string.Equals(p.UserUID, userEntry.Key, StringComparison.Ordinal))) continue;
}
sb.AppendLine(userEntry.Key + ":\"" + userEntry.Value + "\"");
}
sb.AppendLine(NotesEnd);
return sb.ToString();
}
public bool ApplyNotesFromClipboard(string notes, bool overwrite)
{
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))
{
return false;
}
splitNotes.RemoveAll(n => string.Equals(n, NotesStart) || string.Equals(n, NotesEnd));
var comments = _pluginConfiguration.GetCurrentServerUidComments();
foreach (var note in splitNotes)
{
try
{
var splittedEntry = note.Split(":", 2, StringSplitOptions.RemoveEmptyEntries);
var uid = splittedEntry[0];
var comment = splittedEntry[1].Trim('"');
if (comments.ContainsKey(uid) && !overwrite) continue;
_pluginConfiguration.SetCurrentServerUidComment(uid, comment);
}
catch
{
Logger.Warn("Could not parse " + note);
}
}
_pluginConfiguration.Save();
return true;
}
public void Dispose()
{
_pluginInterface.UiBuilder.BuildFonts -= BuildFont;

View File

@@ -106,6 +106,6 @@ public partial class ApiController
public async Task SetModeratorForGroup(string gid, string uid, bool isModerator)
{
if (!IsConnected || string.Equals(SecretKey, "-", System.StringComparison.Ordinal)) return;
await _mareHub!.SendAsync(Api.SendAdminChangeModeratorStatus, gid, uid, isModerator).ConfigureAwait(false);
await _mareHub!.SendAsync(Api.SendGroupSetModerator, gid, uid, isModerator).ConfigureAwait(false);
}
}