Chat Filter using Flag Enums. (#270)

* Backing up local repo before upgrading OS, minor work on chat UI

* Cleaned out unnecessary modded files

* Got a working version of filter toggles based on flag enums

* Added localization to chatbox buttons

* Should actually fix modified proj files, thanks PJB

* Fixed enum operators to unset instead of toggle

* Added a local client class for storing net message details

* Reworked RepopulateChat to pull from a StoredChatMessage list

* Fixed messages dissapearing

* Re-ordered logic to be a bit more efficient with re-drawing chat
This commit is contained in:
tentekal
2019-07-18 17:32:48 -04:00
committed by Pieter-Jan Briers
parent ce1eab9181
commit 92668432a7
4 changed files with 273 additions and 3 deletions

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using Content.Shared.Chat; using Content.Shared.Chat;
using Robust.Client.Graphics.Drawing; using Robust.Client.Graphics.Drawing;
using Robust.Client.Input; using Robust.Client.Input;
@@ -6,6 +7,9 @@ using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Robust.Shared.Localization;
using Robust.Shared.IoC;
namespace Content.Client.Chat namespace Content.Client.Chat
{ {
@@ -13,12 +17,20 @@ namespace Content.Client.Chat
{ {
public delegate void TextSubmitHandler(ChatBox chatBox, string text); public delegate void TextSubmitHandler(ChatBox chatBox, string text);
public delegate void FilterToggledHandler(ChatBox chatBox, Button.ButtonToggledEventArgs e);
private const int MaxLinePixelLength = 500; private const int MaxLinePixelLength = 500;
private readonly IList<string> _inputHistory = new List<string>(); private readonly IList<string> _inputHistory = new List<string>();
private ILocalizationManager localize = IoCManager.Resolve<ILocalizationManager>();
public LineEdit Input { get; private set; } public LineEdit Input { get; private set; }
private OutputPanel contents; public OutputPanel contents;
// Buttons for filtering
public Button AllButton;
public Button OOCButton;
/// <summary> /// <summary>
/// Index while cycling through the input history. -1 means not going through history. /// Index while cycling through the input history. -1 means not going through history.
@@ -50,6 +62,7 @@ namespace Content.Client.Chat
AnchorRight = 1.0f; AnchorRight = 1.0f;
var vBox = new VBoxContainer("VBoxContainer"); var vBox = new VBoxContainer("VBoxContainer");
var hBox = new HBoxContainer("FilterButtonsContainer");
contents = new OutputPanel {SizeFlagsVertical = SizeFlags.FillExpand}; contents = new OutputPanel {SizeFlagsVertical = SizeFlags.FillExpand};
vBox.AddChild(contents); vBox.AddChild(contents);
@@ -59,6 +72,36 @@ namespace Content.Client.Chat
Input.OnTextEntered += Input_OnTextEntered; Input.OnTextEntered += Input_OnTextEntered;
vBox.AddChild(Input); vBox.AddChild(Input);
vBox.AddChild(hBox);
AllButton = new Button()
{
Text = localize.GetString("All"),
Name = "ALL",
TextAlign = Button.AlignMode.Left,
SizeFlagsHorizontal = SizeFlags.Fill,
SizeFlagsStretchRatio = 1,
ToggleMode = true,
Pressed = true
};
OOCButton = new Button()
{
Text = localize.GetString("OOC"),
Name = "OOC",
TextAlign = Button.AlignMode.Left,
SizeFlagsHorizontal = SizeFlags.Fill,
SizeFlagsStretchRatio = 1,
ToggleMode = true,
Pressed = true
};
AllButton.OnToggled += OnFilterToggled;
OOCButton.OnToggled += OnFilterToggled;
hBox.AddChild(AllButton);
hBox.AddChild(OOCButton);
AddChild(vBox); AddChild(vBox);
PanelOverride = new StyleBoxFlat { BackgroundColor = Color.Gray.WithAlpha(0.5f) }; PanelOverride = new StyleBoxFlat { BackgroundColor = Color.Gray.WithAlpha(0.5f) };
@@ -133,6 +176,8 @@ namespace Content.Client.Chat
public event TextSubmitHandler TextSubmitted; public event TextSubmitHandler TextSubmitted;
public event FilterToggledHandler FilterToggled;
public void AddLine(string message, ChatChannel channel, Color color) public void AddLine(string message, ChatChannel channel, Color color)
{ {
if (Disposed) if (Disposed)
@@ -164,5 +209,10 @@ namespace Content.Client.Chat
Input.ReleaseKeyboardFocus(); Input.ReleaseKeyboardFocus();
} }
} }
private void OnFilterToggled(Button.ButtonToggledEventArgs args)
{
FilterToggled?.Invoke(this, args);
}
} }
} }

