using Dalamud.Bindings.ImGui; using Dalamud.Interface; using Dalamud.Interface.Utility.Raii; using LightlessSync.API.Data.Extensions; using LightlessSync.API.Dto.Group; using LightlessSync.UI.Handlers; using LightlessSync.UI.Models; using LightlessSync.WebAPI; using System.Collections.Immutable; using System.Numerics; namespace LightlessSync.UI.Components; public class DrawGroupedGroupFolder : IDrawFolder { private readonly string _tag; private readonly IEnumerable _groups; private readonly TagHandler _tagHandler; private readonly UiSharedService _uiSharedService; private readonly ApiController _apiController; private readonly SelectSyncshellForTagUi _selectSyncshellForTagUi; private readonly RenameSyncshellTagUi _renameSyncshellTagUi; private bool _wasHovered = false; private float _menuWidth; public IImmutableList DrawPairs => _groups.SelectMany(g => g.GroupDrawFolder.DrawPairs).ToImmutableList(); public int OnlinePairs => _groups.SelectMany(g => g.GroupDrawFolder.DrawPairs).Where(g => g.Pair.IsOnline).DistinctBy(g => g.Pair.UserData.UID).Count(); public int TotalPairs => _groups.Sum(g => g.GroupDrawFolder.TotalPairs); public DrawGroupedGroupFolder(IEnumerable groups, TagHandler tagHandler, ApiController apiController, UiSharedService uiSharedService, SelectSyncshellForTagUi selectSyncshellForTagUi, RenameSyncshellTagUi renameSyncshellTagUi, string tag) { _groups = groups; _tagHandler = tagHandler; _uiSharedService = uiSharedService; _selectSyncshellForTagUi = selectSyncshellForTagUi; _renameSyncshellTagUi = renameSyncshellTagUi; _tag = tag; _apiController = apiController; } public void Draw() { string _id = "__folder_syncshells"; if (_tag != "") { _id = $"__folder_{_tag}"; } using var id = ImRaii.PushId(_id); var color = ImRaii.PushColor(ImGuiCol.ChildBg, ImGui.GetColorU32(ImGuiCol.FrameBgHovered), _wasHovered); using (ImRaii.Child("folder__" + _id, new Vector2(UiSharedService.GetWindowContentRegionWidth() - ImGui.GetCursorPosX(), ImGui.GetFrameHeight()))) { ImGui.Dummy(new Vector2(0f, ImGui.GetFrameHeight())); using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(0f, 0f))) ImGui.SameLine(); var icon = _tagHandler.IsTagOpen(_id) ? FontAwesomeIcon.CaretDown : FontAwesomeIcon.CaretRight; ImGui.AlignTextToFramePadding(); _uiSharedService.IconText(icon); if (ImGui.IsItemClicked()) { _tagHandler.SetTagOpen(_id, !_tagHandler.IsTagOpen(_id)); } ImGui.SameLine(); ImGui.AlignTextToFramePadding(); if (_tag != "") { _uiSharedService.IconText(FontAwesomeIcon.FolderPlus); } else { _uiSharedService.IconText(FontAwesomeIcon.UsersRectangle); } using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing with { X = ImGui.GetStyle().ItemSpacing.X / 2f })) { ImGui.SameLine(); ImGui.AlignTextToFramePadding(); ImGui.TextUnformatted("[" + OnlinePairs.ToString() + "]"); } UiSharedService.AttachToolTip(OnlinePairs + " online in all of your joined syncshells" + Environment.NewLine + TotalPairs + " pairs combined in all of your joined syncshells"); ImGui.SameLine(); ImGui.AlignTextToFramePadding(); if (_tag != "") { ImGui.TextUnformatted(_tag); ImGui.SameLine(); DrawPauseButton(); ImGui.SameLine(); DrawMenu(); } else { ImGui.TextUnformatted("All Syncshells"); ImGui.SameLine(); DrawPauseButton(); } } color.Dispose(); _wasHovered = ImGui.IsItemHovered(); ImGui.Separator(); if (_tagHandler.IsTagOpen(_id)) { using var indent = ImRaii.PushIndent(20f); foreach (var entry in _groups) { entry.GroupDrawFolder.Draw(); } } } protected void DrawPauseButton() { if (DrawPairs.Count > 0) { var isPaused = _groups.Select(g => g.GroupFullInfo).All(g => g.GroupUserPermissions.IsPaused()); FontAwesomeIcon pauseIcon = isPaused ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause; var pauseButtonSize = _uiSharedService.GetIconButtonSize(pauseIcon); var windowEndX = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth(); if (_tag != "") { var spacingX = ImGui.GetStyle().ItemSpacing.X; var menuButtonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.EllipsisV); ImGui.SameLine(windowEndX - pauseButtonSize.X - menuButtonSize.X - spacingX); } else { ImGui.SameLine(windowEndX - pauseButtonSize.X); } if (_uiSharedService.IconButton(pauseIcon)) { ChangePauseStateGroups(); } } } protected void ChangePauseStateGroups() { foreach(var group in _groups) { var perm = group.GroupFullInfo.GroupUserPermissions; perm.SetPaused(!perm.IsPaused()); _ = _apiController.GroupChangeIndividualPermissionState(new GroupPairUserPermissionDto(group.GroupFullInfo.Group, new(_apiController.UID), perm)); } } protected void DrawMenu() { var barButtonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.EllipsisV); var windowEndX = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth(); ImGui.SameLine(windowEndX - barButtonSize.X); if (_uiSharedService.IconButton(FontAwesomeIcon.EllipsisV)) { ImGui.OpenPopup("User Flyout Menu"); } if (ImGui.BeginPopup("User Flyout Menu")) { using (ImRaii.PushId($"buttons-syncshell-{_tag}")) GroupMenu(_menuWidth); _menuWidth = ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X; ImGui.EndPopup(); } } protected void GroupMenu(float menuWidth) { ImGui.TextUnformatted("Syncshell Group Menu"); if (_uiSharedService.IconTextButton(FontAwesomeIcon.Users, "Select Syncshells", menuWidth, isInPopup: true)) { _selectSyncshellForTagUi.Open(_tag); } if (_uiSharedService.IconTextButton(FontAwesomeIcon.Edit, "Rename Syncshell Group", menuWidth, isInPopup: true)) { _renameSyncshellTagUi.Open(_tag); } if (_uiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Delete Syncshell Group", menuWidth, isInPopup: true) && UiSharedService.CtrlPressed()) { _tagHandler.RemoveSyncshellTag(_tag); } UiSharedService.AttachToolTip("Hold CTRL to remove this Group permanently."); } }