diff --git a/MareSynchronos/Services/Mediator/Messages.cs b/MareSynchronos/Services/Mediator/Messages.cs index 8f62bf1..03d2d3a 100644 --- a/MareSynchronos/Services/Mediator/Messages.cs +++ b/MareSynchronos/Services/Mediator/Messages.cs @@ -95,5 +95,6 @@ public record GPoseLobbyUserLeave(UserData UserData) : MessageBase; public record GPoseLobbyReceiveCharaData(CharaDataDownloadDto CharaDataDownloadDto) : MessageBase; public record GPoseLobbyReceivePoseData(UserData UserData, PoseData PoseData) : MessageBase; public record GPoseLobbyReceiveWorldData(UserData UserData, WorldData WorldData) : MessageBase; +public record OpenCharaDataHubWithFilterMessage(UserData UserData) : MessageBase; #pragma warning restore S2094 #pragma warning restore MA0048 // File name must match type name \ No newline at end of file diff --git a/MareSynchronos/UI/CharaDataHubUi.cs b/MareSynchronos/UI/CharaDataHubUi.cs index 0e2ab5f..16a306b 100644 --- a/MareSynchronos/UI/CharaDataHubUi.cs +++ b/MareSynchronos/UI/CharaDataHubUi.cs @@ -93,8 +93,17 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase _pairManager = pairManager; _charaDataGposeTogetherManager = charaDataGposeTogetherManager; Mediator.Subscribe(this, (_) => IsOpen |= _configService.Current.OpenMareHubOnGposeStart); + Mediator.Subscribe(this, (msg) => + { + IsOpen = true; + _openDataApplicationShared = true; + _sharedWithYouOwnerFilter = msg.UserData.AliasOrUID; + UpdateFilteredItems(); + }); } + private bool _openDataApplicationShared = false; + public string CharaName(string name) { if (_abbreviateCharaName) @@ -207,7 +216,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase } } - using (var applicationTabItem = ImRaii.TabItem("Data Application")) + using (var applicationTabItem = ImRaii.TabItem("Data Application", _openDataApplicationShared ? ImGuiTabItemFlags.SetSelected : ImGuiTabItemFlags.None)) { if (applicationTabItem) { @@ -243,7 +252,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase } } - using (var gposeTabItem = ImRaii.TabItem("Apply Data")) + using (var gposeTabItem = ImRaii.TabItem("Apply Data", _openDataApplicationShared ? ImGuiTabItemFlags.SetSelected : ImGuiTabItemFlags.None)) { if (gposeTabItem) { @@ -704,7 +713,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase } } - using (var sharedWithYouTabItem = ImRaii.TabItem("Shared With You")) + using (var sharedWithYouTabItem = ImRaii.TabItem("Shared With You", _openDataApplicationShared ? ImGuiTabItemFlags.SetSelected : ImGuiTabItemFlags.None)) { using var id = ImRaii.PushId("sharedWithYouTab"); if (sharedWithYouTabItem) @@ -718,8 +727,12 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase DrawUpdateSharedDataButton(); - - UiSharedService.DrawTree("Filters", () => + int activeFilters = 0; + if (!string.IsNullOrEmpty(_sharedWithYouOwnerFilter)) activeFilters++; + if (!string.IsNullOrEmpty(_sharedWithYouDescriptionFilter)) activeFilters++; + if (_sharedWithYouDownloadableFilter) activeFilters++; + string filtersText = activeFilters == 0 ? "Filters" : $"Filters ({activeFilters} active)"; + UiSharedService.DrawTree($"{filtersText}##filters", () => { var filterWidth = ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X; ImGui.SetNextItemWidth(filterWidth); @@ -758,6 +771,9 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase ImGuiHelpers.ScaledDummy(5); foreach (var entry in _filteredDict ?? []) { + bool isFilteredAndHasToBeOpened = entry.Key.Contains(_sharedWithYouOwnerFilter) && _openDataApplicationShared; + if (isFilteredAndHasToBeOpened) + ImGui.SetNextItemOpen(isFilteredAndHasToBeOpened); UiSharedService.DrawTree($"{entry.Key} - [{entry.Value.Count} Character Data Sets]##{entry.Key}", () => { foreach (var data in entry.Value) @@ -766,6 +782,8 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase } ImGuiHelpers.ScaledDummy(5); }); + if (isFilteredAndHasToBeOpened) + _openDataApplicationShared = false; } } } diff --git a/MareSynchronos/UI/Components/DrawUserPair.cs b/MareSynchronos/UI/Components/DrawUserPair.cs index 9f22998..944a6bc 100644 --- a/MareSynchronos/UI/Components/DrawUserPair.cs +++ b/MareSynchronos/UI/Components/DrawUserPair.cs @@ -8,6 +8,7 @@ using MareSynchronos.API.Dto.Group; using MareSynchronos.API.Dto.User; using MareSynchronos.MareConfiguration; using MareSynchronos.PlayerData.Pairs; +using MareSynchronos.Services; using MareSynchronos.Services.Mediator; using MareSynchronos.Services.ServerConfiguration; using MareSynchronos.UI.Handlers; @@ -28,6 +29,7 @@ public class DrawUserPair private readonly ServerConfigurationManager _serverConfigurationManager; private readonly UiSharedService _uiSharedService; private readonly PlayerPerformanceConfigService _performanceConfigService; + private readonly CharaDataManager _charaDataManager; private float _menuWidth = -1; private bool _wasHovered = false; @@ -36,7 +38,8 @@ public class DrawUserPair ApiController apiController, IdDisplayHandler uIDDisplayHandler, MareMediator mareMediator, SelectTagForPairUi selectTagForPairUi, ServerConfigurationManager serverConfigurationManager, - UiSharedService uiSharedService, PlayerPerformanceConfigService performanceConfigService) + UiSharedService uiSharedService, PlayerPerformanceConfigService performanceConfigService, + CharaDataManager charaDataManager) { _id = id; _pair = entry; @@ -49,6 +52,7 @@ public class DrawUserPair _serverConfigurationManager = serverConfigurationManager; _uiSharedService = uiSharedService; _performanceConfigService = performanceConfigService; + _charaDataManager = charaDataManager; } public Pair Pair => _pair; @@ -326,7 +330,7 @@ public class DrawUserPair private float DrawRightSide() { var pauseIcon = _pair.UserPair!.OwnPermissions.IsPaused() ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause; - var pauseIconSize = _uiSharedService.GetIconButtonSize(pauseIcon); + var pauseButtonSize = _uiSharedService.GetIconButtonSize(pauseIcon); var barButtonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.EllipsisV); var spacingX = ImGui.GetStyle().ItemSpacing.X; var windowEndX = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth(); @@ -339,7 +343,7 @@ public class DrawUserPair ImGui.OpenPopup("User Flyout Menu"); } - currentRightSide -= (pauseIconSize.X + spacingX); + currentRightSide -= (pauseButtonSize.X + spacingX); ImGui.SameLine(currentRightSide); if (_uiSharedService.IconButton(pauseIcon)) { @@ -450,6 +454,19 @@ public class DrawUserPair } } + if (_charaDataManager.SharedWithYouData.TryGetValue(_pair.UserData, out var sharedData)) + { + currentRightSide -= (_uiSharedService.GetIconSize(FontAwesomeIcon.Running).X + (spacingX / 2f)); + ImGui.SameLine(currentRightSide); + _uiSharedService.IconText(FontAwesomeIcon.Running); + UiSharedService.AttachToolTip($"This user has shared {sharedData.Count} Character Data Sets with you." + UiSharedService.TooltipSeparator + + "Click to open the Character Data Hub and show the entries."); + if (ImGui.IsItemClicked(ImGuiMouseButton.Left)) + { + _mediator.Publish(new OpenCharaDataHubWithFilterMessage(_pair.UserData)); + } + } + if (_currentGroup != null) { var icon = FontAwesomeIcon.None; diff --git a/MareSynchronos/UI/DrawEntityFactory.cs b/MareSynchronos/UI/DrawEntityFactory.cs index 65952cf..62b497d 100644 --- a/MareSynchronos/UI/DrawEntityFactory.cs +++ b/MareSynchronos/UI/DrawEntityFactory.cs @@ -1,6 +1,7 @@ using MareSynchronos.API.Dto.Group; using MareSynchronos.MareConfiguration; using MareSynchronos.PlayerData.Pairs; +using MareSynchronos.Services; using MareSynchronos.Services.Mediator; using MareSynchronos.Services.ServerConfiguration; using MareSynchronos.UI.Components; @@ -20,6 +21,7 @@ public class DrawEntityFactory private readonly ServerConfigurationManager _serverConfigurationManager; private readonly UiSharedService _uiSharedService; private readonly PlayerPerformanceConfigService _playerPerformanceConfigService; + private readonly CharaDataManager _charaDataManager; private readonly SelectTagForPairUi _selectTagForPairUi; private readonly TagHandler _tagHandler; private readonly IdDisplayHandler _uidDisplayHandler; @@ -28,7 +30,7 @@ public class DrawEntityFactory SelectTagForPairUi selectTagForPairUi, MareMediator mediator, TagHandler tagHandler, SelectPairForTagUi selectPairForTagUi, ServerConfigurationManager serverConfigurationManager, UiSharedService uiSharedService, - PlayerPerformanceConfigService playerPerformanceConfigService) + PlayerPerformanceConfigService playerPerformanceConfigService, CharaDataManager charaDataManager) { _logger = logger; _apiController = apiController; @@ -40,6 +42,7 @@ public class DrawEntityFactory _serverConfigurationManager = serverConfigurationManager; _uiSharedService = uiSharedService; _playerPerformanceConfigService = playerPerformanceConfigService; + _charaDataManager = charaDataManager; } public DrawFolderGroup CreateDrawGroupFolder(GroupFullInfoDto groupFullInfoDto, @@ -62,6 +65,7 @@ public class DrawEntityFactory public DrawUserPair CreateDrawPair(string id, Pair user, List groups, GroupFullInfoDto? currentGroup) { return new DrawUserPair(id + user.UserData.UID, user, groups, currentGroup, _apiController, _uidDisplayHandler, - _mediator, _selectTagForPairUi, _serverConfigurationManager, _uiSharedService, _playerPerformanceConfigService); + _mediator, _selectTagForPairUi, _serverConfigurationManager, _uiSharedService, _playerPerformanceConfigService, + _charaDataManager); } } \ No newline at end of file diff --git a/MareSynchronos/UI/UISharedService.cs b/MareSynchronos/UI/UISharedService.cs index 4753597..eb5147c 100644 --- a/MareSynchronos/UI/UISharedService.cs +++ b/MareSynchronos/UI/UISharedService.cs @@ -1130,9 +1130,9 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase ImGuiHelpers.ScaledDummy(5); } - public static void DrawTree(string leafName, Action drawOnOpened) + public static void DrawTree(string leafName, Action drawOnOpened, ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags.None) { - using var tree = ImRaii.TreeNode(leafName); + using var tree = ImRaii.TreeNode(leafName, flags); if (tree) { drawOnOpened();