diff --git a/octgnFX/Octgn/Controls/ChatControl.xaml b/octgnFX/Octgn/Controls/ChatControl.xaml index 18cc8a0f2e..4a7a74773c 100644 --- a/octgnFX/Octgn/Controls/ChatControl.xaml +++ b/octgnFX/Octgn/Controls/ChatControl.xaml @@ -91,7 +91,7 @@ Margin="10,0,0,0" Foreground="LightGray" Canvas.ZIndex="1" - Text="/? for user and chat commands" + Text="Type / or @, or just type a message and press enter" IsHitTestVisible="False" Visibility="{Binding ShowChatInputHint,ElementName=thisControl,Converter={StaticResource BooleanToVisibilityConverter}}"/> - - + + + + + + + + diff --git a/octgnFX/Octgn/Controls/ChatControl.xaml.cs b/octgnFX/Octgn/Controls/ChatControl.xaml.cs index 42f98b95f3..553e0947c9 100644 --- a/octgnFX/Octgn/Controls/ChatControl.xaml.cs +++ b/octgnFX/Octgn/Controls/ChatControl.xaml.cs @@ -17,6 +17,7 @@ namespace Octgn.Controls using System.Windows.Input; using CodeBits; + using Octgn.Annotations; using Octgn.Controls.ControlTemplates; using Octgn.Extentions; using Octgn.Utils; @@ -28,7 +29,7 @@ namespace Octgn.Controls /// /// Interaction logic for ChatControl /// - public partial class ChatControl : UserControl,INotifyPropertyChanged,IDisposable + public partial class ChatControl : UserControl, INotifyPropertyChanged, IDisposable { internal static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); #region Privates @@ -73,9 +74,9 @@ public partial class ChatControl : UserControl,INotifyPropertyChanged,IDisposabl public OrderedObservableCollection UserListItems { get; set; } - public OrderedObservableCollection FriendListItems { get; set; } + public OrderedObservableCollection FriendListItems { get; set; } - public OrderedObservableCollection AutoCompleteCollection { get; set; } + public OrderedObservableCollection> AutoCompleteCollection { get; set; } public bool IsAdmin { @@ -215,7 +216,7 @@ public bool AutoCompleteVisible /// public ChatControl() { - this.AutoCompleteCollection = new OrderedObservableCollection(); + this.AutoCompleteCollection = new OrderedObservableCollection>(); AutoCompleteCollection.CollectionChanged += AutoCompleteCollectionOnCollectionChanged; this.UserListItems = new OrderedObservableCollection(); this.FriendListItems = new OrderedObservableCollection(); @@ -359,7 +360,7 @@ private void BanOnClick(object sender, RoutedEventArgs routedEventArgs) if (cm == null) return; var ui = cm.PlacementTarget as UserListItem; if (ui == null) return; - + } private void AddFriendOnClick(object sender, RoutedEventArgs routedEventArgs) @@ -468,7 +469,7 @@ private void RoomOnOnUserListChange(object sender, List users) /// /// The message type. /// - private void RoomOnMessageReceived(object sender, string id,User @from, string message, DateTime receiveTime, LobbyMessageType messageType) + private void RoomOnMessageReceived(object sender, string id, User @from, string message, DateTime receiveTime, LobbyMessageType messageType) { var theFrom = from; var theMessage = message; @@ -486,7 +487,7 @@ private void RoomOnMessageReceived(object sender, string id,User @from, string m theMessage = theMessage.Substring(cl + 1, theMessage.Length - cl - 1).Trim(); } - if (theMessage.ToLowerInvariant().Contains("@" + Program.LobbyClient.Me.UserName.ToLowerInvariant())) + if (theMessage.ToLowerInvariant().Contains(Program.LobbyClient.Me.UserName.ToLowerInvariant())) { Sounds.PlayMessageSound(); } @@ -553,7 +554,7 @@ private void RoomOnMessageReceived(object sender, string id,User @from, string m //{ // return; //} - var ctr = new ChatTableRow(theFrom,theId, theMessage, therTime, themType); + var ctr = new ChatTableRow(theFrom, theId, theMessage, therTime, themType); //var ctr = new ChatTableRow { User = theFrom, Message = theMessage, MessageDate = therTime, MessageType = themType }; ctr.OnMouseUsernameEnter += ChatTableRow_MouseEnter; @@ -626,8 +627,8 @@ private void InvokeRoomUserList() var roomUserList = rar .Where(x => x.UserName.ToLower().Contains(filterText)) .ToArray(); - Dispatcher.BeginInvoke(new Action(() => - this.ResetUserList(rar, roomUserList, UserListItems, x => new ChatUserListItem(Room, x), x => x.User.IsSubbed,UserContextMenu))); + Dispatcher.BeginInvoke(new Action(() => + this.ResetUserList(rar, roomUserList, UserListItems, x => new ChatUserListItem(Room, x), x => x.User.IsSubbed, UserContextMenu))); } private void InvokeFriendList() @@ -638,8 +639,8 @@ private void InvokeFriendList() var fla = Program.LobbyClient.Friends.ToArray(); var friendList = fla.Where(x => x.UserName.ToLower().Contains(filterText)).ToArray(); - Dispatcher.BeginInvoke(new Action(() => - this.ResetUserList(fla, friendList, FriendListItems, x => new FriendListItem(x),x=>true,FriendContextMenu))); + Dispatcher.BeginInvoke(new Action(() => + this.ResetUserList(fla, friendList, FriendListItems, x => new FriendListItem(x), x => true, FriendContextMenu))); } @@ -652,8 +653,8 @@ private void InvokeFriendList() /// Resets the user list visually and internally. Must be called on UI thread. /// private void ResetUserList(User[] fullList, User[] filteredList - , OrderedObservableCollection userItems ,Func create - , Func resetCondition, + , OrderedObservableCollection userItems, Func create + , Func resetCondition, ContextMenu conMenu) where T : UserListItem { lock (resestLocker) @@ -746,6 +747,30 @@ private void UserFilterTextChanged(object sender, TextChangedEventArgs e) #region ChatInput private int autoCompleteStart = -1; + + private Key autoCompleteTriggerKey; + + + private void AutoCompleteDoubleClick(object sender, MouseButtonEventArgs e) + { + try + { + var args = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Enter) + { + RoutedEvent + = + Keyboard + .KeyDownEvent + }; + ChatInputPreviewKeyUp(sender, args); + + } + catch (Exception ex) + { + Log.Warn("AutoCompleteDoubleClick Error", ex); + } + } + /// /// Happens when a key goes up in the chat text box. /// @@ -753,43 +778,75 @@ private void UserFilterTextChanged(object sender, TextChangedEventArgs e) /// Event Arguments private void ChatInputPreviewKeyUp(object sender, KeyEventArgs e) { - if (this.room == null) + try { - return; - } + if (this.room == null) + { + return; + } - if (e.Key == Key.LeftShift || e.Key == Key.RightShift) - { - this.shiftDown = false; - } - else - { + if (e.Key == Key.LeftShift || e.Key == Key.RightShift) + { + this.shiftDown = false; + } + // @ key if (e.Key == Key.D2) { AutoCompleteCollection.Clear(); + autoCompleteTriggerKey = e.Key; foreach (var u in this.UserListItems) { - AutoCompleteCollection.Add(u.User.UserName); + AutoCompleteCollection.Add(new DescriptionItem(u.User.UserName)); } autoCompleteStart = ChatInput.CaretIndex; + e.Handled = true; } - else if (e.Key == Key.Space || e.Key == Key.Escape) + // / key + else if (e.Key == Key.Oem2 && ChatInput.CaretIndex == 1) { AutoCompleteCollection.Clear(); + autoCompleteTriggerKey = e.Key; + foreach (var c in ChatRoom.SlashCommands) + { + AutoCompleteCollection.Add(new DescriptionItem(c.Key, c.Value)); + } + autoCompleteStart = ChatInput.CaretIndex; + } + else if (e.Key == Key.Escape) + { + AutoCompleteCollection.Clear(); + } + else if (e.Key == Key.Space) + { + AutoCompleteCollection.Clear(); + if (AutoCompleteVisible) + { + if (autoCompleteTriggerKey == Key.D2) + { + ChatInput.Select(autoCompleteStart - 1, 1); + ChatInput.SelectedText = ""; + ChatInput.Select(ChatInput.Text.Length, 0); + } + } } else if (e.Key == Key.Enter) { if (AutoCompleteVisible) { if (AutoCompleteListBox.Items.Count == 0) return; - var item = ((string) AutoCompleteListBox.SelectedItem ?? "").Clone() as string; - if (!string.IsNullOrWhiteSpace(item)) + if (AutoCompleteListBox.SelectedIndex == -1) return; + var item = (DescriptionItem)AutoCompleteListBox.SelectedItem; + ChatInput.Select(autoCompleteStart, ChatInput.Text.Length - autoCompleteStart); + ChatInput.SelectedText = item.Item; + ChatInput.Select(ChatInput.Text.Length, 0); + e.Handled = true; + AutoCompleteCollection.Clear(); + if (autoCompleteTriggerKey == Key.D2) { - ChatInput.Select(autoCompleteStart, ChatInput.Text.Length - autoCompleteStart); - ChatInput.SelectedText = item; - e.Handled = true; + ChatInput.Select(autoCompleteStart - 1, 1); + ChatInput.SelectedText = ""; + ChatInput.Select(ChatInput.Text.Length, 0); } - AutoCompleteCollection.Clear(); } } else if (e.Key == Key.Up) @@ -849,16 +906,32 @@ private void ChatInputPreviewKeyUp(object sender, KeyEventArgs e) ChatInput.Select(oldSpot, 0); AutoCompleteCollection.Clear(); - foreach (var i in UserListItems.ToArray()) + if (autoCompleteTriggerKey == Key.D2) { - if (i.User.UserName.StartsWith(set)) - AutoCompleteCollection.Add(i.User.UserName); + foreach (var i in UserListItems.ToArray()) + { + if (i.User.UserName.StartsWith(set)) + AutoCompleteCollection.Add(new DescriptionItem(i.User.UserName)); + } + } + else if (autoCompleteTriggerKey == Key.Oem2) + { + foreach (var i in ChatRoom.SlashCommands) + { + if (i.Key.StartsWith(set)) + AutoCompleteCollection.Add(new DescriptionItem(i.Key, i.Value)); + } } if (AutoCompleteListBox.Items.Count == 0) return; if (AutoCompleteListBox.SelectedIndex == -1) AutoCompleteListBox.SelectedIndex = 0; } } + + } + catch (Exception ex) + { + Log.Warn("ChatInputPreviewKeyUp Error", ex); } } @@ -894,7 +967,7 @@ private void ChatInputPreviewKeyDown(object sender, KeyEventArgs e) this.curMessageCacheItem = -1; e.Handled = true; } - else if(String.IsNullOrWhiteSpace(ChatInput.Text)) + else if (String.IsNullOrWhiteSpace(ChatInput.Text)) { switch (e.Key) { @@ -981,4 +1054,87 @@ public void Dispose() } } } + + public class DescriptionItem : IComparable>, INotifyPropertyChanged where T : IComparable + { + private T item; + + private string description; + + public T Item + { + get + { + return this.item; + } + set + { + if (Equals(value, this.item)) + { + return; + } + this.item = value; + this.OnPropertyChanged("Item"); + } + } + + public string Description + { + get + { + return this.description; + } + set + { + if (value == this.description) + { + return; + } + this.description = value; + this.OnPropertyChanged("Description"); + this.OnPropertyChanged("HasDescription"); + } + } + + public bool HasDescription + { + get + { + return !string.IsNullOrWhiteSpace(Description); + } + } + + public DescriptionItem() + { + } + + public DescriptionItem(T item) + { + Item = item; + Description = ""; + } + + public DescriptionItem(T item, string description) + { + Item = item; + Description = description; + } + + public int CompareTo(DescriptionItem other) + { + return Item.CompareTo(other.Item); + } + + public event PropertyChangedEventHandler PropertyChanged; + + [NotifyPropertyChangedInvocator] + protected virtual void OnPropertyChanged(string propertyName) + { + var handler = PropertyChanged; + if (handler != null) + { + handler(this, new PropertyChangedEventArgs(propertyName)); + } + } + } } diff --git a/octgnFX/Skylabs.Lobby/ChatRoom.cs b/octgnFX/Skylabs.Lobby/ChatRoom.cs index 482aba9f2c..c5987f23da 100644 --- a/octgnFX/Skylabs.Lobby/ChatRoom.cs +++ b/octgnFX/Skylabs.Lobby/ChatRoom.cs @@ -575,6 +575,25 @@ public void Whisper(User user) this.client.Chatting.GetRoom(user); } + private static Dictionary slashCommands; + public static Dictionary SlashCommands + { + get + { + if (slashCommands == null) + { + slashCommands = new Dictionary(); + slashCommands.Add("?","Get Help"); + slashCommands.Add("topic", "Set the room topic(if you have the cred)" + Environment.NewLine + "Usage: /topic This is a really great room"); + slashCommands.Add("msg", "Starts a chat with a specific user" + Environment.NewLine + "Usage: /msg username"); + slashCommands.Add("friend", "Add a friend, or multiple friends(separated by commas)" + Environment.NewLine + "Usage: /friend username[,username2,username3,...]"); + slashCommands.Add("removefriend", "Remove a friend, or multiple friends(separated by commas)" + Environment.NewLine + "Usage: /removefriend username[,username2,username3,...]"); + slashCommands.Add("invite", "Invite user, or multiple users, to a chat room(separated by commas)" + Environment.NewLine + "Usage: /invite username[,username2,username3,...]"); + } + return slashCommands; + } + } + /// /// The send message. /// diff --git a/recentchanges.txt b/recentchanges.txt index e69de29bb2..efb5e18d73 100644 --- a/recentchanges.txt +++ b/recentchanges.txt @@ -0,0 +1,2 @@ +Add spell checking to the chat - Kelly +Add auto complete to the chat - Kelly \ No newline at end of file