diff --git a/LightlessAPI b/LightlessAPI index 3c10380..5bfd21a 160000 --- a/LightlessAPI +++ b/LightlessAPI @@ -1 +1 @@ -Subproject commit 3c10380162b162c47c99f63ecfc627a49887fe84 +Subproject commit 5bfd21aaa90817f14c9e2931e77b20f4276f16ed diff --git a/LightlessSync/UI/BroadcastUI.cs b/LightlessSync/UI/BroadcastUI.cs index 90b19ad..4977fb6 100644 --- a/LightlessSync/UI/BroadcastUI.cs +++ b/LightlessSync/UI/BroadcastUI.cs @@ -131,7 +131,7 @@ namespace LightlessSync.UI ImGuiHelpers.ScaledDummy(0.25f); } - if (ImGui.BeginTabBar("##MyTabBar")) + if (ImGui.BeginTabBar("##BroadcastTabs")) { if (ImGui.BeginTabItem("Lightfinder")) { diff --git a/LightlessSync/UI/EditProfileUi.cs b/LightlessSync/UI/EditProfileUi.cs index 753c790..6c787b3 100644 --- a/LightlessSync/UI/EditProfileUi.cs +++ b/LightlessSync/UI/EditProfileUi.cs @@ -4,14 +4,17 @@ using Dalamud.Interface.Colors; using Dalamud.Interface.ImGuiFileDialog; using Dalamud.Interface.Textures.TextureWraps; using Dalamud.Interface.Utility; +using Dalamud.Interface.Utility.Raii; using LightlessSync.API.Data; using LightlessSync.API.Dto.User; using LightlessSync.Services; using LightlessSync.Services.Mediator; +using LightlessSync.Utils; using LightlessSync.WebAPI; using Microsoft.Extensions.Logging; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; +using System.Numerics; namespace LightlessSync.UI; @@ -30,6 +33,15 @@ public class EditProfileUi : WindowMediatorSubscriberBase private bool _showFileDialogError = false; private bool _wasOpen; + private bool vanityInitialized; // useless for now + private bool textEnabled; + private bool glowEnabled; + private Vector4 textColor; + private Vector4 glowColor; + + private record VanityState(bool TextEnabled, bool GlowEnabled, Vector4 TextColor, Vector4 GlowColor); + private VanityState _savedVanity; + public EditProfileUi(ILogger logger, LightlessMediator mediator, ApiController apiController, UiSharedService uiSharedService, FileDialogManager fileDialogManager, LightlessProfileManager lightlessProfileManager, PerformanceCollectorService performanceCollectorService) @@ -38,8 +50,8 @@ public class EditProfileUi : WindowMediatorSubscriberBase IsOpen = false; this.SizeConstraints = new() { - MinimumSize = new(768, 512), - MaximumSize = new(768, 2000) + MinimumSize = new(850, 640), + MaximumSize = new(850, 700) }; _apiController = apiController; _uiSharedService = uiSharedService; @@ -57,172 +69,314 @@ public class EditProfileUi : WindowMediatorSubscriberBase _pfpTextureWrap = null; } }); + Mediator.Subscribe(this, msg => + { + LoadVanity(); + }); + } + + void DrawNoteLine(string icon, Vector4 color, string text) + { + _uiSharedService.MediumText(icon, color); + ImGui.SameLine(); + + ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 3); + ImGui.TextWrapped(text); + } + + private void LoadVanity() + { + textEnabled = !string.IsNullOrEmpty(_apiController.TextColorHex); + glowEnabled = !string.IsNullOrEmpty(_apiController.TextGlowColorHex); + + textColor = textEnabled ? UIColors.HexToRgba(_apiController.TextColorHex!) : Vector4.One; + glowColor = glowEnabled ? UIColors.HexToRgba(_apiController.TextGlowColorHex!) : Vector4.Zero; + + _savedVanity = new VanityState(textEnabled, glowEnabled, textColor, glowColor); + vanityInitialized = true; } protected override void DrawInternal() { - _uiSharedService.BigText("Current Profile (as saved on server)"); + _uiSharedService.UnderlinedBigText("Notes and Rules for Profiles", UIColors.Get("LightlessYellow")); + ImGui.Dummy(new Vector2(5)); + + ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(2, 2)); + + DrawNoteLine("# ", UIColors.Get("LightlessBlue"), "All users that are paired and unpaused with you will be able to see your profile picture and description."); + DrawNoteLine("! ", UIColors.Get("LightlessYellow"), "Other users have the possibility to report your profile for breaking the rules."); + DrawNoteLine("!!! ", UIColors.Get("DimRed"), "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.)"); + DrawNoteLine("!!! ", UIColors.Get("DimRed"), "AVOID: Slurs of any kind in the description that can be considered highly offensive"); + DrawNoteLine("! ", UIColors.Get("LightlessYellow"), "In case of valid reports from other users this can lead to disabling your profile forever or terminating your Lightless account indefinitely."); + DrawNoteLine("! ", UIColors.Get("LightlessYellow"), "Judgement of your profile validity from reports through staff is not up to debate and the decisions to disable your profile/account permanent."); + DrawNoteLine("! ", UIColors.Get("LightlessBlue"), "If your profile picture or profile description could be considered NSFW, enable the toggle in profile settings."); + + ImGui.PopStyleVar(); + + ImGui.Dummy(new Vector2(3)); var profile = _lightlessProfileManager.GetLightlessProfile(new UserData(_apiController.UID)); - if (profile.IsFlagged) - { - UiSharedService.ColorTextWrapped(profile.Description, ImGuiColors.DalamudRed); - return; - } - - if (!_profileImage.SequenceEqual(profile.ImageData.Value)) - { - _profileImage = profile.ImageData.Value; - _pfpTextureWrap?.Dispose(); - _pfpTextureWrap = _uiSharedService.LoadImage(_profileImage); - } - - if (!string.Equals(_profileDescription, profile.Description, StringComparison.OrdinalIgnoreCase)) - { - _profileDescription = profile.Description; - _descriptionText = _profileDescription; - } - - if (_pfpTextureWrap != null) - { - ImGui.Image(_pfpTextureWrap.Handle, ImGuiHelpers.ScaledVector2(_pfpTextureWrap.Width, _pfpTextureWrap.Height)); - } - - var spacing = ImGui.GetStyle().ItemSpacing.X; - ImGuiHelpers.ScaledRelativeSameLine(256, spacing); - using (_uiSharedService.GameFont.Push()) - { - var descriptionTextSize = ImGui.CalcTextSize(profile.Description, wrapWidth: 256f); - var childFrame = ImGuiHelpers.ScaledVector2(256 + ImGui.GetStyle().WindowPadding.X + ImGui.GetStyle().WindowBorderSize, 256); - if (descriptionTextSize.Y > childFrame.Y) + if (ImGui.BeginTabBar("##EditProfileTabs")) + { + if (ImGui.BeginTabItem("Current Profile")) { - _adjustedForScollBarsOnlineProfile = true; - } - else - { - _adjustedForScollBarsOnlineProfile = false; - } - childFrame = childFrame with - { - X = childFrame.X + (_adjustedForScollBarsOnlineProfile ? ImGui.GetStyle().ScrollbarSize : 0), - }; - if (ImGui.BeginChildFrame(101, childFrame)) - { - UiSharedService.TextWrapped(profile.Description); - } - ImGui.EndChildFrame(); - } + _uiSharedService.MediumText("Current Profile (as saved on server)", UIColors.Get("LightlessPurple")); + ImGui.Dummy(new Vector2(5)); - var nsfw = profile.IsNSFW; - ImGui.BeginDisabled(); - ImGui.Checkbox("Is NSFW", ref nsfw); - ImGui.EndDisabled(); - - 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 Lightless account indefinitely.{Environment.NewLine}" + - $"- Judgement of your profile validity from reports through staff is not up to debate and the 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 picture")) - { - _fileDialogManager.OpenFileDialog("Select new Profile picture", ".png", (success, file) => - { - if (!success) return; - _ = Task.Run(async () => + if (profile.IsFlagged) { - 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)) + UiSharedService.ColorTextWrapped(profile.Description, ImGuiColors.DalamudRed); + return; + } + + if (!_profileImage.SequenceEqual(profile.ImageData.Value)) + { + _profileImage = profile.ImageData.Value; + _pfpTextureWrap?.Dispose(); + _pfpTextureWrap = _uiSharedService.LoadImage(_profileImage); + } + + if (!string.Equals(_profileDescription, profile.Description, StringComparison.OrdinalIgnoreCase)) + { + _profileDescription = profile.Description; + _descriptionText = _profileDescription; + } + + if (_pfpTextureWrap != null) + { + ImGui.Image(_pfpTextureWrap.Handle, ImGuiHelpers.ScaledVector2(_pfpTextureWrap.Width, _pfpTextureWrap.Height)); + } + + var spacing = ImGui.GetStyle().ItemSpacing.X; + ImGuiHelpers.ScaledRelativeSameLine(256, spacing); + using (_uiSharedService.GameFont.Push()) + { + var descriptionTextSize = ImGui.CalcTextSize(profile.Description, wrapWidth: 256f); + var childFrame = ImGuiHelpers.ScaledVector2(256 + ImGui.GetStyle().WindowPadding.X + ImGui.GetStyle().WindowBorderSize, 256); + if (descriptionTextSize.Y > childFrame.Y) { - _showFileDialogError = true; - return; + _adjustedForScollBarsOnlineProfile = true; } - using var image = Image.Load(fileContent); - - if (image.Width > 256 || image.Height > 256 || (fileContent.Length > 250 * 1024)) + else { - _showFileDialogError = true; - return; + _adjustedForScollBarsOnlineProfile = false; } + childFrame = childFrame with + { + X = childFrame.X + (_adjustedForScollBarsOnlineProfile ? ImGui.GetStyle().ScrollbarSize : 0), + }; + if (ImGui.BeginChildFrame(101, childFrame)) + { + UiSharedService.TextWrapped(profile.Description); + } + ImGui.EndChildFrame(); + } - _showFileDialogError = false; - await _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, Convert.ToBase64String(fileContent), Description: 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), Disabled: false, IsNSFW: null, "", Description: 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), Disabled: false, isNsfw, ProfilePictureBase64: null, Description: null)); - } - _uiSharedService.DrawHelpText("If your profile description or image can be considered NSFW, toggle this to ON"); - var widthTextBox = 400; - var posX = ImGui.GetCursorPosX(); - ImGui.TextUnformatted($"Description {_descriptionText.Length}/1500"); - ImGui.SetCursorPosX(posX); - ImGuiHelpers.ScaledRelativeSameLine(widthTextBox, ImGui.GetStyle().ItemSpacing.X); - ImGui.TextUnformatted("Preview (approximate)"); - using (_uiSharedService.GameFont.Push()) - ImGui.InputTextMultiline("##description", ref _descriptionText, 1500, ImGuiHelpers.ScaledVector2(widthTextBox, 200)); + var nsfw = profile.IsNSFW; + ImGui.BeginDisabled(); + ImGui.Checkbox("Is NSFW", ref nsfw); + ImGui.EndDisabled(); - ImGui.SameLine(); - - using (_uiSharedService.GameFont.Push()) - { - var descriptionTextSizeLocal = ImGui.CalcTextSize(_descriptionText, wrapWidth: 256f); - var childFrameLocal = ImGuiHelpers.ScaledVector2(256 + ImGui.GetStyle().WindowPadding.X + ImGui.GetStyle().WindowBorderSize, 200); - if (descriptionTextSizeLocal.Y > childFrameLocal.Y) - { - _adjustedForScollBarsLocalProfile = true; + _uiSharedService.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f); + ImGui.EndTabItem(); } - else - { - _adjustedForScollBarsLocalProfile = false; - } - childFrameLocal = childFrameLocal with - { - X = childFrameLocal.X + (_adjustedForScollBarsLocalProfile ? ImGui.GetStyle().ScrollbarSize : 0), - }; - if (ImGui.BeginChildFrame(102, childFrameLocal)) - { - UiSharedService.TextWrapped(_descriptionText); - } - ImGui.EndChildFrame(); - } - if (_uiSharedService.IconTextButton(FontAwesomeIcon.Save, "Save Description")) - { - _ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, ProfilePictureBase64: null, _descriptionText)); + if (ImGui.BeginTabItem("Profile Settings")) + { + _uiSharedService.MediumText("Profile Settings", UIColors.Get("LightlessPurple")); + ImGui.Dummy(new Vector2(5)); + + if (_uiSharedService.IconTextButton(FontAwesomeIcon.FileUpload, "Upload new profile picture")) + { + _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(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), Disabled: false, IsNSFW: null, Convert.ToBase64String(fileContent), Description: 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), Disabled: false, IsNSFW: null, "", Description: 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), Disabled: false, isNsfw, ProfilePictureBase64: null, Description: null)); + } + _uiSharedService.DrawHelpText("If your profile description or image can be considered NSFW, toggle this to ON"); + var widthTextBox = 400; + var posX = ImGui.GetCursorPosX(); + ImGui.TextUnformatted($"Description {_descriptionText.Length}/1500"); + ImGui.SetCursorPosX(posX); + ImGuiHelpers.ScaledRelativeSameLine(widthTextBox, ImGui.GetStyle().ItemSpacing.X); + ImGui.TextUnformatted("Preview (approximate)"); + using (_uiSharedService.GameFont.Push()) + ImGui.InputTextMultiline("##description", ref _descriptionText, 1500, ImGuiHelpers.ScaledVector2(widthTextBox, 200)); + + ImGui.SameLine(); + + using (_uiSharedService.GameFont.Push()) + { + var descriptionTextSizeLocal = ImGui.CalcTextSize(_descriptionText, wrapWidth: 256f); + var childFrameLocal = ImGuiHelpers.ScaledVector2(256 + ImGui.GetStyle().WindowPadding.X + ImGui.GetStyle().WindowBorderSize, 200); + if (descriptionTextSizeLocal.Y > childFrameLocal.Y) + { + _adjustedForScollBarsLocalProfile = true; + } + else + { + _adjustedForScollBarsLocalProfile = false; + } + childFrameLocal = childFrameLocal with + { + X = childFrameLocal.X + (_adjustedForScollBarsLocalProfile ? ImGui.GetStyle().ScrollbarSize : 0), + }; + if (ImGui.BeginChildFrame(102, childFrameLocal)) + { + UiSharedService.TextWrapped(_descriptionText); + } + ImGui.EndChildFrame(); + } + + if (_uiSharedService.IconTextButton(FontAwesomeIcon.Save, "Save Description")) + { + _ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, ProfilePictureBase64: 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), Disabled: false, IsNSFW: null, ProfilePictureBase64: null, "")); + } + UiSharedService.AttachToolTip("Clears your profile description text"); + + ImGui.EndTabItem(); + } + + if (ImGui.BeginTabItem("Vanity Settings")) + { + _uiSharedService.MediumText("Supporter Vanity Settings", UIColors.Get("LightlessPurple")); + ImGui.Dummy(new Vector2(4)); + DrawNoteLine("# ", UIColors.Get("LightlessPurple"), "Must be a supporter through Patreon/Ko-fi to access these settings."); + + var hasVanity = _apiController.HasVanity; + + if (!hasVanity) + { + UiSharedService.ColorTextWrapped("You do not currently have vanity access. Become a supporter to unlock these features.", UIColors.Get("DimRed")); + ImGui.Dummy(new Vector2(8)); + ImGui.BeginDisabled(); + } + + _uiSharedService.ColoredSeparator(UIColors.Get("LightlessPurpleDefault"), 1.5f); + _uiSharedService.MediumText("Colored UID", UIColors.Get("LightlessPurple")); + ImGui.Dummy(new Vector2(5)); + + var font = UiBuilder.MonoFont; + var playerUID = _apiController.UID; + var playerDisplay = _apiController.DisplayName; + + var previewTextColor = textEnabled ? textColor : Vector4.One; + var previewGlowColor = glowEnabled ? glowColor : Vector4.Zero; + + var seString = SeStringUtils.BuildFormattedPlayerName(playerDisplay, previewTextColor, previewGlowColor); + + using (ImRaii.PushFont(font)) + { + var offsetX = 10f; + var pos = ImGui.GetCursorScreenPos() + new Vector2(offsetX, 0); + var size = ImGui.CalcTextSize(seString.TextValue); + + var padding = new Vector2(6, 3); + var rectMin = pos - padding; + var rectMax = pos + size + padding; + + var bgColor = new Vector4(0.15f, 0.15f, 0.15f, 1f); + var borderColor = UIColors.Get("LightlessPurple"); + + var drawList = ImGui.GetWindowDrawList(); + drawList.AddRectFilled(rectMin, rectMax, ImGui.GetColorU32(bgColor), 6.0f); + drawList.AddRect(rectMin, rectMax, ImGui.GetColorU32(borderColor), 6.0f, ImDrawFlags.None, 1.5f); + + SeStringUtils.RenderSeStringWithHitbox(seString, pos, font); + } + + const float colorPickAlign = 90f; + + DrawNoteLine("- ", UIColors.Get("LightlessPurple"), "Text Color"); + ImGui.SameLine(colorPickAlign); + ImGui.Checkbox("##toggleTextColor", ref textEnabled); + ImGui.SameLine(); + ImGui.BeginDisabled(!textEnabled); + ImGui.ColorEdit4($"##color_text", ref textColor, ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.AlphaPreviewHalf); + ImGui.EndDisabled(); + + DrawNoteLine("- ", UIColors.Get("LightlessPurple"), "Glow Color"); + ImGui.SameLine(colorPickAlign); + ImGui.Checkbox("##toggleGlowColor", ref glowEnabled); + ImGui.SameLine(); + ImGui.BeginDisabled(!glowEnabled); + ImGui.ColorEdit4($"##color_glow", ref glowColor, ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.AlphaPreviewHalf); + ImGui.EndDisabled(); + + bool changed = !Equals(_savedVanity, new VanityState(textEnabled, glowEnabled, textColor, glowColor)); + + if (!changed) + ImGui.BeginDisabled(); + + if (_uiSharedService.IconTextButton(FontAwesomeIcon.Save, "Save Changes")) + { + string? newText = textEnabled ? UIColors.RgbaToHex(textColor) : string.Empty; + string? newGlow = glowEnabled ? UIColors.RgbaToHex(glowColor) : string.Empty; + + _ = _apiController.UserUpdateVanityColors(new UserVanityColorsDto(newText, newGlow)); + + _savedVanity = new VanityState(textEnabled, glowEnabled, textColor, glowColor); + } + + if (!changed) + ImGui.EndDisabled(); + + ImGui.Dummy(new Vector2(5)); + _uiSharedService.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f); + + if (!hasVanity) + ImGui.EndDisabled(); + + ImGui.EndTabItem(); + } + + ImGui.EndTabBar(); } - UiSharedService.AttachToolTip("Sets your profile description text"); - ImGui.SameLine(); - if (_uiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Clear Description")) - { - _ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, ProfilePictureBase64: null, "")); - } - UiSharedService.AttachToolTip("Clears your profile description text"); } protected override void Dispose(bool disposing) diff --git a/LightlessSync/UI/Handlers/IdDisplayHandler.cs b/LightlessSync/UI/Handlers/IdDisplayHandler.cs index 81ed337..048efe9 100644 --- a/LightlessSync/UI/Handlers/IdDisplayHandler.cs +++ b/LightlessSync/UI/Handlers/IdDisplayHandler.cs @@ -98,20 +98,21 @@ public class IdDisplayHandler var font = UiBuilder.MonoFont; - var isAdmin = pair.UserData.IsAdmin; - var isModerator = pair.UserData.IsModerator; + Vector4? textColor = null; + Vector4? glowColor = null; - Vector4? textColor = isAdmin - ? UIColors.Get("LightlessAdminText") - : isModerator - ? UIColors.Get("LightlessModeratorText") - : null; + if (pair.UserData.HasVanity) + { + if (!string.IsNullOrWhiteSpace(pair.UserData.TextColorHex)) + { + textColor = UIColors.HexToRgba(pair.UserData.TextColorHex); + } - Vector4? glowColor = isAdmin - ? UIColors.Get("LightlessAdminGlow") - : isModerator - ? UIColors.Get("LightlessModeratorGlow") - : null; + if (!string.IsNullOrWhiteSpace(pair.UserData.TextGlowColorHex)) + { + glowColor = UIColors.HexToRgba(pair.UserData.TextGlowColorHex); + } + } var seString = (textColor != null || glowColor != null) ? SeStringUtils.BuildFormattedPlayerName(playerText, textColor, glowColor) diff --git a/LightlessSync/UI/JoinSyncshellUI.cs b/LightlessSync/UI/JoinSyncshellUI.cs index 3de9026..b02a84e 100644 --- a/LightlessSync/UI/JoinSyncshellUI.cs +++ b/LightlessSync/UI/JoinSyncshellUI.cs @@ -63,7 +63,7 @@ internal class JoinSyncshellUI : WindowMediatorSubscriberBase "Joining a Syncshell will pair you implicitly with all existing users in the Syncshell." + Environment.NewLine + "All permissions to all users in the Syncshell will be set to the preferred Syncshell permissions on joining, excluding prior set preferred permissions."); ImGui.Separator(); - ImGui.TextUnformatted("Note: Syncshell ID and Password are case sensitive. MSS- is part of Syncshell IDs, unless using Vanity IDs."); + ImGui.TextUnformatted("Note: Syncshell ID and Password are case sensitive. LLS- is part of Syncshell IDs, unless using Vanity IDs."); ImGui.AlignTextToFramePadding(); ImGui.TextUnformatted("Syncshell ID"); diff --git a/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs b/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs index 95f1de8..d268dd8 100644 --- a/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs +++ b/LightlessSync/WebAPI/SignalR/ApIController.Functions.Users.cs @@ -134,6 +134,12 @@ public partial class ApiController await _lightlessHub!.InvokeAsync(nameof(UserSetProfile), userDescription).ConfigureAwait(false); } + public async Task UserUpdateVanityColors(UserVanityColorsDto dto) + { + if (!IsConnected) return; + await _lightlessHub!.InvokeAsync(nameof(UserUpdateVanityColors), dto).ConfigureAwait(false); + } + public async Task UserUpdateDefaultPermissions(DefaultPermissionsDto defaultPermissionsDto) { CheckConnection(); diff --git a/LightlessSync/WebAPI/SignalR/ApiController.cs b/LightlessSync/WebAPI/SignalR/ApiController.cs index 4a4071b..efa6e6f 100644 --- a/LightlessSync/WebAPI/SignalR/ApiController.cs +++ b/LightlessSync/WebAPI/SignalR/ApiController.cs @@ -77,6 +77,10 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IL public DefaultPermissionsDto? DefaultPermissions => _connectionDto?.DefaultPreferredPermissions ?? null; public string DisplayName => _connectionDto?.User.AliasOrUID ?? string.Empty; + public bool HasVanity => _connectionDto?.HasVanity ?? false; + public string TextColorHex => _connectionDto?.TextColorHex ?? string.Empty; + public string TextGlowColorHex => _connectionDto?.TextGlowColorHex ?? string.Empty; + public bool IsConnected => ServerState == ServerState.Connected; public bool IsCurrentVersion => (Assembly.GetExecutingAssembly().GetName().Version ?? new Version(0, 0, 0, 0)) >= (_connectionDto?.CurrentClientVersion ?? new Version(0, 0, 0, 0));