#region License // Copyright (C) 2020 Reetus // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #endregion using System; using System.Collections.ObjectModel; using System.Linq; using System.Text.RegularExpressions; using System.Windows.Input; using System.Windows.Media; using ClassicAssist.Shared; using ClassicAssist.Data.Chat; using ClassicAssist.Data.Macros.Commands; using ClassicAssist.Misc; using ClassicAssist.Shared.Resources; using ClassicAssist.Shared.UO; namespace ClassicAssist.UI.ViewModels { public class ChatViewModel : BaseViewModel { private readonly SolidColorBrush _defaultBrush = new SolidColorBrush( Color.FromArgb( 0xff, 0xcc, 0xcc, 0xcc ) ); private readonly SolidColorBrush _enemyBrush = new SolidColorBrush( Colors.Orange ); private readonly SolidColorBrush _friendBrush = new SolidColorBrush( Colors.LimeGreen ); // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable private readonly ChatManager _manager; private ICommand _changeChannelCommand; private ObservableCollection _channels = new ObservableCollection(); private string _currentChannel; private ObservableCollection _messages = new ObservableCollection(); private string _selectedChannel; private string _title; private ICommand _toggleOptionCommand; private bool _topmost = true; private ObservableCollection _users = new ObservableCollection(); public ChatViewModel() { _manager = ChatManager.GetInstance(); _manager.UserJoinedEvent += OnUserJoined; _manager.UserLeftEvent += OnUserLeft; _manager.ClearUsersEvent += OnClearUsers; _manager.JoinedChatChannelEvent += OnJoinedChatChannel; _manager.LeftChatChannelEvent += OnLeftChatChannel; Engine.DisconnectedEvent += () => OnLeftChatChannel( string.Empty ); _manager.ChannelCreatedEvent += OnChannelCreated; _manager.ChannelRemovedEvent += OnChannelRemoved; if ( !string.IsNullOrEmpty( _manager.CurrentChannel ) ) { OnJoinedChatChannel( _manager.CurrentChannel ); } else { UpdateTitle( Strings.Chat ); } foreach ( string user in _manager.Users ) { //TODO2 Users.AddSorted( new ChatUser { Username = user/*, Colour = GetUserColour( user )*/ } ); } foreach ( string channel in _manager.Channels ) { OnChannelCreated( channel ); } //foreach ( ChatMessage message in _manager.Messages ) //{ // Messages.Add( message ); //} _manager.ChatMessageEvent += OnChatMessage; } public ICommand ChangeChannelCommand => _changeChannelCommand ?? ( _changeChannelCommand = new RelayCommand( ChangeChannel, o => Channels.Count != 0 ) ); public ObservableCollection Channels { get => _channels; set => SetProperty( ref _channels, value ); } public string CurrentChannel { get => _currentChannel; set => SetProperty( ref _currentChannel, value ); } public ObservableCollection Messages { get => _messages; set => SetProperty( ref _messages, value ); } public string SelectedChannel { get => _selectedChannel; set => SetProperty( ref _selectedChannel, value ); } public string Title { get => _title; set => SetProperty( ref _title, value ); } public ICommand ToggleOptionCommand => _toggleOptionCommand ?? ( _toggleOptionCommand = new RelayCommand( ToggleOption, o => true ) ); public bool Topmost { get => _topmost; set => SetProperty( ref _topmost, value ); } public ObservableCollection Users { get => _users; set => SetProperty( ref _users, value ); } private static void ToggleOption( object obj ) { } private void ChangeChannel( object obj ) { if ( !( obj is string channel ) ) { return; } _dispatcher.Invoke( () => { Commands.JoinChatChannel( channel ); } ); } private void OnChannelRemoved( string channel ) { _dispatcher.Invoke( () => { Channels.Remove( channel ); } ); } private void OnChannelCreated( string channel ) { _dispatcher.Invoke( () => { Channels.Add( channel ); } ); } private void OnChatMessage( string username, string channel, string message ) { _dispatcher.Invoke( () => Messages.Add( new ChatMessage { //TODO2 Username = username, Channel = channel, Text = message/*, Colour = GetUserColour( username )*/ } ) ); } private void OnLeftChatChannel( string channel ) { _dispatcher.Invoke( () => { Users.Clear(); CurrentChannel = null; SelectedChannel = null; UpdateTitle( string.Empty ); } ); } private void UpdateTitle( string channel ) { if ( string.IsNullOrEmpty( channel ) ) { Title = Strings.Chat; return; } Title = $"{Strings.Chat} - {channel}"; } private void OnJoinedChatChannel( string channel ) { _dispatcher.Invoke( () => { CurrentChannel = channel; SelectedChannel = channel; UpdateTitle( channel ); } ); } private void OnClearUsers() { _dispatcher.Invoke( () => Users.Clear() ); } private void OnUserLeft( string username, string channel ) { _dispatcher.Invoke( () => { Users.Remove( Users.FirstOrDefault( u => u.Username == username ) ); } ); } private void OnUserJoined( string username, string channel ) { _dispatcher.Invoke( () => { //TODO2 ChatUser user = new ChatUser { Username = username/*, Colour = GetUserColour( username )*/ }; Users.AddSorted( user ); } ); } private SolidColorBrush GetUserColour( string username ) { try { Match matches = Regex.Match( username, @"<(.*)>\s*(.*)" ); if ( !matches.Success ) { return _defaultBrush; } int serial = int.Parse( matches.Groups[1].Value ); if ( serial == Engine.Player?.Serial || MobileCommands.InFriendList( serial ) ) { return _friendBrush; } return serial == AliasCommands.GetAlias( "enemy" ) ? _enemyBrush : _defaultBrush; } catch ( Exception ) { return _defaultBrush; } } } }