diff --git a/ChatController/ChatController.csproj b/ChatController/ChatController.csproj index 2e5e772..eae6e56 100644 --- a/ChatController/ChatController.csproj +++ b/ChatController/ChatController.csproj @@ -72,6 +72,8 @@ + + diff --git a/ChatController/ChatKlassen/ChatMessage.cs b/ChatController/ChatKlassen/ChatMessage.cs index a2c9432..7fc0259 100644 --- a/ChatController/ChatKlassen/ChatMessage.cs +++ b/ChatController/ChatKlassen/ChatMessage.cs @@ -1,12 +1,14 @@ using System; +using System.Collections.ObjectModel; using System.ComponentModel; -using System.Diagnostics; -using System.Text.RegularExpressions; -using System.Windows; +using System.Windows.Documents; using System.Windows.Media; using ChatController.Core; +using ChatController.HauptKlassen; using ChatController.Utilities; using static System.Windows.HorizontalAlignment; +using Application = System.Windows.Application; +using HorizontalAlignment = System.Windows.HorizontalAlignment; namespace ChatController.ChatKlassen { @@ -22,108 +24,82 @@ namespace ChatController.ChatKlassen public bool IsSeparator { get; set; } - public long FileSize { get; set; } + public long SenderId { get; } - // Separator - public ChatMessage(DateTime sendTime) + private ObservableCollection _MessageInlines; + + public ObservableCollection MessageInlines { - Id = Guid.NewGuid(); - IsSeparator = true; - SendTime = sendTime; - - MessageType = ChatMessageType.Separator; + get => _MessageInlines; + set + { + if(false == (_MessageInlines?.Equals(value) ?? false)) + { + _MessageInlines = value; + OnPropertyChanged(nameof(MessageInlines)); + } + } } - //Chat-Ansicht - public ChatMessage(string username, string message, DateTime sendtime, bool isme, long groupId, long fileSize, long messageId) + public ChatMessage(long groupId, long messageId, string userName, string messageText, DateTime sendTime, bool isOwnMessage, long fileSize, string filePath, + string originalImage, string imageName, string thumbnailPath, ImageSource logo, ChatMessageType chatMessageType, long senderId) { - MessageId = messageId; - Id = Guid.NewGuid(); - Username = username; - UserMessage = message; - SendTime = sendtime; - IsMyMessage = isme; + SenderId = senderId; + + MessageType = chatMessageType; + + MessageId = messageId; GroupId = groupId; + Username = userName; - MessageType = IsHyperlink(message) ? ChatMessageType.Hyperlink : ChatMessageType.Message; - } - - // Image-Ansicht - public ChatMessage(string username, string message, DateTime sendtime, bool isme, string filePath, string originalImage, string imageName, long groupId, long fileSize, long messageId) - { - PicturePlaceholderHeight = Utils.GetHeightFromThumbnailUri(filePath); - PictureSource = Utils.GetPicturePlaceholder(); + UserMessage = messageText; + if(!string.IsNullOrEmpty(messageText)) + { + Application.Current.Dispatcher.Invoke(() => + { + MessageInlines = Utils.ConvertLinksToHyperlinks(messageText); + }); + } - MessageId = messageId; - - Id = Guid.NewGuid(); - Username = username; - UserMessage = message; - SendTime = sendtime; - - IsMyMessage = isme; + SendTime = sendTime; + IsMyMessage = isOwnMessage; OriginalImage = originalImage; OriginalImageName = imageName; - - GroupId = groupId; - MessageType = ChatMessageType.Image; - - Utils.DownloadImageAsync(filePath, $"group-{groupId}", CacheCategory.Thumbnail, imageSource => + if(MessageId == 0 && MessageType == ChatMessageType.Image && logo != null) { - PictureSource = imageSource; - }); - } - - //Dokumenten-Ansicht - public ChatMessage(string username, string message, DateTime sendtime, string thumbnailPath, bool isme, string filePath, long groupId, long fileSize, long messageId) - { - ThumbnailPlaceholderHeight = Utils.GetHeightFromThumbnailUri(thumbnailPath); - Thumbnail = Utils.GetPicturePlaceholder(); - - MessageId = messageId; - - Id = Guid.NewGuid(); - Username = username; - UserMessage = message; - SendTime = sendtime; - IsMyMessage = isme; + PictureSource = logo; + PicturePlaceholderHeight = (int) logo.Height; + } FilePath = filePath; - - Utils.DownloadImageAsync(thumbnailPath, $"group-{groupId}", CacheCategory.Thumbnail, imageSource => + + if(!string.IsNullOrWhiteSpace(thumbnailPath)) { - Thumbnail = imageSource; - }); + ThumbnailPlaceholderHeight = Utils.GetHeightFromThumbnailUri(thumbnailPath); + Thumbnail = Utils.GetPicturePlaceholder(); - GroupId = groupId; + Utils.DownloadImageAsync(thumbnailPath, $"group-{groupId}", CacheCategory.Thumbnail, imageSource => + { + Thumbnail = imageSource; + }); + } - MessageType = ChatMessageType.Document; - } + if(MessageType == ChatMessageType.Image && !string.IsNullOrWhiteSpace(filePath)) + { + PicturePlaceholderHeight = Utils.GetHeightFromThumbnailUri(filePath); + PictureSource = Utils.GetPicturePlaceholder(); - // Mit Logo - public ChatMessage(string username, string message, DateTime sendtime, bool isme, ImageSource logo, string originalImage, string imageName, long groupId, long fileSize, long messageId) - { - MessageId = messageId; + Utils.DownloadImageAsync(filePath, $"group-{groupId}", CacheCategory.Thumbnail, imageSource => + { + PictureSource = imageSource; + }); + } - Id = Guid.NewGuid(); - Username = username; - UserMessage = message; - SendTime = sendtime; - - IsMyMessage = isme; - - OriginalImage = originalImage; - OriginalImageName = imageName; - - GroupId = groupId; - - MessageType = ChatMessageType.Image; - - PictureSource = logo; + IsSeparator = MessageType == ChatMessageType.Separator; } public ChatMessageType MessageType { get; } @@ -157,47 +133,6 @@ namespace ChatController.ChatKlassen } } - private static readonly Regex _UrlRegex = new Regex(@"(?#Protocol)^(http(?:s?)\:(\/\/|\\\\)|(w){3}(2|3)?\.{1})(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?"); - - public static bool IsHyperlink(string word) - { - if(word == null) - { - return false; - } - - try - { - if (word.IndexOfAny(@":.\/".ToCharArray()) != -1) - { - if (_UrlRegex.IsMatch(word)) - { - var uri = new Uri(word, UriKind.RelativeOrAbsolute); - - if (!uri.IsAbsoluteUri) - { - uri = new Uri(@"http://" + word, UriKind.Absolute); - } - - if (uri.IsAbsoluteUri) - { - return true; - } - } - else - { - return false; - } - } - } - catch (Exception e) - { - return false; - } - - return false; - } - public bool IsMyMessage { get; set; } public string Username { get; } @@ -223,16 +158,6 @@ namespace ChatController.ChatKlassen public string OriginalImage { get; } public string OriginalImageName { get; } - - public Visibility ChatVisibility => MessageType == ChatMessageType.Message ? Visibility.Visible : Visibility.Collapsed; - - public Visibility HyperlinkVisibility => MessageType == ChatMessageType.Hyperlink ? Visibility.Visible : Visibility.Collapsed; - - public Visibility PictureVisibility => MessageType == ChatMessageType.Image ? Visibility.Visible : Visibility.Collapsed; - - public Visibility PicturePlaceHolderVisibility => MessageType == ChatMessageType.DefaultImage ? Visibility.Visible : Visibility.Collapsed; - - public Visibility DokumentVisibility => MessageType == ChatMessageType.Document ? Visibility.Visible : Visibility.Collapsed; private ImageSource _PictureSource; public ImageSource PictureSource @@ -262,7 +187,7 @@ namespace ChatController.ChatKlassen } } - public object FilePath { get; } + public string FilePath { get; } public long GroupId { get; } @@ -270,28 +195,7 @@ namespace ChatController.ChatKlassen public Guid Id { get; } - public Uri UserMessageAsUri - { - get - { - if(IsHyperlink(UserMessage)) - { - Debug.WriteLine($"Link: {UserMessage}"); - - if(!UserMessage.Contains("http")) - { - return new Uri("http://" + UserMessage); - } - - if(UserMessage.Contains("https") || UserMessage.Contains("http")) - { - return new Uri(UserMessage); - } - } - - return null; - } - } + public ImageSource ProfilePicture => OwnChatCache.GetInstance().GetUserProfilePictureFromCache(SenderId)?.ProfilePicture; protected virtual void OnPropertyChanged(string propertyName) { @@ -308,7 +212,7 @@ namespace ChatController.ChatKlassen return SendTime == message.SendTime; } - return MessageId.Equals(message.MessageId); + return Id.Equals(message.Id) && MessageId.Equals(message.MessageId); } return false; diff --git a/ChatController/ChatKlassen/Contact.cs b/ChatController/ChatKlassen/Contact.cs index 26eb9a2..74a5c02 100644 --- a/ChatController/ChatKlassen/Contact.cs +++ b/ChatController/ChatKlassen/Contact.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.ComponentModel; using System.Windows.Media; using ChatController.LoginKlassen; @@ -82,7 +83,7 @@ namespace ChatController.ChatKlassen public bool IsChatMessageInputGridVisible { 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) + 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 userId2Uri) { Name = pName; ReceivedMessage = pLatestMessage; @@ -108,15 +109,21 @@ namespace ChatController.ChatKlassen accentColorBrushString = "000000"; } } - + AccentColorBrush = new BrushConverter().ConvertFromString($"#{accentColorBrushString}") as SolidColorBrush; + IsGroupChat = pUserCount > 2; + + Utils.DownloadUserProfilePictures(userId2Uri); + Utils.DownloadProfilePictureAsync(profilePicturePath, key, delegate(ImageSource imageSource) { Image = imageSource; }); } + public bool IsGroupChat { get; } + public override bool Equals(object obj) { if(obj is Contact y) diff --git a/ChatController/ChatMainControl.xaml b/ChatController/ChatMainControl.xaml index 3c687ba..5a7c57d 100644 --- a/ChatController/ChatMainControl.xaml +++ b/ChatController/ChatMainControl.xaml @@ -5,6 +5,8 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:converter="clr-namespace:ChatController.Converter" xmlns:chatKlassen="clr-namespace:ChatController.ChatKlassen" + xmlns:core="clr-namespace:ChatController.Core" + xmlns:chatController="clr-namespace:ChatController" mc:Ignorable="d" x:Name="ChatControlling" d:DesignHeight="300" d:DesignWidth="600" Loaded="ChatMainControl_OnLoaded" @@ -13,10 +15,10 @@ + - - + diff --git a/ChatController/ChatMainControl.xaml.cs b/ChatController/ChatMainControl.xaml.cs index 6984223..7068509 100644 --- a/ChatController/ChatMainControl.xaml.cs +++ b/ChatController/ChatMainControl.xaml.cs @@ -484,21 +484,21 @@ namespace ChatController else { var contextItems = ChatListBox.ContextMenu.Items; - var ContextItemSpeichernUnter = (MenuItem)contextItems[0]; - ContextItemSpeichernUnter.Visibility = Visibility.Collapsed; + var contextItemSpeichernUnter = (MenuItem)contextItems[0]; + contextItemSpeichernUnter.Visibility = Visibility.Collapsed; } if(item.PictureSource == null && item.FilePath == null) { var contextItems = ChatListBox.ContextMenu.Items; - var ContextItemSpeichernUnter = (MenuItem)contextItems[2]; - ContextItemSpeichernUnter.Visibility = Visibility.Visible; + var contextItemSpeichernUnter = (MenuItem)contextItems[2]; + contextItemSpeichernUnter.Visibility = Visibility.Visible; } else { var contextItems = ChatListBox.ContextMenu.Items; - var ContextItemSpeichernUnter = (MenuItem)contextItems[2]; - ContextItemSpeichernUnter.Visibility = Visibility.Collapsed; + var contextItemSpeichernUnter = (MenuItem)contextItems[2]; + contextItemSpeichernUnter.Visibility = Visibility.Collapsed; } } } @@ -506,8 +506,8 @@ namespace ChatController { //Schalte speichern unter Aus var contextItems = ChatListBox.ContextMenu.Items; - var ContextItemSpeichernUnter = (MenuItem)contextItems[0]; - ContextItemSpeichernUnter.Visibility = Visibility.Collapsed; + var contextItemSpeichernUnter = (MenuItem)contextItems[0]; + contextItemSpeichernUnter.Visibility = Visibility.Collapsed; } //prüfe ob was in dem Speicher vorhanden ist //Einfügen @@ -516,40 +516,40 @@ namespace ChatController if(dataObject != null && dataObject.GetDataPresent(DataFormats.FileDrop)) { var contextItems = ChatListBox.ContextMenu.Items; - var ContextItemSpeichernUnter = (MenuItem) contextItems[1]; - ContextItemSpeichernUnter.Visibility = Visibility.Visible; + 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; + 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; + var contextItemSpeichernUnter = (MenuItem) contextItems[1]; + contextItemSpeichernUnter.Visibility = Visibility.Visible; } else { var contextItems = ChatListBox.ContextMenu.Items; - var ContextItemSpeichernUnter = (MenuItem)contextItems[1]; - ContextItemSpeichernUnter.Visibility = Visibility.Collapsed; + var contextItemSpeichernUnter = (MenuItem)contextItems[1]; + contextItemSpeichernUnter.Visibility = Visibility.Collapsed; } // Prüfe, ob Dokumentation erlaubt if(CurrentContact.UserIdManage == null && ChatListBox.ContextMenu.Items.Count > 3) { var contextItems = ChatListBox.ContextMenu.Items; - var ContextItemSpeichernUnter = (MenuItem)contextItems[3]; - ContextItemSpeichernUnter.Visibility = Visibility.Collapsed; + 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; + var contextItemSpeichernUnter = (MenuItem)contextItems[3]; + contextItemSpeichernUnter.Visibility = Visibility.Visible; } if(ChatListBox.ContextMenu.Items.Count == 0) @@ -563,13 +563,13 @@ namespace ChatController { if(CurrentContact != null) { - var fileToOpen = Chat.OpenFile(); + var pathToOriginalImage = Chat.OpenFile(); - if(fileToOpen != null) + if(pathToOriginalImage != null) { - var filePath = FileUtils.ScaleImage(fileToOpen, Path.GetExtension(fileToOpen.ToUpperInvariant()), Chat.ChatDaten.MaxUploadSize); + var pathToScaledImage = FileUtils.ScaleImage(pathToOriginalImage, Path.GetExtension(pathToOriginalImage.ToUpperInvariant()), Chat.ChatDaten.MaxUploadSize); - var isFileSizeTooLarge = FileUtils.CheckFileSize(filePath, Chat.ChatDaten.MaxUploadSize); + var isFileSizeTooLarge = FileUtils.CheckFileSize(pathToScaledImage, Chat.ChatDaten.MaxUploadSize); if(isFileSizeTooLarge) { @@ -577,9 +577,9 @@ namespace ChatController return; } - if (!string.IsNullOrWhiteSpace(filePath)) + if (!string.IsNullOrWhiteSpace(pathToScaledImage)) { - _ChatMessages.AddRangeIfElementsNotIn(Chat.AddNewFile(filePath, fileToOpen, CurrentContact.GroupId, GetFirstMessage())); + _ChatMessages.AddRangeIfElementsNotIn(Chat.AddNewFile(pathToScaledImage, pathToOriginalImage, CurrentContact.GroupId, GetFirstMessage())); ChatMessages.MoveCurrentToLast(); @@ -587,11 +587,11 @@ namespace ChatController ChatListBox.ScrollIntoView(currentChatMessage); - Chat.SendFileToContact(CurrentContact, filePath,fileToOpen); + Chat.SendFileToContact(CurrentContact, pathToScaledImage,pathToOriginalImage); - if (!string.IsNullOrWhiteSpace(filePath) && !filePath.Equals(fileToOpen) && File.Exists(filePath)) + if (!string.IsNullOrWhiteSpace(pathToScaledImage) && !pathToScaledImage.Equals(pathToOriginalImage) && File.Exists(pathToScaledImage)) { - File.Delete(filePath); + File.Delete(pathToScaledImage); } } } @@ -606,8 +606,10 @@ namespace ChatController { if(CurrentContact != null && !string.IsNullOrEmpty(Chatbox.Text)) { - _ChatMessages.AddRangeIfElementsNotIn(Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId, GetFirstMessage())); + var messages2Add = Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId, GetFirstMessage()); + _ChatMessages.AddRangeIfElementsNotIn(messages2Add); + OnPropertyChanged(nameof(ChatMessages)); ChatMessages.MoveCurrentToLast(); ChatListBox.ScrollIntoView(ChatMessages.CurrentItem); @@ -753,7 +755,6 @@ namespace ChatController { foreach (var newContact in updatedContacts) { - if (contact.GroupId == newContact.GroupId) { // ReceivedMessage kann null sein! @@ -869,8 +870,19 @@ namespace ChatController if(selectedItem is ChatMessage selectedMessage) { - if(!string.IsNullOrEmpty(selectedMessage.OriginalImage)) + 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) => @@ -963,12 +975,6 @@ namespace ChatController }); } - private void Hyperlink_OnRequestNavigate(object sender, RequestNavigateEventArgs e) - { - Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); - e.Handled = true; - } - private void ButtonReloadGruppen_OnClick(object sender, RoutedEventArgs e) { DoSynchro(); diff --git a/ChatController/Converter/UserProfilePictureVisibilityConverter.cs b/ChatController/Converter/UserProfilePictureVisibilityConverter.cs new file mode 100644 index 0000000..cabb8bf --- /dev/null +++ b/ChatController/Converter/UserProfilePictureVisibilityConverter.cs @@ -0,0 +1,30 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace ChatController.Converter +{ + public class UserProfilePictureVisibilityConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if(values != null && values.Length == 2 && values[0] is bool isMyMessage && values[1] is bool isGroupChat) + { + if(parameter is string test && test == "reverse") + { + return isMyMessage && isGroupChat ? Visibility.Visible : Visibility.Collapsed; + } + + return !isMyMessage && isGroupChat ? Visibility.Visible : Visibility.Collapsed; + } + + return Visibility.Collapsed; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/ChatController/Core/BindableTextBlock.cs b/ChatController/Core/BindableTextBlock.cs new file mode 100644 index 0000000..e089037 --- /dev/null +++ b/ChatController/Core/BindableTextBlock.cs @@ -0,0 +1,31 @@ +using System.Collections.ObjectModel; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; + +namespace ChatController.Core +{ + public class BindableTextBlock : TextBlock + { + public ObservableCollection InlineList + { + get => (ObservableCollection) GetValue(InlineListProperty); + set => SetValue(InlineListProperty, value); + } + + public static readonly DependencyProperty InlineListProperty = DependencyProperty.Register("InlineList", typeof(ObservableCollection), typeof(BindableTextBlock), new UIPropertyMetadata(null, OnPropertyChanged)); + + public static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + if(e.NewValue == null) + { + return; + } + + var textBlock = (BindableTextBlock)sender; + + textBlock.Inlines.Clear(); + textBlock.Inlines.AddRange((ObservableCollection) e.NewValue); + } + } +} diff --git a/ChatController/Core/OwnChatCache.cs b/ChatController/Core/OwnChatCache.cs index cec0077..5699320 100644 --- a/ChatController/Core/OwnChatCache.cs +++ b/ChatController/Core/OwnChatCache.cs @@ -11,6 +11,8 @@ namespace ChatController.Core // Key-> "group-127" oder "user-938" private Dictionary _ImageSourceCache = new Dictionary(); + private Dictionary _UserProfilePictures = new Dictionary(); + private static OwnChatCache _Instance; private OwnChatCache() { } @@ -96,6 +98,41 @@ namespace ChatController.Core null; } } + + public void AddUserProfilePictureToCache(ImageSource imageSource, long userId, string uri) + { + lock(_Lock) + { + if(!_UserProfilePictures.ContainsKey(userId)) + { + _UserProfilePictures.Add(userId, new ProfilePictureObject(userId, uri, imageSource)); + } + } + } + + public ProfilePictureObject GetUserProfilePictureFromCache(long userId) + { + lock(_Lock) + { + return _UserProfilePictures.ContainsKey(userId) ? _UserProfilePictures[userId] : null; + } + } + } + + public class ProfilePictureObject + { + public long UserId { get; set; } + + public string Uri { get; set; } + + public ImageSource ProfilePicture { get; set; } + + public ProfilePictureObject(long userId, string uri, ImageSource profilePicture) + { + UserId = userId; + Uri = uri; + ProfilePicture = profilePicture; + } } public class ImageSourceCacheStorage diff --git a/ChatController/HauptKlassen/Chat.cs b/ChatController/HauptKlassen/Chat.cs index 888e8e7..0b8ba4e 100644 --- a/ChatController/HauptKlassen/Chat.cs +++ b/ChatController/HauptKlassen/Chat.cs @@ -3,7 +3,6 @@ using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; @@ -21,7 +20,6 @@ using System.Windows.Data; using System.Windows.Forms; using System.Windows.Media; using System.Windows.Media.Imaging; -using System.Windows.Threading; using ChatController.Core; using ChatController.Extensions; using ChatController.LoginKlassen; @@ -45,7 +43,7 @@ namespace ChatController.HauptKlassen private readonly List _Contacts = new List(); - public ChatDatenUebergabe ChatDaten { get; set; } + public static ChatDatenUebergabe ChatDaten { get; set; } private UserMessages _UserMessages; private UserMessages _AdditionalUserMessages; @@ -146,9 +144,6 @@ namespace ChatController.HauptKlassen client.ExecuteAsync(request, response => { - // TODO: Entfernen - Debug.WriteLine(response.Content); - _UserMessages = JsonConvert.DeserializeObject(response.Content); if (_UserMessages.Response.HasMorePages) @@ -297,12 +292,9 @@ namespace ChatController.HauptKlassen client.ExecuteAsync(request, response => { - // TODO: Entfernen - Debug.WriteLine(response.Content); - var messageCounter = JsonConvert.DeserializeObject(response.Content); - callback?.Invoke(messageCounter.MessageCount); + callback?.Invoke(messageCounter?.MessageCount ?? 0); }); } catch(Exception exception) @@ -357,25 +349,12 @@ namespace ChatController.HauptKlassen { var result = new List(); - if(previousMessage != null) - { - result.Add(previousMessage); - } - try { - var username = string.Empty; - - var user = ChatDaten.LoggedInUser.Response.User; - - if(user != null) - { - username = $"{user.Firstname} {user.Lastname}"; - } - var time = DateTime.Now; - result.Add(new ChatMessage(username, pMessage, time, true, pGroupId, 0, 0)); + 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); + result.Add(chatMessage); return AddSeparators(result); } @@ -526,81 +505,75 @@ namespace ChatController.HauptKlassen } } - public List AddNewFile(string pFile, string pOriginalFilePath, long pGroupId, ChatMessage previousMessage) + public List AddNewFile(string pathToFile, string originalFilePath, long groupId, ChatMessage previousMessage) { var result = new List(); - if (previousMessage != null) - { - result.Add(previousMessage); - } - try { - if (string.IsNullOrEmpty(pFile) || string.IsNullOrEmpty(pOriginalFilePath)) + if (string.IsNullOrEmpty(pathToFile) || string.IsNullOrEmpty(originalFilePath)) { return result; } - var message = _UserMessages.Response.Messages.Last(); + var latestMessage = _UserMessages.Response.Messages.Last(); var sendTime = DateTime.Now; - if (Constants.ImageFileExtensions.Contains(Path.GetExtension(pFile).ToUpperInvariant())) + if (Constants.ImageFileExtensions.Contains(Path.GetExtension(pathToFile).ToUpperInvariant())) { byte[] file; - using (Stream reader = File.OpenRead(pFile)) + using (Stream reader = File.OpenRead(pathToFile)) { file = Utils.ReadFully(reader); } - - var memoryStream = new MemoryStream(file); - var image = Image.FromStream(memoryStream); - - using (var bitmap = new Bitmap(image)) + + using(var memoryStream = new MemoryStream(file)) { - using (var stream = new MemoryStream()) + var image = Image.FromStream(memoryStream); + + using (var bitmap = new Bitmap(image)) { - short orient = 0; - const int orientationId = 0x0112; - - if (image.PropertyIdList.Contains(orientationId)) + using (var stream = new MemoryStream()) { - var item = image.GetPropertyItem(orientationId); + short orient = 0; + const int orientationId = 0x0112; - orient = BitConverter.ToInt16(item.Value, 0); + if (image.PropertyIdList.Contains(orientationId)) + { + var item = image.GetPropertyItem(orientationId); + + orient = BitConverter.ToInt16(item.Value, 0); - bitmap.SetPropertyItem(item); + bitmap.SetPropertyItem(item); + } + + var flipType = Utils.OrientationToFlipType(orient.ToString()); + + bitmap.RotateFlip(flipType); + + bitmap.Save(stream, ImageFormat.Jpeg); + + + var bitmapImage = new BitmapImage(); + + bitmapImage.BeginInit(); + bitmapImage.StreamSource = new MemoryStream(stream.ToArray()); + bitmapImage.EndInit(); + bitmapImage.Freeze(); + + var chatMessage = new ChatMessage(groupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, Path.GetFileName(pathToFile), sendTime, true, memoryStream.Length, null, pathToFile, Path.GetFileName(pathToFile), null, bitmapImage, ChatMessageType.Image, ChatDaten.LoggedInUser.Response.User.Oid); + result.Add(chatMessage); } - - var flipType = Utils.OrientationToFlipType(orient.ToString()); - - bitmap.RotateFlip(flipType); - - bitmap.Save(stream, ImageFormat.Jpeg); - - - var bitmapImage = new BitmapImage(); - - bitmapImage.BeginInit(); - bitmapImage.StreamSource = new MemoryStream(stream.ToArray()); - bitmapImage.EndInit(); - bitmapImage.Freeze(); - - var filename = Path.GetFileName(pOriginalFilePath).ToLower(); - - filename = filename.Replace(".bmp", ".jpg"); - - result.Add(new ChatMessage(message.User_Name, filename, sendTime, true, bitmapImage, pFile, filename, pGroupId, file.LongLength, message.Id)); } } - - memoryStream.Dispose(); - memoryStream.Close(); } else { - result.Add(new ChatMessage(message.User_Name, Path.GetFileName(pFile), sendTime, message.Smaller_Image, true, pFile, pGroupId, 0, message.Id)); + var linkToThumbnail = $"{ChatDaten.ServerUrl}/document.png"; + + var chatMessage = new ChatMessage(groupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, Path.GetFileName(pathToFile), sendTime, true, 0, pathToFile, null, null, linkToThumbnail, null, ChatMessageType.Document, ChatDaten.LoggedInUser.Response.User.Oid); + result.Add(chatMessage); } return AddSeparators(result); @@ -613,11 +586,11 @@ namespace ChatController.HauptKlassen return result; } - public List AddMediumContextDerNachrichtView(byte[] pFile, string pFileName, long pGroupId, ChatMessage previousMessage) + public List AddFileToMessage(byte[] file, string fileName, long groupId, ChatMessage previousMessage) { var result = new List(); - if (string.IsNullOrEmpty(pFileName)) + if (string.IsNullOrEmpty(fileName)) { return result; } @@ -631,10 +604,10 @@ namespace ChatController.HauptKlassen var sendtime = DateTime.Now; - if (Constants.ImageFileExtensions.Contains(Path.GetExtension(pFileName).ToUpperInvariant())) + if (Constants.ImageFileExtensions.Contains(Path.GetExtension(fileName).ToUpperInvariant())) { var bitmapImage = new BitmapImage(); - var memoryStream = new MemoryStream(pFile); + var memoryStream = new MemoryStream(file); bitmapImage.BeginInit(); bitmapImage.StreamSource = memoryStream; @@ -644,11 +617,16 @@ namespace ChatController.HauptKlassen memoryStream.Close(); ImageSource logo = bitmapImage; - result.Add(new ChatMessage(message.User_Name, Path.GetFileName(pFileName), sendtime, true, logo, pFileName, Path.GetFileName(pFileName), pGroupId, memoryStream.Length, message.Id)); + // Mit Logo + var chatMessage = new ChatMessage(groupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, Path.GetFileName(fileName), sendtime, true, memoryStream.Length, null, fileName, Path.GetFileName(fileName), null, logo, ChatMessageType.Image, ChatDaten.LoggedInUser.Response.User.Oid); + + result.Add(chatMessage); } else { - result.Add(new ChatMessage(message.User_Name, Path.GetFileName(pFileName), sendtime, message.Smaller_Image, true, pFileName, pGroupId, 0, message.Id)); + // Dokument + var chatMessage = new ChatMessage(groupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, Path.GetFileName(fileName), sendtime, true, 0, fileName, null, null, message.Smaller_Image, null, ChatMessageType.Document, ChatDaten.LoggedInUser.Response.User.Oid); + result.Add(chatMessage); } return AddSeparators(result); @@ -847,7 +825,7 @@ namespace ChatController.HauptKlassen var mediaFile = File.ReadAllBytes(fileList[0]); - pChatMainControl.AddMessages(AddMediumContextDerNachrichtView(mediaFile, fileName, pGroupOid, pChatMainControl.GetFirstMessage())); + pChatMainControl.AddMessages(AddFileToMessage(mediaFile, fileName, pGroupOid, pChatMainControl.GetFirstMessage())); CollectionViewSource.GetDefaultView(pChatMainControl.ChatListBox.ItemsSource).Refresh(); @@ -886,7 +864,7 @@ namespace ChatController.HauptKlassen Image image = bitmap; - pChatMainControl.AddMessages(AddMediumContextDerNachrichtView(Utils.ImageToByteArray(image), imageName, pGroupOid, pChatMainControl.GetFirstMessage())); + pChatMainControl.AddMessages(AddFileToMessage(Utils.ImageToByteArray(image), imageName, pGroupOid, pChatMainControl.GetFirstMessage())); CollectionViewSource.GetDefaultView(pChatMainControl.ChatListBox.ItemsSource).Refresh(); @@ -1095,6 +1073,8 @@ namespace ChatController.HauptKlassen var key = $"group-{groupInput.Oid}"; + + contacts.Add(new Contact( groupInput.Name, groupInput.LastMessage, @@ -1106,7 +1086,7 @@ namespace ChatController.HauptKlassen groupInput.CanWrite, groupInput.AccentColor, groupInput.Avatar, - key)); + key, groupInput.Users.ToDictionary(user => user.Oid, user => user.Picture))); if(pShouldUpdateLastTimeStamp) { @@ -1129,11 +1109,6 @@ namespace ChatController.HauptKlassen { var result = new List(); - if(previousMessage != null) - { - result.Add(previousMessage); - } - foreach (var message in pMessages) { var time = DateTime.Parse(message.Timestamp.Date); @@ -1145,16 +1120,16 @@ namespace ChatController.HauptKlassen if (!string.IsNullOrEmpty(message.File)) { var message2Add = Constants.ImageFileExtensions.Contains(Path.GetExtension(message.File).ToUpperInvariant()) ? //SmallerImage ist null - new ChatMessage(message.User_Name, messageText, formattedTime, isLoggedInUsersMessage, message.Smaller_Image, message.File, message.Original_Filename, message.GroupId, message.FileSize, message.Id) : - new ChatMessage(message.User_Name, messageText, formattedTime, message.Smaller_Image, isLoggedInUsersMessage, message.File, message.GroupId, message.FileSize, message.Id); + new ChatMessage(message.GroupId, message.Id, message.User_Name, messageText, formattedTime, isLoggedInUsersMessage, message.FileSize, message.Smaller_Image, message.File, message.Original_Filename, null, null, ChatMessageType.Image, message.UserId) : + new ChatMessage(message.GroupId, message.Id, message.User_Name, messageText, formattedTime, isLoggedInUsersMessage, 0, message.File, null, null, message.Smaller_Image, null, ChatMessageType.Document, message.UserId); result.AddIfNotIn(message2Add); } else { - var message2Add2 = new ChatMessage(message.User_Name, message.Text, formattedTime, isLoggedInUsersMessage, message.GroupId, message.FileSize, message.Id); - - result.AddIfNotIn(message2Add2); + var chatMessage = new ChatMessage(message.GroupId, message.Id, message.User_Name, message.Text, formattedTime, isLoggedInUsersMessage, message.FileSize, null, null, null, null, null, ChatMessageType.Message, message.UserId); + + result.AddIfNotIn(chatMessage); } } @@ -1174,7 +1149,7 @@ namespace ChatController.HauptKlassen { if(message.SendTime.Date != previousMessage.SendTime.Date) { - var separatorMessage = new ChatMessage(null, null, message.SendTime.Date, false, 0, 0, -1) { IsSeparator = true }; + var separatorMessage = new ChatMessage(0, -1, null, null, message.SendTime.Date, false, 0, null, null, null, null, null, ChatMessageType.Separator, 0); separators.Add(separatorMessage); diff --git a/ChatController/LoginControl.xaml b/ChatController/LoginControl.xaml index 3fda31a..49a8ad7 100644 --- a/ChatController/LoginControl.xaml +++ b/ChatController/LoginControl.xaml @@ -4,6 +4,9 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d"> + + + @@ -48,12 +51,30 @@ diff --git a/ChatController/LoginControl.xaml.cs b/ChatController/LoginControl.xaml.cs index 6cfae31..2342200 100644 --- a/ChatController/LoginControl.xaml.cs +++ b/ChatController/LoginControl.xaml.cs @@ -92,10 +92,20 @@ namespace ChatController LeseDateiFallsVorhanden(); #if DEBUG + //_Kundennummer = "4368658436"; + //_ChatCode = "ZMCKb-BckTt"; + //_Benutzername = "muellerp"; + //Password = "F5aTk9Co47JFJCWB2Z7Y"; + + //_Kundennummer = "9988776655"; + //_ChatCode = "K2UPV-qrirb"; + //_Benutzername = "lyndon"; + //Password = "lyndon2travemünde"; + _Kundennummer = "4368658436"; - _ChatCode = "ZMCKb-BckTt"; - _Benutzername = "muellerp"; - Password = "F5aTk9Co47JFJCWB2Z7Y"; + _ChatCode = "B7x0b-FhhJA"; + _Benutzername = "jettenl"; + Password = "n8-yR+3Q=6nX#"; #endif } diff --git a/ChatController/LoginKlassen/UserDaten.cs b/ChatController/LoginKlassen/UserDaten.cs index 5ac46ef..1c41b9e 100644 --- a/ChatController/LoginKlassen/UserDaten.cs +++ b/ChatController/LoginKlassen/UserDaten.cs @@ -53,5 +53,25 @@ namespace ChatController.LoginKlassen public bool IsEmployee { get; set; } public string Token { get; set; } + + public string UserName + { + get + { + var result = string.Empty; + + if(!string.IsNullOrWhiteSpace(Firstname)) + { + result = $"{Firstname} "; + } + + if(!string.IsNullOrWhiteSpace(Lastname)) + { + result += Lastname; + } + + return result; + } + } } } diff --git a/ChatController/Utilities/Utils.cs b/ChatController/Utilities/Utils.cs index 4519508..08b1f7c 100644 --- a/ChatController/Utilities/Utils.cs +++ b/ChatController/Utilities/Utils.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; @@ -7,7 +9,9 @@ using System.Linq; using System.Net; using System.Reflection; using System.Runtime.InteropServices; +using System.Text.RegularExpressions; using System.Windows; +using System.Windows.Documents; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; @@ -38,9 +42,16 @@ namespace ChatController.Utilities return; } - var url = pathToProfilePicture; - - var client = new RestClient(url); + DownloadImage(pathToProfilePicture, imageSource => + { + cache.AddProfilePictureToCache(key, imageSource, pathToProfilePicture); + callback?.Invoke(imageSource); + }); + } + + private static void DownloadImage(string uri, Action callback) + { + var client = new RestClient(uri); var request = new RestRequest { ResponseWriter = stream => @@ -58,8 +69,6 @@ namespace ChatController.Utilities bitmap.EndInit(); bitmap.Freeze(); - cache.AddProfilePictureToCache(key, bitmap, pathToProfilePicture); - callback?.Invoke(bitmap); } }; @@ -70,6 +79,33 @@ namespace ChatController.Utilities client.ExecuteAsync(request, response => { /*Das übernimmt der ResponseWriter von oben*/ }); } + public static void DownloadUserProfilePictures(Dictionary userId2Uris) + { + var cache = OwnChatCache.GetInstance(); + + foreach(var id2Uri in userId2Uris) + { + var userProfilePicture = cache.GetUserProfilePictureFromCache(id2Uri.Key); + + if(userProfilePicture == null) + { + try + { + var uri = id2Uri.Value; + + DownloadImage(uri, profilePicture => + { + cache.AddUserProfilePictureToCache(profilePicture, id2Uri.Key, uri); + }); + } + catch(Exception) + { + + } + } + } + } + public static void DownloadImageAsync(string uri, string key, CacheCategory cacheCategory, Action callback) { if(string.IsNullOrEmpty(uri)) @@ -88,35 +124,11 @@ namespace ChatController.Utilities return; } - var url = uri; - var client = new RestClient(url); - var request = new RestRequest + DownloadImage(uri, imageSource => { - ResponseWriter = stream => - { - var bitmap = new BitmapImage(); - - var localStream = new MemoryStream(); - - stream.CopyTo(localStream); - - localStream.Position = 0; - - bitmap.BeginInit(); - bitmap.StreamSource = localStream; - bitmap.EndInit(); - bitmap.Freeze(); - - cache.AddImageToCache(key, bitmap, cacheCategory, uri); - - callback?.Invoke(bitmap); - } - }; - - request.AddHeader(Constants.Token, AuthToken); - request.AddHeader(Constants.CustomerId, Tenant); - - client.ExecuteAsync(request, response => { }); + cache.AddImageToCache(key, imageSource, cacheCategory, uri); + callback?.Invoke(imageSource); + }); } private static ImageSource GetDefaultImageSource(bool pIsGroup, bool pIsEmployee) @@ -438,5 +450,82 @@ namespace ChatController.Utilities return 100; } + + private static readonly Regex _UrlRegex = new Regex(@"(?#Protocol)(http(?:s?)\:(\/\/|\\\\)|(w){3}(2|3)?\.{1})(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + public static ObservableCollection ConvertLinksToHyperlinks(string messageText) + { + var result = new ObservableCollection(); + + if(messageText == null) + { + return result; + } + + var guidString = Guid.NewGuid().ToString(); + var replacementString = Guid.NewGuid().ToString(); + + var matches = _UrlRegex.Matches(messageText); + + var index2Link = new Dictionary(); + + for(var i = 0; i < matches.Count; i++) + { + var link = matches[i].Value; + + if(!link.Contains("http")) + { + link = $"http://{link}"; + } + + var hyperlink = new Hyperlink(new Run(link)) + { + NavigateUri = new Uri(link, UriKind.Absolute) + }; + + hyperlink.RequestNavigate += (s, e) => + { + Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); + e.Handled = true; + }; + + index2Link[i] = hyperlink; + } + + var splitMessage = _UrlRegex.Replace(messageText, replacementString + guidString).Split(new[] {guidString}, StringSplitOptions.None); + + var linkIndex = 0; + foreach(var text in splitMessage) + { + if(text.Equals(replacementString)) + { + result.Add(index2Link[linkIndex]); + linkIndex++; + } + else if(text.StartsWith(replacementString) || text.EndsWith(replacementString)) + { + var splitLine = text.Split(new[] { replacementString }, StringSplitOptions.None); + + foreach(var partLine in splitLine) + { + if(string.Empty.Equals(partLine)) + { + result.Add(index2Link[linkIndex]); + linkIndex++; + } + else + { + result.Add(new Run(partLine)); + } + } + } + else + { + result.Add(new Run(text)); + } + } + + return result; + } } } diff --git a/PrototypChat/.vs/PrototypChat/v16/.suo b/PrototypChat/.vs/PrototypChat/v16/.suo index 06aa56a..e198421 100644 Binary files a/PrototypChat/.vs/PrototypChat/v16/.suo and b/PrototypChat/.vs/PrototypChat/v16/.suo differ