add mare profiles
This commit is contained in:
		
							
								
								
									
										2
									
								
								MareAPI
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								MareAPI
									
									
									
									
									
								
							 Submodule MareAPI updated: 0065dd3cda...22346739d2
									
								
							| @@ -23,7 +23,7 @@ public class ConfigurationMigrator : IHostedService | |||||||
|  |  | ||||||
|     public void Migrate() |     public void Migrate() | ||||||
|     { |     { | ||||||
|         if (_pi.GetPluginConfig() is Configuration oldConfig) |         if (_pi.GetPluginConfig() is Configurations.Obsolete.Configuration oldConfig) | ||||||
|         { |         { | ||||||
|             _logger.LogInformation("Migrating Configuration from old config style to 1"); |             _logger.LogInformation("Migrating Configuration from old config style to 1"); | ||||||
|  |  | ||||||
| @@ -53,11 +53,15 @@ public class ConfigurationMigrator : IHostedService | |||||||
|         { |         { | ||||||
|             try |             try | ||||||
|             { |             { | ||||||
|                 var serverConfig = JsonConvert.DeserializeObject<ServerConfigV0>(File.ReadAllText(ConfigurationPath(ServerConfigService.ConfigName)))!; |                 var content = File.ReadAllText(ConfigurationPath(ServerConfigService.ConfigName)); | ||||||
|  |                 if (!content.Contains("\"Version\": 1")) | ||||||
|                 if (serverConfig.Version == 0) |  | ||||||
|                 { |                 { | ||||||
|                     MigrateServerConfigV0toV1(serverConfig); |                     var serverConfig = JsonConvert.DeserializeObject<ServerConfigV0>(content); | ||||||
|  |  | ||||||
|  |                     if (serverConfig != null && serverConfig.Version == 0) | ||||||
|  |                     { | ||||||
|  |                         MigrateServerConfigV0toV1(serverConfig); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             catch (Exception ex) |             catch (Exception ex) | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ public class MareConfig : IMareConfiguration | |||||||
|     public string CacheFolder { get; set; } = string.Empty; |     public string CacheFolder { get; set; } = string.Empty; | ||||||
|     public bool DisableOptionalPluginWarnings { get; set; } = false; |     public bool DisableOptionalPluginWarnings { get; set; } = false; | ||||||
|     public NotificationLocation ErrorNotification { get; set; } = NotificationLocation.Both; |     public NotificationLocation ErrorNotification { get; set; } = NotificationLocation.Both; | ||||||
|  |     public string ExportFolder { get; set; } = string.Empty; | ||||||
|     public bool FileScanPaused { get; set; } = false; |     public bool FileScanPaused { get; set; } = false; | ||||||
|     public NotificationLocation InfoNotification { get; set; } = NotificationLocation.Toast; |     public NotificationLocation InfoNotification { get; set; } = NotificationLocation.Toast; | ||||||
|     public bool InitialScanComplete { get; set; } = false; |     public bool InitialScanComplete { get; set; } = false; | ||||||
| @@ -19,6 +20,9 @@ public class MareConfig : IMareConfiguration | |||||||
|     public bool OpenGposeImportOnGposeStart { get; set; } = false; |     public bool OpenGposeImportOnGposeStart { get; set; } = false; | ||||||
|     public bool OpenPopupOnAdd { get; set; } = true; |     public bool OpenPopupOnAdd { get; set; } = true; | ||||||
|     public int ParallelDownloads { get; set; } = 10; |     public int ParallelDownloads { get; set; } = 10; | ||||||
|  |     public float ProfileDelay { get; set; } = 2; | ||||||
|  |     public bool ProfilesAllowNsfw { get; set; } = false; | ||||||
|  |     public bool ProfilesShow { get; set; } = true; | ||||||
|     public bool ReverseUserSort { get; set; } = false; |     public bool ReverseUserSort { get; set; } = false; | ||||||
|     public bool ShowCharacterNameInsteadOfNotesForVisible { get; set; } = false; |     public bool ShowCharacterNameInsteadOfNotesForVisible { get; set; } = false; | ||||||
|     public bool ShowOfflineUsersSeparately { get; set; } = true; |     public bool ShowOfflineUsersSeparately { get; set; } = true; | ||||||
| @@ -36,5 +40,4 @@ public class MareConfig : IMareConfiguration | |||||||
|     public int TransferBarsWidth { get; set; } = 250; |     public int TransferBarsWidth { get; set; } = 250; | ||||||
|     public int Version { get; set; } = 1; |     public int Version { get; set; } = 1; | ||||||
|     public NotificationLocation WarningNotification { get; set; } = NotificationLocation.Both; |     public NotificationLocation WarningNotification { get; set; } = NotificationLocation.Both; | ||||||
|     public string ExportFolder { get; set; } = string.Empty; |  | ||||||
| } | } | ||||||
| @@ -37,6 +37,7 @@ | |||||||
|     <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" /> |     <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" /> | ||||||
|     <PackageReference Include="Penumbra.Api" Version="1.0.7" /> |     <PackageReference Include="Penumbra.Api" Version="1.0.7" /> | ||||||
|     <PackageReference Include="Penumbra.String" Version="1.0.3" /> |     <PackageReference Include="Penumbra.String" Version="1.0.3" /> | ||||||
|  |     <PackageReference Include="SixLabors.ImageSharp" Version="3.0.0" /> | ||||||
|     <PackageReference Include="SonarAnalyzer.CSharp" Version="8.54.0.64047"> |     <PackageReference Include="SonarAnalyzer.CSharp" Version="8.54.0.64047"> | ||||||
|       <PrivateAssets>all</PrivateAssets> |       <PrivateAssets>all</PrivateAssets> | ||||||
|       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||||
|   | |||||||
| @@ -84,8 +84,8 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|     public IntPtr Address { get; set; } |     public IntPtr Address { get; set; } | ||||||
|     public unsafe Character* Character => (Character*)Address; |     public unsafe Character* Character => (Character*)Address; | ||||||
|     public Lazy<Dalamud.Game.ClientState.Objects.Types.GameObject?> GameObjectLazy { get; private set; } |  | ||||||
|     public IntPtr CurrentAddress => _getAddress.Invoke(); |     public IntPtr CurrentAddress => _getAddress.Invoke(); | ||||||
|  |     public Lazy<Dalamud.Game.ClientState.Objects.Types.GameObject?> GameObjectLazy { get; private set; } | ||||||
|     public string Name { get; private set; } |     public string Name { get; private set; } | ||||||
|     public ObjectKind ObjectKind { get; } |     public ObjectKind ObjectKind { get; } | ||||||
|     private byte[] CustomizeData { get; set; } = new byte[26]; |     private byte[] CustomizeData { get; set; } = new byte[26]; | ||||||
| @@ -101,6 +101,8 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase | |||||||
|             { |             { | ||||||
|                 curPtr = _getAddress.Invoke(); |                 curPtr = _getAddress.Invoke(); | ||||||
|  |  | ||||||
|  |                 if (curPtr == IntPtr.Zero) return true; | ||||||
|  |  | ||||||
|                 var drawObj = GetDrawObj(curPtr); |                 var drawObj = GetDrawObj(curPtr); | ||||||
|                 return IsBeingDrawn(drawObj, curPtr); |                 return IsBeingDrawn(drawObj, curPtr); | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -99,6 +99,7 @@ public sealed class PairManager : DisposableMediatorSubscriberBase | |||||||
|     { |     { | ||||||
|         if (_allClientPairs.TryGetValue(user, out var pair)) |         if (_allClientPairs.TryGetValue(user, out var pair)) | ||||||
|         { |         { | ||||||
|  |             Mediator.Publish(new ClearProfileDataMessage(pair.UserData)); | ||||||
|             pair.MarkOffline(); |             pair.MarkOffline(); | ||||||
|             RecreateLazy(); |             RecreateLazy(); | ||||||
|         } |         } | ||||||
| @@ -107,6 +108,9 @@ public sealed class PairManager : DisposableMediatorSubscriberBase | |||||||
|     public void MarkPairOnline(OnlineUserIdentDto dto, bool sendNotif = true) |     public void MarkPairOnline(OnlineUserIdentDto dto, bool sendNotif = true) | ||||||
|     { |     { | ||||||
|         if (!_allClientPairs.ContainsKey(dto.User)) throw new InvalidOperationException("No user found for " + dto); |         if (!_allClientPairs.ContainsKey(dto.User)) throw new InvalidOperationException("No user found for " + dto); | ||||||
|  |  | ||||||
|  |         Mediator.Publish(new ClearProfileDataMessage(dto.User)); | ||||||
|  |  | ||||||
|         var pair = _allClientPairs[dto.User]; |         var pair = _allClientPairs[dto.User]; | ||||||
|         if (pair.HasCachedPlayer) return; |         if (pair.HasCachedPlayer) return; | ||||||
|  |  | ||||||
| @@ -213,6 +217,12 @@ public sealed class PairManager : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|         if (pair.UserPair == null) throw new InvalidOperationException("No direct pair for " + dto); |         if (pair.UserPair == null) throw new InvalidOperationException("No direct pair for " + dto); | ||||||
|  |  | ||||||
|  |         if (pair.UserPair.OtherPermissions.IsPaused() != dto.Permissions.IsPaused() | ||||||
|  |             || pair.UserPair.OtherPermissions.IsPaired() != dto.Permissions.IsPaired()) | ||||||
|  |         { | ||||||
|  |             Mediator.Publish(new ClearProfileDataMessage(dto.User)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         pair.UserPair.OtherPermissions = dto.Permissions; |         pair.UserPair.OtherPermissions = dto.Permissions; | ||||||
|  |  | ||||||
|         Logger.LogTrace("Paired: {synced}, Paused: {paused}, Anims: {anims}, Sounds: {sounds}", |         Logger.LogTrace("Paired: {synced}, Paused: {paused}, Anims: {anims}, Sounds: {sounds}", | ||||||
| @@ -229,6 +239,12 @@ public sealed class PairManager : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|         if (pair.UserPair == null) throw new InvalidOperationException("No direct pair for " + dto); |         if (pair.UserPair == null) throw new InvalidOperationException("No direct pair for " + dto); | ||||||
|  |  | ||||||
|  |         if (pair.UserPair.OwnPermissions.IsPaused() != dto.Permissions.IsPaused() | ||||||
|  |             || pair.UserPair.OwnPermissions.IsPaired() != dto.Permissions.IsPaired()) | ||||||
|  |         { | ||||||
|  |             Mediator.Publish(new ClearProfileDataMessage(dto.User)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         pair.UserPair.OwnPermissions = dto.Permissions; |         pair.UserPair.OwnPermissions = dto.Permissions; | ||||||
|  |  | ||||||
|         Logger.LogTrace("Paired: {synced}, Paused: {paused}, Anims: {anims}, Sounds: {sounds}", |         Logger.LogTrace("Paired: {synced}, Paused: {paused}, Anims: {anims}, Sounds: {sounds}", | ||||||
|   | |||||||
| @@ -66,7 +66,11 @@ public sealed class Plugin : IDalamudPlugin | |||||||
|             collection.AddSingleton<FileUploadManager>(); |             collection.AddSingleton<FileUploadManager>(); | ||||||
|             collection.AddSingleton<FileTransferOrchestrator>(); |             collection.AddSingleton<FileTransferOrchestrator>(); | ||||||
|             collection.AddSingleton<MarePlugin>(); |             collection.AddSingleton<MarePlugin>(); | ||||||
|             collection.AddSingleton<UidDisplayHandler>(); |             collection.AddSingleton<MareProfileManager>(); | ||||||
|  |             collection.AddSingleton<UidDisplayHandler>((s) => new UidDisplayHandler(s.GetRequiredService<ILogger<UidDisplayHandler>>(), pluginInterface.UiBuilder, | ||||||
|  |                 s.GetRequiredService<MareProfileManager>(), | ||||||
|  |                 s.GetRequiredService<UiSharedService>(), s.GetRequiredService<PairManager>(), | ||||||
|  |                 s.GetRequiredService<ServerConfigurationManager>(), s.GetRequiredService<MareConfigService>())); | ||||||
|             collection.AddSingleton((s) => new DalamudUtilService(s.GetRequiredService<ILogger<DalamudUtilService>>(), |             collection.AddSingleton((s) => new DalamudUtilService(s.GetRequiredService<ILogger<DalamudUtilService>>(), | ||||||
|                 clientState, objectTable, framework, gameGui, condition, gameData, |                 clientState, objectTable, framework, gameGui, condition, gameData, | ||||||
|                 s.GetRequiredService<MareMediator>(), s.GetRequiredService<PerformanceCollectorService>())); |                 s.GetRequiredService<MareMediator>(), s.GetRequiredService<PerformanceCollectorService>())); | ||||||
| @@ -119,6 +123,9 @@ public sealed class Plugin : IDalamudPlugin | |||||||
|             collection.AddScoped<WindowMediatorSubscriberBase, GposeUi>(); |             collection.AddScoped<WindowMediatorSubscriberBase, GposeUi>(); | ||||||
|             collection.AddScoped<WindowMediatorSubscriberBase, IntroUi>(); |             collection.AddScoped<WindowMediatorSubscriberBase, IntroUi>(); | ||||||
|             collection.AddScoped<WindowMediatorSubscriberBase, DownloadUi>(); |             collection.AddScoped<WindowMediatorSubscriberBase, DownloadUi>(); | ||||||
|  |             collection.AddScoped<WindowMediatorSubscriberBase, EditProfileUi>((s) => new EditProfileUi(s.GetRequiredService<ILogger<EditProfileUi>>(), | ||||||
|  |                 s.GetRequiredService<MareMediator>(), s.GetRequiredService<ApiController>(), pluginInterface.UiBuilder, s.GetRequiredService<UiSharedService>(), | ||||||
|  |                 s.GetRequiredService<FileDialogManager>(), s.GetRequiredService<MareProfileManager>())); | ||||||
|             collection.AddScoped<CacheCreationService>(); |             collection.AddScoped<CacheCreationService>(); | ||||||
|             collection.AddScoped<TransientResourceManager>(); |             collection.AddScoped<TransientResourceManager>(); | ||||||
|             collection.AddScoped<PlayerDataFactory>(); |             collection.AddScoped<PlayerDataFactory>(); | ||||||
|   | |||||||
							
								
								
									
										80
									
								
								MareSynchronos/Services/MareProfileManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								MareSynchronos/Services/MareProfileManager.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,5 +1,6 @@ | |||||||
| using Dalamud.Game.ClientState.Objects.Types; | using Dalamud.Game.ClientState.Objects.Types; | ||||||
| using Dalamud.Interface.Internal.Notifications; | using Dalamud.Interface.Internal.Notifications; | ||||||
|  | using MareSynchronos.API.Data; | ||||||
| using MareSynchronos.API.Dto; | using MareSynchronos.API.Dto; | ||||||
| using MareSynchronos.PlayerData.Handlers; | using MareSynchronos.PlayerData.Handlers; | ||||||
| using MareSynchronos.WebAPI.Files.Models; | using MareSynchronos.WebAPI.Files.Models; | ||||||
| @@ -54,5 +55,6 @@ public record DownloadStartedMessage(GameObjectHandler DownloadId, Dictionary<st | |||||||
| public record DownloadFinishedMessage(GameObjectHandler DownloadId) : IMessage; | public record DownloadFinishedMessage(GameObjectHandler DownloadId) : IMessage; | ||||||
| public record UiToggleMessage(Type UiType) : IMessage; | public record UiToggleMessage(Type UiType) : IMessage; | ||||||
| public record PlayerUploadingMessage(GameObjectHandler Handler, bool IsUploading) : IMessage; | public record PlayerUploadingMessage(GameObjectHandler Handler, bool IsUploading) : IMessage; | ||||||
|  | public record ClearProfileDataMessage(UserData? UserData = null) : IMessage; | ||||||
|  |  | ||||||
| #pragma warning restore MA0048 // File name must match type name | #pragma warning restore MA0048 // File name must match type name | ||||||
| @@ -409,17 +409,16 @@ public class CompactUi : WindowMediatorSubscriberBase | |||||||
|             .OrderBy( |             .OrderBy( | ||||||
|                 u => _configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(u.PlayerName) |                 u => _configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(u.PlayerName) | ||||||
|                     ? u.PlayerName |                     ? u.PlayerName | ||||||
|                     : (u.GetNote() ?? u.UserData.AliasOrUID), StringComparer.OrdinalIgnoreCase) |                     : (u.GetNote() ?? u.UserData.AliasOrUID), StringComparer.OrdinalIgnoreCase).ToList(); | ||||||
|             .Select(c => new DrawUserPair(c, _uidDisplayHandler, _apiController, _selectGroupForPairUi)).ToList(); |  | ||||||
|  |  | ||||||
|         if (_configService.Current.ReverseUserSort) |         if (_configService.Current.ReverseUserSort) | ||||||
|         { |         { | ||||||
|             users.Reverse(); |             users.Reverse(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         var onlineUsers = users.Where(u => u.IsOnline || u.UserPair!.OwnPermissions.IsPaused()).ToList(); |         var onlineUsers = users.Where(u => u.IsOnline || u.UserPair!.OwnPermissions.IsPaused()).Select(c => new DrawUserPair("Online" + c.UserData.UID, c, _uidDisplayHandler, _apiController, _selectGroupForPairUi)).ToList(); | ||||||
|         var visibleUsers = onlineUsers.Where(u => u.IsVisible).ToList(); |         var visibleUsers = users.Where(u => u.IsVisible).Select(c => new DrawUserPair("Visible" + c.UserData.UID, c, _uidDisplayHandler, _apiController, _selectGroupForPairUi)).ToList(); | ||||||
|         var offlineUsers = users.Except(onlineUsers).ToList(); |         var offlineUsers = users.Where(u => !u.IsOnline && !u.UserPair!.OwnPermissions.IsPaused()).Select(c => new DrawUserPair("Offline" + c.UserData.UID, c, _uidDisplayHandler, _apiController, _selectGroupForPairUi)).ToList(); | ||||||
|  |  | ||||||
|         ImGui.BeginChild("list", new Vector2(WindowContentWidth, ySize), border: false); |         ImGui.BeginChild("list", new Vector2(WindowContentWidth, ySize), border: false); | ||||||
|  |  | ||||||
| @@ -444,7 +443,7 @@ public class CompactUi : WindowMediatorSubscriberBase | |||||||
|  |  | ||||||
|         if (_apiController.ServerState is ServerState.Connected) |         if (_apiController.ServerState is ServerState.Connected) | ||||||
|         { |         { | ||||||
|             ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() - buttonSize.X) / 2 - (userSize.X + textSize.X) / 2 - ImGui.GetStyle().ItemSpacing.X / 2); |             ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth()) / 2 - (userSize.X + textSize.X) / 2 - ImGui.GetStyle().ItemSpacing.X / 2); | ||||||
|             if (!printShard) ImGui.AlignTextToFramePadding(); |             if (!printShard) ImGui.AlignTextToFramePadding(); | ||||||
|             ImGui.TextColored(ImGuiColors.ParsedGreen, userCount); |             ImGui.TextColored(ImGuiColors.ParsedGreen, userCount); | ||||||
|             ImGui.SameLine(); |             ImGui.SameLine(); | ||||||
| @@ -460,17 +459,33 @@ public class CompactUi : WindowMediatorSubscriberBase | |||||||
|         if (printShard) |         if (printShard) | ||||||
|         { |         { | ||||||
|             ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetStyle().ItemSpacing.Y); |             ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetStyle().ItemSpacing.Y); | ||||||
|             ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() - buttonSize.X) / 2 - shardTextSize.X / 2); |             ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth()) / 2 - shardTextSize.X / 2); | ||||||
|             ImGui.TextUnformatted(shardConnection); |             ImGui.TextUnformatted(shardConnection); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         ImGui.SameLine(); | ||||||
|  |         if (printShard) | ||||||
|  |         { | ||||||
|  |             ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((userSize.Y + textSize.Y) / 2 + shardTextSize.Y) / 2 - ImGui.GetStyle().ItemSpacing.Y + buttonSize.Y / 2); | ||||||
|  |         } | ||||||
|  |         var color = UiSharedService.GetBoolColor(!_serverManager.CurrentServer!.FullPause); | ||||||
|  |         var connectedIcon = !_serverManager.CurrentServer.FullPause ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink; | ||||||
|  |  | ||||||
|  |         if (_apiController.ServerState is ServerState.Connected) | ||||||
|  |         { | ||||||
|  |             ImGui.SetCursorPosX(0 + ImGui.GetStyle().ItemSpacing.X); | ||||||
|  |             if (ImGuiComponents.IconButton(FontAwesomeIcon.UserCircle)) | ||||||
|  |             { | ||||||
|  |                 Mediator.Publish(new UiToggleMessage(typeof(EditProfileUi))); | ||||||
|  |             } | ||||||
|  |             UiSharedService.AttachToolTip("Edit your Mare Profile"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() - buttonSize.X); |         ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth() - buttonSize.X); | ||||||
|         if (printShard) |         if (printShard) | ||||||
|         { |         { | ||||||
|             ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((userSize.Y + textSize.Y) / 2 + shardTextSize.Y) / 2 - ImGui.GetStyle().ItemSpacing.Y + buttonSize.Y / 2); |             ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((userSize.Y + textSize.Y) / 2 + shardTextSize.Y) / 2 - ImGui.GetStyle().ItemSpacing.Y + buttonSize.Y / 2); | ||||||
|         } |         } | ||||||
|         var color = UiSharedService.GetBoolColor(!_serverManager.CurrentServer!.FullPause); |  | ||||||
|         var connectedIcon = !_serverManager.CurrentServer.FullPause ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink; |  | ||||||
|  |  | ||||||
|         if (_apiController.ServerState is not (ServerState.Reconnecting or ServerState.Disconnecting)) |         if (_apiController.ServerState is not (ServerState.Reconnecting or ServerState.Disconnecting)) | ||||||
|         { |         { | ||||||
|   | |||||||
| @@ -14,16 +14,14 @@ namespace MareSynchronos.UI.Components; | |||||||
|  |  | ||||||
| public class DrawGroupPair : DrawPairBase | public class DrawGroupPair : DrawPairBase | ||||||
| { | { | ||||||
|     private readonly ApiController _apiController; |  | ||||||
|     private readonly GroupPairFullInfoDto _fullInfoDto; |     private readonly GroupPairFullInfoDto _fullInfoDto; | ||||||
|     private readonly GroupFullInfoDto _group; |     private readonly GroupFullInfoDto _group; | ||||||
|     private string _banReason = string.Empty; |     private string _banReason = string.Empty; | ||||||
|     private bool _banUserPopupOpen; |     private bool _banUserPopupOpen; | ||||||
|     private bool _showModalBanUser; |     private bool _showModalBanUser; | ||||||
|  |  | ||||||
|     public DrawGroupPair(Pair entry, ApiController apiController, GroupFullInfoDto group, GroupPairFullInfoDto fullInfoDto, UidDisplayHandler handler) : base(entry, handler) |     public DrawGroupPair(string id, Pair entry, ApiController apiController, GroupFullInfoDto group, GroupPairFullInfoDto fullInfoDto, UidDisplayHandler handler) : base(id, entry, apiController, handler) | ||||||
|     { |     { | ||||||
|         _apiController = apiController; |  | ||||||
|         _group = group; |         _group = group; | ||||||
|         _fullInfoDto = fullInfoDto; |         _fullInfoDto = fullInfoDto; | ||||||
|     } |     } | ||||||
| @@ -115,7 +113,7 @@ public class DrawGroupPair : DrawPairBase | |||||||
|  |  | ||||||
|         bool showInfo = (individualAnimDisabled || individualSoundsDisabled || animDisabled || soundsDisabled); |         bool showInfo = (individualAnimDisabled || individualSoundsDisabled || animDisabled || soundsDisabled); | ||||||
|         bool showPlus = _pair.UserPair == null; |         bool showPlus = _pair.UserPair == null; | ||||||
|         bool showBars = userIsOwner || (userIsModerator && !entryIsMod && !entryIsOwner); |         bool showBars = (userIsOwner || (userIsModerator && !entryIsMod && !entryIsOwner)) || !_pair.IsPaused; | ||||||
|  |  | ||||||
|         var spacing = ImGui.GetStyle().ItemSpacing.X; |         var spacing = ImGui.GetStyle().ItemSpacing.X; | ||||||
|         var permIcon = (individualAnimDisabled || individualSoundsDisabled) ? FontAwesomeIcon.ExclamationTriangle |         var permIcon = (individualAnimDisabled || individualSoundsDisabled) ? FontAwesomeIcon.ExclamationTriangle | ||||||
| @@ -267,6 +265,17 @@ public class DrawGroupPair : DrawPairBase | |||||||
|                 } |                 } | ||||||
|                 UiSharedService.AttachToolTip("Hold CTRL and SHIFT and click to transfer ownership of this Syncshell to " + (_fullInfoDto.UserAliasOrUID) + Environment.NewLine + "WARNING: This action is irreversible."); |                 UiSharedService.AttachToolTip("Hold CTRL and SHIFT and click to transfer ownership of this Syncshell to " + (_fullInfoDto.UserAliasOrUID) + Environment.NewLine + "WARNING: This action is irreversible."); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             ImGui.Separator(); | ||||||
|  |             if (!_pair.IsPaused) | ||||||
|  |             { | ||||||
|  |                 if (UiSharedService.IconTextButton(FontAwesomeIcon.ExclamationTriangle, "Report Mare Profile")) | ||||||
|  |                 { | ||||||
|  |                     ImGui.CloseCurrentPopup(); | ||||||
|  |                     _showModalReport = true; | ||||||
|  |                 } | ||||||
|  |                 UiSharedService.AttachToolTip("Report this users Mare Profile to the administrative team"); | ||||||
|  |             } | ||||||
|             ImGui.EndPopup(); |             ImGui.EndPopup(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,18 +1,27 @@ | |||||||
| using Dalamud.Interface; | using Dalamud.Interface; | ||||||
|  | using Dalamud.Interface.Colors; | ||||||
| using ImGuiNET; | using ImGuiNET; | ||||||
| using MareSynchronos.PlayerData.Pairs; | using MareSynchronos.PlayerData.Pairs; | ||||||
| using MareSynchronos.UI.Handlers; | using MareSynchronos.UI.Handlers; | ||||||
|  | using MareSynchronos.WebAPI; | ||||||
|  |  | ||||||
| namespace MareSynchronos.UI.Components; | namespace MareSynchronos.UI.Components; | ||||||
|  |  | ||||||
| public abstract class DrawPairBase | public abstract class DrawPairBase | ||||||
| { | { | ||||||
|  |     protected static bool _showModalReport = false; | ||||||
|  |     protected readonly ApiController _apiController; | ||||||
|     protected Pair _pair; |     protected Pair _pair; | ||||||
|  |     private static bool _reportPopupOpen = false; | ||||||
|  |     private static string _reportReason = string.Empty; | ||||||
|     private readonly UidDisplayHandler _displayHandler; |     private readonly UidDisplayHandler _displayHandler; | ||||||
|  |     private readonly string _id; | ||||||
|  |  | ||||||
|     protected DrawPairBase(Pair entry, UidDisplayHandler uIDDisplayHandler) |     protected DrawPairBase(string id, Pair entry, ApiController apiController, UidDisplayHandler uIDDisplayHandler) | ||||||
|     { |     { | ||||||
|  |         _id = id; | ||||||
|         _pair = entry; |         _pair = entry; | ||||||
|  |         _apiController = apiController; | ||||||
|         _displayHandler = uIDDisplayHandler; |         _displayHandler = uIDDisplayHandler; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -30,6 +39,38 @@ public abstract class DrawPairBase | |||||||
|         var posX = ImGui.GetCursorPosX(); |         var posX = ImGui.GetCursorPosX(); | ||||||
|         var rightSide = DrawRightSide(textPosY, originalY); |         var rightSide = DrawRightSide(textPosY, originalY); | ||||||
|         DrawName(originalY, posX, rightSide); |         DrawName(originalY, posX, rightSide); | ||||||
|  |  | ||||||
|  |         if (_showModalReport && !_reportPopupOpen) | ||||||
|  |         { | ||||||
|  |             ImGui.OpenPopup("Report Profile"); | ||||||
|  |             _reportPopupOpen = true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!_showModalReport) _reportPopupOpen = false; | ||||||
|  |  | ||||||
|  |         if (ImGui.BeginPopupModal("Report Profile", ref _showModalReport, UiSharedService.PopupWindowFlags)) | ||||||
|  |         { | ||||||
|  |             UiSharedService.TextWrapped("Report " + (_pair.UserData.AliasOrUID) + " Mare Profile"); | ||||||
|  |             ImGui.InputTextMultiline("##reportReason", ref _reportReason, 500, new System.Numerics.Vector2(500 - ImGui.GetStyle().ItemSpacing.X * 2, 200)); | ||||||
|  |             UiSharedService.TextWrapped($"Note: Sending a report will disable the offending profile globally.{Environment.NewLine}" + | ||||||
|  |                 $"The report will be sent to the team of your currently connected Mare Synchronos Service.{Environment.NewLine}" + | ||||||
|  |                 $"The report will include your user and your contact info (Discord User).{Environment.NewLine}" + | ||||||
|  |                 $"Depending on the severity of the offense the users Mare profile or account can be permanently disabled or banned."); | ||||||
|  |             UiSharedService.ColorTextWrapped("Report spam and wrong reports will not be tolerated and can lead to permanent account suspension.", ImGuiColors.DalamudRed); | ||||||
|  |             if (string.IsNullOrEmpty(_reportReason)) ImGui.BeginDisabled(); | ||||||
|  |             if (ImGui.Button("Send Report")) | ||||||
|  |             { | ||||||
|  |                 ImGui.CloseCurrentPopup(); | ||||||
|  |                 var reason = _reportReason; | ||||||
|  |                 _ = _apiController.UserReportProfile(new(_pair.UserData, reason)); | ||||||
|  |                 _reportReason = string.Empty; | ||||||
|  |                 _showModalReport = false; | ||||||
|  |                 _reportPopupOpen = false; | ||||||
|  |             } | ||||||
|  |             if (string.IsNullOrEmpty(_reportReason)) ImGui.EndDisabled(); | ||||||
|  |             UiSharedService.SetScaledWindowSize(500); | ||||||
|  |             ImGui.EndPopup(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected abstract void DrawLeftSide(float textPosY, float originalY); |     protected abstract void DrawLeftSide(float textPosY, float originalY); | ||||||
| @@ -38,6 +79,6 @@ public abstract class DrawPairBase | |||||||
|  |  | ||||||
|     private void DrawName(float originalY, float leftSide, float rightSide) |     private void DrawName(float originalY, float leftSide, float rightSide) | ||||||
|     { |     { | ||||||
|         _displayHandler.DrawPairText(_pair, leftSide, originalY, () => rightSide - leftSide); |         _displayHandler.DrawPairText(_id, _pair, leftSide, originalY, () => rightSide - leftSide); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -13,14 +13,12 @@ namespace MareSynchronos.UI.Components; | |||||||
|  |  | ||||||
| public class DrawUserPair : DrawPairBase | public class DrawUserPair : DrawPairBase | ||||||
| { | { | ||||||
|     private readonly ApiController _apiController; |  | ||||||
|     private readonly SelectGroupForPairUi _selectGroupForPairUi; |     private readonly SelectGroupForPairUi _selectGroupForPairUi; | ||||||
|  |  | ||||||
|     public DrawUserPair(Pair entry, UidDisplayHandler displayHandler, ApiController apiController, SelectGroupForPairUi selectGroupForPairUi) : base(entry, displayHandler) |     public DrawUserPair(string id, Pair entry, UidDisplayHandler displayHandler, ApiController apiController, SelectGroupForPairUi selectGroupForPairUi) : base(id, entry, apiController, displayHandler) | ||||||
|     { |     { | ||||||
|         if (_pair.UserPair == null) throw new ArgumentException("Pair must be UserPair", nameof(entry)); |         if (_pair.UserPair == null) throw new ArgumentException("Pair must be UserPair", nameof(entry)); | ||||||
|         _pair = entry; |         _pair = entry; | ||||||
|         _apiController = apiController; |  | ||||||
|         _selectGroupForPairUi = selectGroupForPairUi; |         _selectGroupForPairUi = selectGroupForPairUi; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -209,5 +207,16 @@ public class DrawUserPair : DrawPairBase | |||||||
|             _ = _apiController.UserRemovePair(new(entry.UserData)); |             _ = _apiController.UserRemovePair(new(entry.UserData)); | ||||||
|         } |         } | ||||||
|         UiSharedService.AttachToolTip("Hold CTRL and click to unpair permanently from " + entryUID); |         UiSharedService.AttachToolTip("Hold CTRL and click to unpair permanently from " + entryUID); | ||||||
|  |  | ||||||
|  |         ImGui.Separator(); | ||||||
|  |         if (!entry.IsPaused) | ||||||
|  |         { | ||||||
|  |             if (UiSharedService.IconTextButton(FontAwesomeIcon.ExclamationTriangle, "Report Mare Profile")) | ||||||
|  |             { | ||||||
|  |                 ImGui.CloseCurrentPopup(); | ||||||
|  |                 _showModalReport = true; | ||||||
|  |             } | ||||||
|  |             UiSharedService.AttachToolTip("Report this users Mare Profile to the administrative team"); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -402,7 +402,7 @@ internal sealed class GroupPanel | |||||||
|                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator()) |                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator()) | ||||||
|                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned()) |                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned()) | ||||||
|                 .ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase) |                 .ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase) | ||||||
|                 .Select(c => new DrawGroupPair(c, ApiController, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value, |                 .Select(c => new DrawGroupPair(groupDto.GID + c.UserData.UID, c, ApiController, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value, | ||||||
|                     _uidDisplayHandler)) |                     _uidDisplayHandler)) | ||||||
|                 .ToList(); |                 .ToList(); | ||||||
|             var onlineUsers = pairsInGroup.Where(u => u.IsOnline && !u.IsVisible) |             var onlineUsers = pairsInGroup.Where(u => u.IsOnline && !u.IsVisible) | ||||||
| @@ -410,7 +410,7 @@ internal sealed class GroupPanel | |||||||
|                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator()) |                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator()) | ||||||
|                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned()) |                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned()) | ||||||
|                 .ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase) |                 .ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase) | ||||||
|                 .Select(c => new DrawGroupPair(c, ApiController, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value, |                 .Select(c => new DrawGroupPair(groupDto.GID + c.UserData.UID, c, ApiController, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value, | ||||||
|                     _uidDisplayHandler)) |                     _uidDisplayHandler)) | ||||||
|                 .ToList(); |                 .ToList(); | ||||||
|             var offlineUsers = pairsInGroup.Where(u => !u.IsOnline && !u.IsVisible) |             var offlineUsers = pairsInGroup.Where(u => !u.IsOnline && !u.IsVisible) | ||||||
| @@ -418,7 +418,7 @@ internal sealed class GroupPanel | |||||||
|                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator()) |                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsModerator()) | ||||||
|                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned()) |                 .ThenByDescending(u => u.GroupPair[groupDto].GroupPairStatusInfo.IsPinned()) | ||||||
|                 .ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase) |                 .ThenBy(u => u.GetNote() ?? u.UserData.AliasOrUID, StringComparer.OrdinalIgnoreCase) | ||||||
|                 .Select(c => new DrawGroupPair(c, ApiController, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value, |                 .Select(c => new DrawGroupPair(groupDto.GID + c.UserData.UID, c, ApiController, groupDto, c.GroupPair.Single(g => GroupDataComparer.Instance.Equals(g.Key.Group, groupDto.Group)).Value, | ||||||
|                     _uidDisplayHandler)) |                     _uidDisplayHandler)) | ||||||
|                 .ToList(); |                 .ToList(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -111,7 +111,7 @@ public class PairGroupsUi | |||||||
|         DrawName(tag, isSpecialTag, visibleInThisTag, usersInThisTag.Count(), otherUidsTaggedWithTag?.Count); |         DrawName(tag, isSpecialTag, visibleInThisTag, usersInThisTag.Count(), otherUidsTaggedWithTag?.Count); | ||||||
|         if (!isSpecialTag) |         if (!isSpecialTag) | ||||||
|         { |         { | ||||||
|             if (onlineUsers.First() is DrawUserPair) |             if (onlineUsers.Any() && onlineUsers.First() is DrawUserPair) | ||||||
|             { |             { | ||||||
|                 UiSharedService.DrawWithID($"group-{tag}-buttons", () => DrawButtons(tag, allUsers.Cast<DrawUserPair>().Where(p => otherUidsTaggedWithTag!.Contains(p.UID)).ToList())); |                 UiSharedService.DrawWithID($"group-{tag}-buttons", () => DrawButtons(tag, allUsers.Cast<DrawUserPair>().Where(p => otherUidsTaggedWithTag!.Contains(p.UID)).ToList())); | ||||||
|             } |             } | ||||||
|   | |||||||
							
								
								
									
										187
									
								
								MareSynchronos/UI/EditProfileUi.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								MareSynchronos/UI/EditProfileUi.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | |||||||
|  | using Dalamud.Interface; | ||||||
|  | using Dalamud.Interface.Colors; | ||||||
|  | using Dalamud.Interface.ImGuiFileDialog; | ||||||
|  | using ImGuiNET; | ||||||
|  | using ImGuiScene; | ||||||
|  | using MareSynchronos.API.Data; | ||||||
|  | using MareSynchronos.API.Data.Enum; | ||||||
|  | using MareSynchronos.API.Dto.User; | ||||||
|  | using MareSynchronos.Services; | ||||||
|  | using MareSynchronos.Services.Mediator; | ||||||
|  | using MareSynchronos.WebAPI; | ||||||
|  | using Microsoft.Extensions.Logging; | ||||||
|  |  | ||||||
|  | namespace MareSynchronos.UI; | ||||||
|  |  | ||||||
|  | public class EditProfileUi : WindowMediatorSubscriberBase | ||||||
|  | { | ||||||
|  |     private readonly ApiController _apiController; | ||||||
|  |     private readonly FileDialogManager _fileDialogManager; | ||||||
|  |     private readonly MareProfileManager _mareProfileManager; | ||||||
|  |     private readonly UiBuilder _uiBuilder; | ||||||
|  |     private readonly UiSharedService _uiSharedService; | ||||||
|  |     private string _descriptionText; | ||||||
|  |     private bool _loadedPrior = false; | ||||||
|  |     private TextureWrap? _pfpTextureWrap; | ||||||
|  |     private bool _showFileDialogError = false; | ||||||
|  |     private bool _wasOpen; | ||||||
|  |  | ||||||
|  |     public EditProfileUi(ILogger<EditProfileUi> logger, MareMediator mediator, | ||||||
|  |         ApiController apiController, UiBuilder uiBuilder, UiSharedService uiSharedService, | ||||||
|  |         FileDialogManager fileDialogManager, MareProfileManager mareProfileManager) : base(logger, mediator, "Mare Synchronos Edit Profile###MareSynchronosEditProfileUI") | ||||||
|  |     { | ||||||
|  |         IsOpen = false; | ||||||
|  |         this.SizeConstraints = new() | ||||||
|  |         { | ||||||
|  |             MinimumSize = new(768, 512), | ||||||
|  |             MaximumSize = new(2000, 2000) | ||||||
|  |         }; | ||||||
|  |         _apiController = apiController; | ||||||
|  |         _uiBuilder = uiBuilder; | ||||||
|  |         _uiSharedService = uiSharedService; | ||||||
|  |         _fileDialogManager = fileDialogManager; | ||||||
|  |         _mareProfileManager = mareProfileManager; | ||||||
|  |  | ||||||
|  |         Mediator.Subscribe<GposeStartMessage>(this, (_) => { _wasOpen = IsOpen; IsOpen = false; }); | ||||||
|  |         Mediator.Subscribe<GposeEndMessage>(this, (_) => IsOpen = _wasOpen); | ||||||
|  |         Mediator.Subscribe<DisconnectedMessage>(this, (_) => IsOpen = false); | ||||||
|  |         Mediator.Subscribe<ClearProfileDataMessage>(this, (msg) => | ||||||
|  |         { | ||||||
|  |             if (string.Equals(msg.UserData.UID, _apiController.UID, StringComparison.Ordinal)) | ||||||
|  |             { | ||||||
|  |                 _pfpTextureWrap?.Dispose(); | ||||||
|  |                 _pfpTextureWrap = null; | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public override void Draw() | ||||||
|  |     { | ||||||
|  |         _uiSharedService.BigText("Current Profile"); | ||||||
|  |  | ||||||
|  |         var (loaded, profile) = _mareProfileManager.GetMareProfile(new API.Data.UserData(_apiController.UID)); | ||||||
|  |  | ||||||
|  |         if (!loaded) | ||||||
|  |         { | ||||||
|  |             _loadedPrior = false; | ||||||
|  |             _descriptionText = string.Empty; | ||||||
|  |             ImGui.TextUnformatted("Loading profile..."); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             if (profile.IsFlagged) | ||||||
|  |             { | ||||||
|  |                 UiSharedService.ColorTextWrapped(profile.Description, ImGuiColors.DalamudRed); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (!_loadedPrior) | ||||||
|  |             { | ||||||
|  |                 _descriptionText = profile.Description; | ||||||
|  |                 _loadedPrior = true; | ||||||
|  |                 _pfpTextureWrap?.Dispose(); | ||||||
|  |                 _pfpTextureWrap = _uiBuilder.LoadImage(Convert.FromBase64String(profile.Base64ProfilePicture)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (_pfpTextureWrap != null) | ||||||
|  |         { | ||||||
|  |             ImGui.Image(_pfpTextureWrap.ImGuiHandle, new System.Numerics.Vector2(_pfpTextureWrap.Width, _pfpTextureWrap.Height)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         ImGui.SameLine(256); | ||||||
|  |         var posX = ImGui.GetCursorPosX(); | ||||||
|  |         var spacing = ImGui.GetStyle().ItemSpacing.X; | ||||||
|  |         var width = UiSharedService.GetWindowContentRegionWidth() - posX + spacing; | ||||||
|  |         if (ImGui.BeginChildFrame(100, new System.Numerics.Vector2(width, 256))) | ||||||
|  |         { | ||||||
|  |             var nsfw = profile.IsNSFW; | ||||||
|  |             ImGui.BeginDisabled(); | ||||||
|  |             ImGui.Checkbox("Is NSFW", ref nsfw); | ||||||
|  |             ImGui.EndDisabled(); | ||||||
|  |             UiSharedService.TextWrapped("Description:" + Environment.NewLine + profile.Description); | ||||||
|  |         } | ||||||
|  |         ImGui.EndChildFrame(); | ||||||
|  |  | ||||||
|  |         ImGui.Separator(); | ||||||
|  |         _uiSharedService.BigText("Notes and Rules for Profiles"); | ||||||
|  |  | ||||||
|  |         ImGui.TextWrapped($"- All users that are paired and unpaused with you will be able to see your profile picture and description.{Environment.NewLine}" + | ||||||
|  |             $"- Other users have the possibility to report your profile for breaking the rules.{Environment.NewLine}" + | ||||||
|  |             $"- !!! AVOID: anything as profile image that can be considered highly illegal or obscene (bestiality, anything that could be considered a sexual act with a minor (that includes Lalafells), etc.){Environment.NewLine}" + | ||||||
|  |             $"- !!! AVOID: slurs of any kind in the description that can be considered highly offensive{Environment.NewLine}" + | ||||||
|  |             $"- In case of valid reports from other users this can lead to disabling your profile forever or terminating your Mare account indefinitely.{Environment.NewLine}" + | ||||||
|  |             $"- Judgement of your profile validity from reports through staff is not up to debate and decisions to disable your profile/account permanent.{Environment.NewLine}" + | ||||||
|  |             $"- If your profile picture or profile description could be considered NSFW, enable the toggle below."); | ||||||
|  |         ImGui.Separator(); | ||||||
|  |         _uiSharedService.BigText("Profile Settings"); | ||||||
|  |  | ||||||
|  |         if (UiSharedService.IconTextButton(FontAwesomeIcon.FileUpload, "Upload new profile image")) | ||||||
|  |         { | ||||||
|  |             _fileDialogManager.OpenFileDialog("Select new Profile picture", ".png", (success, file) => | ||||||
|  |             { | ||||||
|  |                 if (!success) return; | ||||||
|  |                 Task.Run(async () => | ||||||
|  |                 { | ||||||
|  |                     var fileContent = File.ReadAllBytes(file); | ||||||
|  |                     using MemoryStream ms = new(fileContent); | ||||||
|  |                     var format = await Image.DetectFormatAsync(ms).ConfigureAwait(false); | ||||||
|  |                     if (!format.FileExtensions.Contains("png", StringComparer.OrdinalIgnoreCase)) | ||||||
|  |                     { | ||||||
|  |                         _showFileDialogError = true; | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                     using var image = Image.Load<Rgba32>(fileContent); | ||||||
|  |  | ||||||
|  |                     if (image.Width > 256 || image.Height > 256 || (fileContent.Length > 250 * 1024)) | ||||||
|  |                     { | ||||||
|  |                         _showFileDialogError = true; | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     _showFileDialogError = false; | ||||||
|  |                     await _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), false, null, Convert.ToBase64String(fileContent), null)) | ||||||
|  |                         .ConfigureAwait(false); | ||||||
|  |                 }); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |         UiSharedService.AttachToolTip("Select and upload a new profile picture"); | ||||||
|  |         ImGui.SameLine(); | ||||||
|  |         if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Clear uploaded profile picture")) | ||||||
|  |         { | ||||||
|  |             _ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), false, null, "", null)); | ||||||
|  |         } | ||||||
|  |         UiSharedService.AttachToolTip("Clear your currently uploaded profile picture"); | ||||||
|  |         if (_showFileDialogError) | ||||||
|  |         { | ||||||
|  |             UiSharedService.ColorTextWrapped("The profile picture must be a PNG file with a maximum height and width of 256px and 250KiB size", ImGuiColors.DalamudRed); | ||||||
|  |         } | ||||||
|  |         var isNsfw = profile.IsNSFW; | ||||||
|  |         if (ImGui.Checkbox("Profile is NSFW", ref isNsfw)) | ||||||
|  |         { | ||||||
|  |             _ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), false, isNsfw, null, null)); | ||||||
|  |         } | ||||||
|  |         UiSharedService.DrawHelpText("If your profile description or image can be considered NSFW, toggle this to ON"); | ||||||
|  |         var widthTextBox = UiSharedService.GetWindowContentRegionWidth() - posX + spacing; | ||||||
|  |         ImGui.TextUnformatted($"Description {_descriptionText.Length}/750"); | ||||||
|  |         ImGui.InputTextMultiline("##description", ref _descriptionText, 750, new System.Numerics.Vector2(widthTextBox, 200)); | ||||||
|  |         if (UiSharedService.IconTextButton(FontAwesomeIcon.Save, "Save Description")) | ||||||
|  |         { | ||||||
|  |             _ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), false, null, null, _descriptionText)); | ||||||
|  |         } | ||||||
|  |         UiSharedService.AttachToolTip("Sets your profile description text"); | ||||||
|  |         ImGui.SameLine(); | ||||||
|  |         if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Clear Description")) | ||||||
|  |         { | ||||||
|  |             _ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), false, null, null, "")); | ||||||
|  |         } | ||||||
|  |         UiSharedService.AttachToolTip("Clears your profile description text"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     protected override void Dispose(bool disposing) | ||||||
|  |     { | ||||||
|  |         base.Dispose(disposing); | ||||||
|  |         _pfpTextureWrap?.Dispose(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -3,53 +3,186 @@ using ImGuiNET; | |||||||
| using MareSynchronos.PlayerData.Pairs; | using MareSynchronos.PlayerData.Pairs; | ||||||
| using MareSynchronos.Services.ServerConfiguration; | using MareSynchronos.Services.ServerConfiguration; | ||||||
| using MareSynchronos.MareConfiguration; | using MareSynchronos.MareConfiguration; | ||||||
|  | using Dalamud.Interface.Colors; | ||||||
|  | using MareSynchronos.API.Data.Extensions; | ||||||
|  | using ImGuiScene; | ||||||
|  | using System.Numerics; | ||||||
|  | using Microsoft.Extensions.Logging; | ||||||
|  | using MareSynchronos.Services; | ||||||
|  |  | ||||||
| namespace MareSynchronos.UI.Handlers; | namespace MareSynchronos.UI.Handlers; | ||||||
|  |  | ||||||
| public class UidDisplayHandler | public class UidDisplayHandler | ||||||
| { | { | ||||||
|  |     private readonly ILogger<UidDisplayHandler> _logger; | ||||||
|     private readonly MareConfigService _mareConfigService; |     private readonly MareConfigService _mareConfigService; | ||||||
|  |     private readonly MareProfileManager _mareProfileManager; | ||||||
|     private readonly PairManager _pairManager; |     private readonly PairManager _pairManager; | ||||||
|     private readonly ServerConfigurationManager _serverManager; |     private readonly ServerConfigurationManager _serverManager; | ||||||
|     private readonly Dictionary<string, bool> _showUidForEntry = new(StringComparer.Ordinal); |     private readonly Dictionary<string, bool> _showUidForEntry = new(StringComparer.Ordinal); | ||||||
|  |     private readonly UiBuilder _uiBuilder; | ||||||
|  |     private readonly UiSharedService _uiSharedService; | ||||||
|     private string _editNickEntry = string.Empty; |     private string _editNickEntry = string.Empty; | ||||||
|     private string _editUserComment = string.Empty; |     private string _editUserComment = string.Empty; | ||||||
|  |     private string _lastMouseOverUid = string.Empty; | ||||||
|  |     private byte[] _lastProfilePicture = Array.Empty<byte>(); | ||||||
|  |     private DateTime? _popupTime; | ||||||
|  |     private TextureWrap? _textureWrap; | ||||||
|  |  | ||||||
|     public UidDisplayHandler(PairManager pairManager, ServerConfigurationManager serverManager, MareConfigService mareConfigService) |     public UidDisplayHandler(ILogger<UidDisplayHandler> logger, UiBuilder uiBuilder, MareProfileManager mareProfileManager, | ||||||
|  |         UiSharedService uiSharedService, PairManager pairManager, ServerConfigurationManager serverManager, MareConfigService mareConfigService) | ||||||
|     { |     { | ||||||
|  |         _logger = logger; | ||||||
|  |         _uiBuilder = uiBuilder; | ||||||
|  |         _mareProfileManager = mareProfileManager; | ||||||
|  |         _uiSharedService = uiSharedService; | ||||||
|         _pairManager = pairManager; |         _pairManager = pairManager; | ||||||
|         _serverManager = serverManager; |         _serverManager = serverManager; | ||||||
|         _mareConfigService = mareConfigService; |         _mareConfigService = mareConfigService; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void DrawPairText(Pair entry, float textPosX, float originalY, Func<float> editBoxWidth) |     public void DrawPairText(string id, Pair pair, float textPosX, float originalY, Func<float> editBoxWidth) | ||||||
|     { |     { | ||||||
|         ImGui.SameLine(textPosX); |         ImGui.SameLine(textPosX); | ||||||
|         (bool textIsUid, string playerText) = GetPlayerText(entry); |         (bool textIsUid, string playerText) = GetPlayerText(pair); | ||||||
|         if (!string.Equals(_editNickEntry, entry.UserData.UID, StringComparison.Ordinal)) |         if (!string.Equals(_editNickEntry, pair.UserData.UID, StringComparison.Ordinal)) | ||||||
|         { |         { | ||||||
|             ImGui.SetCursorPosY(originalY); |             ImGui.SetCursorPosY(originalY); | ||||||
|             if (textIsUid) ImGui.PushFont(UiBuilder.MonoFont); |             if (textIsUid) ImGui.PushFont(UiBuilder.MonoFont); | ||||||
|             ImGui.TextUnformatted(playerText); |             ImGui.TextUnformatted(playerText); | ||||||
|             if (textIsUid) ImGui.PopFont(); |             if (textIsUid) ImGui.PopFont(); | ||||||
|             UiSharedService.AttachToolTip("Left click to switch between UID display and nick" + Environment.NewLine + |             if (ImGui.IsItemHovered()) | ||||||
|                           "Right click to change nick for " + entry.UserData.UID); |             { | ||||||
|  |                 if (!string.Equals(_lastMouseOverUid, id)) | ||||||
|  |                 { | ||||||
|  |                     _popupTime = DateTime.UtcNow.AddSeconds(_mareConfigService.Current.ProfileDelay); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 _lastMouseOverUid = id; | ||||||
|  |  | ||||||
|  |                 if (_popupTime > DateTime.UtcNow || !_mareConfigService.Current.ProfilesShow) | ||||||
|  |                 { | ||||||
|  |                     ImGui.SetTooltip("Left click to switch between UID display and nick" + Environment.NewLine + "Right click to change nick for " + pair.UserData.AliasOrUID); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     try | ||||||
|  |                     { | ||||||
|  |                         var spacing = ImGui.GetStyle().ItemSpacing; | ||||||
|  |  | ||||||
|  |                         ImGui.SetNextWindowSizeConstraints(new Vector2(512 + spacing.X * 4, 256 + spacing.Y * 3), new Vector2(512 + spacing.X * 4, 512 + spacing.Y * 3)); | ||||||
|  |                         ImGui.BeginTooltip(); | ||||||
|  |  | ||||||
|  |                         var mareProfile = _mareProfileManager.GetMareProfile(pair.UserData); | ||||||
|  |  | ||||||
|  |                         if (_textureWrap == null || !mareProfile.Profile.ImageData.Value.SequenceEqual(_lastProfilePicture)) | ||||||
|  |                         { | ||||||
|  |                             _textureWrap?.Dispose(); | ||||||
|  |                             _lastProfilePicture = mareProfile.Profile.ImageData.Value; | ||||||
|  |                             _textureWrap = _uiBuilder.LoadImage(_lastProfilePicture); | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         var drawList = ImGui.GetWindowDrawList(); | ||||||
|  |                         var rect = drawList.GetClipRectMin(); | ||||||
|  |                         var rectMax = drawList.GetClipRectMax(); | ||||||
|  |  | ||||||
|  |                         ImGui.Indent(256 + spacing.X * 2); | ||||||
|  |                         if (_uiSharedService.UidFontBuilt) ImGui.PushFont(_uiSharedService.UidFont); | ||||||
|  |                         UiSharedService.ColorText(pair.UserData.AliasOrUID, ImGuiColors.HealerGreen); | ||||||
|  |                         if (_uiSharedService.UidFontBuilt) ImGui.PopFont(); | ||||||
|  |                         var pos = ImGui.GetCursorPos(); | ||||||
|  |                         var note = _serverManager.GetNoteForUid(pair.UserData.UID); | ||||||
|  |                         if (!string.IsNullOrEmpty(note)) | ||||||
|  |                         { | ||||||
|  |                             UiSharedService.ColorText(note, ImGuiColors.DalamudGrey); | ||||||
|  |                         } | ||||||
|  |                         string status = pair.IsVisible ? "Visible" : (pair.IsOnline ? "Online" : "Offline"); | ||||||
|  |                         UiSharedService.ColorText(status, (pair.IsVisible || pair.IsOnline) ? ImGuiColors.HealerGreen : ImGuiColors.DalamudRed); | ||||||
|  |                         if (pair.IsVisible) | ||||||
|  |                         { | ||||||
|  |                             ImGui.SameLine(); | ||||||
|  |                             ImGui.TextUnformatted($"({pair.PlayerName})"); | ||||||
|  |                         } | ||||||
|  |                         if (pair.UserPair != null) | ||||||
|  |                         { | ||||||
|  |                             ImGui.TextUnformatted("Directly paired"); | ||||||
|  |                             if (pair.UserPair.OwnPermissions.IsPaused()) | ||||||
|  |                             { | ||||||
|  |                                 ImGui.SameLine(); | ||||||
|  |                                 UiSharedService.ColorText("You: paused", ImGuiColors.DalamudYellow); | ||||||
|  |                             } | ||||||
|  |                             if (pair.UserPair.OtherPermissions.IsPaused()) | ||||||
|  |                             { | ||||||
|  |                                 ImGui.SameLine(); | ||||||
|  |                                 UiSharedService.ColorText("They: paused", ImGuiColors.DalamudYellow); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         if (pair.GroupPair.Any()) | ||||||
|  |                         { | ||||||
|  |                             ImGui.TextUnformatted("Paired through Syncshells:"); | ||||||
|  |                             foreach (var groupPair in pair.GroupPair) | ||||||
|  |                             { | ||||||
|  |                                 ImGui.TextUnformatted("- " + groupPair.Key.GroupAliasOrGID); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         var posDone = ImGui.GetCursorPos(); | ||||||
|  |                         UiSharedService.TextWrapped(mareProfile.Profile.Description); | ||||||
|  |                         ImGui.Unindent(); | ||||||
|  |  | ||||||
|  |                         var sepColor = ImGui.GetStyle().Colors[(int)ImGuiCol.Separator]; | ||||||
|  |  | ||||||
|  |                         bool tallerThanWide = _textureWrap.Height >= _textureWrap.Width; | ||||||
|  |                         var stretchFactor = tallerThanWide ? 256f / _textureWrap.Height : 256f / _textureWrap.Width; | ||||||
|  |                         var newWidth = _textureWrap.Width * stretchFactor; | ||||||
|  |                         var newHeight = _textureWrap.Height * stretchFactor; | ||||||
|  |                         var remainingWidth = (256f - newWidth) / 2f; | ||||||
|  |                         var remainingHeight = (256f - newHeight) / 2f; | ||||||
|  |                         drawList.AddImage(_textureWrap.ImGuiHandle, new Vector2(rect.X + spacing.X + remainingWidth, rect.Y + spacing.Y + remainingHeight), | ||||||
|  |                             new Vector2(rect.X + spacing.X + remainingWidth + newWidth, rect.Y + spacing.Y + remainingHeight + newHeight)); | ||||||
|  |  | ||||||
|  |                         drawList.AddLine(new Vector2(rect.X + 256 + spacing.X * 2, rect.Y + pos.Y - spacing.Y), | ||||||
|  |                             new Vector2(rectMax.X - spacing.X, rect.Y + pos.Y - spacing.Y), | ||||||
|  |                             UiSharedService.Color((byte)(sepColor.X * 255), (byte)(sepColor.Y * 255), (byte)(sepColor.Z * 255), (byte)(sepColor.W * 255))); | ||||||
|  |                         drawList.AddLine(new Vector2(rect.X + 256 + spacing.X * 2, rect.Y + posDone.Y - spacing.Y), | ||||||
|  |                             new Vector2(rectMax.X - spacing.X, rect.Y + posDone.Y - spacing.Y), | ||||||
|  |                             UiSharedService.Color((byte)(sepColor.X * 255), (byte)(sepColor.Y * 255), (byte)(sepColor.Z * 255), (byte)(sepColor.W * 255))); | ||||||
|  |  | ||||||
|  |                         ImGui.EndTooltip(); | ||||||
|  |                     } | ||||||
|  |                     catch (Exception ex) | ||||||
|  |                     { | ||||||
|  |                         _logger.LogWarning("Error during draw tooltip", ex); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 if (string.Equals(_lastMouseOverUid, id)) | ||||||
|  |                 { | ||||||
|  |                     _lastProfilePicture = Array.Empty<byte>(); | ||||||
|  |                     _lastMouseOverUid = string.Empty; | ||||||
|  |                     _textureWrap?.Dispose(); | ||||||
|  |                     _textureWrap = null; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|             if (ImGui.IsItemClicked(ImGuiMouseButton.Left)) |             if (ImGui.IsItemClicked(ImGuiMouseButton.Left)) | ||||||
|             { |             { | ||||||
|                 var prevState = textIsUid; |                 var prevState = textIsUid; | ||||||
|                 if (_showUidForEntry.ContainsKey(entry.UserData.UID)) |                 if (_showUidForEntry.ContainsKey(pair.UserData.UID)) | ||||||
|                 { |                 { | ||||||
|                     prevState = _showUidForEntry[entry.UserData.UID]; |                     prevState = _showUidForEntry[pair.UserData.UID]; | ||||||
|                 } |                 } | ||||||
|                 _showUidForEntry[entry.UserData.UID] = !prevState; |                 _showUidForEntry[pair.UserData.UID] = !prevState; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) |             if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) | ||||||
|             { |             { | ||||||
|                 var pair = _pairManager.DirectPairs.Find(p => string.Equals(p.UserData.UID, _editNickEntry, StringComparison.Ordinal)); |                 var nickEntryPair = _pairManager.DirectPairs.Find(p => string.Equals(p.UserData.UID, _editNickEntry, StringComparison.Ordinal)); | ||||||
|                 pair?.SetNote(_editUserComment); |                 nickEntryPair?.SetNote(_editUserComment); | ||||||
|                 _editUserComment = entry.GetNote() ?? string.Empty; |                 _editUserComment = pair.GetNote() ?? string.Empty; | ||||||
|                 _editNickEntry = entry.UserData.UID; |                 _editNickEntry = pair.UserData.UID; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
| @@ -59,7 +192,7 @@ public class UidDisplayHandler | |||||||
|             ImGui.SetNextItemWidth(editBoxWidth.Invoke()); |             ImGui.SetNextItemWidth(editBoxWidth.Invoke()); | ||||||
|             if (ImGui.InputTextWithHint("", "Nick/Notes", ref _editUserComment, 255, ImGuiInputTextFlags.EnterReturnsTrue)) |             if (ImGui.InputTextWithHint("", "Nick/Notes", ref _editUserComment, 255, ImGuiInputTextFlags.EnterReturnsTrue)) | ||||||
|             { |             { | ||||||
|                 _serverManager.SetNoteForUid(entry.UserData.UID, _editUserComment); |                 _serverManager.SetNoteForUid(pair.UserData.UID, _editUserComment); | ||||||
|                 _serverManager.SaveNotes(); |                 _serverManager.SaveNotes(); | ||||||
|                 _editNickEntry = string.Empty; |                 _editNickEntry = string.Empty; | ||||||
|             } |             } | ||||||
| @@ -81,7 +214,7 @@ public class UidDisplayHandler | |||||||
|         { |         { | ||||||
|             if (string.IsNullOrEmpty(playerText)) |             if (string.IsNullOrEmpty(playerText)) | ||||||
|             { |             { | ||||||
|                 playerText = pair.UserData.UID; |                 playerText = pair.UserData.AliasOrUID; | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
| @@ -90,7 +223,7 @@ public class UidDisplayHandler | |||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             playerText = pair.UserData.UID; |             playerText = pair.UserData.AliasOrUID; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (_mareConfigService.Current.ShowCharacterNameInsteadOfNotesForVisible && pair.IsVisible && !showUidInsteadOfName) |         if (_mareConfigService.Current.ShowCharacterNameInsteadOfNotesForVisible && pair.IsVisible && !showUidInsteadOfName) | ||||||
|   | |||||||
| @@ -490,9 +490,11 @@ public class SettingsUi : WindowMediatorSubscriberBase | |||||||
|         ImGui.Separator(); |         ImGui.Separator(); | ||||||
|         UiSharedService.FontText("UI", _uiShared.UidFont); |         UiSharedService.FontText("UI", _uiShared.UidFont); | ||||||
|         var showNameInsteadOfNotes = _configService.Current.ShowCharacterNameInsteadOfNotesForVisible; |         var showNameInsteadOfNotes = _configService.Current.ShowCharacterNameInsteadOfNotesForVisible; | ||||||
|         var reverseUserSort = _configService.Current.ReverseUserSort; |  | ||||||
|         var showVisibleSeparate = _configService.Current.ShowVisibleUsersSeparately; |         var showVisibleSeparate = _configService.Current.ShowVisibleUsersSeparately; | ||||||
|         var showOfflineSeparate = _configService.Current.ShowOfflineUsersSeparately; |         var showOfflineSeparate = _configService.Current.ShowOfflineUsersSeparately; | ||||||
|  |         var showProfiles = _configService.Current.ProfilesShow; | ||||||
|  |         var showNsfwProfiles = _configService.Current.ProfilesAllowNsfw; | ||||||
|  |         var profileDelay = _configService.Current.ProfileDelay; | ||||||
|  |  | ||||||
|         if (ImGui.Checkbox("Show separate Visible group", ref showVisibleSeparate)) |         if (ImGui.Checkbox("Show separate Visible group", ref showVisibleSeparate)) | ||||||
|         { |         { | ||||||
| @@ -515,12 +517,30 @@ public class SettingsUi : WindowMediatorSubscriberBase | |||||||
|         } |         } | ||||||
|         UiSharedService.DrawHelpText("This will show the character name instead of custom set note when a character is visible"); |         UiSharedService.DrawHelpText("This will show the character name instead of custom set note when a character is visible"); | ||||||
|  |  | ||||||
|         if (ImGui.Checkbox("Reverse user sort", ref reverseUserSort)) |         if (ImGui.Checkbox("Show Mare Profiles on Hover", ref showProfiles)) | ||||||
|         { |         { | ||||||
|             _configService.Current.ReverseUserSort = reverseUserSort; |             Mediator.Publish(new ClearProfileDataMessage()); | ||||||
|  |             _configService.Current.ProfilesShow = showProfiles; | ||||||
|             _configService.Save(); |             _configService.Save(); | ||||||
|         } |         } | ||||||
|         UiSharedService.DrawHelpText("This reverses the user sort from A->Z to Z->A"); |         UiSharedService.DrawHelpText("This will show the configured user profile after a set delay"); | ||||||
|  |         ImGui.Indent(); | ||||||
|  |         if (!showProfiles) ImGui.BeginDisabled(); | ||||||
|  |         if (ImGui.Checkbox("Show profiles marked as NSFW", ref showNsfwProfiles)) | ||||||
|  |         { | ||||||
|  |             Mediator.Publish(new ClearProfileDataMessage()); | ||||||
|  |             _configService.Current.ProfilesAllowNsfw = showNsfwProfiles; | ||||||
|  |             _configService.Save(); | ||||||
|  |         } | ||||||
|  |         UiSharedService.DrawHelpText("Will show profiles that have the NSFW tag enabled"); | ||||||
|  |         if (ImGui.SliderFloat("Hover Delay", ref profileDelay, 1, 10)) | ||||||
|  |         { | ||||||
|  |             _configService.Current.ProfileDelay = profileDelay; | ||||||
|  |             _configService.Save(); | ||||||
|  |         } | ||||||
|  |         UiSharedService.DrawHelpText("Delay until the profile should be displayed"); | ||||||
|  |         if (!showProfiles) ImGui.EndDisabled(); | ||||||
|  |         ImGui.Unindent(); | ||||||
|  |  | ||||||
|         ImGui.Separator(); |         ImGui.Separator(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -161,13 +161,13 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|     public static uint Color(Vector4 color) |     public static uint Color(Vector4 color) | ||||||
|     { |     { | ||||||
|         uint ret = (byte)(color.W); |         uint ret = (byte)(color.W * 255); | ||||||
|         ret <<= 8; |         ret <<= 8; | ||||||
|         ret += (byte)(color.X); |         ret += (byte)(color.Z * 255); | ||||||
|         ret <<= 8; |         ret <<= 8; | ||||||
|         ret += (byte)(color.Y); |         ret += (byte)(color.Y * 255); | ||||||
|         ret <<= 8; |         ret <<= 8; | ||||||
|         ret += (byte)(color.Z); |         ret += (byte)(color.X * 255); | ||||||
|         return ret; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -452,6 +452,13 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase | |||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public void BigText(string text) | ||||||
|  |     { | ||||||
|  |         if (UidFontBuilt) ImGui.PushFont(UidFont); | ||||||
|  |         ImGui.TextUnformatted(text); | ||||||
|  |         if (UidFontBuilt) ImGui.PopFont(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public void DrawCacheDirectorySetting() |     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); |         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); | ||||||
|   | |||||||
| @@ -49,6 +49,12 @@ public partial class ApiController | |||||||
|         return await _mareHub!.InvokeAsync<List<UserPairDto>>(nameof(UserGetPairedClients)).ConfigureAwait(false); |         return await _mareHub!.InvokeAsync<List<UserPairDto>>(nameof(UserGetPairedClients)).ConfigureAwait(false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public async Task<UserProfileDto> UserGetProfile(UserDto dto) | ||||||
|  |     { | ||||||
|  |         if (!IsConnected) return new UserProfileDto(dto.User, false, null, null, null); | ||||||
|  |         return await _mareHub!.InvokeAsync<UserProfileDto>(nameof(UserGetProfile), dto).ConfigureAwait(false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public async Task UserPushData(UserCharaDataMessageDto dto) |     public async Task UserPushData(UserCharaDataMessageDto dto) | ||||||
|     { |     { | ||||||
|         try |         try | ||||||
| @@ -67,11 +73,23 @@ public partial class ApiController | |||||||
|         await _mareHub!.SendAsync(nameof(UserRemovePair), userDto).ConfigureAwait(false); |         await _mareHub!.SendAsync(nameof(UserRemovePair), userDto).ConfigureAwait(false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public async Task UserReportProfile(UserProfileReportDto userDto) | ||||||
|  |     { | ||||||
|  |         if (!IsConnected) return; | ||||||
|  |         await _mareHub!.SendAsync(nameof(UserReportProfile), userDto).ConfigureAwait(false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public async Task UserSetPairPermissions(UserPermissionsDto userPermissions) |     public async Task UserSetPairPermissions(UserPermissionsDto userPermissions) | ||||||
|     { |     { | ||||||
|         await _mareHub!.SendAsync(nameof(UserSetPairPermissions), userPermissions).ConfigureAwait(false); |         await _mareHub!.SendAsync(nameof(UserSetPairPermissions), userPermissions).ConfigureAwait(false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public async Task UserSetProfile(UserProfileDto userDescription) | ||||||
|  |     { | ||||||
|  |         if (!IsConnected) return; | ||||||
|  |         await _mareHub!.InvokeAsync(nameof(UserSetProfile), userDescription).ConfigureAwait(false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private async Task PushCharacterDataInternal(CharacterData character, List<UserData> visibleCharacters) |     private async Task PushCharacterDataInternal(CharacterData character, List<UserData> visibleCharacters) | ||||||
|     { |     { | ||||||
|         Logger.LogInformation("Pushing character data for {hash} to {charas}", character.DataHash.Value, string.Join(", ", visibleCharacters.Select(c => c.AliasOrUID))); |         Logger.LogInformation("Pushing character data for {hash} to {charas}", character.DataHash.Value, string.Join(", ", visibleCharacters.Select(c => c.AliasOrUID))); | ||||||
|   | |||||||
| @@ -162,6 +162,13 @@ public partial class ApiController | |||||||
|         return Task.CompletedTask; |         return Task.CompletedTask; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public Task Client_UserUpdateProfile(UserDto dto) | ||||||
|  |     { | ||||||
|  |         Logger.LogDebug("Client_UserUpdateProfile: {dto}", dto); | ||||||
|  |         ExecuteSafely(() => Mediator.Publish(new ClearProfileDataMessage(dto.User))); | ||||||
|  |         return Task.CompletedTask; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public Task Client_UserUpdateSelfPairPermissions(UserPermissionsDto dto) |     public Task Client_UserUpdateSelfPairPermissions(UserPermissionsDto dto) | ||||||
|     { |     { | ||||||
|         Logger.LogDebug("Client_UserUpdateSelfPairPermissions: {dto}", dto); |         Logger.LogDebug("Client_UserUpdateSelfPairPermissions: {dto}", dto); | ||||||
| @@ -277,6 +284,12 @@ public partial class ApiController | |||||||
|         _mareHub!.On(nameof(Client_UserUpdateOtherPairPermissions), act); |         _mareHub!.On(nameof(Client_UserUpdateOtherPairPermissions), act); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public void OnUserUpdateProfile(Action<UserDto> act) | ||||||
|  |     { | ||||||
|  |         if (_initialized) return; | ||||||
|  |         _mareHub!.On(nameof(Client_UserUpdateProfile), act); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public void OnUserUpdateSelfPairPermissions(Action<UserPermissionsDto> act) |     public void OnUserUpdateSelfPairPermissions(Action<UserPermissionsDto> act) | ||||||
|     { |     { | ||||||
|         if (_initialized) return; |         if (_initialized) return; | ||||||
|   | |||||||
| @@ -244,6 +244,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM | |||||||
|         OnUserUpdateOtherPairPermissions(dto => Client_UserUpdateOtherPairPermissions(dto)); |         OnUserUpdateOtherPairPermissions(dto => Client_UserUpdateOtherPairPermissions(dto)); | ||||||
|         OnUserUpdateSelfPairPermissions(dto => Client_UserUpdateSelfPairPermissions(dto)); |         OnUserUpdateSelfPairPermissions(dto => Client_UserUpdateSelfPairPermissions(dto)); | ||||||
|         OnUserReceiveUploadStatus(dto => Client_UserReceiveUploadStatus(dto)); |         OnUserReceiveUploadStatus(dto => Client_UserReceiveUploadStatus(dto)); | ||||||
|  |         OnUserUpdateProfile(dto => Client_UserUpdateProfile(dto)); | ||||||
|  |  | ||||||
|         OnGroupChangePermissions((dto) => Client_GroupChangePermissions(dto)); |         OnGroupChangePermissions((dto) => Client_GroupChangePermissions(dto)); | ||||||
|         OnGroupDelete((dto) => Client_GroupDelete(dto)); |         OnGroupDelete((dto) => Client_GroupDelete(dto)); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 rootdarkarchon
					rootdarkarchon