Merge branch 'master' of ssh://float.beyondsoft.de/git/beyondSoft/Chat

This commit is contained in:
Christian
2023-07-25 11:33:57 +02:00
8 changed files with 495 additions and 216 deletions

View File

@@ -196,7 +196,7 @@ namespace ChatController.ChatKlassen
public Guid Id { get; } public Guid Id { get; }
public ImageSource ProfilePicture => OwnChatCache.GetInstance().GetUserProfilePictureFromCache(SenderId)?.ProfilePicture; public ImageSource ProfilePicture => OwnChatCache.GetInstance().GetAvatarByUserId(SenderId);
protected virtual void OnPropertyChanged(string propertyName) protected virtual void OnPropertyChanged(string propertyName)
{ {

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using ChatController.Core; using ChatController.Core;
@@ -85,8 +86,17 @@ namespace ChatController.ChatKlassen
public bool IsChatMessageInputGridVisible { get; } public bool IsChatMessageInputGridVisible { get; }
public Dictionary<long, string> UserId2Uri { get; }
public string Key { get; }
public string ProfilePicturePath { get; }
public Contact(string pName, GroupLatestMessage pLatestMessage, DateTime pTimeStamp, int pGroupId, string pUserIdManage, bool pOnlyEmployees, int pUserCount, bool isChatMessageInputGridVisible, string accentColorBrushString, string profilePicturePath, string key, Dictionary<long, string> userId2Uri) public Contact(string pName, GroupLatestMessage pLatestMessage, DateTime pTimeStamp, int pGroupId, string pUserIdManage, bool pOnlyEmployees, int pUserCount, bool isChatMessageInputGridVisible, string accentColorBrushString, string profilePicturePath, string key, Dictionary<long, string> userId2Uri)
{ {
ProfilePicturePath = profilePicturePath;
Key = key;
UserId2Uri = userId2Uri;
Name = pName; Name = pName;
ReceivedMessage = pLatestMessage; ReceivedMessage = pLatestMessage;
TimeStamp = pTimeStamp; TimeStamp = pTimeStamp;
@@ -96,8 +106,6 @@ namespace ChatController.ChatKlassen
IsChatMessageInputGridVisible = isChatMessageInputGridVisible; IsChatMessageInputGridVisible = isChatMessageInputGridVisible;
Utils.DownloadUserProfilePicturesAsync(userId2Uri);
if (accentColorBrushString is null) if (accentColorBrushString is null)
{ {
if(!(pUserIdManage is null)) if(!(pUserIdManage is null))
@@ -117,11 +125,6 @@ namespace ChatController.ChatKlassen
AccentColorBrush = new BrushConverter().ConvertFromString($"#{accentColorBrushString}") as SolidColorBrush; AccentColorBrush = new BrushConverter().ConvertFromString($"#{accentColorBrushString}") as SolidColorBrush;
IsGroupChat = pUserCount > 2; IsGroupChat = pUserCount > 2;
Utils.DownloadGroupProfilePictureAsync(profilePicturePath, key, delegate(ImageSource imageSource)
{
Image = imageSource;
});
} }
public bool IsGroupChat { get; } public bool IsGroupChat { get; }

View File

@@ -383,87 +383,79 @@ namespace ChatController
// ToDo: Hier kommt es immer wieder zu einer NullPointerException // ToDo: Hier kommt es immer wieder zu einer NullPointerException
private void SelectContact(Contact contact) private void SelectContact(Contact contact)
{ {
try if(contact is null)
{ {
if(contact is null) return;
}
ChatMessageFileWrapper = null;
ShouldInterruptContactsThread = true;
StartWaitingImmediately();
_ScrollPrueferAktivieren = false;
if(contact.HasUnreadMessages)
{
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)
{ {
return; if(obj is ContactDependencyObject contactDependencyObject && Equals(contactDependencyObject.Contact, contact))
}
ChatMessageFileWrapper = null;
ShouldInterruptContactsThread = true;
// Zeigt die Warteanimation (das Rädchen)
StartWaitingImmediately();
_ScrollPrueferAktivieren = false;
if(contact.HasUnreadMessages)
{
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 && Equals(contactDependencyObject.Contact, contact)) Clientlist.SelectedItem = obj;
{
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();
});
});
} }
catch(Exception exception)
_ChatMessages.Clear();
OnPropertyChanged(nameof(_ChatMessages));
Chat.LoadChatMessagesForContactAsync(currentContact, GetFirstMessage(), chatMessages =>
{ {
throw; 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() private void SetContextHandler()
@@ -515,11 +507,19 @@ namespace ChatController
private void SaveAsOnClick(object sender, RoutedEventArgs routedEventArgs) private void SaveAsOnClick(object sender, RoutedEventArgs routedEventArgs)
{ {
foreach(var items in ChatListBox.SelectedItems) var selectedChatMessages = new List<ChatMessage>();
{
var chatMessage = (ChatMessage) items;
Chat.SaveFileAs(chatMessage); foreach(var selectedItem in ChatListBox.SelectedItems)
{
if(selectedItem is ChatMessage message)
{
selectedChatMessages.AddIfNotIn(message);
}
}
foreach(var message in selectedChatMessages)
{
Chat.SaveFileAs(message);
} }
} }
@@ -730,8 +730,6 @@ namespace ChatController
ChatMessageFileWrapper = null; ChatMessageFileWrapper = null;
Chatbox.Text = string.Empty; Chatbox.Text = string.Empty;
//DoSynchro();
} }
public Visibility ChatListBoxVisibility => (Chat?.IsInBroadcastMode ?? false) || !(ChatMessageFileWrapper is null) ? Visibility.Collapsed : Visibility.Visible; public Visibility ChatListBoxVisibility => (Chat?.IsInBroadcastMode ?? false) || !(ChatMessageFileWrapper is null) ? Visibility.Collapsed : Visibility.Visible;
@@ -761,7 +759,12 @@ namespace ChatController
return; return;
} }
StartWaitingImmediately();
await SendMessage(); await SendMessage();
EndWaiting();
CheckForNewMessagesForContact(CurrentContact);
ListenGloballyForMessages();
} }
private void Chatbox_OnGotFocus(object sender, RoutedEventArgs e) private void Chatbox_OnGotFocus(object sender, RoutedEventArgs e)
@@ -988,25 +991,30 @@ namespace ChatController
{ {
if(!ShouldInterruptContactsThread && !(CurrentContact is null)) if(!ShouldInterruptContactsThread && !(CurrentContact is null))
{ {
Chat.CheckIfNewMessagesExistAsync(CurrentContact.GroupId, hasNewMessages => CheckForNewMessagesForContact(pCurrentContact);
}
}
private void CheckForNewMessagesForContact(Contact contact)
{
Chat.CheckIfNewMessagesExistAsync(CurrentContact.GroupId, hasNewMessages =>
{
if(!hasNewMessages)
{ {
if(!hasNewMessages) return;
{ }
return;
}
Chat.LoadChatMessagesForContactAsync(pCurrentContact, GetFirstMessage(), chatMessages => Chat.LoadChatMessagesForContactAsync(contact, GetFirstMessage(), chatMessages =>
{
this.Dispatch(() =>
{ {
this.Dispatch(() => _ChatMessages.Clear();
{ _ChatMessages.AddRangeIfElementsNotIn(chatMessages);
_ChatMessages.Clear();
_ChatMessages.AddRangeIfElementsNotIn(chatMessages);
WpfUtils.ScrollToBottomOfListBox(ChatListBox); WpfUtils.ScrollToBottomOfListBox(ChatListBox);
});
}); });
}); });
} });
} }
private void Suche_OnTextChanged(object sender, TextChangedEventArgs e) private void Suche_OnTextChanged(object sender, TextChangedEventArgs e)
@@ -1115,11 +1123,6 @@ namespace ChatController
private ChatControlWaitLayer _WaitLayer; private ChatControlWaitLayer _WaitLayer;
public void StartWaiting()
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action<string>) StartWaitingImmediately);
}
public void StartWaitingImmediately(string dialogText = null) public void StartWaitingImmediately(string dialogText = null)
{ {
if(!(_WaitLayer is null)) if(!(_WaitLayer is null))
@@ -1137,7 +1140,7 @@ namespace ChatController
public void EndWaiting() public void EndWaiting()
{ {
Dispatcher.BeginInvoke( Dispatcher.BeginInvoke(
DispatcherPriority.Background, DispatcherPriority.Normal,
(Action) delegate (Action) delegate
{ {
if(_WaitLayer is null) if(_WaitLayer is null)

View File

@@ -1,11 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Media; using System.Windows.Media;
using ChatController.Extensions;
namespace ChatController.Core namespace ChatController.Core
{ {
public class OwnChatCache public class OwnChatCache
{ {
public static string BaseUri { get; set; }
public long? LoggedOnUserId { get; set; } public long? LoggedOnUserId { get; set; }
private static readonly object _Lock = new object(); private static readonly object _Lock = new object();
@@ -42,6 +47,157 @@ namespace ChatController.Core
} }
} }
private Dictionary<DefaultAvatarType, ImageSource> _DefaultAvatars = new Dictionary<DefaultAvatarType, ImageSource>();
private List<ProfilePictureObject> _AvatarCache = new List<ProfilePictureObject>();
public void AddAvatar(string uri, ImageSource avatar, long? userId, int? groupId)
{
lock(_Lock)
{
if(uri is null || avatar is null)
{
return;
}
if(_AvatarCache is null)
{
_AvatarCache = new List<ProfilePictureObject>();
}
if(!string.IsNullOrWhiteSpace(BaseUri))
{
if(_DefaultAvatars is null)
{
_DefaultAvatars = new Dictionary<DefaultAvatarType, ImageSource>();
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_employee.png"))
{
_DefaultAvatars.AddAndIgnoreDuplicates(DefaultAvatarType.Employee, avatar);
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_employee_group.png"))
{
_DefaultAvatars.AddAndIgnoreDuplicates(DefaultAvatarType.EmployeeGroup, avatar);
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_client.png"))
{
_DefaultAvatars.AddAndIgnoreDuplicates(DefaultAvatarType.Client, avatar);
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_client_group.png"))
{
_DefaultAvatars.AddAndIgnoreDuplicates(DefaultAvatarType.ClientGroup, avatar);
}
}
if(!_AvatarCache.Any(ppo => ppo.Uri.Equals(uri) && ppo.UserId == userId && ppo.GroupId == groupId))
{
_AvatarCache.Add(new ProfilePictureObject(userId, uri, avatar, groupId));
}
}
}
public ImageSource GetAvatar(string uri, long? userId, int? groupId)
{
lock(_Lock)
{
if(uri is null || _AvatarCache is null)
{
return null;
}
if(!string.IsNullOrWhiteSpace(BaseUri))
{
if(_DefaultAvatars is null)
{
_DefaultAvatars = new Dictionary<DefaultAvatarType, ImageSource>();
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_employee.png"))
{
return _DefaultAvatars[DefaultAvatarType.Employee];
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_employee_group.png"))
{
return _DefaultAvatars[DefaultAvatarType.EmployeeGroup];
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_client.png"))
{
return _DefaultAvatars[DefaultAvatarType.Client];
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_client_group.png"))
{
return _DefaultAvatars[DefaultAvatarType.ClientGroup];
}
}
return _AvatarCache.FirstOrDefault(f => uri.Equals(f.Uri) && f.UserId == userId && f.GroupId == groupId)?.ProfilePicture;
}
}
/// <summary>
/// Gibt das Profilbild des Absenders einer Nachricht in Gruppenchats zurück
/// </summary>
/// <param name="userId">UserId des Absenders einer Nachricht</param>
/// <returns>Profilbild des Absenders einer Nachricht mit der angegebenen UserId</returns>
public ImageSource GetAvatarByUserId(long userId)
{
lock(_Lock)
{
return _AvatarCache.FirstOrDefault(f => f.UserId.HasValue && f.UserId.Value.Equals(userId))?.ProfilePicture;
}
}
public bool IsAvatarInCache(string uri, long? userId, int? groupId)
{
lock(_Lock)
{
if(uri is null)
{
return false;
}
if(!string.IsNullOrWhiteSpace(BaseUri))
{
if(_DefaultAvatars is null)
{
_DefaultAvatars = new Dictionary<DefaultAvatarType, ImageSource>();
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_employee.png"))
{
return _DefaultAvatars.ContainsKey(DefaultAvatarType.Employee);
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_employee_group.png"))
{
return _DefaultAvatars.ContainsKey(DefaultAvatarType.EmployeeGroup);
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_client.png"))
{
return _DefaultAvatars.ContainsKey(DefaultAvatarType.Client);
}
if(uri.Equals($"{BaseUri}/ownChat_avatar_client_group.png"))
{
return _DefaultAvatars.ContainsKey(DefaultAvatarType.ClientGroup);
}
}
return _AvatarCache?.Any(a => uri.Equals(a.Uri) && a.UserId == userId && a.GroupId == groupId) ?? false;
}
}
// Key-> "group-127" oder "user-938" // Key-> "group-127" oder "user-938"
private Dictionary<string, ImageSourceCacheStorage> _ImageSourceCache = new Dictionary<string, ImageSourceCacheStorage>(); private Dictionary<string, ImageSourceCacheStorage> _ImageSourceCache = new Dictionary<string, ImageSourceCacheStorage>();
@@ -126,7 +282,12 @@ namespace ChatController.Core
{ {
if(!_UserProfilePictures.ContainsKey(userId)) if(!_UserProfilePictures.ContainsKey(userId))
{ {
_UserProfilePictures.Add(userId, new ProfilePictureObject(userId, uri, imageSource)); Debug.WriteLine($"+++>OwnChatCache.AddUserProfilePictureToCache: Füge Avatar zum Cache hinzu {userId}");
_UserProfilePictures.Add(userId, new ProfilePictureObject(userId, uri, imageSource, null));
}
else
{
Debug.WriteLine($">>>OwnChatCache.AddUserProfilePictureToCache: Cache enthält bereits den Avatar von {userId}");
} }
} }
} }
@@ -150,14 +311,17 @@ namespace ChatController.Core
public class ProfilePictureObject public class ProfilePictureObject
{ {
public long UserId { get; set; } public long? UserId { get; set; }
public string Uri { get; set; } public string Uri { get; set; }
public ImageSource ProfilePicture { get; set; } public ImageSource ProfilePicture { get; set; }
public ProfilePictureObject(long userId, string uri, ImageSource profilePicture) public int? GroupId { get; set; }
public ProfilePictureObject(long? userId, string uri, ImageSource profilePicture, int? groupId)
{ {
GroupId = groupId;
UserId = userId; UserId = userId;
Uri = uri; Uri = uri;
ProfilePicture = profilePicture; ProfilePicture = profilePicture;
@@ -252,4 +416,12 @@ namespace ChatController.Core
Thumbnail, Thumbnail,
MessageAttachment MessageAttachment
} }
public enum DefaultAvatarType
{
Employee = 0,
EmployeeGroup = 1,
Client = 2,
ClientGroup = 3
}
} }

View File

@@ -4,6 +4,7 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
@@ -308,7 +309,16 @@ namespace ChatController.HauptKlassen
var chatMessage = new ChatMessage(pGroupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, pMessage, time, true, 0, null, null, null, null, null, ChatMessageType.Message, ChatDaten.LoggedInUser.Response.User.Oid); var chatMessage = new ChatMessage(pGroupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, pMessage, time, true, 0, null, null, null, null, null, ChatMessageType.Message, ChatDaten.LoggedInUser.Response.User.Oid);
var result = AddSeparators(new List<ChatMessage> {previousMessage, chatMessage}); var messages = new List<ChatMessage>();
if(!(previousMessage is null))
{
messages.Add(previousMessage);
}
messages.Add(chatMessage);
var result = AddSeparators(messages);
result.Remove(previousMessage); result.Remove(previousMessage);
@@ -572,57 +582,64 @@ namespace ChatController.HauptKlassen
public void SaveFileAs(ChatMessage pChatMessage) public void SaveFileAs(ChatMessage pChatMessage)
{ {
if(!(pChatMessage.PictureSource is null)) var originalImage = pChatMessage.OriginalImage;
var fileUri = originalImage;
if(originalImage is null)
{ {
SaveAs(1, Path.GetFileName(pChatMessage.OriginalImage), DownloadMediaFile(pChatMessage.OriginalImage)); fileUri = pChatMessage.FilePath;
} }
if(fileUri is null)
{
return;
}
SaveAs(Path.GetFileName(fileUri), DownloadMediaFile(fileUri));
} }
private byte[] DownloadMediaFile(string pFilePath) private static byte[] DownloadMediaFile(string uriToFile)
{ {
byte[] mediaFile = null; byte[] mediaFile;
using(var webClient = new WebClient()) using(var webClient = new WebClient())
{ {
webClient.Credentials = CredentialCache.DefaultCredentials; webClient.Credentials = CredentialCache.DefaultCredentials;
webClient.Headers[Constants.Token] = ChatDaten.AuthToken; webClient.Headers[Constants.Token] = ChatDaten.AuthToken;
webClient.Headers[Constants.CustomerId] = ChatDaten.Kundennummer; webClient.Headers[Constants.CustomerId] = ChatDaten.Kundennummer;
mediaFile = webClient.DownloadData(pFilePath); mediaFile = webClient.DownloadData(uriToFile);
} }
return mediaFile; return mediaFile;
} }
private void SaveAs(int pFilterType, string pFileName, byte[] pMediaFile) private static void SaveAs(string pFileName, byte[] pMediaFile)
{ {
var saveFileDialog = new SaveFileDialog {FileName = Path.GetFileName(pFileName)}; var saveFileDialog = new SaveFileDialog {FileName = pFileName};
switch(pFilterType) saveFileDialog.Title = "ownChat";
saveFileDialog.Filter = "All files (*.*)|*.*";
saveFileDialog.DefaultExt = Path.GetExtension(pFileName);
if(saveFileDialog.DefaultExt.Length > 0)
{ {
case 1: saveFileDialog.AddExtension = true;
saveFileDialog.Filter = Resource.SaveFileDialogFilter_Images; saveFileDialog.Filter = $"{saveFileDialog.DefaultExt} files (*.{saveFileDialog.DefaultExt})|*.{saveFileDialog.DefaultExt}|{saveFileDialog.Filter}";
saveFileDialog.Title = Resource.SaveFIleDialogTitle_Images; saveFileDialog.FilterIndex = 0;
saveFileDialog.ShowDialog();
break;
case 2:
saveFileDialog.Filter = Resource.SaveFileDialogFilter_Documents;
saveFileDialog.Title = Resource.SaveFIleDialogTitle_Documents;
saveFileDialog.ShowDialog();
break;
case 3:
saveFileDialog.Filter = Resource.SaveFileDialogFilter_Audio;
saveFileDialog.Title = Resource.SaveFIleDialogTitle_Audio;
saveFileDialog.ShowDialog();
break;
} }
if (!string.IsNullOrEmpty(saveFileDialog.FileName)) saveFileDialog.ShowDialog();
if (string.IsNullOrEmpty(saveFileDialog.FileName))
{ {
var fileStream = (FileStream)saveFileDialog.OpenFile(); return;
}
using (var fileStream = (FileStream)saveFileDialog.OpenFile())
{
fileStream.Write(pMediaFile, 0, pMediaFile.Length); fileStream.Write(pMediaFile, 0, pMediaFile.Length);
fileStream.Close();
} }
} }
@@ -889,6 +906,25 @@ namespace ChatController.HauptKlassen
} }
} }
Task.Run(() =>
{
var userId2Uris = new Dictionary<long, string>();
foreach(var contact in contacts)
{
foreach(var test in contact.UserId2Uri)
{
userId2Uris.AddAndIgnoreDuplicates(test.Key, test.Value);
}
}
Utils.DownloadUserProfilePicturesSync(userId2Uris);
foreach(var contact in contacts)
{
contact.Image = Utils.DownloadImageSync(contact.ProfilePicturePath, null, contact.GroupId);
}
});
return contacts; return contacts;
} }
@@ -896,7 +932,7 @@ namespace ChatController.HauptKlassen
{ {
var result = new List<ChatMessage>(); var result = new List<ChatMessage>();
foreach(var message in pMessages) foreach(var message in pMessages ?? new Messages[0])
{ {
var time = DateTime.Parse(message.Timestamp.Date); var time = DateTime.Parse(message.Timestamp.Date);
var clientZone = TimeZoneInfo.Local; var clientZone = TimeZoneInfo.Local;
@@ -930,6 +966,8 @@ namespace ChatController.HauptKlassen
chatMessages = new List<ChatMessage>(); chatMessages = new List<ChatMessage>();
} }
var test = chatMessages.Any(a => a is null);
var messagesWithoutSeparators = chatMessages.Where(message => !message.IsSeparator).OrderBy(message => message.SendTime).ToList(); var messagesWithoutSeparators = chatMessages.Where(message => !message.IsSeparator).OrderBy(message => message.SendTime).ToList();
var separators = new List<ChatMessage>(); var separators = new List<ChatMessage>();

View File

@@ -161,6 +161,7 @@ namespace ChatController.HauptKlassen
_BaseUrl = lookupResult.Url; _BaseUrl = lookupResult.Url;
ServerUrl = _BaseUrl; ServerUrl = _BaseUrl;
OwnChatCache.BaseUri = _BaseUrl;
var result = false; var result = false;

View File

@@ -11,7 +11,6 @@ using ChatController.HauptKlassen;
using ChatController.LoginKlassen; using ChatController.LoginKlassen;
using ChatController.Utilities; using ChatController.Utilities;
using ChatController.Utilities.Extensions; using ChatController.Utilities.Extensions;
using Cursors = System.Windows.Input.Cursors;
using MessageBox = System.Windows.MessageBox; using MessageBox = System.Windows.MessageBox;
using Panel = System.Windows.Controls.Panel; using Panel = System.Windows.Controls.Panel;
using Path = System.IO.Path; using Path = System.IO.Path;
@@ -115,8 +114,8 @@ namespace ChatController
} }
_WaitLayer = new ChatControlWaitLayer(); _WaitLayer = new ChatControlWaitLayer();
Panel.SetZIndex(_WaitLayer, int.MaxValue);
RootGrid.Children.Add(_WaitLayer); RootGrid.Children.Add(_WaitLayer);
Panel.SetZIndex(_WaitLayer, int.MaxValue);
_WaitLayer.RefreshUI(); _WaitLayer.RefreshUI();
} }
@@ -136,49 +135,41 @@ namespace ChatController
private void Anmelden() private void Anmelden()
{ {
try if(!string.IsNullOrWhiteSpace(_Kundennummer) && !string.IsNullOrWhiteSpace(_ChatCode) && !string.IsNullOrWhiteSpace(_Benutzername) && Password.Length > 0)
{ {
if(!string.IsNullOrWhiteSpace(_Kundennummer) && !string.IsNullOrWhiteSpace(_ChatCode) && !string.IsNullOrWhiteSpace(_Benutzername) && Password.Length > 0) StartWaiting();
var login = new Login(_Kundennummer, _ChatCode, _Benutzername, PasswordBox.Password);
login.DoLoginAsync(chatDatenUebergabe =>
{ {
StartWaiting(); this.Dispatch(() =>
{
EndWaiting();
var login = new Login(_Kundennummer, _ChatCode, _Benutzername, PasswordBox.Password); if(chatDatenUebergabe is null)
{
return;
}
login.DoLoginAsync(chatDatenUebergabe => AutosetDaten();
OnLogin?.Invoke(chatDatenUebergabe);
});
},
errorMessage =>
{ {
this.Dispatch(() => this.Dispatch(() =>
{ {
EndWaiting(); EndWaiting();
if(chatDatenUebergabe is null) MessageBox.Show(errorMessage, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
{
return;
}
AutosetDaten();
OnLogin?.Invoke(chatDatenUebergabe);
}); });
}, });
errorMessage =>
{
this.Dispatch(() =>
{
EndWaiting();
MessageBox.Show(errorMessage, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
});
});
}
else
{
MessageBox.Show("Bitte alle Felder ausfüllen!", "Info", MessageBoxButton.OK);
}
} }
finally else
{ {
EndWaiting(); MessageBox.Show("Bitte alle Felder ausfüllen!", "Info", MessageBoxButton.OK);
Cursor = Cursors.Arrow;
} }
} }
@@ -209,7 +200,8 @@ namespace ChatController
} }
#if DEBUG #if DEBUG
var debugFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "debug-info.txt"); //var debugFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "debug-info.txt");
var debugFile = @"C:\Users\Lyndon Jetten\Desktop\debug-info.txt";
if (File.Exists(debugFile)) if (File.Exists(debugFile))
{ {
using(var streamReader2 = new StreamReader(debugFile, true)) using(var streamReader2 = new StreamReader(debugFile, true))

View File

@@ -7,7 +7,6 @@ using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Windows; using System.Windows;
@@ -17,7 +16,6 @@ using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using ChatController.Core; using ChatController.Core;
using RestSharp; using RestSharp;
using MessageBox = System.Windows.MessageBox;
using PixelFormat = System.Drawing.Imaging.PixelFormat; using PixelFormat = System.Drawing.Imaging.PixelFormat;
namespace ChatController.Utilities namespace ChatController.Utilities
@@ -25,50 +23,30 @@ namespace ChatController.Utilities
public class Utils public class Utils
{ {
public static string AuthToken { get; set; } public static string AuthToken { get; set; }
public static string Tenant { get; set; } public static string Tenant { get; set; }
public static DateTime DefaultDate = new DateTime(1, 1, 1); public static DateTime DefaultDate = new DateTime(1, 1, 1);
public static void DownloadGroupProfilePictureAsync(string pathToProfilePicture, string key, Action<ImageSource> callback) public static void DownloadUserProfilePicturesSync(Dictionary<long, string> userIds2Uris)
{ {
var cache = OwnChatCache.GetInstance();
var cachedProfileImage = cache.GetCachedProfilePicture(key, pathToProfilePicture);
if (!(cachedProfileImage is null))
{
callback?.Invoke(cachedProfileImage);
return;
}
DownloadImage(pathToProfilePicture, imageSource =>
{
cache.AddProfilePictureToCache(key, imageSource, pathToProfilePicture);
callback?.Invoke(imageSource);
});
}
public static void DownloadUserProfilePicturesAsync(Dictionary<long, string> userIds2Uris)
{
var cache = OwnChatCache.GetInstance();
foreach(var userId2Uri in userIds2Uris) foreach(var userId2Uri in userIds2Uris)
{ {
if(cache.IsUserProfilePictureInCache(userId2Uri.Key)) DownloadImageSync(userId2Uri.Value, userId2Uri.Key, null);
{
continue;
}
DownloadImage(userId2Uri.Value, imageSource =>
{
cache.AddUserProfilePictureToCache(imageSource, userId2Uri.Key, userId2Uri.Value);
});
} }
} }
/// <summary>
/// Lädt ein Bild aus einer Nachricht herunter.
/// </summary>
/// <param name="uri">Uri zum Bild</param>
/// <param name="callback">Callback-Methode, die nach dem Herunterladen des Bildes aufgerufen wird und das Bild zurückgibt. Fügt das Bild der GUI hinzu.</param>
private static void DownloadImage(string uri, Action<ImageSource> callback) private static void DownloadImage(string uri, Action<ImageSource> callback)
{ {
#if DEBUG
Debug.WriteLine($"####{uri} wird heruntergeladen (Utils.DownloadImage) ...");
#endif
var client = new RestClient(uri); var client = new RestClient(uri);
var request = new RestRequest var request = new RestRequest
{ {
@@ -110,7 +88,7 @@ namespace ChatController.Utilities
private static Rotation GetRotationFromExifTag(int value) private static Rotation GetRotationFromExifTag(int value)
{ {
switch (value) switch(value)
{ {
case 6: case 6:
return Rotation.Rotate90; return Rotation.Rotate90;
@@ -130,7 +108,7 @@ namespace ChatController.Utilities
callback?.Invoke(null); callback?.Invoke(null);
return; return;
} }
var cache = OwnChatCache.GetInstance(); var cache = OwnChatCache.GetInstance();
var cachedImage = cache.GetImageSourceFromCache(key, uri, cacheCategory); var cachedImage = cache.GetImageSourceFromCache(key, uri, cacheCategory);
@@ -150,7 +128,7 @@ namespace ChatController.Utilities
public static void DownloadDocumentThumbnail(string uri, Action<ImageSource> callback) public static void DownloadDocumentThumbnail(string uri, Action<ImageSource> callback)
{ {
if (string.IsNullOrEmpty(uri)) if(string.IsNullOrEmpty(uri))
{ {
callback?.Invoke(null); callback?.Invoke(null);
return; return;
@@ -254,7 +232,7 @@ namespace ChatController.Utilities
public static ImageSource ConvertIconToImageSource(Icon pIcon) public static ImageSource ConvertIconToImageSource(Icon pIcon)
{ {
var bitmap = new Bitmap(pIcon.Width, pIcon.Height); var bitmap = new Bitmap(pIcon.Width, pIcon.Height);
var graphics = Graphics.FromImage(bitmap); var graphics = Graphics.FromImage(bitmap);
graphics.DrawIcon(pIcon, 0, 0); graphics.DrawIcon(pIcon, 0, 0);
@@ -264,7 +242,7 @@ namespace ChatController.Utilities
bitmap.Save("icon.ico", ImageFormat.Icon); bitmap.Save("icon.ico", ImageFormat.Icon);
var imageSource = ImageSourceForBitmap(bitmap); var imageSource = ImageSourceForBitmap(bitmap);
bitmap.Dispose(); bitmap.Dispose();
return imageSource; return imageSource;
@@ -290,7 +268,7 @@ namespace ChatController.Utilities
public static Icon ImageSourceToIcon(ImageSource pImageSource) public static Icon ImageSourceToIcon(ImageSource pImageSource)
{ {
var bitmapSource = (BitmapSource) pImageSource; var bitmapSource = (BitmapSource)pImageSource;
var width = bitmapSource.PixelWidth; var width = bitmapSource.PixelWidth;
var height = bitmapSource.PixelHeight; var height = bitmapSource.PixelHeight;
@@ -316,7 +294,7 @@ namespace ChatController.Utilities
var memoryBlockPointer = Marshal.AllocHGlobal(height * stride); var memoryBlockPointer = Marshal.AllocHGlobal(height * stride);
bitmapSource.CopyPixels(new Int32Rect(x, y, newWidth, newHeight), memoryBlockPointer, newHeight * stride, stride); bitmapSource.CopyPixels(new Int32Rect(x, y, newWidth, newHeight), memoryBlockPointer, newHeight * stride, stride);
var bitmap = new Bitmap(newWidth, newHeight, stride, PixelFormat.Format32bppPArgb, memoryBlockPointer); var bitmap = new Bitmap(newWidth, newHeight, stride, PixelFormat.Format32bppPArgb, memoryBlockPointer);
return Icon.FromHandle(bitmap.GetHicon()); return Icon.FromHandle(bitmap.GetHicon());
@@ -394,7 +372,7 @@ namespace ChatController.Utilities
{ {
var splitUri = uri.Split('/'); var splitUri = uri.Split('/');
if(splitUri.Length>=2) if(splitUri.Length >= 2)
{ {
var heightStr = splitUri[splitUri.Length - 2]; var heightStr = splitUri[splitUri.Length - 2];
@@ -449,7 +427,7 @@ namespace ChatController.Utilities
index2Link[i] = hyperlink; index2Link[i] = hyperlink;
} }
var splitMessage = _UrlRegex.Replace(messageText, replacementString + guidString).Split(new[] {guidString}, StringSplitOptions.None); var splitMessage = _UrlRegex.Replace(messageText, replacementString + guidString).Split(new[] { guidString }, StringSplitOptions.None);
var linkIndex = 0; var linkIndex = 0;
foreach(var text in splitMessage) foreach(var text in splitMessage)
@@ -484,5 +462,97 @@ namespace ChatController.Utilities
return result; return result;
} }
public static string GetUserIdFromProfilePictureUri(string uri)
{
#if DEBUG
if(string.IsNullOrWhiteSpace(uri))
{
return uri;
}
string userId = null;
var splitUri = uri.Split('/');
if(splitUri.Length <= 0)
{
return null;
}
var lastIndex = splitUri.Length - 1;
var fileName = splitUri[lastIndex];
var splitFileName = fileName.Split('_');
if(splitFileName.Length > 0)
{
userId = long.TryParse(splitFileName[0], out var unused) ? splitFileName[0] : fileName;
}
return userId;
#endif
}
public static ImageSource DownloadImageSync(string uri, long? userId, int? groupId)
{
var userOrGroup = "FEHLER: USER-ID UND GROUP-ID SIND NULL!";
if(groupId.HasValue && userId is null)
{
userOrGroup = $"GroupId {groupId}";
}
else if(groupId is null && userId.HasValue)
{
userOrGroup = $"UserId {userId}";
}
var cache = OwnChatCache.GetInstance();
if(cache.IsAvatarInCache(uri, userId, groupId))
{
return cache.GetAvatar(uri, userId, groupId);
}
Debug.WriteLine($"####Lade {uri} für {userOrGroup} herunter ...");
var request = WebRequest.Create(uri);
request.Credentials = CredentialCache.DefaultCredentials;
request.Headers[Constants.Token] = AuthToken;
request.Headers[Constants.CustomerId] = Tenant;
using(var response = request.GetResponse())
{
var responseStream = response?.GetResponseStream();
if(responseStream is null)
{
return null;
}
var rotation = Rotation.Rotate0;
using(var image = Image.FromStream(responseStream))
{
if(image.PropertyIdList.Contains(0x112))
{
rotation = GetRotationFromExifTag(image.GetPropertyItem(0x112).Value[0]);
}
var bitmap = new BitmapImage();
var localStream = new MemoryStream();
image.Save(localStream, image.RawFormat);
localStream.Position = 0;
bitmap.BeginInit();
bitmap.StreamSource = localStream;
bitmap.Rotation = rotation;
bitmap.EndInit();
bitmap.Freeze();
cache.AddAvatar(uri, bitmap, userId, groupId);
return cache.GetAvatar(uri, userId, groupId);
}
}
}
} }
} }