using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Threading; using ChatController.Annotations; using ChatController.ChatKlassen; using ChatController.Extensions; using ChatController.HauptKlassen; using ChatController.LoginKlassen; using ChatController.Utilities; using ChatController.Utilities.Extensions; using Application = System.Windows.Forms.Application; using Button = System.Windows.Controls.Button; using Cursors = System.Windows.Input.Cursors; using DataFormats = System.Windows.DataFormats; using KeyEventArgs = System.Windows.Input.KeyEventArgs; using MenuItem = System.Windows.Controls.MenuItem; using MessageBox = System.Windows.MessageBox; using Orientation = System.Windows.Controls.Orientation; using Panel = System.Windows.Controls.Panel; using Path = System.IO.Path; using ScrollBar = System.Windows.Controls.Primitives.ScrollBar; using Timer = System.Windows.Forms.Timer; namespace ChatController { public partial class ChatMainControl : INotifyPropertyChanged { private readonly Dictionary> _Group2NotifyIcons = new Dictionary>(); private readonly Dictionary _GroupId2DateTime = new Dictionary(); private string _ThreadExceptionMessage; public string ThreadExceptionMessage { get => _ThreadExceptionMessage; set { if(!Equals(_ThreadExceptionMessage, value)) { _ThreadExceptionMessage = value; OnPropertyChanged(nameof(ThreadExceptionMessage)); OnPropertyChanged(nameof(CurrentContactInformationString)); OnPropertyChanged(nameof(CurrencContactInfoForeground)); OnPropertyChanged(nameof(ThreadExceptionImageSource)); } } } private readonly ImageSource _ThreadExceptionImageSource; public ImageSource ThreadExceptionImageSource => ThreadExceptionMessage != null ? _ThreadExceptionImageSource : CurrentContact?.Image; public SolidColorBrush CurrencContactInfoForeground => ThreadExceptionMessage != null ? new SolidColorBrush(Color.FromRgb(185, 65, 0)) : CurrentContact?.AccentColorBrush ?? new SolidColorBrush(Colors.Transparent); public string CurrentContactInformationString => ThreadExceptionMessage ?? CurrentContact?.Name; private Window _ContainingWindow; public Window ContainingWindow { get => _ContainingWindow; set { _ContainingWindow = value; if(value != null) { _ContainingWindow.Deactivated += ContainingWindowOnDeactivated; _ContainingWindow.Activated += ContainingWindowOnActivated; } } } public Chat Chat { get; set; } private Contact _CurrentContact; public Contact CurrentContact { get => _CurrentContact; set { if(!Equals(_CurrentContact, value)) { _CurrentContact = value; OnPropertyChanged(nameof(CurrentContact)); OnPropertyChanged(nameof(ChatMessageInputGridVisibility)); OnPropertyChanged(nameof(Chat)); OnPropertyChanged(nameof(CurrentContactInformationString)); OnPropertyChanged(nameof(CurrencContactInfoForeground)); OnPropertyChanged(nameof(ThreadExceptionImageSource)); } } } public ObservableCollection ContactList { get { return _ContactList == null ? new ObservableCollection() : new ObservableCollection(_ContactList.OrderByDescending(contact => contact.TimeStamp)); } } public Visibility ChatMessageInputGridVisibility { get { if(_CurrentContact == null) { return Visibility.Collapsed; } return _CurrentContact.IsChatMessageInputGridVisible ? Visibility.Visible : Visibility.Collapsed; } } private List _ContactList; private bool _ScrollPrueferAktivieren; public bool ShouldInterruptContactsThread = true; private readonly List _CreatedTempFiles = new List(); private readonly Dictionary> _MenuItemName2Callback = new Dictionary>(); private bool _IsDesktopVersion = true; private bool _IsInBackground; public ChatMainControl() { InitializeComponent(); _ThreadExceptionImageSource = new BitmapImage(new Uri("pack://application:,,,/ChatController;component/Ressourcen/warning-exclamation-mark.png", UriKind.Absolute)); _ChatMessages = new ObservableCollection(); ChatMessages = CollectionViewSource.GetDefaultView(_ChatMessages) as ListCollectionView; if (ChatMessages != null) { ChatMessages.CustomSort = new ChatMessageComparer(); } DataContext = this; ReloadGruppen.Visibility = Visibility.Collapsed; } private void ContainingWindowOnDeactivated(object sender, EventArgs e) { _IsInBackground = true; } private void ContainingWindowOnActivated(object sender, EventArgs e) { _IsInBackground = false; } private readonly ObservableCollection _ChatMessages; public ListCollectionView ChatMessages { get; set; } public void InitMitChatdaten(ChatDatenUebergabe cdu) { Chat = new Chat(cdu, exception => { this.Dispatch( () => { EndWaiting(); MessageBox.Show($"Fehler: {exception.Message}", "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); }); }, exception => { this.Dispatch( () => { if(exception == null) { ThreadExceptionMessage = null; } ThreadExceptionMessage = exception?.Message?.Contains("500") ?? false ? "ownChat ist vorrübergehend nicht verfügbar. Bitte versuchen Sie es später noch einmal." : null; }); }); OnPropertyChanged(nameof(Chat)); _ContactList = Chat.AddContacts(); OnPropertyChanged(nameof(ContactList)); ReadNewSyncFile(); foreach (var contact in _ContactList) { if (_GroupId2DateTime.ContainsKey(contact.GroupId)) { var isUnread = _GroupId2DateTime[contact.GroupId].IsUnread; contact.IsNewMessage = isUnread; contact.HasUnreadMessages = contact.IsNewMessage; } } GlobalListeningThreadtimer?.Stop(); GlobalListeningThreadtimer = null; InitGlobalListeningThread(); Clientlist.Items.Refresh(); } public void ShowNotification(string pTitle, GroupLatestMessage pMessage, int pGroupId) { var notificationIcon = Resource.ownchat_favicon; var contact = _ContactList.FirstOrDefault(a => a.GroupId == pGroupId); if (contact != null) { notificationIcon = Utils.ImageSourceToIcon(contact.Image); } var notifyIcon = new NotifyIcon { Icon = notificationIcon, Visible = true, Tag = pMessage }; notifyIcon.BalloonTipClicked += (sender, args) => { DisposeAndRemoveNotification((NotifyIcon)sender, pGroupId); if(_ContainingWindow == null) { return; } if (_ContainingWindow.WindowState == WindowState.Minimized) { _ContainingWindow.WindowState = WindowState.Normal; } _ContainingWindow.Activate(); var selectedContact = _ContactList?.FirstOrDefault(f => f?.GroupId == pGroupId); if(selectedContact != null) { SelectContact(selectedContact); } }; notifyIcon.BalloonTipClosed += (sender, args) => { // TODO: wird beim ausblenden bzw. automatischem Schließen des "Balloons" ausgelöst DisposeAndRemoveNotification((NotifyIcon)sender, pGroupId); }; _Group2NotifyIcons.AddOrUpdateValueInDictionary(pGroupId, notifyIcon); _Group2NotifyIcons[pGroupId].Find(f => f.Tag is GroupLatestMessage message && message.Id.Equals(pMessage.Id))?.ShowBalloonTip(Constants.NotificationTimeout, pTitle, "Sie haben eine neue Nachricht", ToolTipIcon.None); } public void ClearNotifications() { foreach(var group2NotifyIcon in _Group2NotifyIcons) { foreach(var notifyIcon in group2NotifyIcon.Value) { notifyIcon.Icon = null; notifyIcon.Dispose(); Application.DoEvents(); } } _Group2NotifyIcons.Clear(); } private void DisposeAndRemoveNotification(IDisposable pNotification, long pGroupId) { pNotification.Dispose(); _Group2NotifyIcons.Remove(pGroupId); Application.DoEvents(); } public void ResetStyle() { EmojiButton.Style = null; MediaButton.Style = null; ReloadGruppen.Visibility = Visibility.Visible; _IsDesktopVersion = false; } private void CurrentContactImage_OnMouseDoubleClick(object sender, MouseButtonEventArgs e) { if(e.ClickCount == 2) { Chat.ShowProfilePicture(_CurrentContact); } } private void Clientlist_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { if(Clientlist?.SelectedItem is Contact selectedContact) { SelectContact(selectedContact); } } private void SelectContact(Contact pContact) { if(pContact == null) { return; } ShouldInterruptContactsThread = true; StartWaitingImmediately(); _ScrollPrueferAktivieren = false; if (pContact.HasUnreadMessages) { pContact.HasUnreadMessages = false; Clientlist.Items.Refresh(); } var currentContact = pContact; pContact.IsNewMessage = false; var shouldChangeIcon = _ContactList.Any(contact => contact.IsNewMessage); if(shouldChangeIcon) { ContainingWindow.Icon = Utils.ConvertIconToImageSource(Resource.ownchat_favicon); } CurrentContact = currentContact; if(Clientlist.Items.Contains(pContact)) { Clientlist.SelectedItem = pContact; } _ChatMessages.Clear(); Chat.LoadChatMessagesForContactAsync(currentContact, GetFirstMessage(), chatMessages => { this.Dispatch(() => { _ChatMessages.AddRangeIfElementsNotIn(chatMessages); WpfUtils.ScrollToBottomOfListBox(ChatListBox); ChatListBox.ContextMenu = Chat.ErstelleKontextMenue(); SetContextHandler(); _ScrollPrueferAktivieren = true; ListenForMessages(); Cursor = Cursors.Arrow; WriteToNewSyncFile(); ShouldInterruptContactsThread = false; EndWaiting(); }); }); } private void SetContextHandler() { var contextItems = ChatListBox?.ContextMenu?.Items; if(contextItems == null) { return; } foreach (var menuItemText in _MenuItemName2Callback.Keys) { var callback = _MenuItemName2Callback[menuItemText]; var menuItem = new MenuItem(); menuItem.Click += (s, e2) => { callback(menuItemText); }; menuItem.Header = menuItemText; contextItems.Add(menuItem); } if(contextItems.Count > 0) { var saveAsMenuItem = (MenuItem) contextItems[0]; saveAsMenuItem.Click += SaveAsOnClick; } if(contextItems.Count > 1) { var pasteMenuItem = (MenuItem) contextItems[1]; pasteMenuItem.Click += PasteOnClick; } // neu und vor Einfügen setzen und anpassen if(contextItems.Count > 2) { var copyMenuItem = (MenuItem) contextItems[2]; copyMenuItem.Click += CopyOnClick; } } private void SaveAsOnClick(object sender, RoutedEventArgs routedEventArgs) { foreach (var items in ChatListBox.SelectedItems) { var chatMessage = (ChatMessage) items; Chat.SaveFileAs(chatMessage); } } private void PasteOnClick(object sender, RoutedEventArgs routedEventArgs) { Chat.Paste(CurrentContact.GroupId,this); } private void CopyOnClick(object sender, RoutedEventArgs routedEventArgs) { var chatMessages = string.Empty; foreach (var items in ChatListBox.SelectedItems) { var item = (ChatMessage) items; chatMessages += item.UserMessage + "\n"; } if(!string.IsNullOrWhiteSpace(chatMessages)) { Chat.Copy(chatMessages, 1); } } private void Chat_OnContextMenuOpening(object sender, ContextMenuEventArgs e) { if(ChatListBox?.ContextMenu == null) { return; } if(ChatListBox.SelectedItems is List chatMessages) { if(chatMessages.Count > 0) { foreach(var items in chatMessages) { var item = (ChatMessage) items; if(item?.PictureSource != null) { if(ChatListBox.ContextMenu != null) { var contextItems = ChatListBox.ContextMenu.Items; ((MenuItem)contextItems[0]).Visibility = Visibility.Visible; } } else { var contextItems = ChatListBox.ContextMenu.Items; var ContextItemSpeichernUnter = (MenuItem)contextItems[0]; ContextItemSpeichernUnter.Visibility = Visibility.Collapsed; } if(item.PictureSource == null && item.FilePath == null) { var contextItems = ChatListBox.ContextMenu.Items; var ContextItemSpeichernUnter = (MenuItem)contextItems[2]; ContextItemSpeichernUnter.Visibility = Visibility.Visible; } else { var contextItems = ChatListBox.ContextMenu.Items; var ContextItemSpeichernUnter = (MenuItem)contextItems[2]; ContextItemSpeichernUnter.Visibility = Visibility.Collapsed; } } } else { //Schalte speichern unter Aus var contextItems = ChatListBox.ContextMenu.Items; var ContextItemSpeichernUnter = (MenuItem)contextItems[0]; ContextItemSpeichernUnter.Visibility = Visibility.Collapsed; } //prüfe ob was in dem Speicher vorhanden ist //Einfügen var dataObject = System.Windows.Forms.Clipboard.GetDataObject(); if(dataObject != null && dataObject.GetDataPresent(DataFormats.FileDrop)) { var contextItems = ChatListBox.ContextMenu.Items; var ContextItemSpeichernUnter = (MenuItem) contextItems[1]; ContextItemSpeichernUnter.Visibility = Visibility.Visible; } else if(dataObject != null && dataObject.GetDataPresent(DataFormats.Text)) { var contextItems = ChatListBox.ContextMenu.Items; var ContextItemSpeichernUnter = (MenuItem) contextItems[1]; ContextItemSpeichernUnter.Visibility = Visibility.Visible; } else if(dataObject != null && dataObject.GetDataPresent(DataFormats.Bitmap)) { var contextItems = ChatListBox.ContextMenu.Items; var ContextItemSpeichernUnter = (MenuItem) contextItems[1]; ContextItemSpeichernUnter.Visibility = Visibility.Visible; } else { var contextItems = ChatListBox.ContextMenu.Items; var ContextItemSpeichernUnter = (MenuItem)contextItems[1]; ContextItemSpeichernUnter.Visibility = Visibility.Collapsed; } // Prüfe, ob Dokumentation erlaubt if(CurrentContact.UserIdManage == null && ChatListBox.ContextMenu.Items.Count > 3) { var contextItems = ChatListBox.ContextMenu.Items; var ContextItemSpeichernUnter = (MenuItem)contextItems[3]; ContextItemSpeichernUnter.Visibility = Visibility.Collapsed; } else if(ChatListBox.ContextMenu.Items.Count > 3) { var contextItems = ChatListBox.ContextMenu.Items; var ContextItemSpeichernUnter = (MenuItem)contextItems[3]; ContextItemSpeichernUnter.Visibility = Visibility.Visible; } if(ChatListBox.ContextMenu.Items.Count == 0) { ChatListBox.ContextMenu.Visibility = Visibility.Collapsed; } } } private void MediaButton_OnClick(object sender, RoutedEventArgs e) { if(CurrentContact != null) { var fileToOpen = Chat.OpenFile(); if(fileToOpen != null) { var filePath = FileUtils.ScaleImage(fileToOpen, Path.GetExtension(fileToOpen.ToUpperInvariant()), Chat.ChatDaten.MaxUploadSize); var isFileSizeTooLarge = FileUtils.CheckFileSize(filePath, Chat.ChatDaten.MaxUploadSize); if(isFileSizeTooLarge) { MessageBox.Show($"Die ausgewählte Datei ist zu groß. Die maximale Größe beträgt {Chat.ChatDaten.MaxUploadSize / 1000 / 1000} MB", "Senden nicht möglich", MessageBoxButton.OK, MessageBoxImage.Warning); return; } if (!string.IsNullOrWhiteSpace(filePath)) { _ChatMessages.AddRangeIfElementsNotIn(Chat.AddNewFile(filePath, fileToOpen, CurrentContact.GroupId, GetFirstMessage())); ChatMessages.MoveCurrentToLast(); var currentChatMessage = ChatMessages.CurrentItem; ChatListBox.ScrollIntoView(currentChatMessage); Chat.SendFileToContact(CurrentContact, filePath,fileToOpen); if (!string.IsNullOrWhiteSpace(filePath) && !filePath.Equals(fileToOpen) && File.Exists(filePath)) { File.Delete(filePath); } } } } else { MessageBox.Show("Bitte wählen Sie einen Kontakt aus.","ownChat",MessageBoxButton.OK, MessageBoxImage.Information); } } private void SendButton_OnClick(object sender, RoutedEventArgs e) { if(CurrentContact != null && !string.IsNullOrEmpty(Chatbox.Text)) { _ChatMessages.AddRangeIfElementsNotIn(Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId, GetFirstMessage())); ChatMessages.MoveCurrentToLast(); ChatListBox.ScrollIntoView(ChatMessages.CurrentItem); WpfUtils.ScrollToBottomOfListBox(ChatListBox); Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId); Chatbox.Text = string.Empty; } } private void Chatbox_OnGotFocus(object sender, RoutedEventArgs e) { if (Chatbox.Text.Equals("Nachricht schreiben")) { Chatbox.Text = string.Empty; Chatbox.Foreground = new SolidColorBrush(Colors.Black); } } private void Chatbox_OnKeyDownHandler(object sender, KeyEventArgs e) { try { //if (e.Key == Key.Return) //{ // if(CurrentContact != null && !string.IsNullOrEmpty(Chatbox.Text)) // { // Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId); // OnPropertyChanged(nameof(CurrentChatMessages)); // ChatListBox.Items.MoveCurrentToLast(); // ChatListBox.ScrollIntoView(ChatListBox.Items.CurrentItem); // Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId); // Chatbox.Text = string.Empty; // } //} } catch (Exception ed) { MessageBox.Show("Beim Senden einer Nachricht ist ein Fehler aufgetreten. " + ed.Message + "\n" + ed.StackTrace, "Fehler", MessageBoxButton.OK); } } public delegate void EmojiiDelegate(Button button); public event EmojiiDelegate OnEmojii; private void EmojiButton_OnClick(object sender, RoutedEventArgs e) { OnEmojii?.Invoke(EmojiButton); } private void Chat_OnScrollChanged(object sender, ScrollChangedEventArgs e) { var scrollBarList = Utils.GetVisualChildCollection(ChatListBox); foreach (var scrollBar in scrollBarList) { if (scrollBar.Orientation == Orientation.Horizontal) { _ScrollPrueferAktivieren = true; } else { scrollBar.ValueChanged += VerticalScrollbarChanged; } } } private void VerticalScrollbarChanged(object sender, RoutedPropertyChangedEventArgs routedPropertyChangedEventArgs) { if (_ScrollPrueferAktivieren) { var scrollBar = (ScrollBar) sender; if (!(scrollBar.Value > 0)) { StartWaitingImmediately(); _ScrollPrueferAktivieren = false; ChatMessages.MoveCurrentToFirst(); var currentChatMessage = ChatMessages.CurrentItem; var selectedContact = (Contact) Clientlist.SelectedItem; Chat.LoadMoreMessagesAsync(selectedContact, GetFirstMessage(), chatMessages => { this.Dispatch(() => { EndWaiting(); _ChatMessages.AddRangeIfElementsNotIn(chatMessages); ChatListBox.ScrollIntoView(currentChatMessage); }); }); } } } private void ListenForMessages() { EmojisListeningThreadTimer?.Stop(); EmojisListeningThreadTimer = null; InitListeningThread(CurrentContact); } public Timer EmojisListeningThreadTimer; public Timer GlobalListeningThreadtimer { get; set; } private void InitGlobalListeningThread() { GlobalListeningThreadtimer = new Timer(); GlobalListeningThreadtimer.Tick += GlobalListeningThreadTimerTickEvent; GlobalListeningThreadtimer.Interval = 10000; GlobalListeningThreadtimer.Start(); } private void GlobalListeningThreadTimerTickEvent(object sender, EventArgs e) { ListenGloballyForMessages(); } private void ListenGloballyForMessages() { Chat.GetNumberOfAllNewMessagesAsync(newMessagesCount => { if(newMessagesCount > 0) { Chat.UpdateContactList(updatedContactList => { var updatedContacts = updatedContactList.ToList(); this.Dispatch(() => { foreach (var contact in _ContactList) { foreach (var newContact in updatedContacts) { if (contact.GroupId == newContact.GroupId) { // ReceivedMessage kann null sein! if (contact.ReceivedMessage != null && !contact.ReceivedMessage.Id.Equals(newContact.ReceivedMessage?.Id)) { contact.ReceivedMessage = newContact.ReceivedMessage; contact.TimeStamp = newContact.TimeStamp; var selectedContact = (Contact)Clientlist.SelectedItem; // Angemeldeter Benutzer var userOid = Chat.ChatDaten.LoggedInUser.Response.User.Oid; var senderId = contact.ReceivedMessage?.UserId; var receiverId = userOid; var receiverGroupId = newContact.GroupId; var selectedGroupId = selectedContact?.GroupId; if (senderId != receiverId && (_IsInBackground || receiverGroupId != selectedGroupId)) { if (ContainingWindow != null) { ContainingWindow.Icon = Utils.ConvertIconToImageSource(Resource.oC_favico_NewMessage); } ShowNotification(newContact.Name, newContact.ReceivedMessage, newContact.GroupId); } // Wenn der momentan ausgewählte Kontakt der aktuelle Kontakt in der Schleife ist, werden die Nachrichten nicht als ungelesen angezeigt, sonst schon. if (CurrentContact != null && newContact.GroupId == CurrentContact.GroupId) { contact.HasUnreadMessages = false; } else { contact.HasUnreadMessages = true; contact.IsNewMessage = true; } } } } if (!updatedContacts.Contains(contact)) { _ContactList.ToList().Remove(contact); } } Clientlist.Items.Refresh(); }); }); } }); } private void InitListeningThread(Contact currentContact) { EmojisListeningThreadTimer = new Timer {Tag = currentContact}; EmojisListeningThreadTimer.Tick += ListeningThreadTimerTickEvent; EmojisListeningThreadTimer.Interval = 10000; EmojisListeningThreadTimer.Start(); } private void ListeningThreadTimerTickEvent(object sender, EventArgs e) { ListenForMessagesForCurrentContact((Contact) ((Timer) sender).Tag); } private void ListenForMessagesForCurrentContact(Contact pCurrentContact) { if (!ShouldInterruptContactsThread) { Chat.CheckIfNewMessagesExistAsync(CurrentContact.GroupId, hasNewMessages => { if(!hasNewMessages) { return; } Chat.LoadChatMessagesForContactAsync(pCurrentContact, GetFirstMessage(), chatMessages => { this.Dispatch(() => { _ChatMessages.Clear(); _ChatMessages.AddRangeIfElementsNotIn(chatMessages); WpfUtils.ScrollToBottomOfListBox(ChatListBox); }); }); }); } } private void Suche_OnTextChanged(object sender, TextChangedEventArgs e) { CollectionViewSource.GetDefaultView(Clientlist.ItemsSource).Refresh(); } private bool UserFilter(object item) { if (string.IsNullOrEmpty(Suche.Text)) { return true; } return (item as Contact).Name.IndexOf(Suche.Text, StringComparison.OrdinalIgnoreCase) >= 0; } private void Chat_OnMouseDoubleClick(object sender, MouseButtonEventArgs e) { if(ChatListBox.SelectedItems.Count > 0) { var selectedItem = ChatListBox.SelectedItems[0]; if(selectedItem is ChatMessage selectedMessage) { if(!string.IsNullOrEmpty(selectedMessage.OriginalImage)) { StartWaitingImmediately(); Chat.ShowPicture(selectedMessage.OriginalImage, CurrentContact.GroupId, (imageSource, windowTitle) => { this.Dispatch(() => { EndWaiting(); Chat.ShowPictureWindow(imageSource, windowTitle); }); }); } else if(selectedMessage.FilePath != null) { StartWaitingImmediately(); LoadDocumentAsync(selectedMessage.FilePath.ToString(), Path.GetFileName(selectedMessage.FilePath.ToString()), EndWaiting); } } } } private void LoadDocumentAsync(string uri, string fileName, Action callback) { try { var path = Path.Combine(Path.GetTempPath(), fileName); _CreatedTempFiles.Add(path); if(!File.Exists(path)) { Chat.DownloadFileAsync(uri, path, () => { this.Dispatch(() => { if (File.Exists(path)) { Process.Start(path); } callback?.Invoke(); }); }); } else { Process.Start(path); callback?.Invoke(); } } catch(Exception exception) { EndWaiting(); MessageBox.Show(exception.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } } private ChatControlWaitLayer _WaitLayer; public void StartWaiting() { Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)StartWaitingImmediately); } public void StartWaitingImmediately() { if (_WaitLayer == null) { _WaitLayer = new ChatControlWaitLayer(); Grid.SetRowSpan(_WaitLayer, 3); RootGrid.Children.Add(_WaitLayer); Panel.SetZIndex(_WaitLayer, int.MaxValue); _WaitLayer.RefreshChatUI(); } } public void EndWaiting() { Dispatcher.BeginInvoke( DispatcherPriority.Background, (Action) delegate { if(_WaitLayer != null) { RootGrid.Children.Remove(_WaitLayer); _WaitLayer = null; } }); } private void Hyperlink_OnRequestNavigate(object sender, RequestNavigateEventArgs e) { Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); e.Handled = true; } private void ButtonReloadGruppen_OnClick(object sender, RoutedEventArgs e) { DoSynchro(); } private void DoSynchro() { try { StartWaitingImmediately(); WriteToNewSyncFile(); Chat.ReloadGroupsAsync(data => { this.Dispatch(() => { _ContactList = Chat.UpdateContacts(data); // <- dauert eine Sekunde! OnPropertyChanged(nameof(ContactList)); ReadNewSyncFile(); AddViewFilterToClientlist(); EndWaiting(); }); }); } catch (Exception e) { EndWaiting(); MessageBox.Show("Ein Fehler bei der Synchronisation ist aufgetreten.\nFehler:\n" + e.Message, "Fehler", MessageBoxButton.OK); } } // Speichert die TimeStamps der zuletzt empfangenen Nachrichten public void WriteToNewSyncFile() { try { if (File.Exists(Path.Combine(Utils.GetAndCreateUserAppDataPath(), Resource.SyncFile2Name))) { File.SetAttributes(Path.Combine(Utils.GetAndCreateUserAppDataPath(), Resource.SyncFile2Name), FileAttributes.Normal); File.Delete(Path.Combine(Utils.GetAndCreateUserAppDataPath(), Resource.SyncFile2Name)); } using (var streamWriter = new StreamWriter(Path.Combine(Utils.GetAndCreateUserAppDataPath(), Resource.SyncFile2Name))) { Encoding enc = new UTF8Encoding(); foreach (var contact in _ContactList.ToList().Where(contact => contact.ReceivedMessage != null)) { var text = contact.GroupId + ";" + contact.TimeStamp.ToUniversalTime() + ";" + contact.IsNewMessage + ";"; var bytes = enc.GetBytes(text); var base64String = Convert.ToBase64String(bytes); streamWriter.WriteLine(base64String); } File.SetAttributes(Path.Combine(Utils.GetAndCreateUserAppDataPath(), Resource.SyncFile2Name), FileAttributes.ReadOnly); } } catch (Exception exception) { } } public void ReadNewSyncFile() { try { if(File.Exists(Path.Combine(Utils.GetAndCreateUserAppDataPath(), Resource.SyncFile2Name))) { using (var streamReader = new StreamReader(Path.Combine(Utils.GetAndCreateUserAppDataPath(), Resource.SyncFile2Name), true)) { string line; _GroupId2DateTime.Clear(); while ((line = streamReader.ReadLine()) != null) { var encodedTextBytes = Convert.FromBase64String(line); var plainText = Encoding.UTF8.GetString(encodedTextBytes); var splitPlainText = plainText.Split(';'); // Ist kein Datum vorhanden -> 01.01.0001 00:00:00 var groupId = int.Parse(splitPlainText[0]); var dateTime = DateTime.Parse(splitPlainText[1]); var isUnread = splitPlainText.Length <= 2 || string.IsNullOrEmpty(splitPlainText[2]) || bool.Parse(splitPlainText[2]); _GroupId2DateTime.Add(groupId, new SyncFileInfoStruct(isUnread, dateTime)); } } var latestDateTime = Utils.DefaultDate; foreach(var id2dateTime in _GroupId2DateTime) { if(id2dateTime.Value.TimeStamp > latestDateTime) { latestDateTime = id2dateTime.Value.TimeStamp; } } Chat.LastTimeStamp = latestDateTime.GetUnixTimeStamp(); } } catch (Exception e) { } } // Wird im BeWoPlaner benutzt public List GetContactsWithoutUnreadMessages() { var contacts = new List(); Clientlist.Items.Refresh(); foreach(var contactItem in Clientlist.Items) { if(contactItem is Contact contact && contact.HasUnreadMessages && !string.IsNullOrEmpty(contact.ReceivedMessage?.Text)) { contacts.Add(contact); } } return contacts; } // Wird im BeWoPlaner benutzt public void ResetNumberOfUnreadMessages(Dictionary pGroupId2DateTime) { if(pGroupId2DateTime != null) { foreach(var contact in _ContactList) { foreach(var groupId2DateTime in pGroupId2DateTime) { if(contact.GroupId == groupId2DateTime.Key) { contact.HasUnreadMessages = false; } } } } } // Wird im BeWoPlaner benutzt public List GetSelectedMessages() { var messages = (from object selectedItem in ChatListBox.SelectedItems select selectedItem as ChatMessage).ToList(); return messages.Count > 0 ? messages : null; } // Wird im BeWoPlaner benutzt public Contact GetCurrentContactWithUserIdManage() { return CurrentContact?.UserIdManage != null ? CurrentContact : null; } // Wird im BeWoPlaner benutzt public Contact GetCurrentContact() { return CurrentContact; } // Wird im BeWoPlaner benutzt public void AddContextMenu(string menuItemText, Action callBackAction) { if (!_MenuItemName2Callback.ContainsKey(menuItemText)) { _MenuItemName2Callback.Add(menuItemText, callBackAction); } } public void DeleteTempFiles() { foreach (var file in _CreatedTempFiles) { try { if (File.Exists(file)) { File.Delete(file); } } catch (Exception e) { //ignore } } } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private void ChatMainControl_OnLoaded(object sender, RoutedEventArgs e) { AddViewFilterToClientlist(); } private void AddViewFilterToClientlist() { var view = (CollectionView)CollectionViewSource.GetDefaultView(Clientlist.ItemsSource); view.Filter = UserFilter; } private void Chatbox_OnTextChanged(object sender, TextChangedEventArgs e) { if(string.IsNullOrWhiteSpace(Chatbox.Text)) { Chatbox.Height = 25; } } public void AddMessages(List newMessages) { _ChatMessages.AddRangeIfElementsNotIn(newMessages); } public ChatMessage GetFirstMessage() { return _ChatMessages.FirstOrDefault(); } } }