diff --git a/Content.Client/Chat/ChatBox.cs b/Content.Client/Chat/ChatBox.cs index a081ed59eb..58df66d9ef 100644 --- a/Content.Client/Chat/ChatBox.cs +++ b/Content.Client/Chat/ChatBox.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Content.Shared.Chat; using Robust.Client.Graphics.Drawing; using Robust.Client.Input; @@ -6,6 +7,9 @@ using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Maths; using Robust.Shared.Utility; +using Robust.Shared.Localization; +using Robust.Shared.IoC; + namespace Content.Client.Chat { @@ -13,12 +17,20 @@ namespace Content.Client.Chat { public delegate void TextSubmitHandler(ChatBox chatBox, string text); + public delegate void FilterToggledHandler(ChatBox chatBox, Button.ButtonToggledEventArgs e); + private const int MaxLinePixelLength = 500; private readonly IList _inputHistory = new List(); + private ILocalizationManager localize = IoCManager.Resolve(); + public LineEdit Input { get; private set; } - private OutputPanel contents; + public OutputPanel contents; + + // Buttons for filtering + public Button AllButton; + public Button OOCButton; /// /// Index while cycling through the input history. -1 means not going through history. @@ -50,6 +62,7 @@ namespace Content.Client.Chat AnchorRight = 1.0f; var vBox = new VBoxContainer("VBoxContainer"); + var hBox = new HBoxContainer("FilterButtonsContainer"); contents = new OutputPanel {SizeFlagsVertical = SizeFlags.FillExpand}; vBox.AddChild(contents); @@ -59,6 +72,36 @@ namespace Content.Client.Chat Input.OnTextEntered += Input_OnTextEntered; 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); PanelOverride = new StyleBoxFlat { BackgroundColor = Color.Gray.WithAlpha(0.5f) }; @@ -133,6 +176,8 @@ namespace Content.Client.Chat public event TextSubmitHandler TextSubmitted; + public event FilterToggledHandler FilterToggled; + public void AddLine(string message, ChatChannel channel, Color color) { if (Disposed) @@ -164,5 +209,10 @@ namespace Content.Client.Chat Input.ReleaseKeyboardFocus(); } } + + private void OnFilterToggled(Button.ButtonToggledEventArgs args) + { + FilterToggled?.Invoke(this, args); + } } } diff --git a/Content.Client/Chat/ChatFilterUI.cs b/Content.Client/Chat/ChatFilterUI.cs new file mode 100644 index 0000000000..809983d75c --- /dev/null +++ b/Content.Client/Chat/ChatFilterUI.cs @@ -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, + }; + + + } + } +} \ No newline at end of file diff --git a/Content.Client/Chat/ChatManager.cs b/Content.Client/Chat/ChatManager.cs index 08cea601ef..1705758401 100644 --- a/Content.Client/Chat/ChatManager.cs +++ b/Content.Client/Chat/ChatManager.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Net; using Content.Client.Interfaces.Chat; using Content.Shared.Chat; using Robust.Client.Console; @@ -7,6 +9,7 @@ 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 { @@ -16,6 +19,16 @@ namespace Content.Client.Chat private const char OOCAlias = '['; private const char MeAlias = '@'; + public List filteredHistory = new List(); + + // 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 [Dependency] private readonly IClientNetManager _netManager; [Dependency] private readonly IClientConsole _console; @@ -33,19 +46,27 @@ namespace Content.Client.Chat if (_currentChatBox != null) { _currentChatBox.TextSubmitted -= _onChatBoxTextSubmitted; + _currentChatBox.FilterToggled -= _onFilterButtonToggled; } _currentChatBox = chatBox; if (_currentChatBox != null) { _currentChatBox.TextSubmitted += _onChatBoxTextSubmitted; + _currentChatBox.FilterToggled += _onFilterButtonToggled; } } - private void _onChatMessage(MsgChatMessage message) + private void WriteChatMessage(StoredChatMessage 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 messageText = message.Message; if (!string.IsNullOrEmpty(message.MessageWrap)) @@ -64,6 +85,7 @@ namespace Content.Client.Chat } _currentChatBox?.AddLine(messageText, message.Channel, color); + } 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 filteredMessages) + { + _currentChatBox.contents.Clear(); + + // Copy list for enumeration + List filteredMessagesCopy = new List(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; + } + } } } diff --git a/Content.Client/Chat/StoredChatMessage.cs b/Content.Client/Chat/StoredChatMessage.cs new file mode 100644 index 0000000000..33392229cc --- /dev/null +++ b/Content.Client/Chat/StoredChatMessage.cs @@ -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 + + /// + /// Client's own copies of chat messages used in filtering locally + /// + + /// + /// Actual Message contents, i.e. words + /// + public string Message { get; set; } + + /// + /// Message channel, used for filtering + /// + public ChatChannel Channel { get; set; } + + /// + /// What to "wrap" the message contents with. Example is stuff like 'Joe says: "{0}"' + /// + public string MessageWrap { get; set; } + + public StoredChatMessage(MsgChatMessage netMsg) + { + /// + /// Constructor to copy a net message into stored client variety + /// + + Message = netMsg.Message; + Channel = netMsg.Channel; + MessageWrap = netMsg.MessageWrap; + } + } +} \ No newline at end of file