Files
Chat/ChatController/ChatMainControl.xaml.cs
LynJet aa0004ec07 Verschickte Bilder werden jetzt korrekt rotiert angezeigt.
Die Synchronisation der Kontaktliste nach dem Senden einer Nachricht wird korrekt aktualisiert.
2022-06-03 16:40:47 +02:00

1242 lines
45 KiB
C#

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.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<long, List<NotifyIcon>> _Group2NotifyIcons = new Dictionary<long, List<NotifyIcon>>();
private readonly Dictionary<int, SyncFileInfoStruct> _GroupId2DateTime = new Dictionary<int, SyncFileInfoStruct>();
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<Contact> ContactList
{
get
{
return _ContactList == null ? new ObservableCollection<Contact>() : new ObservableCollection<Contact>(_ContactList.OrderByDescending(contact => contact.TimeStamp));
}
}
public Visibility ChatMessageInputGridVisibility
{
get
{
if(_CurrentContact is null)
{
return Visibility.Collapsed;
}
return _CurrentContact.IsChatMessageInputGridVisible ? Visibility.Visible : Visibility.Collapsed;
}
}
private List<Contact> _ContactList;
private bool _ScrollPrueferAktivieren;
public bool ShouldInterruptContactsThread = true;
private readonly List<string> _CreatedTempFiles = new List<string>();
private readonly Dictionary<string, Action<string>> _MenuItemName2Callback = new Dictionary<string, Action<string>>();
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<ChatMessage>();
ChatMessages = CollectionViewSource.GetDefaultView(_ChatMessages) as ListCollectionView;
if (!(ChatMessages is 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<ChatMessage> _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 is 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)
{
try
{
if (pContact == null)
{
return;
}
ShouldInterruptContactsThread = true;
StartWaitingImmediately();
_ScrollPrueferAktivieren = false;
if (pContact.HasUnreadMessages)
{
pContact.HasUnreadMessages = false;
Clientlist.Items.Refresh();
OnPropertyChanged(nameof(ContactList));
}
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();
OnPropertyChanged(nameof(_ChatMessages));
Chat.LoadChatMessagesForContactAsync(currentContact, GetFirstMessage(), chatMessages =>
{
this.Dispatch(() =>
{
_ChatMessages.Clear();
_ChatMessages.AddRangeIfElementsNotIn(chatMessages);
OnPropertyChanged(nameof(_ChatMessages));
WpfUtils.ScrollToBottomOfListBox(ChatListBox);
ChatListBox.ContextMenu = Chat.ErstelleKontextMenue();
SetContextHandler();
_ScrollPrueferAktivieren = true;
ListenForMessages();
Cursor = Cursors.Arrow;
WriteToNewSyncFile();
ShouldInterruptContactsThread = false;
EndWaiting();
});
});
}
catch(Exception exception)
{
#if DEBUG
var desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
using(var fileStream = new FileStream(Path.Combine(desktop, "ownchat_log.txt"), FileMode.OpenOrCreate))
{
using(var streamWriter = new StreamWriter(fileStream))
{
streamWriter.WriteLine(exception.ToString());
}
}
#endif
MessageBox.Show(exception.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
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<ChatMessage> 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 pathToOriginalImage = Chat.OpenFile();
if(pathToOriginalImage != null)
{
var pathToScaledImage = FileUtils.ScaleImage(pathToOriginalImage, Path.GetExtension(pathToOriginalImage.ToUpperInvariant()), Chat.ChatDaten.MaxUploadSize);
var isFileSizeTooLarge = FileUtils.CheckFileSize(pathToScaledImage, 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(pathToScaledImage))
{
_ChatMessages.AddRangeIfElementsNotIn(Chat.AddNewFile(pathToScaledImage, pathToOriginalImage, CurrentContact.GroupId, GetFirstMessage()));
ChatMessages.MoveCurrentToLast();
var currentChatMessage = ChatMessages.CurrentItem;
ChatListBox.ScrollIntoView(currentChatMessage);
Chat.SendFileToContact(CurrentContact, pathToScaledImage,pathToOriginalImage);
if (!string.IsNullOrWhiteSpace(pathToScaledImage) && !pathToScaledImage.Equals(pathToOriginalImage) && File.Exists(pathToScaledImage))
{
File.Delete(pathToScaledImage);
}
}
}
}
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))
{
var messages2Add = Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId, GetFirstMessage());
_ChatMessages.AddRangeIfElementsNotIn(messages2Add);
OnPropertyChanged(nameof(ChatMessages));
ChatMessages.MoveCurrentToLast();
ChatListBox.ScrollIntoView(ChatMessages.CurrentItem);
WpfUtils.ScrollToBottomOfListBox(ChatListBox);
Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId);
Chatbox.Text = string.Empty;
Thread.Sleep(500);
DoSynchro();
}
}
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<ScrollBar>(ChatListBox);
foreach (var scrollBar in scrollBarList)
{
if (scrollBar.Orientation == Orientation.Horizontal)
{
_ScrollPrueferAktivieren = true;
}
else
{
scrollBar.ValueChanged += VerticalScrollbarChanged;
}
}
}
private void VerticalScrollbarChanged(object sender, RoutedPropertyChangedEventArgs<double> 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();
OnPropertyChanged(nameof(ChatMessages));
OnPropertyChanged(nameof(ContactList));
});
});
}
});
}
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))
{
var uri = new Uri(selectedMessage.OriginalImage);
if(uri.IsFile)
{
var bitmapImage = new BitmapImage(uri);
bitmapImage.Freeze();
Chat.ShowPictureWindow(bitmapImage, "Test");
return;
}
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 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<Contact> GetContactsWithoutUnreadMessages()
{
var contacts = new List<Contact>();
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<long, DateTime> 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<ChatMessage> 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<string> 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<ChatMessage> newMessages)
{
_ChatMessages.AddRangeIfElementsNotIn(newMessages);
}
public ChatMessage GetFirstMessage()
{
return _ChatMessages.FirstOrDefault();
}
}
}