Die Akzentfarbe von den Chatgruppen vom Server wird berücksichtigt. Bilder sind im richtigen Seitenverhältnis skaliert. Ein Bild, das man gerade erst verschickt hat und das man öffnen will, bevor es auf dem Server angekommen ist, wird jetzt erst angezeigt, sobald es auf dem Server ist. Die Textbox für eine neue Nachricht wird nur angezeigt, wenn eine Gruppe ausgewählt ist und wenn man das Recht hat Nachrichten an diese Gruppe zu verschicken. Diverse Codeverbesserungen.
1105 lines
39 KiB
C#
1105 lines
39 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.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.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 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 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<ChatMessage> CurrentChatMessages => _CurrentContact != null && _Chat != null ? new ObservableCollection<ChatMessage>(_Chat.Messages) : new ObservableCollection<ChatMessage>();
|
|
|
|
public Contact CurrentContact
|
|
{
|
|
get => _CurrentContact;
|
|
|
|
set
|
|
{
|
|
if(!Equals(_CurrentContact, value))
|
|
{
|
|
_CurrentContact = value;
|
|
|
|
OnPropertyChanged(nameof(CurrentContact));
|
|
OnPropertyChanged(nameof(ChatMessageInputGridVisibility));
|
|
OnPropertyChanged(nameof(CurrentChatMessages));
|
|
}
|
|
}
|
|
}
|
|
|
|
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 == 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();
|
|
|
|
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);
|
|
});
|
|
});
|
|
|
|
_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) =>
|
|
{
|
|
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.Dispose();
|
|
}
|
|
}
|
|
|
|
_Group2NotifyIcons.Clear();
|
|
}
|
|
|
|
private void DisposeAndRemoveNotification(IDisposable pNotification, long pGroupId)
|
|
{
|
|
pNotification.Dispose();
|
|
_Group2NotifyIcons.Remove(pGroupId);
|
|
}
|
|
|
|
public void ResetStyle()
|
|
{
|
|
EmojiButton.Style = null;
|
|
MediaButton.Style = null;
|
|
ReloadGruppen.Visibility = Visibility.Visible;
|
|
_IsDesktopVersion = false;
|
|
}
|
|
|
|
private void AktChatUser_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
|
|
{
|
|
_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;
|
|
|
|
AktChatUserList.Items.Clear();
|
|
|
|
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);
|
|
}
|
|
|
|
AktChatUserList.Items.Add(currentContact);
|
|
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)
|
|
{
|
|
var kontakt = (Contact)AktChatUserList.Items[0];
|
|
_Chat.Paste(kontakt.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 = 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
|
|
var kontakt = (Contact)AktChatUserList.Items[0];
|
|
if(kontakt.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 (AktChatUserList.Items.Count > 0)
|
|
{
|
|
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 (!AktChatUserList.Items.IsEmpty && !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 (!AktChatUserList.Items.IsEmpty && !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;
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: Asynchron machen?
|
|
private void VerticalScrollbarChanged(object sender, RoutedPropertyChangedEventArgs<double> 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((Contact)AktChatUserList.Items[0]);
|
|
}
|
|
|
|
public Timer EmojisListeningThreadTimer;
|
|
public Timer GlobalListeningThreadtimer { get; set; }
|
|
|
|
private void InitGlobalListeningThread()
|
|
{
|
|
GlobalListeningThreadtimer = new Timer();
|
|
GlobalListeningThreadtimer.Tick += GlobalListeningThreadTimerTickEvent;
|
|
GlobalListeningThreadtimer.Interval = 2000;
|
|
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();
|
|
|
|
Contact currentContact = null;
|
|
|
|
if (AktChatUserList.HasItems)
|
|
{
|
|
currentContact = (Contact) AktChatUserList.Items[0];
|
|
}
|
|
|
|
foreach (var contact in _ContactList)
|
|
{
|
|
foreach (var newContact in contacts)
|
|
{
|
|
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;
|
|
|
|
// TODO: Prüfen, ob die App im Hintergrund oder minimiert ist
|
|
if (Clientlist.SelectedItem != null && !((Contact)Clientlist.SelectedItem).GroupId.Equals(newContact.GroupId) || Clientlist.SelectedItem == null || _IsInBackground)
|
|
{
|
|
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 = 2000;
|
|
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();
|
|
|
|
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 GetCurrentContact()
|
|
{
|
|
if(AktChatUserList != null && AktChatUserList.Items.Count > 0)
|
|
{
|
|
var contact = (Contact) AktChatUserList.Items[0];
|
|
|
|
return contact.UserIdManage == null ? null : contact;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// 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)
|
|
{
|
|
var view = (CollectionView)CollectionViewSource.GetDefaultView(Clientlist.ItemsSource);
|
|
view.Filter = UserFilter;
|
|
}
|
|
}
|
|
}
|