using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; 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; } } } private Chat _Chat; private Contact _CurrentContact; public ObservableCollection CurrentChatMessages => _CurrentContact != null && _Chat != null ? new ObservableCollection(_Chat.Messages) : new ObservableCollection(); public Contact CurrentContact { get => _CurrentContact; set { if(!Equals(_CurrentContact, value)) { _CurrentContact = value; OnPropertyChanged(nameof(CurrentContact)); OnPropertyChanged(nameof(ChatMessageInputGridVisibility)); OnPropertyChanged(nameof(CurrentChatMessages)); 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)); DataContext = this; ReloadGruppen.Visibility = Visibility.Collapsed; } private void ContainingWindowOnDeactivated(object sender, EventArgs e) { _IsInBackground = true; } private void ContainingWindowOnActivated(object sender, EventArgs e) { _IsInBackground = false; } 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; }); }); _ContactList = _Chat.AddContacts(); OnPropertyChanged(nameof(ContactList)); ReadNewSyncFile(); foreach (var contact in _ContactList) { if (_GroupId2DateTime.ContainsKey(contact.GroupId)) { var dateTimeFromFile = _GroupId2DateTime[contact.GroupId].TimeStamp; var isUnread = _GroupId2DateTime[contact.GroupId].IsUnread; var isYounger = contact.TimeStamp > dateTimeFromFile; 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.WindowState == WindowState.Minimized) { _ContainingWindow.WindowState = WindowState.Normal; } _ContainingWindow.Activate(); SelectContact(_ContactList.FirstOrDefault(f => f.GroupId.Equals(pGroupId))); }; 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 != null) { SelectContact((Contact) Clientlist.SelectedItem); } } // WebRequest: LoadChatMessagesForContact private void SelectContact(Contact pContact) { if(pContact == null) { return; } ShouldInterruptContactsThread = true; Cursor = Cursors.Wait; _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.GetImageSourceFromIcon(Resource.ownchat_favicon); } CurrentContact = currentContact; if(Clientlist.Items.Contains(pContact)) { Clientlist.SelectedItem = pContact; } var chatMessages = _Chat.LoadChatMessagesForContact(currentContact); OnPropertyChanged(nameof(CurrentChatMessages)); if (VisualTreeHelper.GetChildrenCount(ChatListBox) > 0) { var border = (Border) VisualTreeHelper.GetChild(ChatListBox, 0); var scrollViewer = (ScrollViewer) VisualTreeHelper.GetChild(border, 0); scrollViewer.ScrollToBottom(); } ChatListBox.ContextMenu = _Chat.ErstelleKontextMenue(); SetContextHandler(); _ScrollPrueferAktivieren = true; ListenForMessages(); Cursor = Cursors.Arrow; WriteToNewSyncFile(); ShouldInterruptContactsThread = false; } 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 = items as ChatMessage; if(item?.ImageSources != 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.ImageSources == 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)) { _Chat.AddNewFile(filePath, fileToOpen, CurrentContact.GroupId); OnPropertyChanged(nameof(CurrentChatMessages)); ChatListBox.Items.MoveCurrentToLast(); ChatListBox.ScrollIntoView(ChatListBox.Items.CurrentItem); _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)) { _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; } } 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; } } } // TODO: Asynchron machen? private void VerticalScrollbarChanged(object sender, RoutedPropertyChangedEventArgs routedPropertyChangedEventArgs) { if (_ScrollPrueferAktivieren) { var scrollBar = (ScrollBar) sender; if (!(scrollBar.Value > 0)) { Cursor = Cursors.Wait; _ScrollPrueferAktivieren = false; ChatListBox.Items.MoveCurrentToFirst(); var currentChatMessage = ChatListBox.Items.CurrentItem as ChatMessage; var kontakt = (Contact) Clientlist.SelectedItem; _Chat.LoadMoreMessages(kontakt); // Ab hier käme das ins Callback OnPropertyChanged(nameof(CurrentChatMessages)); if(currentChatMessage != null) { ChatListBox.ScrollIntoView(currentChatMessage); } Cursor = Cursors.Arrow; } } } 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() { var numberOfNewMessages = _Chat.GetNumberOfAllNewMessages(); if (numberOfNewMessages > 0) { Dispatcher.BeginInvoke( DispatcherPriority.Normal, (Action)delegate { var contacts = _Chat.NeueGroupklassenKontakte().ToList(); foreach (var contact in _ContactList) { foreach (var newContact in contacts) { if(newContact == null) { continue; } 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.GetImageSourceFromIcon(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 (!_ContactList.Contains(newContact)) { _ContactList.ToList().Add(newContact); } } if (!contacts.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) { var hasNewMessages = _Chat.CheckIfNewMessagesExist(pCurrentContact); if (hasNewMessages) { Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)delegate { _Chat.LoadChatMessagesForContact(pCurrentContact); OnPropertyChanged(nameof(CurrentChatMessages)); ChatListBox.Items.MoveCurrentToLast(); ChatListBox.ScrollIntoView(ChatListBox.Items.CurrentItem); }); } } } private void Suche_OnTextChanged(object sender, TextChangedEventArgs e) { OnPropertyChanged(nameof(CurrentChatMessages)); 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) { Cursor = Cursors.Wait; var chatItems = ChatListBox.SelectedItems; if (chatItems.Count > 0) { foreach (var items in chatItems) { var item = items as ChatMessage; if (item?.OriginalImage != null) { StartWaitingImmediately(); _Chat.ShowPicture(item.OriginalImage, EndWaiting); } else if(item?.FilePath != null) { var filename = Path.GetFileName(item.FilePath.ToString()); LoadDocument(item.FilePath.ToString(), filename); } } Cursor = Cursors.Arrow; } else { Cursor = Cursors.Arrow; } } private void LoadDocument(string link, string filename) { try { StartWaiting(); var path = Path.Combine(Path.GetTempPath(), filename); _CreatedTempFiles.Add(path); if (!File.Exists(path)) { using (var webClient = new WebClient()) { webClient.DownloadFile(link, path); } if (File.Exists(path)) { Process.Start(path); } } else { Process.Start(path); } } catch (Exception e) { } finally { EndWaiting(); } } 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(e.Uri.ToString()); } private void ButtonReloadGruppen_OnClick(object sender, RoutedEventArgs e) { DoSynchro(); } private void DoSynchro() { try { StartWaitingImmediately(); WriteToNewSyncFile(); _Chat.ReloadGroupsAsync(data => { this.Dispatch(() => { _ContactList = _Chat.GroupklassenAktuallisieren(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 GetCurrentContact() { return CurrentContact?.UserIdManage != null ? CurrentContact : null; } // 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; } } } }