View File

@@ -0,0 +1,64 @@
using Robust.Client.Graphics;
using Robust.Client.Graphics.Drawing;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.Utility;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.ViewVariables;
using Content.Client.Chat;
namespace Content.Client.Chat
{
public class ChatFilterUI : SS14Window
{
protected override void Initialize()
{
base.Initialize();
HideOnClose = true;
Title = "Filter Channels";
Visible = false;
var margin = new MarginContainer()
{
MarginTop = 5f,
MarginLeft = 5f,
MarginRight = -5f,
MarginBottom = -5f,
};
margin.SetAnchorAndMarginPreset(LayoutPreset.TopRight);
var vbox = new VBoxContainer();
vbox.SetAnchorAndMarginPreset(LayoutPreset.TopRight);
var descMargin = new MarginContainer()
{
MarginTop = 5f,
MarginLeft = 5f,
MarginRight = -5f,
MarginBottom = -5f,
SizeFlagsHorizontal = SizeFlags.Fill,
SizeFlagsStretchRatio = 2,
};
var hbox = new HBoxContainer()
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
};
var vboxInfo = new VBoxContainer()
{
SizeFlagsVertical = SizeFlags.FillExpand,
SizeFlagsStretchRatio = 3,
};
}
}
}

View File

@@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Net;
using Content.Client.Interfaces.Chat; using Content.Client.Interfaces.Chat;
using Content.Shared.Chat; using Content.Shared.Chat;
using Robust.Client.Console; using Robust.Client.Console;
@@ -7,6 +9,7 @@ using Robust.Shared.IoC;
using Robust.Shared.Log; using Robust.Shared.Log;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Robust.Client.UserInterface.Controls;
namespace Content.Client.Chat namespace Content.Client.Chat
{ {
@@ -16,6 +19,16 @@ namespace Content.Client.Chat
private const char OOCAlias = '['; private const char OOCAlias = '[';
private const char MeAlias = '@'; private const char MeAlias = '@';
public List<StoredChatMessage> filteredHistory = new List<StoredChatMessage>();
// Filter Button States
private bool _ALLstate;
private bool _Localstate;
private bool _OOCstate;
// Flag Enums for holding filtered channels
private ChatChannel _filteredChannels;
#pragma warning disable 649 #pragma warning disable 649
[Dependency] private readonly IClientNetManager _netManager; [Dependency] private readonly IClientNetManager _netManager;
[Dependency] private readonly IClientConsole _console; [Dependency] private readonly IClientConsole _console;
@@ -33,19 +46,27 @@ namespace Content.Client.Chat
if (_currentChatBox != null) if (_currentChatBox != null)
{ {
_currentChatBox.TextSubmitted -= _onChatBoxTextSubmitted; _currentChatBox.TextSubmitted -= _onChatBoxTextSubmitted;
_currentChatBox.FilterToggled -= _onFilterButtonToggled;
} }
_currentChatBox = chatBox; _currentChatBox = chatBox;
if (_currentChatBox != null) if (_currentChatBox != null)
{ {
_currentChatBox.TextSubmitted += _onChatBoxTextSubmitted; _currentChatBox.TextSubmitted += _onChatBoxTextSubmitted;
_currentChatBox.FilterToggled += _onFilterButtonToggled;
} }
} }
private void _onChatMessage(MsgChatMessage message) private void WriteChatMessage(StoredChatMessage message)
{ {
Logger.Debug($"{message.Channel}: {message.Message}"); Logger.Debug($"{message.Channel}: {message.Message}");
if (IsFiltered(message.Channel))
{
Logger.Debug($"Message filtered: {message.Channel}: {message.Message}");
return;
}
var color = Color.DarkGray; var color = Color.DarkGray;
var messageText = message.Message; var messageText = message.Message;
if (!string.IsNullOrEmpty(message.MessageWrap)) if (!string.IsNullOrEmpty(message.MessageWrap))
@@ -64,6 +85,7 @@ namespace Content.Client.Chat
} }
_currentChatBox?.AddLine(messageText, message.Channel, color); _currentChatBox?.AddLine(messageText, message.Channel, color);
} }
private void _onChatBoxTextSubmitted(ChatBox chatBox, string text) private void _onChatBoxTextSubmitted(ChatBox chatBox, string text)
@@ -104,5 +126,90 @@ namespace Content.Client.Chat
} }
} }
} }
private void _onFilterButtonToggled(ChatBox chatBox, Button.ButtonToggledEventArgs e)
{
// TODO make toggled ALL button flip all button states programatically + visually
switch (e.Button.Name)
{
case "Local":
_Localstate = !_Localstate;
if (_Localstate)
{
_filteredChannels |= ChatChannel.Local;
break;
}
else
{
_filteredChannels &= ~ChatChannel.Local;
break;
}
case "OOC":
_OOCstate = !_OOCstate;
if (_OOCstate)
{
_filteredChannels |= ChatChannel.OOC;
break;
}
else
{
_filteredChannels &= ~ChatChannel.OOC;
break;
}
default:
_ALLstate = !_ALLstate;
if (_ALLstate)
{
_filteredChannels = ChatChannel.OOC | ChatChannel.Local;
break;
}
else
{
_filteredChannels &= ~ChatChannel.OOC;
_filteredChannels &= ~ChatChannel.Local;
break;
}
}
RepopulateChat(filteredHistory);
}
private void RepopulateChat(List<StoredChatMessage> filteredMessages)
{
_currentChatBox.contents.Clear();
// Copy list for enumeration
List<StoredChatMessage> filteredMessagesCopy = new List<StoredChatMessage>(filteredMessages);
foreach (StoredChatMessage msg in filteredMessagesCopy)
{
WriteChatMessage(msg);
}
}
private void _onChatMessage(MsgChatMessage msg)
{
Logger.Debug($"{msg.Channel}: {msg.Message}");
// Log all incoming chat to repopulate when filter is un-toggled
StoredChatMessage storedMessage = new StoredChatMessage(msg);
filteredHistory.Add(storedMessage);
WriteChatMessage(storedMessage);
}
private bool IsFiltered(ChatChannel channel)
{
if (_filteredChannels.HasFlag(channel))
{
return true;
}
else
{
return false;
}
}
} }
} }

View File

@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using Content.Client.Interfaces.Chat;
using Content.Shared.Chat;
using Robust.Client.Console;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using Robust.Client.UserInterface.Controls;
namespace Content.Client.Chat
{
public class StoredChatMessage
{
// TODO Make me reflected with respect to MsgChatMessage
/// <summary>
/// Client's own copies of chat messages used in filtering locally
/// </summary>
/// <summary>
/// Actual Message contents, i.e. words
/// </summary>
public string Message { get; set; }
/// <summary>
/// Message channel, used for filtering
/// </summary>
public ChatChannel Channel { get; set; }
/// <summary>
/// What to "wrap" the message contents with. Example is stuff like 'Joe says: "{0}"'
/// </summary>
public string MessageWrap { get; set; }
public StoredChatMessage(MsgChatMessage netMsg)
{
/// <summary>
/// Constructor to copy a net message into stored client variety
/// </summary>
Message = netMsg.Message;
Channel = netMsg.Channel;
MessageWrap = netMsg.MessageWrap;
}
}
}