Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Подсветка текста в фильтрах QOL #14

Merged
merged 11 commits into from
Nov 9, 2024
70 changes: 70 additions & 0 deletions Content.Client/Options/UI/OptionsTabControlRow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using Content.Client._CorvaxNext.Options.UI;
using Content.Client.Stylesheets;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
Expand Down Expand Up @@ -120,6 +121,21 @@ public OptionSliderFloatCVar AddOptionPercentSlider(
{
return AddOption(new OptionSliderFloatCVar(this, _cfg, cVar, slider, min, max, scale, FormatPercent));
}

// Corvax-Highlights-Start
/// <summary>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

закрой тэгами по типу // Corvax-Highlights-Start // Corvax-Highlights-End // Corvax-Highlights

/// Add a color slider option, backed by a simple string CVar.
/// </summary>
/// <param name="cVar">The CVar represented by the slider.</param>
/// <param name="slider">The UI control for the option.</param>
/// <returns>The option instance backing the added option.</returns>
public OptionColorSliderCVar AddOptionColorSlider(
CVarDef<string> cVar,
OptionColorSlider slider)
{
return AddOption(new OptionColorSliderCVar(this, _cfg, cVar, slider));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

в Corvax CVars

}
// Corvax-Highlights-End

/// <summary>
/// Add a slider option, backed by a simple integer CVar.
Expand Down Expand Up @@ -518,6 +534,60 @@ private void UpdateLabelValue()
}
}

/// <summary>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

закрой тэгами корвакса

/// Implementation of a CVar option that simply corresponds with a string <see cref="OptionColorSlider"/>.
/// </summary>
/// <seealso cref="OptionsTabControlRow"/>
public sealed class OptionColorSliderCVar : BaseOptionCVar<string>
{
private readonly OptionColorSlider _slider;

protected override string Value
{
get => _slider.Slider.Color.ToHex();
set
{
_slider.Slider.Color = Color.FromHex(value);
UpdateLabelColor();
}
}

// Corvax-Highlights-Start
/// <summary>
/// Creates a new instance of this type.
/// </summary>
/// <remarks>
/// <para>
/// It is generally more convenient to call overloads on <see cref="OptionsTabControlRow"/>
/// such as <see cref="OptionsTabControlRow.AddOptionPercentSlider"/> instead of instantiating this type directly.
/// </para>
/// </remarks>
/// <param name="controller">The control row that owns this option.</param>
/// <param name="cfg">The configuration manager to get and set values from.</param>
/// <param name="cVar">The CVar that is being controlled by this option.</param>
/// <param name="slider">The UI control for the option.</param>
public OptionColorSliderCVar(
OptionsTabControlRow controller,
IConfigurationManager cfg,
CVarDef<string> cVar,
OptionColorSlider slider) : base(controller, cfg, cVar)
{
_slider = slider;

slider.Slider.OnColorChanged += _ =>
{
ValueChanged();
UpdateLabelColor();
};
}
// Corvax-Highlights-End

private void UpdateLabelColor()
{
_slider.ExampleLabel.FontColorOverride = Color.FromHex(Value);
}
}

/// <summary>
/// Implementation of a CVar option that simply corresponds with an integer <see cref="OptionSlider"/>.
/// </summary>
Expand Down
9 changes: 8 additions & 1 deletion Content.Client/Options/UI/Tabs/AccessibilityTab.xaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Control xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="clr-namespace:Content.Client.Options.UI">
xmlns:ui="clr-namespace:Content.Client.Options.UI"
xmlns:cnui="clr-namespace:Content.Client._CorvaxNext.Options.UI">
<BoxContainer Orientation="Vertical">
<ScrollContainer VerticalExpand="True" HScrollEnabled="False">
<BoxContainer Orientation="Vertical" Margin="8">
Expand All @@ -9,6 +10,12 @@
<CheckBox Name="ColorblindFriendlyCheckBox" Text="{Loc 'ui-options-colorblind-friendly'}" />
<ui:OptionSlider Name="ChatWindowOpacitySlider" Title="{Loc 'ui-options-chat-window-opacity'}" />
<ui:OptionSlider Name="ScreenShakeIntensitySlider" Title="{Loc 'ui-options-screen-shake-intensity'}" />
<!-- Corvax-Highlights-Start -->
<CheckBox Name="AutoFillHighlightsCheckBox" Text="{Loc 'ui-options-auto-fill-highlights'}" />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

закрой тэгами корвакса

<cnui:OptionColorSlider Name="HighlightsColorSlider"
Title="{Loc 'ui-options-highlights-color'}"
Example="{Loc 'ui-options-highlights-color-example'}"/>
<!-- Corvax-Highlights-End -->
</BoxContainer>
</ScrollContainer>
<ui:OptionsTabControlRow Name="Control" Access="Public" />
Expand Down
7 changes: 7 additions & 0 deletions Content.Client/Options/UI/Tabs/AccessibilityTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.XAML;
// Corvax-Highlights-Start
using Content.Shared.Corvax.CCCVars;
// Corvax-Highlights-End

