1771 lines
63 KiB
C#
1771 lines
63 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.Threading;
|
|
using System.Threading.Tasks;
|
|
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 CheckBox = System.Windows.Controls.CheckBox;
|
|
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))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_ThreadExceptionMessage = value;
|
|
OnPropertyChanged(nameof(ThreadExceptionMessage));
|
|
OnPropertyChanged(nameof(CurrentContactInformationString));
|
|
OnPropertyChanged(nameof(CurrencContactInfoForeground));
|
|
OnPropertyChanged(nameof(ThreadExceptionImageSource));
|
|
}
|
|
}
|
|
|
|
private readonly ImageSource _ThreadExceptionImageSource;
|
|
|
|
public ImageSource ThreadExceptionImageSource => !(ThreadExceptionMessage is null) ? _ThreadExceptionImageSource : CurrentContact?.Image;
|
|
|
|
public SolidColorBrush CurrencContactInfoForeground => !(ThreadExceptionMessage is 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 is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_ContainingWindow.Deactivated += ContainingWindowOnDeactivated;
|
|
_ContainingWindow.Activated += ContainingWindowOnActivated;
|
|
}
|
|
}
|
|
|
|
private Chat _Chat;
|
|
public Chat Chat
|
|
{
|
|
get => _Chat;
|
|
set
|
|
{
|
|
_Chat = value;
|
|
OnPropertyChanged(nameof(Chat));
|
|
OnPropertyChanged(nameof(ChatMessageInputGridVisibility));
|
|
OnPropertyChanged(nameof(ChatListBoxVisibility));
|
|
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
|
|
OnPropertyChanged(nameof(StapelmodusChatGridVisibility));
|
|
}
|
|
}
|
|
|
|
private Contact _CurrentContact;
|
|
|
|
public Contact CurrentContact
|
|
{
|
|
get => _CurrentContact;
|
|
|
|
set
|
|
{
|
|
if(Equals(_CurrentContact, value))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_CurrentContact = value;
|
|
|
|
OnPropertyChanged(nameof(CurrentContact));
|
|
OnPropertyChanged(nameof(ChatMessageInputGridVisibility));
|
|
OnPropertyChanged(nameof(Chat));
|
|
OnPropertyChanged(nameof(CurrentContactInformationString));
|
|
OnPropertyChanged(nameof(CurrencContactInfoForeground));
|
|
OnPropertyChanged(nameof(ThreadExceptionImageSource));
|
|
}
|
|
}
|
|
|
|
public ObservableSortCollection<ContactDependencyObject> ContactList
|
|
{
|
|
get => _ContactList ?? (_ContactList = new ObservableSortCollection<ContactDependencyObject>());
|
|
|
|
set
|
|
{
|
|
_ContactList = new ObservableSortCollection<ContactDependencyObject>(value);
|
|
_ContactList.Sort((x, y) => DateTime.Compare(y.Contact.TimeStamp, x.Contact.TimeStamp));
|
|
|
|
OnPropertyChanged(nameof(ContactList));
|
|
}
|
|
}
|
|
|
|
public Visibility ChatMessageInputGridVisibility
|
|
{
|
|
get
|
|
{
|
|
if(_CurrentContact is null && Chat?.IsInBroadcastMode == false)
|
|
{
|
|
return Visibility.Collapsed;
|
|
}
|
|
|
|
return false == (Chat?.IsInBroadcastMode ?? false) && !(_CurrentContact is null) ? _CurrentContact.IsChatMessageInputGridVisible ? Visibility.Visible : Visibility.Collapsed : Chat?.IsInBroadcastMode ?? false ? Visibility.Visible : Visibility.Collapsed;
|
|
}
|
|
}
|
|
|
|
private ObservableSortCollection<ContactDependencyObject> _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));
|
|
BroadcastButtonImageSource = new BitmapImage(new Uri("pack://application:,,,/ChatController;component/Ressourcen/tasks-solid.png", UriKind.Absolute));
|
|
InvertedBroadcastButtonImageSource = new BitmapImage(new Uri("pack://application:,,,/ChatController;component/Ressourcen/tasks-solid-inverted.png", UriKind.Absolute));
|
|
|
|
_ChatMessages = new ObservableCollection<ChatMessage>();
|
|
ChatMessages = CollectionViewSource.GetDefaultView(_ChatMessages) as ListCollectionView;
|
|
|
|
if(!(ChatMessages is null))
|
|
{
|
|
ChatMessages.CustomSort = new ChatMessageComparer();
|
|
}
|
|
|
|
DataContext = this;
|
|
|
|
ProgressOverlayVisibility = Visibility.Collapsed;
|
|
|
|
StartWaitingImmediately();
|
|
|
|
var deleteImagesTask = new Task(() =>
|
|
{
|
|
try
|
|
{
|
|
var files = Directory.GetFiles(Path.GetTempPath(), "*_tmp_img_owch.*", SearchOption.TopDirectoryOnly);
|
|
|
|
foreach(var file in files)
|
|
{
|
|
if(!File.Exists(file))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
File.Delete(file);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
this.Dispatch(EndWaiting);
|
|
}
|
|
});
|
|
|
|
deleteImagesTask.Start();
|
|
}
|
|
|
|
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 = new ObservableSortCollection<ContactDependencyObject>();
|
|
|
|
foreach(var contact in Chat.AddContacts())
|
|
{
|
|
ContactList.Add(new ContactDependencyObject(contact));
|
|
}
|
|
|
|
ContactList.Sort((x, y) => DateTime.Compare(y.Contact.TimeStamp, x.Contact.TimeStamp));
|
|
|
|
OnPropertyChanged(nameof(ContactList));
|
|
|
|
ReadNewSyncFile();
|
|
|
|
foreach(var contactDependencyObject in _ContactList)
|
|
{
|
|
if(_GroupId2DateTime.ContainsKey(contactDependencyObject.Contact.GroupId))
|
|
{
|
|
var isUnread = _GroupId2DateTime[contactDependencyObject.Contact.GroupId].IsUnread;
|
|
|
|
contactDependencyObject.Contact.IsNewMessage = isUnread;
|
|
contactDependencyObject.Contact.HasUnreadMessages = contactDependencyObject.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.Contact.GroupId == pGroupId);
|
|
|
|
if(!(contact is null))
|
|
{
|
|
notificationIcon = Utils.ImageSourceToIcon(contact.Contact.Image);
|
|
}
|
|
|
|
var notifyIcon = new NotifyIcon { Icon = notificationIcon, Visible = true, Tag = pMessage };
|
|
|
|
notifyIcon.BalloonTipClicked += (sender, args) =>
|
|
{
|
|
DisposeAndRemoveNotification((NotifyIcon)sender, pGroupId);
|
|
|
|
if(_ContainingWindow is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_ContainingWindow.WindowState == WindowState.Minimized)
|
|
{
|
|
_ContainingWindow.WindowState = WindowState.Normal;
|
|
}
|
|
|
|
_ContainingWindow.Activate();
|
|
|
|
var selectedContact = _ContactList?.FirstOrDefault(f => f?.Contact.GroupId == pGroupId);
|
|
if(!(selectedContact?.Contact is null))
|
|
{
|
|
SelectContact(selectedContact.Contact);
|
|
}
|
|
};
|
|
|
|
notifyIcon.BalloonTipClosed += (sender, args) =>
|
|
{
|
|
// 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();
|
|
}
|
|
|
|
private void CurrentContactImage_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
|
|
{
|
|
if(e.ClickCount == 2)
|
|
{
|
|
Chat.ShowProfilePicture(_CurrentContact);
|
|
}
|
|
}
|
|
|
|
private void Clientlist_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
if(Chat.IsInBroadcastMode)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(Clientlist?.SelectedItem is ContactDependencyObject selectedContactDependencyObject && !(selectedContactDependencyObject.Contact is null))
|
|
{
|
|
SelectContact(selectedContactDependencyObject.Contact);
|
|
}
|
|
}
|
|
|
|
// ToDo: Hier kommt es immer wieder zu einer NullPointerException
|
|
private void SelectContact(Contact contact)
|
|
{
|
|
if(contact is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ChatMessageFileWrapper = null;
|
|
|
|
ShouldInterruptContactsThread = true;
|
|
|
|
StartWaitingImmediately();
|
|
|
|
_ScrollPrueferAktivieren = false;
|
|
|
|
if(contact?.HasUnreadMessages ?? false)
|
|
{
|
|
contact.HasUnreadMessages = false;
|
|
|
|
Clientlist?.Items.Refresh();
|
|
OnPropertyChanged(nameof(ContactList));
|
|
}
|
|
|
|
var currentContact = contact;
|
|
|
|
contact.IsNewMessage = false;
|
|
|
|
var shouldChangeIcon = _ContactList.Any(contactDependencyObject => contactDependencyObject?.Contact?.IsNewMessage ?? false);
|
|
if(shouldChangeIcon)
|
|
{
|
|
ContainingWindow.Icon = Utils.ConvertIconToImageSource(Resource.ownchat_favicon);
|
|
}
|
|
|
|
CurrentContact = currentContact;
|
|
|
|
OnPropertyChanged(nameof(IsSendButtonEnabled));
|
|
|
|
if(!(Clientlist is null))
|
|
{
|
|
foreach(var obj in Clientlist.Items)
|
|
{
|
|
if(obj is ContactDependencyObject contactDependencyObject && contact != null && contactDependencyObject.Contact != null && Equals(contactDependencyObject.Contact, contact))
|
|
{
|
|
Clientlist.SelectedItem = obj;
|
|
}
|
|
}
|
|
}
|
|
|
|
_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();
|
|
});
|
|
});
|
|
}
|
|
|
|
private void SetContextHandler()
|
|
{
|
|
var contextItems = ChatListBox?.ContextMenu?.Items;
|
|
|
|
if(contextItems is 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)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var copyMenuItem = (MenuItem) contextItems[2];
|
|
copyMenuItem.Click += CopyOnClick;
|
|
}
|
|
|
|
private void SaveAsOnClick(object sender, RoutedEventArgs routedEventArgs)
|
|
{
|
|
var selectedChatMessages = new List<ChatMessage>();
|
|
|
|
foreach(var selectedItem in ChatListBox.SelectedItems)
|
|
{
|
|
if(selectedItem is ChatMessage message)
|
|
{
|
|
selectedChatMessages.AddIfNotIn(message);
|
|
}
|
|
}
|
|
|
|
foreach(var message in selectedChatMessages)
|
|
{
|
|
Chat.SaveFileAs(message);
|
|
}
|
|
}
|
|
|
|
private async void PasteOnClick(object sender, RoutedEventArgs routedEventArgs)
|
|
{
|
|
await Chat.Paste(CurrentContact.GroupId,this);
|
|
}
|
|
|
|
private void CopyOnClick(object sender, RoutedEventArgs routedEventArgs)
|
|
{
|
|
var textToCopy = string.Empty;
|
|
|
|
foreach (var items in ChatListBox.SelectedItems)
|
|
{
|
|
var item = (ChatMessage) items;
|
|
|
|
textToCopy += item.UserMessage + Environment.NewLine;
|
|
}
|
|
|
|
if(!string.IsNullOrWhiteSpace(textToCopy))
|
|
{
|
|
Chat.Copy(textToCopy, 1);
|
|
}
|
|
}
|
|
|
|
private void Chat_OnContextMenuOpening(object sender, ContextMenuEventArgs e)
|
|
{
|
|
if(ChatListBox?.ContextMenu is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(ChatListBox.SelectedItems is List<ChatMessage> chatMessages)
|
|
{
|
|
if(chatMessages.Count > 0)
|
|
{
|
|
foreach(var chatMessage in chatMessages)
|
|
{
|
|
if(!(chatMessage?.PictureSource is null))
|
|
{
|
|
if(!(ChatListBox.ContextMenu is 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(chatMessage?.PictureSource is null && chatMessage?.FilePath is 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 is null) && dataObject.GetDataPresent(DataFormats.FileDrop))
|
|
{
|
|
var contextItems = ChatListBox.ContextMenu.Items;
|
|
var contextItemSpeichernUnter = (MenuItem) contextItems[1];
|
|
contextItemSpeichernUnter.Visibility = Visibility.Visible;
|
|
}
|
|
else if(!(dataObject is null) && dataObject.GetDataPresent(DataFormats.Text))
|
|
{
|
|
var contextItems = ChatListBox.ContextMenu.Items;
|
|
var contextItemSpeichernUnter = (MenuItem) contextItems[1];
|
|
contextItemSpeichernUnter.Visibility = Visibility.Visible;
|
|
}
|
|
else if(!(dataObject is 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 is 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 is null))
|
|
{
|
|
var pathToOriginalImage = Chat.OpenFile();
|
|
|
|
if(!File.Exists(pathToOriginalImage))
|
|
{
|
|
return;
|
|
}
|
|
|
|
StartWaitingImmediately("Skaliere Bild ...");
|
|
|
|
var scalingTask = new Task(() =>
|
|
{
|
|
try
|
|
{
|
|
var pathToScaledImage = FileUtils.ScaleImage(pathToOriginalImage, Path.GetExtension(pathToOriginalImage.ToUpperInvariant()), Chat.ChatDaten.MaxUploadSize);
|
|
|
|
var isFileSizeTooLarge = FileUtils.CheckFileSize(pathToScaledImage, Chat.ChatDaten.MaxUploadSize);
|
|
|
|
if(isFileSizeTooLarge)
|
|
{
|
|
this.Dispatch(() =>
|
|
{
|
|
EndWaiting();
|
|
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(File.Exists(pathToScaledImage))
|
|
{
|
|
ChatMessageFileWrapper = new ChatMessageFileWrapper(pathToOriginalImage, pathToScaledImage, $"{Chat.ChatDaten.ServerUrl}/document.png");
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
this.Dispatch(EndWaiting);
|
|
}
|
|
});
|
|
|
|
scalingTask.Start();
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show("Bitte wählen Sie einen Kontakt aus.","ownChat",MessageBoxButton.OK, MessageBoxImage.Information);
|
|
}
|
|
}
|
|
|
|
private async Task SendMessage()
|
|
{
|
|
if(CurrentContact is null || (string.IsNullOrEmpty(Chatbox.Text) && string.IsNullOrWhiteSpace(ChatMessageFileWrapper?.ScaledFilePath)))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var isFileInMessage = !(ChatMessageFileWrapper is null) && File.Exists(ChatMessageFileWrapper.ScaledFilePath);
|
|
|
|
var messageText = Chatbox.Text;
|
|
|
|
var newMessages = isFileInMessage ?
|
|
Chat.AddNewFile(ChatMessageFileWrapper.ScaledFilePath, ChatMessageFileWrapper.OriginalFilePath, CurrentContact.GroupId, GetFirstMessage(), messageText) :
|
|
Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId, GetFirstMessage());
|
|
|
|
_ChatMessages.AddRangeIfElementsNotIn(newMessages);
|
|
|
|
OnPropertyChanged(nameof(ChatMessages));
|
|
|
|
ChatMessages.MoveCurrentToLast();
|
|
ChatListBox.ScrollIntoView(ChatMessages.CurrentItem);
|
|
|
|
WpfUtils.ScrollToBottomOfListBox(ChatListBox);
|
|
|
|
if(isFileInMessage)
|
|
{
|
|
await Chat.SendFileToContact(CurrentContact, ChatMessageFileWrapper.ScaledFilePath, ChatMessageFileWrapper.OriginalFilePath, Chatbox.Text);
|
|
}
|
|
else
|
|
{
|
|
await Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId);
|
|
}
|
|
|
|
ChatMessageFileWrapper = null;
|
|
Chatbox.Text = string.Empty;
|
|
}
|
|
|
|
public Visibility ChatListBoxVisibility => (Chat?.IsInBroadcastMode ?? false) || !(ChatMessageFileWrapper is null) ? Visibility.Collapsed : Visibility.Visible;
|
|
|
|
public Visibility FilePreviewGridVisibility => string.IsNullOrWhiteSpace(ChatMessageFileWrapper?.OriginalFilePath) ? Visibility.Collapsed : Visibility.Visible;
|
|
|
|
private ChatMessageFileWrapper _ChatMessageFileWrapper;
|
|
public ChatMessageFileWrapper ChatMessageFileWrapper
|
|
{
|
|
get => _ChatMessageFileWrapper;
|
|
set
|
|
{
|
|
_ChatMessageFileWrapper = value;
|
|
|
|
OnPropertyChanged(nameof(ChatMessageFileWrapper));
|
|
OnPropertyChanged(nameof(IsSendButtonEnabled));
|
|
OnPropertyChanged(nameof(FilePreviewGridVisibility));
|
|
OnPropertyChanged(nameof(ChatListBoxVisibility));
|
|
}
|
|
}
|
|
|
|
private async void SendButton_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
if(Chat.IsInBroadcastMode)
|
|
{
|
|
SendBroadcastMessage();
|
|
return;
|
|
}
|
|
|
|
StartWaitingImmediately();
|
|
await SendMessage();
|
|
EndWaiting();
|
|
|
|
CheckForNewMessagesForContact(CurrentContact);
|
|
ListenGloballyForMessages();
|
|
}
|
|
|
|
private void Chatbox_OnGotFocus(object sender, RoutedEventArgs e)
|
|
{
|
|
if(!Chatbox.Text.Equals("Nachricht schreiben"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Chatbox.Text = string.Empty;
|
|
Chatbox.Foreground = new SolidColorBrush(Colors.Black);
|
|
}
|
|
|
|
private void Chatbox_OnKeyDownHandler(object sender, KeyEventArgs e)
|
|
{
|
|
//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;
|
|
// }
|
|
//}
|
|
|
|
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
|
|
OnPropertyChanged(nameof(IsSendButtonEnabled));
|
|
}
|
|
|
|
private void Chatbox_OnKeyUpHandler(object sender, KeyEventArgs e)
|
|
{
|
|
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
|
|
OnPropertyChanged(nameof(IsSendButtonEnabled));
|
|
}
|
|
|
|
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)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var scrollBar = (ScrollBar) sender;
|
|
|
|
if(scrollBar.Value > 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
StartWaitingImmediately();
|
|
|
|
_ScrollPrueferAktivieren = false;
|
|
|
|
ChatMessages.MoveCurrentToFirst();
|
|
|
|
var currentChatMessage = ChatMessages.CurrentItem;
|
|
|
|
if(Clientlist.SelectedItem is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var selectedContact = ((ContactDependencyObject) Clientlist.SelectedItem).Contact;
|
|
|
|
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 += (s, e) => { ListenGloballyForMessages(); };
|
|
GlobalListeningThreadtimer.Interval = 10000;
|
|
GlobalListeningThreadtimer.Start();
|
|
}
|
|
|
|
private void ListenGloballyForMessages()
|
|
{
|
|
Chat.GetNumberOfAllNewMessagesAsync(newMessagesCount =>
|
|
{
|
|
if(newMessagesCount > 0)
|
|
{
|
|
Chat.UpdateContactList(updatedContactList =>
|
|
{
|
|
var updatedContacts = updatedContactList.ToList();
|
|
|
|
this.Dispatch(() =>
|
|
{
|
|
foreach (var contactDependencyObject in _ContactList)
|
|
{
|
|
foreach (var newContact in updatedContacts)
|
|
{
|
|
if(contactDependencyObject.Contact.GroupId != newContact.GroupId)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// ReceivedMessage kann null sein!
|
|
if(contactDependencyObject.Contact.ReceivedMessage is null || contactDependencyObject.Contact.ReceivedMessage.Id.Equals(newContact.ReceivedMessage?.Id))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
contactDependencyObject.Contact.ReceivedMessage = newContact.ReceivedMessage;
|
|
contactDependencyObject.Contact.TimeStamp = newContact.TimeStamp;
|
|
|
|
Contact selectedContact = null;
|
|
|
|
if(Clientlist.SelectedItem is ContactDependencyObject selectedContactDependencyObject)
|
|
{
|
|
selectedContact = selectedContactDependencyObject.Contact;
|
|
}
|
|
|
|
// Angemeldeter Benutzer
|
|
var userOid = Chat.ChatDaten.LoggedInUser.Response.User.Oid;
|
|
|
|
var senderId = contactDependencyObject.Contact.ReceivedMessage?.UserId;
|
|
var receiverId = userOid;
|
|
var receiverGroupId = newContact.GroupId;
|
|
var selectedGroupId = selectedContact?.GroupId;
|
|
|
|
if(senderId != receiverId && (_IsInBackground || receiverGroupId != selectedGroupId))
|
|
{
|
|
if(!(ContainingWindow is 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 is null) && newContact.GroupId == CurrentContact.GroupId)
|
|
{
|
|
contactDependencyObject.Contact.HasUnreadMessages = false;
|
|
}
|
|
else
|
|
{
|
|
contactDependencyObject.Contact.HasUnreadMessages = true;
|
|
contactDependencyObject.Contact.IsNewMessage = true;
|
|
}
|
|
}
|
|
|
|
if(!updatedContacts.Contains(contactDependencyObject.Contact))
|
|
{
|
|
_ContactList.ToList().Remove(contactDependencyObject);
|
|
}
|
|
}
|
|
|
|
ContactList.Sort((x, y) => DateTime.Compare(y.Contact.TimeStamp, x.Contact.TimeStamp));
|
|
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 && !(CurrentContact is null))
|
|
{
|
|
CheckForNewMessagesForContact(pCurrentContact);
|
|
}
|
|
}
|
|
|
|
private void CheckForNewMessagesForContact(Contact contact)
|
|
{
|
|
Chat.CheckIfNewMessagesExistAsync(CurrentContact.GroupId, hasNewMessages =>
|
|
{
|
|
if(!hasNewMessages)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Chat.LoadChatMessagesForContactAsync(contact, 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;
|
|
}
|
|
|
|
if(item is ContactDependencyObject contactDependencyObject)
|
|
{
|
|
return contactDependencyObject.Contact.Name.IndexOf(Suche.Text, StringComparison.OrdinalIgnoreCase) >= 0;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void Chat_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
|
|
{
|
|
if(ChatListBox.SelectedItems.Count <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var selectedItem = ChatListBox.SelectedItems[0];
|
|
|
|
if(!(selectedItem is ChatMessage selectedMessage))
|
|
{
|
|
return;
|
|
}
|
|
|
|
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 is null))
|
|
{
|
|
StartWaitingImmediately();
|
|
|
|
LoadDocumentAsync(selectedMessage.FilePath, Path.GetFileName(selectedMessage.FilePath), 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();
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
EndWaiting();
|
|
|
|
}
|
|
}
|
|
|
|
private ChatControlWaitLayer _WaitLayer;
|
|
|
|
public void StartWaitingImmediately(string dialogText = null)
|
|
{
|
|
if(!(_WaitLayer is null))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_WaitLayer = new ChatControlWaitLayer(dialogText);
|
|
Grid.SetRowSpan(_WaitLayer, 3);
|
|
RootGrid.Children.Add(_WaitLayer);
|
|
Panel.SetZIndex(_WaitLayer, int.MaxValue);
|
|
_WaitLayer.RefreshChatUI();
|
|
}
|
|
|
|
public void EndWaiting()
|
|
{
|
|
Dispatcher.BeginInvoke(
|
|
DispatcherPriority.Normal,
|
|
(Action) delegate
|
|
{
|
|
if(_WaitLayer is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
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 = new ObservableSortCollection<ContactDependencyObject>();
|
|
foreach(var contact in Chat.UpdateContacts(data))
|
|
{
|
|
ContactList.Add(new ContactDependencyObject(contact));
|
|
}
|
|
|
|
ContactList.Sort((x, y) => DateTime.Compare(y.Contact.TimeStamp, x.Contact.TimeStamp));
|
|
|
|
if(!(CurrentContact is null))
|
|
{
|
|
var selectedElement = ContactList.FirstOrDefault(f => f.Contact.GroupId == CurrentContact.GroupId);
|
|
|
|
if(!(selectedElement is null))
|
|
{
|
|
Clientlist.SelectedItem = selectedElement;
|
|
}
|
|
}
|
|
|
|
OnPropertyChanged(nameof(ContactList));
|
|
|
|
ReadNewSyncFile();
|
|
|
|
AddViewFilterToClientlist();
|
|
|
|
EndWaiting();
|
|
});
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
EndWaiting();
|
|
}
|
|
}
|
|
|
|
// 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.Contact.ReceivedMessage is null)))
|
|
{
|
|
var text = contact.Contact.GroupId + ";" + contact.Contact.TimeStamp.ToUniversalTime() + ";" + contact.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)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
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()) is 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)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
// 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 ContactDependencyObject contactDependencyObject && contactDependencyObject.Contact.HasUnreadMessages && !string.IsNullOrEmpty(contactDependencyObject.Contact.ReceivedMessage?.Text))
|
|
{
|
|
contacts.Add(contactDependencyObject.Contact);
|
|
}
|
|
}
|
|
|
|
return contacts;
|
|
}
|
|
|
|
// Wird im BeWoPlaner benutzt
|
|
public void ResetNumberOfUnreadMessages(Dictionary<long, DateTime> pGroupId2DateTime)
|
|
{
|
|
if(pGroupId2DateTime is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach(var contactDependencyObject in _ContactList)
|
|
{
|
|
foreach(var groupId2DateTime in pGroupId2DateTime)
|
|
{
|
|
if(contactDependencyObject.Contact.GroupId == groupId2DateTime.Key)
|
|
{
|
|
contactDependencyObject.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 is 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)
|
|
{
|
|
//ignore okeee
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
|
|
OnPropertyChanged(nameof(IsSendButtonEnabled));
|
|
}
|
|
|
|
public void AddMessages(List<ChatMessage> newMessages)
|
|
{
|
|
_ChatMessages.AddRangeIfElementsNotIn(newMessages);
|
|
}
|
|
|
|
public ChatMessage GetFirstMessage()
|
|
{
|
|
return _ChatMessages.FirstOrDefault();
|
|
}
|
|
|
|
|
|
#region Stapelnachricht
|
|
|
|
public ImageSource BroadcastButtonImageSource { get; }
|
|
public ImageSource InvertedBroadcastButtonImageSource { get; }
|
|
|
|
private Visibility _ProgressOverlayVisibility;
|
|
public Visibility ProgressOverlayVisibility
|
|
{
|
|
get => _ProgressOverlayVisibility;
|
|
set
|
|
{
|
|
_ProgressOverlayVisibility = value;
|
|
OnPropertyChanged(nameof(ProgressOverlayVisibility));
|
|
OnPropertyChanged(nameof(NormalViewVisibility));
|
|
OnPropertyChanged(nameof(StapelmodusChatGridVisibility));
|
|
OnPropertyChanged(nameof(ChatListBoxVisibility));
|
|
}
|
|
}
|
|
|
|
public Visibility NormalViewVisibility => ProgressOverlayVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
|
|
|
|
public Visibility StapelmodusChatGridVisibility => (Chat?.IsInBroadcastMode ?? false) && ProgressOverlayVisibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
|
|
|
|
public bool IsSendButtonEnabled => (!string.IsNullOrEmpty(Chatbox.Text) || File.Exists(ChatMessageFileWrapper?.ScaledFilePath)) && !(CurrentContact is null);
|
|
|
|
public bool IsBroadcastButtonEnabled
|
|
{
|
|
get
|
|
{
|
|
var isInBroadcastMode = Chat?.IsInBroadcastMode ?? false;
|
|
var hasSelectedContacts = GetSelectedContacts().Any();
|
|
var hasTextOrFile = !string.IsNullOrEmpty(Chatbox.Text) || File.Exists(BroadcastMessageFileWrapper?.ScaledFilePath);
|
|
|
|
return isInBroadcastMode && hasSelectedContacts && hasTextOrFile;
|
|
}
|
|
}
|
|
|
|
private Contact _PreviousContact;
|
|
|
|
private CancellationTokenSource _CancellationTokenSource;
|
|
|
|
private const string DefaultBroadcastInfoText = "Sie befinden Sich im Stapel-Modus. In diesem Modus können Sie eine Nachricht in einem Schritt an mehrere Empfänger & Gruppen senden. Bitte setzen Sie dazu in der Kontaktliste bei den gewünschten Empfängern & Gruppen ein Häkchen und schreiben Sie Ihre Nachricht wie gewohnt. Wenn Sie auf senden klicken, wird die Nachricht an alle ausgewählten Empfänger & Gruppen gesendet.";
|
|
|
|
private string _BroadcastInfoText;
|
|
public string BroadcastInfoText
|
|
{
|
|
get => _BroadcastInfoText ?? (_BroadcastInfoText = DefaultBroadcastInfoText);
|
|
set
|
|
{
|
|
_BroadcastInfoText = $"{DefaultBroadcastInfoText}{Environment.NewLine}{value}";
|
|
OnPropertyChanged(BroadcastInfoText);
|
|
}
|
|
}
|
|
|
|
private double _BroadcastProgressValue;
|
|
public double BroadcastProgressValue
|
|
{
|
|
get => _BroadcastProgressValue;
|
|
set
|
|
{
|
|
_BroadcastProgressValue = value;
|
|
OnPropertyChanged(nameof(BroadcastProgressValue));
|
|
}
|
|
}
|
|
|
|
public Visibility RemoveFileFromBroadcastMessageVisibility => BroadcastMessageFileWrapper is null ? Visibility.Collapsed : Visibility;
|
|
|
|
private ChatMessageFileWrapper _BroadcastMessageFileWrapper;
|
|
public ChatMessageFileWrapper BroadcastMessageFileWrapper
|
|
{
|
|
get => _BroadcastMessageFileWrapper;
|
|
set
|
|
{
|
|
_BroadcastMessageFileWrapper = value;
|
|
|
|
OnPropertyChanged(nameof(BroadcastMessageFileWrapper));
|
|
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
|
|
OnPropertyChanged(nameof(RemoveFileFromBroadcastMessageVisibility));
|
|
}
|
|
}
|
|
|
|
private void BroadcastToggleButton_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
Chat.IsInBroadcastMode = !Chat.IsInBroadcastMode;
|
|
|
|
BroadcastProgressValue = 0;
|
|
|
|
DeselectAllContacts();
|
|
|
|
if(Chat.IsInBroadcastMode)
|
|
{
|
|
_CancellationTokenSource = new CancellationTokenSource();
|
|
_PreviousContact = CurrentContact;
|
|
CurrentContact = null;
|
|
ToggleButtonImage.Source = InvertedBroadcastButtonImageSource;
|
|
}
|
|
else
|
|
{
|
|
CloseBroadcastMode();
|
|
}
|
|
|
|
OnPropertyChanged(nameof(StapelmodusChatGridVisibility));
|
|
OnPropertyChanged(nameof(ChatListBoxVisibility));
|
|
OnPropertyChanged(nameof(IsSendButtonEnabled));
|
|
OnPropertyChanged(nameof(ChatMessageInputGridVisibility));
|
|
OnPropertyChanged(nameof(BroadcastMessageFileWrapper));
|
|
}
|
|
|
|
private async void SendBroadcastMessage()
|
|
{
|
|
var selectedContacts = GetSelectedContacts();
|
|
|
|
if(selectedContacts.Count == 0 || string.IsNullOrEmpty(Chatbox.Text) && BroadcastMessageFileWrapper.ChatMessageImageSource is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var result = new OwnChatMessageBox("JA", "ABBRECHEN", $"Sind Sie sicher? Ihre Nachricht wird an {selectedContacts.Count} Empfänger & Gruppen verschickt!", "Stapelnachricht") { Owner = ContainingWindow }.ShowDialog();
|
|
|
|
if(result != true)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var wasCompleted = false;
|
|
var progress = new Progress<BroadcastProgressReportModel>();
|
|
progress.ProgressChanged += ReportProgress;
|
|
|
|
try
|
|
{
|
|
ProgressOverlayVisibility = Visibility.Visible;
|
|
wasCompleted = await SendBroadcast(progress, _CancellationTokenSource.Token);
|
|
}
|
|
catch(OperationCanceledException)
|
|
{
|
|
BroadcastInfoText = "Der Broadcast wurde abgebrochen.";
|
|
}
|
|
finally
|
|
{
|
|
ProgressOverlayVisibility = Visibility.Collapsed;
|
|
}
|
|
|
|
DoSynchro();
|
|
|
|
if(wasCompleted)
|
|
{
|
|
new OwnChatMessageBox(null, "OK", $"Die Nachricht wurde erfolgreich an {selectedContacts.Count} Empfänger & Gruppen versandt.", "Stapelnachricht") { Owner = ContainingWindow }.ShowDialog();
|
|
}
|
|
|
|
CloseBroadcastMode();
|
|
}
|
|
|
|
private async Task<bool> SendBroadcast(IProgress<BroadcastProgressReportModel> progress, CancellationToken cancellationToken)
|
|
{
|
|
var count = 0;
|
|
var report = new BroadcastProgressReportModel();
|
|
|
|
var selectedContacts = GetSelectedContacts();
|
|
|
|
foreach(var contactDependencyObject in selectedContacts.Where(selectedContact => selectedContact.Contact.IsChatMessageInputGridVisible))
|
|
{
|
|
if(BroadcastMessageFileWrapper is null)
|
|
{
|
|
await Chat.SendMessage(Chatbox.Text, contactDependencyObject.Contact.GroupId);
|
|
}
|
|
else
|
|
{
|
|
await Chat.SendFileToContact(contactDependencyObject.Contact, BroadcastMessageFileWrapper.ScaledFilePath, BroadcastMessageFileWrapper.OriginalFilePath, Chatbox.Text);
|
|
}
|
|
|
|
contactDependencyObject.SetValue(ListItemHelper.IsCheckedProperty, false);
|
|
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
|
|
count++;
|
|
report.PercentageComplete = count * 100 / selectedContacts.Count;
|
|
|
|
progress.Report(report);
|
|
}
|
|
|
|
return count == selectedContacts.Count;
|
|
}
|
|
|
|
private void ReportProgress(object sender, BroadcastProgressReportModel e)
|
|
{
|
|
BroadcastProgressValue = e.PercentageComplete;
|
|
}
|
|
|
|
private void SelectAllContacts_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
if(!(sender is CheckBox checkBox))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var isChecked = checkBox.IsChecked ?? false;
|
|
|
|
foreach(var contactDependencyObject in ContactList)
|
|
{
|
|
contactDependencyObject.SetValue(ListItemHelper.IsCheckedProperty, isChecked);
|
|
}
|
|
|
|
OnPropertyChanged(nameof(ContactList));
|
|
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
|
|
}
|
|
|
|
private void SendBroatcastButton_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
SendBroadcastMessage();
|
|
}
|
|
|
|
private void CancelBroadcastButton_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
_CancellationTokenSource?.Cancel();
|
|
BroadcastMessageFileWrapper = null;
|
|
Chatbox.Text = string.Empty;
|
|
}
|
|
|
|
private void AddMediaFileToBroadcastMessage_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
if(!Chat.IsInBroadcastMode)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var originalFilePath = Chat.OpenFile();
|
|
|
|
if(!File.Exists(originalFilePath))
|
|
{
|
|
return;
|
|
}
|
|
|
|
StartWaitingImmediately("Skaliere Bild ...");
|
|
|
|
var scalingTask = new Task(() =>
|
|
{
|
|
try
|
|
{
|
|
var scaledImagePath = FileUtils.ScaleImage(originalFilePath, Path.GetExtension(originalFilePath.ToUpperInvariant()), Chat.ChatDaten.MaxUploadSize);
|
|
|
|
var isFileSizeTooLarge = FileUtils.CheckFileSize(scaledImagePath, 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(File.Exists(scaledImagePath))
|
|
{
|
|
BroadcastMessageFileWrapper = new ChatMessageFileWrapper(originalFilePath, scaledImagePath, $"{Chat.ChatDaten.ServerUrl}/document.png");
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
this.Dispatch(EndWaiting);
|
|
}
|
|
});
|
|
|
|
scalingTask.Start();
|
|
}
|
|
|
|
private void CloseBroadcastMode()
|
|
{
|
|
Chatbox.Text = string.Empty;
|
|
|
|
BroadcastToggleButton.IsChecked = false;
|
|
Chat.IsInBroadcastMode = false;
|
|
|
|
_CancellationTokenSource = null;
|
|
BroadcastMessageFileWrapper = null;
|
|
BroadcastProgressValue = 0;
|
|
ProgressOverlayVisibility = Visibility.Collapsed;
|
|
|
|
DeselectAllContacts();
|
|
|
|
OnPropertyChanged(nameof(IsSendButtonEnabled));
|
|
OnPropertyChanged(nameof(ChatMessageInputGridVisibility));
|
|
OnPropertyChanged(nameof(BroadcastMessageFileWrapper));
|
|
|
|
ToggleButtonImage.Source = BroadcastButtonImageSource;
|
|
OnPropertyChanged(nameof(StapelmodusChatGridVisibility));
|
|
|
|
if(!(_PreviousContact is null))
|
|
{
|
|
SelectContact(_PreviousContact);
|
|
}
|
|
}
|
|
|
|
private void ContactCheckBox_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
|
|
}
|
|
|
|
private void ContactCheckBox_OnChecked(object sender, RoutedEventArgs e)
|
|
{
|
|
UpdateContactSelection();
|
|
}
|
|
|
|
private void UpdateContactSelection()
|
|
{
|
|
OnPropertyChanged(nameof(ContactList));
|
|
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
|
|
|
|
bool? newValue = null;
|
|
|
|
var selectedContacts = GetSelectedContacts();
|
|
var allSelectableContacts = ContactList.Where(contactDependencyObject => contactDependencyObject.Contact.IsChatMessageInputGridVisible).ToList();
|
|
|
|
if(selectedContacts.Count == allSelectableContacts.Count)
|
|
{
|
|
newValue = true;
|
|
}
|
|
|
|
if(selectedContacts.Count == 0)
|
|
{
|
|
newValue = false;
|
|
}
|
|
|
|
SelectAllContactsCheckBox.IsChecked = newValue;
|
|
}
|
|
|
|
private List<ContactDependencyObject> GetSelectedContacts()
|
|
{
|
|
var result = new List<ContactDependencyObject>();
|
|
|
|
foreach(var contactDependencyObject in ContactList.Where(contactDependencyObject => contactDependencyObject.Contact.IsChatMessageInputGridVisible))
|
|
{
|
|
if(contactDependencyObject.GetValue(ListItemHelper.IsCheckedProperty) is bool isChecked && isChecked)
|
|
{
|
|
result.AddIfNotIn(contactDependencyObject);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private void DeselectAllContacts()
|
|
{
|
|
foreach(var contactDependencyObject in ContactList)
|
|
{
|
|
contactDependencyObject.SetValue(ListItemHelper.IsCheckedProperty, false);
|
|
}
|
|
}
|
|
|
|
private void RemoveBroadcastFileAttachmentButton_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
BroadcastMessageFileWrapper = null;
|
|
}
|
|
|
|
#endregion
|
|
|
|
private void RemoveFileAttachmentButton_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
ChatMessageFileWrapper = null;
|
|
}
|
|
}
|
|
}
|