 14575a4a6b
			
		
	
	14575a4a6b
	
	
	
		
			
			* add jwt expiry * start of 0.9 api impl * some stuff idk * some more impl * some cleanup * remove grouppair, add configuration, rework some pair drawing stuff * do some stuff * rework some ui * I don't even know anymore * add cancellationtoken * token bla * ui fixes etc * probably individual adding/removing now working fully as expected * add working report popup * I guess it's more syncshell shit or so * popup shit idk * work out most of the syncshell bullshit I guess * delete some old crap * are we actually getting closer to the end * update pair info stuff * more fixes/adjustments, idk * refactor some things * some rework * some more cleanup * cleanup * make menu buttons w i d e * better icon text buttons * add all syncshell folder and ordering fixes --------- Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com>
		
			
				
	
	
		
			234 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Dalamud.Interface;
 | |
| using Dalamud.Interface.Colors;
 | |
| using Dalamud.Interface.Utility.Raii;
 | |
| using ImGuiNET;
 | |
| using MareSynchronos.API.Data.Extensions;
 | |
| using MareSynchronos.API.Dto.Group;
 | |
| using MareSynchronos.PlayerData.Pairs;
 | |
| using MareSynchronos.WebAPI;
 | |
| using System.Globalization;
 | |
| using System.Numerics;
 | |
| 
 | |
| namespace MareSynchronos.UI.Components.Popup;
 | |
| 
 | |
| internal class SyncshellAdminPopupHandler : IPopupHandler
 | |