namespace Content.Client.Options.UI.Tabs;

Expand All @@ -17,6 +20,10 @@ public AccessibilityTab()
Control.AddOptionCheckBox(CCVars.ReducedMotion, ReducedMotionCheckBox);
Control.AddOptionPercentSlider(CCVars.ChatWindowOpacity, ChatWindowOpacitySlider);
Control.AddOptionPercentSlider(CCVars.ScreenShakeIntensity, ScreenShakeIntensitySlider);
// Corvax-Highlights-Start
Control.AddOptionCheckBox(CCCVars.ChatAutoFillHighlights, AutoFillHighlightsCheckBox);
Control.AddOptionColorSlider(CCCVars.ChatHighlightsColor, HighlightsColorSlider);
// Corvax-Highlights-End

Control.Initialize();
}
Expand Down
128 changes: 127 additions & 1 deletion Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,16 @@
using Robust.Shared.Timing;
using Robust.Shared.Utility;

// Corvax-Highlights-Start
using Content.Client.CharacterInfo;
using static Content.Client.CharacterInfo.CharacterInfoSystem;
using Content.Shared.Corvax.CCCVars;
// Corvax-Highlights-End

namespace Content.Client.UserInterface.Systems.Chat;

public sealed class ChatUIController : UIController
// Corvax-Highlights
public sealed class ChatUIController : UIController, IOnSystemChanged<CharacterInfoSystem>
{
[Dependency] private readonly IClientAdminManager _admin = default!;
[Dependency] private readonly IChatManager _manager = default!;
Expand All @@ -65,6 +72,9 @@ public sealed class ChatUIController : UIController
[UISystemDependency] private readonly TransformSystem? _transform = default;
[UISystemDependency] private readonly MindSystem? _mindSystem = default!;
[UISystemDependency] private readonly RoleCodewordSystem? _roleCodewordSystem = default!;
// Corvax-Highlights-Start
[UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!;
// Corvax-Highlights-End

[ValidatePrototypeId<ColorPalettePrototype>]
private const string ChatNamePalette = "ChatNames";
Expand Down Expand Up @@ -149,6 +159,25 @@ private readonly Dictionary<EntityUid, SpeechBubbleQueueData> _queuedSpeechBubbl
/// </summary>
private readonly Dictionary<ChatChannel, int> _unreadMessages = new();

// Corvax-Highlights-Start
/// <summary>
/// A list of words to be highlighted in the chatbox.
/// </summary>
private List<string> _highlights = [];

/// <summary>
/// The color (hex) in witch the words will be highlighted as.
/// </summary>
private string? _highlightsColor;

private bool _autoFillHighlightsEnabled;

/// <summary>
/// A bool to keep track if the 'CharacterUpdated' event is a new player attaching or the opening of the character info panel.
/// </summary>
private bool _charInfoIsAttach = false;
// Corvax-Highlights-End

// TODO add a cap for this for non-replays
public readonly List<(GameTick Tick, ChatMessage Msg)> History = new();

Expand All @@ -172,6 +201,9 @@ private readonly Dictionary<EntityUid, SpeechBubbleQueueData> _queuedSpeechBubbl
public event Action<ChatSelectChannel>? SelectableChannelsChanged;
public event Action<ChatChannel, int?>? UnreadMessageCountsUpdated;
public event Action<ChatMessage>? MessageAdded;
// Corvax-Highlights-Start
public event Action<string>? HighlightsUpdated;
// Corvax-Highlights-End

public override void Initialize()
{
Expand Down Expand Up @@ -240,6 +272,21 @@ public override void Initialize()

_config.OnValueChanged(CCVars.ChatWindowOpacity, OnChatWindowOpacityChanged);

// Corvax-Highlights-Start
_config.OnValueChanged(CCCVars.ChatAutoFillHighlights, (value) => { _autoFillHighlightsEnabled = value; });
_autoFillHighlightsEnabled = _config.GetCVar(CCCVars.ChatAutoFillHighlights);

_config.OnValueChanged(CCCVars.ChatHighlightsColor, (value) => { _highlightsColor = value; });
_highlightsColor = _config.GetCVar(CCCVars.ChatHighlightsColor);

// Load highlights if any were saved.
string highlights = _config.GetCVar(CCCVars.ChatHighlights);

if (!string.IsNullOrEmpty(highlights))
{
UpdateHighlights(highlights);
}
// Corvax-Highlights-End
}

public void OnScreenLoad()
Expand All @@ -257,6 +304,69 @@ public void OnScreenUnload()
SetMainChat(false);
}

// Corvax-Highlights-Start
public void OnSystemLoaded(CharacterInfoSystem system)
{
system.OnCharacterUpdate += CharacterUpdated;
}

public void OnSystemUnloaded(CharacterInfoSystem system)
{
system.OnCharacterUpdate -= CharacterUpdated;
}

private void CharacterUpdated(CharacterData data)
{
// If the _charInfoIsAttach is false then the character panel created the event, dismiss.
if (!_charInfoIsAttach)
return;

var (_, job, _, _, entityName) = data;

// If the character has a normal name (eg. "Name Surname" and not "Name Initial Surname" or a particular species name)
// subdivide it so that the name and surname individually get highlighted.
if (entityName.Count(c => c == ' ') == 1)
entityName = entityName.Replace(' ', '\n');

string newHighlights = entityName;

// Convert the job title to kebab-case and use it as a key for the loc file.
string jobKey = job.Replace(' ', '-').ToLower();

if (Loc.TryGetString($"highlights-{jobKey}", out var jobMatches))
newHighlights += '\n' + jobMatches.Replace(", ", "\n");

UpdateHighlights(newHighlights);
HighlightsUpdated?.Invoke(newHighlights);
_charInfoIsAttach = false;
}

public void UpdateHighlights(string highlights)
{
// Save the newly provided list of highlighs if different.
if (!_config.GetCVar(CCCVars.ChatHighlights).Equals(highlights, StringComparison.CurrentCultureIgnoreCase))
{
_config.SetCVar(CCCVars.ChatHighlights, highlights);
_config.SaveToFile();
}

// If the word is surrounded by "" we replace them with a whole-word regex tag.
highlights = highlights.Replace("\"", "\\b");

// Fill the array with the highlights separated by newlines, disregarding empty entries.
string[] arrHighlights = highlights.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
_highlights.Clear();
foreach (var keyword in arrHighlights)
{
_highlights.Add(keyword);
}

// Arrange the list in descending order so that when highlighting,
// the full word (eg. "Security") appears before the abbreviation (eg. "Sec").
_highlights.Sort((x, y) => y.Length.CompareTo(x.Length));
}
// Corvax-Highlights-End

private void OnChatWindowOpacityChanged(float opacity)
{
SetChatWindowOpacity(opacity);
Expand Down Expand Up @@ -426,6 +536,14 @@ public void SetSpeechBubbleRoot(LayoutContainer root)
private void OnAttachedChanged(EntityUid uid)
{
UpdateChannelPermissions();

// Corvax-Highlights-Start
if (_autoFillHighlightsEnabled)
{
_charInfoIsAttach = true;
_characterInfo.RequestCharacterInfo();
}
// Corvax-Highlights-End
}

private void AddSpeechBubble(ChatMessage msg, SpeechBubble.SpeechType speechType)
Expand Down Expand Up @@ -824,6 +942,14 @@ public void ProcessChatMessage(ChatMessage msg, bool speechBubble = true)
msg.WrappedMessage = SharedChatSystem.InjectTagInsideTag(msg, "Name", "color", GetNameColor(SharedChatSystem.GetStringInsideTag(msg, "Name")));
}

// Corvax-Highlights-Start
// Color any words choosen by the client.
foreach (var highlight in _highlights)
{
msg.WrappedMessage = SharedChatSystem.InjectTagAroundString(msg, highlight, "color", _highlightsColor);
}
// Corvax-Highlights-End

// Color any codewords for minds that have roles that use them
if (_player.LocalUser != null && _mindSystem != null && _roleCodewordSystem != null)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
<controls:ChannelFilterPopup
xmlns="https://spacestation14.io"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

закрывай изменения тэгами корвакса

xmlns:controls="clr-namespace:Content.Client.UserInterface.Systems.Chat.Controls">
<PanelContainer Name="FilterPopupPanel" StyleClasses="BorderedWindowPanel">
<BoxContainer Orientation="Horizontal">
<Control MinSize="4 0"/>
<BoxContainer Name="FilterVBox" MinWidth="110" Margin="0 10" Orientation="Vertical" SeparationOverride="4"/>
<!-- Corvax-Highlights-Start -->
<BoxContainer Orientation="Horizontal" SeparationOverride="8" Margin="10 0">
<BoxContainer Name="FilterVBox" MinWidth="105" Margin="0 10" Orientation="Vertical" SeparationOverride="4"/>
<BoxContainer Name="HighlightsVBox" MinWidth="120" Margin="0 10" Orientation="Vertical" SeparationOverride="4">
<Label Text="{Loc 'hud-chatbox-highlights'}"/>
<!-- Custom background for the TextEdit -->
<PanelContainer>
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#323446"/>
</PanelContainer.PanelOverride>
<TextEdit Name="HighlightEdit" MinHeight="150" Margin="5 5"/>
</PanelContainer>
<Button Name="HighlightButton" Text="{Loc 'hud-chatbox-highlights-button'}" ToolTip="{Loc 'hud-chatbox-highlights-tooltip'}"/>
</BoxContainer>
<!-- Corvax-Highlights-End -->
</BoxContainer>
</PanelContainer>
</controls:ChannelFilterPopup>
Loading
Loading