| {
 | |
|     private readonly ApiController _apiController;
 | |
|     private readonly List<string> _oneTimeInvites = [];
 | |
|     private readonly PairManager _pairManager;
 | |
|     private readonly UiSharedService _uiSharedService;
 | |
|     private List<BannedGroupUserDto> _bannedUsers = [];
 | |
|     private GroupFullInfoDto _groupFullInfo = null!;
 | |
|     private bool _isModerator = false;
 | |
|     private bool _isOwner = false;
 | |
|     private int _multiInvites = 30;
 | |
|     private string _newPassword = string.Empty;
 | |
|     private bool _pwChangeSuccess = true;
 | |
| 
 | |
|     public SyncshellAdminPopupHandler(ApiController apiController, UiSharedService uiSharedService, PairManager pairManager)
 | |
|     {
 | |
|         _apiController = apiController;
 | |
|         _uiSharedService = uiSharedService;
 | |
|         _pairManager = pairManager;
 | |
|     }
 | |
| 
 | |
|     public Vector2 PopupSize => new(700, 500);
 | |
| 
 | |
|     public void DrawContent()
 | |
|     {
 | |
|         if (!_isModerator && !_isOwner) return;
 | |
| 
 | |
|         _groupFullInfo = _pairManager.Groups[_groupFullInfo.Group];
 | |
| 
 | |
|         using (ImRaii.PushFont(_uiSharedService.UidFont))
 | |
|             ImGui.TextUnformatted(_groupFullInfo.GroupAliasOrGID + " Administrative Panel");
 | |
| 
 | |
|         ImGui.Separator();
 | |
|         var perm = _groupFullInfo.GroupPermissions;
 | |
| 
 | |
|         var inviteNode = ImRaii.TreeNode("Invites");
 | |
|         if (inviteNode)
 | |
|         {
 | |
|             bool isInvitesDisabled = perm.IsDisableInvites();
 | |
| 
 | |
|             if (UiSharedService.IconTextButton(isInvitesDisabled ? FontAwesomeIcon.Unlock : FontAwesomeIcon.Lock,
 | |
|                 isInvitesDisabled ? "Unlock Syncshell" : "Lock Syncshell"))
 | |
|             {
 | |
|                 perm.SetDisableInvites(!isInvitesDisabled);
 | |
|                 _ = _apiController.GroupChangeGroupPermissionState(new(_groupFullInfo.Group, perm));
 | |
|             }
 | |
| 
 | |
|             ImGui.Dummy(new(2f));
 | |
| 
 | |
|             UiSharedService.TextWrapped("One-time invites work as single-use passwords. Use those if you do not want to distribute your Syncshell password.");
 | |
|             if (UiSharedService.IconTextButton(FontAwesomeIcon.Envelope, "Single one-time invite"))
 | |
|             {
 | |
|                 ImGui.SetClipboardText(_apiController.GroupCreateTempInvite(new(_groupFullInfo.Group), 1).Result.FirstOrDefault() ?? string.Empty);
 | |
|             }
 | |
|             UiSharedService.AttachToolTip("Creates a single-use password for joining the syncshell which is valid for 24h and copies it to the clipboard.");
 | |
|             ImGui.InputInt("##amountofinvites", ref _multiInvites);
 | |
|             ImGui.SameLine();
 | |
|             using (ImRaii.Disabled(_multiInvites <= 1 || _multiInvites > 100))
 | |
|             {
 | |
|                 if (UiSharedService.IconTextButton(FontAwesomeIcon.Envelope, "Generate " + _multiInvites + " one-time invites"))
 | |
|                 {
 | |
|                     _oneTimeInvites.AddRange(_apiController.GroupCreateTempInvite(new(_groupFullInfo.Group), _multiInvites).Result);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (_oneTimeInvites.Any())
 | |
|             {
 | |
|                 var invites = string.Join(Environment.NewLine, _oneTimeInvites);
 | |
|                 ImGui.InputTextMultiline("Generated Multi Invites", ref invites, 5000, new(0, 0), ImGuiInputTextFlags.ReadOnly);
 | |
|                 if (UiSharedService.IconTextButton(FontAwesomeIcon.Copy, "Copy Invites to clipboard"))
 | |
|                 {
 | |
|                     ImGui.SetClipboardText(invites);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         inviteNode.Dispose();
 | |
| 
 | |
|         var mgmtNode = ImRaii.TreeNode("User Management");
 | |
|         if (mgmtNode)
 | |
|         {
 | |
|             if (UiSharedService.IconTextButton(FontAwesomeIcon.Broom, "Clear Syncshell"))
 | |
|             {
 | |
|                 _ = _apiController.GroupClear(new(_groupFullInfo.Group));
 | |
|             }
 | |
|             UiSharedService.AttachToolTip("This will remove all non-pinned, non-moderator users from the Syncshell");
 | |
| 
 | |
|             ImGui.Dummy(new(2f));
 | |
| 
 | |
|             if (UiSharedService.IconTextButton(FontAwesomeIcon.Retweet, "Refresh Banlist from Server"))
 | |
|             {
 | |
|                 _bannedUsers = _apiController.GroupGetBannedUsers(new GroupDto(_groupFullInfo.Group)).Result;
 | |
|             }
 | |
| 
 | |
|             if (ImGui.BeginTable("bannedusertable" + _groupFullInfo.GID, 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingStretchProp | ImGuiTableFlags.ScrollY))
 | |
|             {
 | |
|                 ImGui.TableSetupColumn("UID", ImGuiTableColumnFlags.None, 1);
 | |
|                 ImGui.TableSetupColumn("Alias", ImGuiTableColumnFlags.None, 1);
 | |
|                 ImGui.TableSetupColumn("By", ImGuiTableColumnFlags.None, 1);
 | |
|                 ImGui.TableSetupColumn("Date", ImGuiTableColumnFlags.None, 2);
 | |
|                 ImGui.TableSetupColumn("Reason", ImGuiTableColumnFlags.None, 3);
 | |
|                 ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.None, 1);
 | |
| 
 | |
|                 ImGui.TableHeadersRow();
 | |
| 
 | |
|                 foreach (var bannedUser in _bannedUsers.ToList())
 | |
|                 {
 | |
|                     ImGui.TableNextColumn();
 | |
|                     ImGui.TextUnformatted(bannedUser.UID);
 | |
|                     ImGui.TableNextColumn();
 | |
|                     ImGui.TextUnformatted(bannedUser.UserAlias ?? string.Empty);
 | |
|                     ImGui.TableNextColumn();
 | |
|                     ImGui.TextUnformatted(bannedUser.BannedBy);
 | |
|                     ImGui.TableNextColumn();
 | |
|                     ImGui.TextUnformatted(bannedUser.BannedOn.ToLocalTime().ToString(CultureInfo.CurrentCulture));
 | |
|                     ImGui.TableNextColumn();
 | |
|                     UiSharedService.TextWrapped(bannedUser.Reason);
 | |
|                     ImGui.TableNextColumn();
 | |
|                     if (UiSharedService.IconTextButton(FontAwesomeIcon.Check, "Unban#" + bannedUser.UID))
 | |
|                     {
 | |
|                         _ = _apiController.GroupUnbanUser(bannedUser);
 | |
|                         _bannedUsers.RemoveAll(b => string.Equals(b.UID, bannedUser.UID, StringComparison.Ordinal));
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 ImGui.EndTable();
 | |
|             }
 | |
|         }
 | |
|         mgmtNode.Dispose();
 | |
| 
 | |
|         var permNode = ImRaii.TreeNode("Permissions");
 | |
|         if (permNode)
 | |
|         {
 | |
|             bool isDisableAnimations = perm.IsPreferDisableAnimations();
 | |
|             bool isDisableSounds = perm.IsPreferDisableSounds();
 | |
|             bool isDisableVfx = perm.IsPreferDisableVFX();
 | |
| 
 | |
|             ImGui.AlignTextToFramePadding();
 | |
|             ImGui.Text("Suggest Sound Sync");
 | |
|             UiSharedService.BooleanToColoredIcon(!isDisableSounds);
 | |
|             ImGui.SameLine(230);
 | |
|             if (UiSharedService.IconTextButton(isDisableSounds ? FontAwesomeIcon.VolumeUp : FontAwesomeIcon.VolumeMute,
 | |
|                 isDisableSounds ? "Suggest to enable sound sync" : "Suggest to disable sound sync"))
 | |
|             {
 | |
|                 perm.SetPreferDisableSounds(!perm.IsPreferDisableSounds());
 | |
|                 _ = _apiController.GroupChangeGroupPermissionState(new(_groupFullInfo.Group, perm));
 | |
|             }
 | |
| 
 | |
|             ImGui.AlignTextToFramePadding();
 | |
|             ImGui.Text("Suggest Animation Sync");
 | |
|             UiSharedService.BooleanToColoredIcon(!isDisableAnimations);
 | |
|             ImGui.SameLine(230);
 | |
|             if (UiSharedService.IconTextButton(isDisableAnimations ? FontAwesomeIcon.Running : FontAwesomeIcon.Stop,
 | |
|                 isDisableAnimations ? "Suggest to enable animation sync" : "Suggest to disable animation sync"))
 | |
|             {
 | |
|                 perm.SetPreferDisableAnimations(!perm.IsPreferDisableAnimations());
 | |
|                 _ = _apiController.GroupChangeGroupPermissionState(new(_groupFullInfo.Group, perm));
 | |
|             }
 | |
| 
 | |
|             ImGui.AlignTextToFramePadding();
 | |
|             ImGui.Text("Suggest VFX Sync");
 | |
|             UiSharedService.BooleanToColoredIcon(!isDisableVfx);
 | |
|             ImGui.SameLine(230);
 | |
|             if (UiSharedService.IconTextButton(isDisableVfx ? FontAwesomeIcon.Sun : FontAwesomeIcon.Circle,
 | |
|                 isDisableVfx ? "Suggest to enable vfx sync" : "Suggest to disable vfx sync"))
 | |
|             {
 | |
|                 perm.SetPreferDisableVFX(!perm.IsPreferDisableVFX());
 | |
|                 _ = _apiController.GroupChangeGroupPermissionState(new(_groupFullInfo.Group, perm));
 | |
|             }
 | |
| 
 | |
|             UiSharedService.TextWrapped("Note: those suggested permissions will be shown to users on joining the Syncshell.");
 | |
|         }
 | |
|         permNode.Dispose();
 | |
| 
 | |
|         if (_isOwner)
 | |
|         {
 | |
|             var ownerNode = ImRaii.TreeNode("Owner Settings");
 | |
|             if (ownerNode)
 | |
|             {
 | |
|                 ImGui.AlignTextToFramePadding();
 | |
|                 ImGui.TextUnformatted("New Password");
 | |
|                 ImGui.SameLine();
 | |
|                 ImGui.InputTextWithHint("##changepw", "Min 10 characters", ref _newPassword, 50);
 | |
|                 ImGui.SameLine();
 | |
|                 using (ImRaii.Disabled(_newPassword.Length < 10))
 | |
|                 {
 | |
|                     if (UiSharedService.IconTextButton(FontAwesomeIcon.Passport, "Change Password"))
 | |
|                     {
 | |
|                         _pwChangeSuccess = _apiController.GroupChangePassword(new GroupPasswordDto(_groupFullInfo.Group, _newPassword)).Result;
 | |
|                         _newPassword = string.Empty;
 | |
|                     }
 | |
|                 }
 | |
|                 UiSharedService.AttachToolTip("Password requires to be at least 10 characters long. This action is irreversible.");
 | |
| 
 | |
|                 if (!_pwChangeSuccess)
 | |
|                 {
 | |
|                     UiSharedService.ColorTextWrapped("Failed to change the password. Password requires to be at least 10 characters long.", ImGuiColors.DalamudYellow);
 | |
|                 }
 | |
| 
 | |
|                 if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Delete Syncshell") && UiSharedService.CtrlPressed() && UiSharedService.ShiftPressed())
 | |
|                 {
 | |
|                     ImGui.CloseCurrentPopup();
 | |
|                     _ = _apiController.GroupDelete(new(_groupFullInfo.Group));
 | |
|                 }
 | |
|                 UiSharedService.AttachToolTip("Hold CTRL and Shift and click to delete this Syncshell." + Environment.NewLine + "WARNING: this action is irreversible.");
 | |
|             }
 | |
|             ownerNode.Dispose();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public void Open(GroupFullInfoDto groupFullInfo)
 | |
|     {
 | |
|         _groupFullInfo = groupFullInfo;
 | |
|         _isOwner = string.Equals(_groupFullInfo.OwnerUID, _apiController.UID, StringComparison.Ordinal);
 | |
|         _isModerator = _groupFullInfo.GroupUserInfo.IsModerator();
 | |
|         _newPassword = string.Empty;
 | |
|         _bannedUsers.Clear();
 | |
|         _oneTimeInvites.Clear();
 | |
|         _multiInvites = 30;
 | |
|         _pwChangeSuccess = true;
 | |
|     }
 | |
| } |