Abruf der Nachrichten asynchron gemacht

Bilder werden im Cache gespeichert
This commit is contained in:
Lyndon Jetten
2021-07-14 19:33:50 +02:00
parent f707884585
commit b9b9caec58
14 changed files with 1003 additions and 864 deletions

View File

@@ -37,16 +37,13 @@
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="DevExpress.Mvvm.v17.1, Version=17.1.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\libs\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="RestSharp">
<HintPath>..\libs\RestSharp.dll</HintPath>
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\PrototypChat\packages\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -54,10 +51,6 @@
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
@@ -109,6 +102,7 @@
<Compile Include="Utilities\OwnChatEnums.cs" />
<Compile Include="Utilities\SyncFileInfoStruct.cs" />
<Compile Include="Utilities\Utils.cs" />
<Compile Include="Utilities\WpfUtils.cs" />
</ItemGroup>
<ItemGroup>
<Page Include="ChatEmojiiControl.xaml">
@@ -150,6 +144,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="ownchat_favicon.ico" />
<Resource Include="Ressourcen\ownchat_image_placeholder.png" />
<Resource Include="Ressourcen\warning-exclamation-mark.png" />
<None Include="packages.config" />
<None Include="Resources\oC-favico_NewMessage.ico" />

View File

@@ -9,8 +9,10 @@ using static System.Windows.HorizontalAlignment;
namespace ChatController.ChatKlassen
{
public class ChatMessage
public class ChatMessage : INotifyPropertyChanged
{
public long MessageId { get; set; }
public int TimeStringMaxWidth => IsSeparator ? int.MaxValue : 350;
public int MessageMaxWidth => IsSeparator ? int.MaxValue : 500;
@@ -32,67 +34,127 @@ namespace ChatController.ChatKlassen
}
//Chat-Ansicht
public ChatMessage(string username, string message, DateTime sendtime, bool isme, long pGroupId, long fileSize)
public ChatMessage(string username, string message, DateTime sendtime, bool isme, long groupId, long fileSize, long messageId)
{
MessageId = messageId;
Id = Guid.NewGuid();
Username = username;
UserMessage = message;
SendTime = sendtime;
IsMyMessage = isme;
GroupId = pGroupId;
GroupId = groupId;
MessageType = IsHyperlink(message) ? ChatMessageType.Hyperlink : ChatMessageType.Message;
}
// Image-Ansicht
public ChatMessage(string username, string message, DateTime sendtime, bool isme, ImageSource image, string originalImage, string imageName, long pGroupId, long fileSize)
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();
MessageId = messageId;
Id = Guid.NewGuid();
Username = username;
UserMessage = message;
SendTime = sendtime;
ImageSources = image;
IsMyMessage = isme;
OriginalImage = originalImage;
OriginalImageName = imageName;
GroupId = pGroupId;
GroupId = groupId;
MessageType = ChatMessageType.Image;
Utils.DownloadImageAsync(filePath, $"group-{groupId}", CacheCategory.Thumbnail, imageSource =>
{
PictureSource = imageSource;
});
}
//Dokumenten-Ansicht
public ChatMessage(string pUsername, string pMessageText, DateTime pSendTime, string pSmallerImagePath, bool pIsLoggedInUsersMessage, string pUrl, long pGroupId, long fileSize)
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 = pUsername;
UserMessage = pMessageText;
SendTime = pSendTime;
IsMyMessage = pIsLoggedInUsersMessage;
Username = username;
UserMessage = message;
SendTime = sendtime;
IsMyMessage = isme;
FilePath = pUrl;
FilePath = filePath;
var cache = OwnChatCache.GetInstance();
var imgSrc = cache.GetImageSourceFromCache($"group-{pGroupId}");
if(imgSrc == null)
Utils.DownloadImageAsync(thumbnailPath, $"group-{groupId}", CacheCategory.Thumbnail, imageSource =>
{
imgSrc = Utils.CreateImageSourceFromPath(pSmallerImagePath);
}
Thumbnail = imageSource;
});
Thumbnail = imgSrc;
GroupId = pGroupId;
GroupId = groupId;
MessageType = ChatMessageType.Document;
}
// 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;
Id = Guid.NewGuid();
Username = username;
UserMessage = message;
SendTime = sendtime;
IsMyMessage = isme;
OriginalImage = originalImage;
OriginalImageName = imageName;
GroupId = groupId;
MessageType = ChatMessageType.Image;
PictureSource = logo;
}
public ChatMessageType MessageType { get; }
public ImageSource Thumbnail { get; }
private ImageSource _Thumbnail;
public ImageSource Thumbnail
{
get => _Thumbnail;
set
{
if(!Equals(_Thumbnail, value))
{
_Thumbnail = value;
OnPropertyChanged(nameof(Thumbnail));
}
}
}
private int _ThumbnailPlaceholderHeight;
public int ThumbnailPlaceholderHeight
{
get => _ThumbnailPlaceholderHeight;
set
{
if(!Equals(_ThumbnailPlaceholderHeight, value))
{
_ThumbnailPlaceholderHeight = value;
OnPropertyChanged(nameof(ThumbnailPlaceholderHeight));
}
}
}
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})*)(?:&amp;(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?");
@@ -171,7 +233,33 @@ namespace ChatController.ChatKlassen
public Visibility DokumentVisibility => MessageType == ChatMessageType.Document ? Visibility.Visible : Visibility.Collapsed;
public ImageSource ImageSources { get; }
private ImageSource _PictureSource;
public ImageSource PictureSource
{
get => _PictureSource;
set
{
if(!Equals(_PictureSource, value))
{
_PictureSource = value;
OnPropertyChanged(nameof(PictureSource));
}
}
}
private int _PicturePlaceholderHeight;
public int PicturePlaceholderHeight
{
get => _PicturePlaceholderHeight;
set
{
if (!Equals(_PicturePlaceholderHeight, value))
{
_PicturePlaceholderHeight = value;
OnPropertyChanged(nameof(PicturePlaceholderHeight));
}
}
}
public object FilePath { get; }
@@ -217,7 +305,7 @@ namespace ChatController.ChatKlassen
return SendTime == message.SendTime;
}
return message.Id.Equals(Id);
return MessageId.Equals(message.MessageId);
}
return false;

View File

@@ -1,8 +1,8 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Media;
using ChatController.LoginKlassen;
using ChatController.Utilities;
using Brush = System.Windows.Media.Brush;
namespace ChatController.ChatKlassen
@@ -60,7 +60,19 @@ namespace ChatController.ChatKlassen
}
}
public ImageSource Image { get; }
private ImageSource _Image;
public ImageSource Image
{
get => _Image;
set
{
if(!Equals(_Image, value))
{
_Image = value;
OnPropertyChanged(nameof(Image));
}
}
}
public DateTime TimeStamp { get; set; }
@@ -70,9 +82,7 @@ namespace ChatController.ChatKlassen
public bool IsChatMessageInputGridVisible { get; }
public Bitmap ProfilePicture { get; }
public Contact(string pName, GroupLatestMessage pLatestMessage, DateTime pTimeStamp, int pGroupId, string pUserIdManage, bool pOnlyEmployees, int pUserCount, bool isChatMessageInputGridVisible, string accentColorBrushString, Bitmap profilePicture, ImageSource image)
public Contact(string pName, GroupLatestMessage pLatestMessage, DateTime pTimeStamp, int pGroupId, string pUserIdManage, bool pOnlyEmployees, int pUserCount, bool isChatMessageInputGridVisible, string accentColorBrushString, string profilePicturePath, string key)
{
Name = pName;
ReceivedMessage = pLatestMessage;
@@ -81,8 +91,6 @@ namespace ChatController.ChatKlassen
UserIdManage = pUserIdManage;
HasUnreadMessages = false;
ProfilePicture = profilePicture;
IsChatMessageInputGridVisible = isChatMessageInputGridVisible;
if(accentColorBrushString == null)
@@ -103,7 +111,10 @@ namespace ChatController.ChatKlassen
AccentColorBrush = new BrushConverter().ConvertFromString($"#{accentColorBrushString}") as SolidColorBrush;
Image = image;
Utils.DownloadProfilePictureAsync(profilePicturePath, key, delegate(ImageSource imageSource)
{
Image = imageSource;
});
}
public override bool Equals(object obj)
@@ -122,7 +133,6 @@ namespace ChatController.ChatKlassen
return Name == y.Name &&
IsNewMessage == y.IsNewMessage &&
Equals(ProfilePicture, y.ProfilePicture) &&
TimeStamp.Equals(y.TimeStamp) &&
GroupId == y.GroupId &&
UserIdManage == y.UserIdManage &&
@@ -138,7 +148,6 @@ namespace ChatController.ChatKlassen
{
var hashCode = Name != null ? Name.GetHashCode() : 0;
hashCode = (hashCode * 397) ^ (ProfilePicture != null ? ProfilePicture.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ GroupId;
hashCode = (hashCode * 397) ^ (UserIdManage != null ? UserIdManage.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ IsChatMessageInputGridVisible.GetHashCode();

View File

@@ -89,7 +89,7 @@
</Grid.ColumnDefinitions>
<Ellipse Grid.Column="1" Width='32' Height='32' RenderOptions.BitmapScalingMode="HighQuality">
<Ellipse.Fill>
<ImageBrush ImageSource='{Binding Image}' Stretch='UniformToFill' RenderOptions.BitmapScalingMode="HighQuality" />
<ImageBrush ImageSource='{Binding Image, UpdateSourceTrigger=PropertyChanged}' Stretch='UniformToFill' RenderOptions.BitmapScalingMode="HighQuality" />
</Ellipse.Fill>
</Ellipse>
<Grid Grid.Column="3" >
@@ -148,6 +148,12 @@
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- /Gruppensuchtemplate -->
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}" />
<Setter Property="Width" Value="12" />
<Setter Property="Height" Value="40" />
</Style>
</UserControl.Resources>
<Grid x:Name="RootGrid">
<Border x:Name="rootBorder" Background="{StaticResource DarkBackColor}" Padding="0" Margin="0" BorderThickness="0">
@@ -226,11 +232,22 @@
<TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="8" TextWrapping="Wrap" Text="{Binding CurrentContactInformationString}" FontSize="16" Foreground="{Binding CurrencContactInfoForeground}" />
</Grid>
<ListBox x:Name="ChatListBox" ItemsSource="{Binding CurrentChatMessages, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch" ScrollViewer.CanContentScroll="False" VerticalAlignment="Stretch" Grid.Row="1"
VirtualizingStackPanel.IsVirtualizing="True" BorderThickness="0" VirtualizingStackPanel.VirtualizationMode="Recycling" SelectionMode="Extended"
MouseDoubleClick="Chat_OnMouseDoubleClick" ScrollViewer.ScrollChanged="Chat_OnScrollChanged" Background="{StaticResource LightBackColor}"
ContextMenuOpening="Chat_OnContextMenuOpening" Padding="20" d:DataContext="{d:DesignData ChatMessage}">
<ListBox x:Name="ChatListBox"
ItemsSource="{Binding ChatMessages, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch"
ScrollViewer.CanContentScroll="False"
VerticalAlignment="Stretch"
Grid.Row="1"
VirtualizingStackPanel.IsVirtualizing="True"
BorderThickness="0"
VirtualizingStackPanel.VirtualizationMode="Recycling"
SelectionMode="Extended"
MouseDoubleClick="Chat_OnMouseDoubleClick"
ScrollViewer.ScrollChanged="Chat_OnScrollChanged"
Background="{StaticResource LightBackColor}"
ContextMenuOpening="Chat_OnContextMenuOpening"
Padding="20"
d:DataContext="{d:DesignData ChatMessage}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="{Binding HorizontalAlignmentValue}" />
@@ -306,7 +323,7 @@
</StackPanel>
<DockPanel DockPanel.Dock="Bottom" Visibility="{Binding PictureVisibility}" >
<StackPanel Orientation="Vertical">
<Image MaxWidth="300" Source="{Binding ImageSources}" x:Name="imgChatMessage" Stretch="UniformToFill"/>
<Image MaxWidth="300" Height="{Binding PicturePlaceholderHeight, UpdateSourceTrigger=PropertyChanged}" Source="{Binding PictureSource, UpdateSourceTrigger=PropertyChanged}" x:Name="imgChatMessage" Stretch="UniformToFill"/>
<TextBlock Text="{Binding UserMessage}" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="14"/>
</StackPanel>
</DockPanel>
@@ -318,7 +335,8 @@
</DockPanel>
<DockPanel DockPanel.Dock="Bottom" Visibility="{Binding DokumentVisibility}" >
<StackPanel Orientation="Vertical">
<Image ToolTip="Dokument öffnen" Height="100" Width="150" Source="{Binding Path=Thumbnail}" Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Center" />
<!-- Platzhalter mit Höhe 100 -->
<Image ToolTip="Dokument öffnen" Height="{Binding ThumbnailPlaceholderHeight, UpdateSourceTrigger=PropertyChanged}" Width="150" Source="{Binding Path=Thumbnail}" Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Center" />
<TextBlock Margin="2,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding UserMessage}" FontSize="14"/>
</StackPanel>
</DockPanel>
@@ -351,13 +369,14 @@
Visibility="Visible"
BorderThickness="0"
VerticalContentAlignment="Top"
MinHeight="25" MaxHeight="200"
MinHeight="69" MaxHeight="200"
FontSize="15"
Padding="2"
ToolTip="Schreiben Sie hier eine Nachricht hinein"
Margin="2"
VerticalAlignment="Stretch"
GotFocus="Chatbox_OnGotFocus"
AcceptsReturn="True"
KeyDown="Chatbox_OnKeyDownHandler"
TextChanged="Chatbox_OnTextChanged">
<TextBox.Resources>

View File

@@ -5,7 +5,6 @@ using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
@@ -90,11 +89,9 @@ namespace ChatController
}
}
private Chat _Chat;
public Chat Chat { get; set; }
private Contact _CurrentContact;
public ObservableCollection<ChatMessage> CurrentChatMessages => _CurrentContact != null && _Chat != null ? new ObservableCollection<ChatMessage>(_Chat.Messages) : new ObservableCollection<ChatMessage>();
public Contact CurrentContact
{
get => _CurrentContact;
@@ -107,7 +104,7 @@ namespace ChatController
OnPropertyChanged(nameof(CurrentContact));
OnPropertyChanged(nameof(ChatMessageInputGridVisibility));
OnPropertyChanged(nameof(CurrentChatMessages));
OnPropertyChanged(nameof(Chat));
OnPropertyChanged(nameof(CurrentContactInformationString));
OnPropertyChanged(nameof(CurrencContactInfoForeground));
OnPropertyChanged(nameof(ThreadExceptionImageSource));
@@ -156,6 +153,13 @@ namespace ChatController
_ThreadExceptionImageSource = new BitmapImage(new Uri("pack://application:,,,/ChatController;component/Ressourcen/warning-exclamation-mark.png", UriKind.Absolute));
_ChatMessages = new ObservableCollection<ChatMessage>();
ChatMessages = CollectionViewSource.GetDefaultView(_ChatMessages) as ListCollectionView;
if (ChatMessages != null)
{
ChatMessages.CustomSort = new ChatMessageComparer();
}
DataContext = this;
ReloadGruppen.Visibility = Visibility.Collapsed;
@@ -171,9 +175,12 @@ namespace ChatController
_IsInBackground = false;
}
private readonly ObservableCollection<ChatMessage> _ChatMessages;
public ListCollectionView ChatMessages { get; set; }
public void InitMitChatdaten(ChatDatenUebergabe cdu)
{
_Chat = new Chat(cdu, exception => {
Chat = new Chat(cdu, exception => {
this.Dispatch(
() => {
EndWaiting();
@@ -193,7 +200,10 @@ namespace ChatController
});
});
_ContactList = _Chat.AddContacts();
OnPropertyChanged(nameof(Chat));
_ContactList = Chat.AddContacts();
OnPropertyChanged(nameof(ContactList));
ReadNewSyncFile();
@@ -202,11 +212,8 @@ namespace ChatController
{
if (_GroupId2DateTime.ContainsKey(contact.GroupId))
{
var dateTimeFromFile = _GroupId2DateTime[contact.GroupId].TimeStamp;
var isUnread = _GroupId2DateTime[contact.GroupId].IsUnread;
var isYounger = contact.TimeStamp > dateTimeFromFile;
contact.IsNewMessage = isUnread;
contact.HasUnreadMessages = contact.IsNewMessage;
}
@@ -301,19 +308,18 @@ namespace ChatController
{
if(e.ClickCount == 2)
{
_Chat.ShowProfilePicture(_CurrentContact);
Chat.ShowProfilePicture(_CurrentContact);
}
}
private void Clientlist_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(Clientlist?.SelectedItem != null && Clientlist?.SelectedItem is Contact selectedContact)
if(Clientlist?.SelectedItem is Contact selectedContact)
{
SelectContact(selectedContact);
}
}
// WebRequest: LoadChatMessagesForContact
private void SelectContact(Contact pContact)
{
if(pContact == null)
@@ -323,7 +329,8 @@ namespace ChatController
ShouldInterruptContactsThread = true;
Cursor = Cursors.Wait;
StartWaitingImmediately();
_ScrollPrueferAktivieren = false;
if (pContact.HasUnreadMessages)
@@ -339,7 +346,7 @@ namespace ChatController
var shouldChangeIcon = _ContactList.Any(contact => contact.IsNewMessage);
if(shouldChangeIcon)
{
ContainingWindow.Icon = Utils.GetImageSourceFromIcon(Resource.ownchat_favicon);
ContainingWindow.Icon = Utils.ConvertIconToImageSource(Resource.ownchat_favicon);
}
CurrentContact = currentContact;
@@ -349,18 +356,17 @@ namespace ChatController
Clientlist.SelectedItem = pContact;
}
var chatMessages = _Chat.LoadChatMessagesForContact(currentContact);
_ChatMessages.Clear();
OnPropertyChanged(nameof(CurrentChatMessages));
if (VisualTreeHelper.GetChildrenCount(ChatListBox) > 0)
Chat.LoadChatMessagesForContactAsync(currentContact, GetFirstMessage(), chatMessages =>
{
var border = (Border) VisualTreeHelper.GetChild(ChatListBox, 0);
var scrollViewer = (ScrollViewer) VisualTreeHelper.GetChild(border, 0);
scrollViewer.ScrollToBottom();
}
this.Dispatch(() =>
{
_ChatMessages.AddRangeIfElementsNotIn(chatMessages);
ChatListBox.ContextMenu = _Chat.ErstelleKontextMenue();
WpfUtils.ScrollToBottomOfListBox(ChatListBox);
ChatListBox.ContextMenu = Chat.ErstelleKontextMenue();
SetContextHandler();
_ScrollPrueferAktivieren = true;
@@ -370,6 +376,10 @@ namespace ChatController
WriteToNewSyncFile();
ShouldInterruptContactsThread = false;
EndWaiting();
});
});
}
private void SetContextHandler()
@@ -423,13 +433,13 @@ namespace ChatController
{
var chatMessage = (ChatMessage) items;
_Chat.SaveFileAs(chatMessage);
Chat.SaveFileAs(chatMessage);
}
}
private void PasteOnClick(object sender, RoutedEventArgs routedEventArgs)
{
_Chat.Paste(CurrentContact.GroupId,this);
Chat.Paste(CurrentContact.GroupId,this);
}
private void CopyOnClick(object sender, RoutedEventArgs routedEventArgs)
@@ -445,7 +455,7 @@ namespace ChatController
if(!string.IsNullOrWhiteSpace(chatMessages))
{
_Chat.Copy(chatMessages, 1);
Chat.Copy(chatMessages, 1);
}
}
@@ -462,8 +472,8 @@ namespace ChatController
{
foreach(var items in chatMessages)
{
var item = items as ChatMessage;
if(item?.ImageSources != null)
var item = (ChatMessage) items;
if(item?.PictureSource != null)
{
if(ChatListBox.ContextMenu != null)
{
@@ -478,7 +488,7 @@ namespace ChatController
ContextItemSpeichernUnter.Visibility = Visibility.Collapsed;
}
if(item.ImageSources == null && item.FilePath == null)
if(item.PictureSource == null && item.FilePath == null)
{
var contextItems = ChatListBox.ContextMenu.Items;
var ContextItemSpeichernUnter = (MenuItem)contextItems[2];
@@ -553,30 +563,31 @@ namespace ChatController
{
if(CurrentContact != null)
{
var fileToOpen = _Chat.OpenFile();
var fileToOpen = Chat.OpenFile();
if(fileToOpen != null)
{
var filePath = FileUtils.ScaleImage(fileToOpen, Path.GetExtension(fileToOpen.ToUpperInvariant()), _Chat.ChatDaten.MaxUploadSize);
var filePath = FileUtils.ScaleImage(fileToOpen, Path.GetExtension(fileToOpen.ToUpperInvariant()), Chat.ChatDaten.MaxUploadSize);
var isFileSizeTooLarge = FileUtils.CheckFileSize(filePath, _Chat.ChatDaten.MaxUploadSize);
var isFileSizeTooLarge = FileUtils.CheckFileSize(filePath, Chat.ChatDaten.MaxUploadSize);
if(isFileSizeTooLarge)
{
MessageBox.Show($"Die ausgewählte Datei ist zu groß. Die maximale Größe beträgt {_Chat.ChatDaten.MaxUploadSize / 1000 / 1000} MB", "Senden nicht möglich", MessageBoxButton.OK, MessageBoxImage.Warning);
MessageBox.Show($"Die ausgewählte Datei ist zu groß. Die maximale Größe beträgt {Chat.ChatDaten.MaxUploadSize / 1000 / 1000} MB", "Senden nicht möglich", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (!string.IsNullOrWhiteSpace(filePath))
{
_Chat.AddNewFile(filePath, fileToOpen, CurrentContact.GroupId);
_ChatMessages.AddRangeIfElementsNotIn(Chat.AddNewFile(filePath, fileToOpen, CurrentContact.GroupId, GetFirstMessage()));
OnPropertyChanged(nameof(CurrentChatMessages));
ChatMessages.MoveCurrentToLast();
ChatListBox.Items.MoveCurrentToLast();
ChatListBox.ScrollIntoView(ChatListBox.Items.CurrentItem);
var currentChatMessage = ChatMessages.CurrentItem;
_Chat.SendFileToContact(CurrentContact, filePath,fileToOpen);
ChatListBox.ScrollIntoView(currentChatMessage);
Chat.SendFileToContact(CurrentContact, filePath,fileToOpen);
if (!string.IsNullOrWhiteSpace(filePath) && !filePath.Equals(fileToOpen) && File.Exists(filePath))
{
@@ -595,14 +606,15 @@ namespace ChatController
{
if(CurrentContact != null && !string.IsNullOrEmpty(Chatbox.Text))
{
_Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId);
_ChatMessages.AddRangeIfElementsNotIn(Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId, GetFirstMessage()));
OnPropertyChanged(nameof(CurrentChatMessages));
ChatMessages.MoveCurrentToLast();
ChatListBox.Items.MoveCurrentToLast();
ChatListBox.ScrollIntoView(ChatListBox.Items.CurrentItem);
ChatListBox.ScrollIntoView(ChatMessages.CurrentItem);
_Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId);
WpfUtils.ScrollToBottomOfListBox(ChatListBox);
Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId);
Chatbox.Text = string.Empty;
}
@@ -621,22 +633,22 @@ namespace ChatController
{
try
{
if (e.Key == Key.Return)
{
if(CurrentContact != null && !string.IsNullOrEmpty(Chatbox.Text))
{
_Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId);
//if (e.Key == Key.Return)
//{
// if(CurrentContact != null && !string.IsNullOrEmpty(Chatbox.Text))
// {
// Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId);
OnPropertyChanged(nameof(CurrentChatMessages));
// OnPropertyChanged(nameof(CurrentChatMessages));
ChatListBox.Items.MoveCurrentToLast();
ChatListBox.ScrollIntoView(ChatListBox.Items.CurrentItem);
// ChatListBox.Items.MoveCurrentToLast();
// ChatListBox.ScrollIntoView(ChatListBox.Items.CurrentItem);
_Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId);
// Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId);
Chatbox.Text = string.Empty;
}
}
// Chatbox.Text = string.Empty;
// }
//}
}
catch (Exception ed)
{
@@ -669,7 +681,6 @@ namespace ChatController
}
}
// TODO: Asynchron machen?
private void VerticalScrollbarChanged(object sender, RoutedPropertyChangedEventArgs<double> routedPropertyChangedEventArgs)
{
if (_ScrollPrueferAktivieren)
@@ -678,25 +689,27 @@ namespace ChatController
if (!(scrollBar.Value > 0))
{
Cursor = Cursors.Wait;
StartWaitingImmediately();
_ScrollPrueferAktivieren = false;
ChatListBox.Items.MoveCurrentToFirst();
var currentChatMessage = ChatListBox.Items.CurrentItem as ChatMessage;
ChatMessages.MoveCurrentToFirst();
var kontakt = (Contact) Clientlist.SelectedItem;
var currentChatMessage = ChatMessages.CurrentItem;
_Chat.LoadMoreMessages(kontakt); // Ab hier käme das ins Callback
var selectedContact = (Contact) Clientlist.SelectedItem;
OnPropertyChanged(nameof(CurrentChatMessages));
if(currentChatMessage != null)
Chat.LoadMoreMessagesAsync(selectedContact, GetFirstMessage(), chatMessages =>
{
ChatListBox.ScrollIntoView(currentChatMessage);
}
this.Dispatch(() =>
{
EndWaiting();
Cursor = Cursors.Arrow;
_ChatMessages.AddRangeIfElementsNotIn(chatMessages);
ChatListBox.ScrollIntoView(currentChatMessage);
});
});
}
}
}
@@ -726,24 +739,20 @@ namespace ChatController
private void ListenGloballyForMessages()
{
var numberOfNewMessages = _Chat.GetNumberOfAllNewMessages();
if (numberOfNewMessages > 0)
Chat.GetNumberOfAllNewMessagesAsync(newMessagesCount =>
{
Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
(Action)delegate
if(newMessagesCount > 0)
{
var contacts = _Chat.NeueGroupklassenKontakte().ToList();
Chat.UpdateContactList(updatedContactList =>
{
var updatedContacts = updatedContactList.ToList();
this.Dispatch(() =>
{
foreach (var contact in _ContactList)
{
foreach (var newContact in contacts)
foreach (var newContact in updatedContacts)
{
if(newContact == null)
{
continue;
}
if (contact.GroupId == newContact.GroupId)
{
@@ -755,7 +764,7 @@ namespace ChatController
var selectedContact = (Contact)Clientlist.SelectedItem;
// Angemeldeter Benutzer
var userOid = _Chat.ChatDaten.LoggedInUser.Response.User.Oid;
var userOid = Chat.ChatDaten.LoggedInUser.Response.User.Oid;
var senderId = contact.ReceivedMessage?.UserId;
var receiverId = userOid;
@@ -766,7 +775,7 @@ namespace ChatController
{
if (ContainingWindow != null)
{
ContainingWindow.Icon = Utils.GetImageSourceFromIcon(Resource.oC_favico_NewMessage);
ContainingWindow.Icon = Utils.ConvertIconToImageSource(Resource.oC_favico_NewMessage);
}
ShowNotification(newContact.Name, newContact.ReceivedMessage, newContact.GroupId);
@@ -784,14 +793,9 @@ namespace ChatController
}
}
}
if (!_ContactList.Contains(newContact))
{
_ContactList.ToList().Add(newContact);
}
}
if (!contacts.Contains(contact))
if (!updatedContacts.Contains(contact))
{
_ContactList.ToList().Remove(contact);
}
@@ -799,7 +803,9 @@ namespace ChatController
Clientlist.Items.Refresh();
});
});
}
});
}
private void InitListeningThread(Contact currentContact)
@@ -819,27 +825,29 @@ namespace ChatController
{
if (!ShouldInterruptContactsThread)
{
var hasNewMessages = _Chat.CheckIfNewMessagesExist(pCurrentContact);
if (hasNewMessages)
Chat.CheckIfNewMessagesExistAsync(CurrentContact.GroupId, hasNewMessages =>
{
Dispatcher.BeginInvoke(DispatcherPriority.Background,
(Action)delegate
if(!hasNewMessages)
{
_Chat.LoadChatMessagesForContact(pCurrentContact);
OnPropertyChanged(nameof(CurrentChatMessages));
ChatListBox.Items.MoveCurrentToLast();
ChatListBox.ScrollIntoView(ChatListBox.Items.CurrentItem);
});
return;
}
Chat.LoadChatMessagesForContactAsync(pCurrentContact, GetFirstMessage(), chatMessages =>
{
this.Dispatch(() =>
{
_ChatMessages.Clear();
_ChatMessages.AddRangeIfElementsNotIn(chatMessages);
WpfUtils.ScrollToBottomOfListBox(ChatListBox);
});
});
});
}
}
private void Suche_OnTextChanged(object sender, TextChangedEventArgs e)
{
OnPropertyChanged(nameof(CurrentChatMessages));
CollectionViewSource.GetDefaultView(Clientlist.ItemsSource).Refresh();
}
@@ -855,69 +863,70 @@ namespace ChatController
private void Chat_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
Cursor = Cursors.Wait;
var chatItems = ChatListBox.SelectedItems;
if (chatItems.Count > 0)
if(ChatListBox.SelectedItems.Count > 0)
{
foreach (var items in chatItems)
{
var item = items as ChatMessage;
var selectedItem = ChatListBox.SelectedItems[0];
if (item?.OriginalImage != null)
if(selectedItem is ChatMessage selectedMessage)
{
if(!string.IsNullOrEmpty(selectedMessage.OriginalImage))
{
StartWaitingImmediately();
_Chat.ShowPicture(item.OriginalImage, EndWaiting);
}
else if(item?.FilePath != null)
Chat.ShowPicture(selectedMessage.OriginalImage, CurrentContact.GroupId, (imageSource, windowTitle) =>
{
var filename = Path.GetFileName(item.FilePath.ToString());
LoadDocument(item.FilePath.ToString(), filename);
this.Dispatch(() =>
{
EndWaiting();
Chat.ShowPictureWindow(imageSource, windowTitle);
});
});
}
else if(selectedMessage.FilePath != null)
{
StartWaitingImmediately();
LoadDocumentAsync(selectedMessage.FilePath.ToString(), Path.GetFileName(selectedMessage.FilePath.ToString()), EndWaiting);
}
}
}
}
Cursor = Cursors.Arrow;
}
else
{
Cursor = Cursors.Arrow;
}
}
private void LoadDocument(string link, string filename)
private void LoadDocumentAsync(string uri, string fileName, Action callback)
{
try
{
StartWaiting();
var path = Path.Combine(Path.GetTempPath(), fileName);
var path = Path.Combine(Path.GetTempPath(), filename);
_CreatedTempFiles.Add(path);
if(!File.Exists(path))
{
using (var webClient = new WebClient())
Chat.DownloadFileAsync(uri, path, () =>
{
this.Dispatch(() =>
{
webClient.DownloadFile(link, path);
}
if (File.Exists(path))
{
Process.Start(path);
}
callback?.Invoke();
});
});
}
else
{
Process.Start(path);
}
}
catch (Exception e)
{
callback?.Invoke();
}
finally
}
catch(Exception exception)
{
EndWaiting();
MessageBox.Show(exception.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
@@ -973,11 +982,11 @@ namespace ChatController
WriteToNewSyncFile();
_Chat.ReloadGroupsAsync(data =>
Chat.ReloadGroupsAsync(data =>
{
this.Dispatch(() =>
{
_ContactList = _Chat.GroupklassenAktuallisieren(data); // <- dauert eine Sekunde!
_ContactList = Chat.UpdateContacts(data); // <- dauert eine Sekunde!
OnPropertyChanged(nameof(ContactList));
ReadNewSyncFile();
@@ -1066,7 +1075,7 @@ namespace ChatController
}
}
_Chat.LastTimeStamp = latestDateTime.GetUnixTimeStamp();
Chat.LastTimeStamp = latestDateTime.GetUnixTimeStamp();
}
}
catch (Exception e)
@@ -1184,5 +1193,15 @@ namespace ChatController
Chatbox.Height = 25;
}
}
public void AddMessages(List<ChatMessage> newMessages)
{
_ChatMessages.AddRangeIfElementsNotIn(newMessages);
}
public ChatMessage GetFirstMessage()
{
return _ChatMessages.FirstOrDefault();
}
}
}

View File

@@ -1,17 +1,15 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Media;
namespace ChatController.Core
{
public class OwnChatCache
{
// Key-> "group-127" oder "user-938"
private Dictionary<string, ImageSourceCacheObject> _ImageSources = new Dictionary<string, ImageSourceCacheObject>();
private static readonly object _Lock = new object();
// Key-> "group-127" oder "user-938"
private Dictionary<string, BitmapCacheObject> _Bitmaps = new Dictionary<string, BitmapCacheObject>();
private Dictionary<string, ImageSourceCacheStorage> _ImageSourceCache = new Dictionary<string, ImageSourceCacheStorage>();
private static OwnChatCache _Instance;
@@ -25,109 +23,156 @@ namespace ChatController.Core
public void ClearAll()
{
ClearImageSources();
ClearBitmaps();
}
public void ClearImageSources()
{
_ImageSources.Clear();
lock(_Lock)
{
_ImageSourceCache.Clear();
}
}
public void ClearBitmaps()
public ImageSource GetImageSourceFromCache(string key, string name, CacheCategory cacheCategory)
{
_Bitmaps.Clear();
}
public ImageSource GetImageSourceFromCache(string key)
lock(_Lock)
{
if(key == null || _ImageSources == null || !_ImageSources.ContainsKey(key))
if(key == null || _ImageSourceCache == null || !_ImageSourceCache.ContainsKey(key))
{
return null;
}
var imageSourceCacheObject = _ImageSources[key];
var imageSourceCacheObject = _ImageSourceCache[key].GetCachedImageSource(cacheCategory, name);
var expirationDate = imageSourceCacheObject.ExpirationDate;
return expirationDate < DateTime.Now ? null : imageSourceCacheObject.Image;
}
public void AddImageToCache(string key, ImageSource imageSource)
{
if(_ImageSources == null)
{
_ImageSources = new Dictionary<string, ImageSourceCacheObject>();
}
var newImageSourceCacheObject = new ImageSourceCacheObject(imageSource);
if(_ImageSources.ContainsKey(key))
{
_ImageSources[key] = newImageSourceCacheObject;
}
else
{
_ImageSources.Add(key, newImageSourceCacheObject);
return imageSourceCacheObject?.Image;
}
}
public Bitmap GetBitmapFromCache(string key)
public void AddImageToCache(string key, ImageSource imageSource, CacheCategory cacheCategory, string name)
{
if(key == null || _Bitmaps == null || !_Bitmaps.ContainsKey(key))
lock(_Lock)
{
if(_ImageSourceCache == null)
{
_ImageSourceCache = new Dictionary<string, ImageSourceCacheStorage>();
}
if(!_ImageSourceCache.ContainsKey(key))
{
_ImageSourceCache.Add(key, new ImageSourceCacheStorage());
}
_ImageSourceCache[key].AddImageSourceToCachedObjects(imageSource, cacheCategory, name);
}
}
public void AddProfilePictureToCache(string key, ImageSource imageSource)
{
lock(_Lock)
{
if(!_ImageSourceCache.ContainsKey(key))
{
_ImageSourceCache.Add(key, new ImageSourceCacheStorage());
}
_ImageSourceCache[key].SetCachedProfilePicture(imageSource);
}
}
public ImageSource GetCachedProfilePicture(string key)
{
lock(_Lock)
{
return _ImageSourceCache.ContainsKey(key) ?
_ImageSourceCache[key].GetCachedProfilePicture() :
null;
}
}
}
public class ImageSourceCacheStorage
{
private ImageSourceCacheObject _ProfilePicture;
public ImageSource GetCachedProfilePicture()
{
return _ProfilePicture?.ExpirationDate > DateTime.Now ? _ProfilePicture.Image : null;
}
public void SetCachedProfilePicture(ImageSource avatarImageSource)
{
if(avatarImageSource != null)
{
_ProfilePicture = new ImageSourceCacheObject(avatarImageSource, CacheCategory.ProfilePicture);
}
}
public Dictionary<CacheCategory, Dictionary<string, ImageSourceCacheObject>> CachedObjects { get; set; }
public ImageSourceCacheStorage()
{
CachedObjects = new Dictionary<CacheCategory, Dictionary<string, ImageSourceCacheObject>>();
}
public ImageSourceCacheObject GetCachedImageSource(CacheCategory cacheCategory, string name)
{
if(CachedObjects.ContainsKey(cacheCategory) && CachedObjects[cacheCategory].ContainsKey(name))
{
var imageSourceCacheObject = CachedObjects[cacheCategory][name];
return imageSourceCacheObject?.ExpirationDate > DateTime.Now ? imageSourceCacheObject : null;
}
return null;
}
var bitmapCacheObject = _Bitmaps[key];
var expirationDate = bitmapCacheObject.ExpirationDate;
return expirationDate < DateTime.Now ? null : bitmapCacheObject.Bitmap;
public void AddImageSourceToCachedObjects(ImageSource imageSource, CacheCategory cacheCategory, string name)
{
if(CachedObjects == null)
{
CachedObjects = new Dictionary<CacheCategory, Dictionary<string, ImageSourceCacheObject>>();
}
public void AddBitmapToCache(string key, Bitmap bitmap)
{
if(_Bitmaps == null)
{
_Bitmaps = new Dictionary<string, BitmapCacheObject>();
}
var newImageSourceCacheObject = new ImageSourceCacheObject(imageSource, cacheCategory);
var newBitmapCacheObject = new BitmapCacheObject(bitmap);
if(_Bitmaps.ContainsKey(key))
if(CachedObjects.ContainsKey(cacheCategory) )
{
_Bitmaps[key] = newBitmapCacheObject;
if (CachedObjects[cacheCategory].ContainsKey(name))
{
CachedObjects[cacheCategory][name] = newImageSourceCacheObject;
}
else
{
_Bitmaps.Add(key, newBitmapCacheObject);
CachedObjects[cacheCategory].Add(name, newImageSourceCacheObject);
}
}
else
{
CachedObjects.Add(cacheCategory, new Dictionary<string, ImageSourceCacheObject> {{name, newImageSourceCacheObject } });
}
}
}
public class ImageSourceCacheObject
{
public CacheCategory CacheCategory { get; }
public DateTime ExpirationDate { get; }
public ImageSource Image { get; }
public ImageSourceCacheObject(ImageSource imageSource)
public ImageSourceCacheObject(ImageSource imageSource, CacheCategory cacheCategory)
{
ExpirationDate = DateTime.Now.AddYears(1);
Image = imageSource;
CacheCategory = cacheCategory;
}
}
public class BitmapCacheObject
public enum CacheCategory
{
public DateTime ExpirationDate { get; }
public Bitmap Bitmap { get; }
public BitmapCacheObject(Bitmap bitmap)
{
ExpirationDate = DateTime.Now.AddYears(1);
Bitmap = bitmap;
}
ProfilePicture,
Thumbnail,
MessageAttachment
}
}

View File

@@ -1,8 +1,9 @@
using ChatController.ChatKlassen;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
@@ -12,26 +13,30 @@ using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Web;
using System.Windows;
using System.Windows.Controls;
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;
using ChatController.Utilities;
using ChatController.Utilities.Extensions;
using RestSharp;
using RestSharp.Extensions.MonoHttp;
using Application = System.Windows.Forms.Application;
using RestSharp.Extensions;
using Clipboard = System.Windows.Forms.Clipboard;
using ContextMenu = System.Windows.Controls.ContextMenu;
using DataFormats = System.Windows.Forms.DataFormats;
using Image = System.Drawing.Image;
using MessageBox = System.Windows.MessageBox;
using Size = System.Drawing.Size;
namespace ChatController.HauptKlassen
{
// Ist quasi das ViewModel
public class Chat
{
public Action<Exception> ExceptionCallback { get; set; }
@@ -39,8 +44,6 @@ namespace ChatController.HauptKlassen
private readonly List<Contact> _Contacts = new List<Contact>();
public List<ChatMessage> Messages { get; set; } = new List<ChatMessage>();
public ChatDatenUebergabe ChatDaten { get; set; }
private UserMessages _UserMessages;
@@ -103,93 +106,46 @@ namespace ChatController.HauptKlassen
private const string PubKeyE1 = "04245C2DA22AFD1C4BA65D97732731ACB2A06962EF65E8A6B0F0AC4B9FFF1C0B700FD3982F4DFC0F009B37F074055732972E05EF2A4325A3FB6E342713F64F7E69D302995EEB244792C1249BE6B1218FC12481FC68CC1F69BA58F51922F774C616";
// WebRequest
public List<Contact> AddContacts()
{
_Contacts.AddRange(GenerateContactsFromServerResponse(ChatDaten.AlleGruppen.Response.Groups.ToArray(), true));
var groupInputs = ChatDaten?.AlleGruppen?.Response?.Groups?.ToArray() ?? new GroupInput[0];
_Contacts.AddRange(GenerateContactsFromServerResponse(groupInputs, true));
return _Contacts;
}
public IOrderedEnumerable<ChatMessage> LoadChatMessagesForContact(Contact currentContact)
// Klick auf Kontakt. Die Collection muss davor geleert werden.
// Führt zu doppelter neuester Nachricht, wenn man vorher eine verschickt hat!
public void LoadChatMessagesForContactAsync(Contact contact, ChatMessage previousMessage, Action<List<ChatMessage>> callback)
{
if (currentContact != null)
if(contact != null)
{
LoadMessagesFromServer(currentContact.GroupId);
Messages.Clear();
LoadMessagesFromServerAsync(contact.GroupId, delegate
{
callback?.Invoke(AddMessagesFromServerResponse(_UserMessages.Response.Messages, previousMessage));
});
AddMessagesFromServerResponse(_UserMessages.Response.Messages);
return;
}
return Messages.OrderBy(r => r.SendTime);
callback?.Invoke(new List<ChatMessage>());
}
// WebRequest
private ImageSource DownloadImage(string pUri)
private void LoadMessagesFromServerAsync(long groupId, Action callback)
{
try
{
return DownloadImageWithRestRequest(pUri);
}
catch (Exception exception)
{
ExceptionCallback?.Invoke(exception);
return null;
}
}
var url = $"{ChatDaten.ServerUrl}{Constants.LoadMessagesForGroupUrl}{groupId}";
private ImageSource DownloadImageWithRestRequest(string uri)
{
Bitmap bitmap = null;
if(!string.IsNullOrWhiteSpace(uri))
{
var client = new RestClient(uri);
var request = new RestRequest(Method.GET)
{
ResponseWriter = responseStream =>
{
try
{
bitmap = new Bitmap(responseStream);
}
catch(Exception exception)
{
}
}
};
var client = new RestClient(url);
var request = new RestRequest();
request.AddHeader(Constants.Token, ChatDaten.AuthToken);
request.AddHeader(Constants.CustomerId, ChatDaten.Kundennummer);
client.DownloadData(request);
}
return bitmap != null ? Utils.ImageSourceForBitmap(bitmap) : null;
}
// WebRequest
private void LoadMessagesFromServer(long pGroupId)
client.ExecuteAsync(request, response =>
{
try
{
var endurl = ChatDaten.ServerUrl + Constants.LoadMessagesForGroupUrl + pGroupId;
var webRequest = WebRequest.Create(endurl);
webRequest.Credentials = CredentialCache.DefaultCredentials;
webRequest.Headers[Constants.Token] = ChatDaten.AuthToken;
webRequest.Headers[Constants.CustomerId] = ChatDaten.Kundennummer;
using (var response = webRequest.GetResponse())
{
var serverResponse = Utils.ReadStream(response);
if (!string.IsNullOrEmpty(serverResponse))
{
_UserMessages = JsonConvert.DeserializeObject<UserMessages>(serverResponse);
_UserMessages = JsonConvert.DeserializeObject<UserMessages>(response.Content);
if (_UserMessages.Response.HasMorePages)
{
@@ -200,10 +156,9 @@ namespace ChatController.HauptKlassen
{
_HasNextPage = false;
}
}
}
ThreadExceptionCallback?.Invoke(null);
callback?.Invoke();
});
}
catch (Exception exception)
{
@@ -211,21 +166,25 @@ namespace ChatController.HauptKlassen
}
}
// WebRequest
public void LoadMoreMessages(Contact pContact)
public void LoadMoreMessagesAsync(Contact contact, ChatMessage previousMessage, Action<List<ChatMessage>> callback)
{
if (_HasNextPage)
LoadMoreMessagesFromServerAsync(contact.GroupId, _NextPage, () =>
{
LoadMoreMessagesFromServer(pContact.GroupId, _NextPage);
AddMessagesFromServerResponse(_AdditionalUserMessages.Response.Messages);
}
callback?.Invoke(AddMessagesFromServerResponse(_AdditionalUserMessages?.Response.Messages ?? new Messages[0], previousMessage));
});
}
private void LoadMoreMessagesFromServerAsync(long groupId, string page, Action callback)
{
try
{
var pageParam = page.Split('=');
if(page == null || !page.Contains("="))
{
callback?.Invoke();
return;
}
var pageParam = page.Split('=')[1];
var url = $"{ChatDaten.ServerUrl}/api/chat/messages?groupid={groupId}&page={pageParam}";
@@ -256,53 +215,9 @@ namespace ChatController.HauptKlassen
}
}
// WebRequest
private void LoadMoreMessagesFromServer(long pGroupId, string pPage)
{
try
{
var page = pPage.Split('=');
var endurl = ChatDaten.ServerUrl + "/api/chat/messages?groupid=" + pGroupId + "&page=" + page[1];
var request = WebRequest.Create(endurl);
request.Credentials = CredentialCache.DefaultCredentials;
request.Headers[Constants.Token] = ChatDaten.AuthToken;
request.Headers[Constants.CustomerId] = ChatDaten.Kundennummer;
var response = request.GetResponse();
var responseFromServer = Utils.ReadStream(response);
if (!string.IsNullOrEmpty(responseFromServer))
{
_AdditionalUserMessages = null;
_AdditionalUserMessages = JsonConvert.DeserializeObject<UserMessages>(responseFromServer);
if (_AdditionalUserMessages.Response.HasMorePages)
{
_NextPage = _AdditionalUserMessages.Response.NextPage;
_HasNextPage = true;
}
else
{
_HasNextPage = false;
}
}
response.Close();
}
catch (Exception exception)
{
ExceptionCallback?.Invoke(exception);
}
}
private double _FormerMessagesCount;
// WebRequest
public bool CheckIfNewMessagesExist(Contact currentContact)
public void CheckIfNewMessagesExistAsync(long groupId, Action<bool> callback)
{
var span = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var timespan = Convert.ToInt64(span.TotalSeconds);
@@ -312,141 +227,131 @@ namespace ChatController.HauptKlassen
timespan = _UserMessages.Response.Messages.First().Created_At;
}
if (currentContact != null)
GetNumberOfNewMessagesAsync(groupId, timespan, numberOfNewMessages =>
{
var currentMessagesCount = GetNumberOfNewMessages(currentContact.GroupId, timespan);
var hasNewMessages = numberOfNewMessages != _FormerMessagesCount;
if (currentMessagesCount.Equals(_FormerMessagesCount))
{
return false;
_FormerMessagesCount = numberOfNewMessages;
callback?.Invoke(hasNewMessages);
});
}
_FormerMessagesCount = currentMessagesCount;
return true;
}
return false;
}
// WebRequest
private double GetNumberOfNewMessages(long pGroupId, long pLastTimeStamp)
private void GetNumberOfNewMessagesAsync(long groupId, long lastTimeStamp, Action<double> callback)
{
try
{
var url = $"{ChatDaten.ServerUrl}{Constants.LoadOwnChatNewsUrl}{pGroupId}/{pLastTimeStamp}";
var url = $"{ChatDaten.ServerUrl}{Constants.LoadOwnChatNewsUrl}{groupId}/{lastTimeStamp}";
var webRequest = WebRequest.Create(url);
var client = new RestClient(url);
var request = new RestRequest();
webRequest.Credentials = CredentialCache.DefaultCredentials;
webRequest.Headers[Constants.Token] = ChatDaten.AuthToken;
webRequest.Headers[Constants.CustomerId] = ChatDaten.Kundennummer;
request.AddHeader(Constants.Token, ChatDaten.AuthToken);
request.AddHeader(Constants.CustomerId, ChatDaten.Kundennummer);
var response = webRequest.GetResponse();
client.ExecuteAsync(request, response =>
{
var messageCounter = JsonConvert.DeserializeObject<MessageCounter>(response.Content);
var responseFromServer = Utils.ReadStream(response);
var messageCounter = JsonConvert.DeserializeObject<MessageCounter>(responseFromServer);
return messageCounter.MessageCount;
callback?.Invoke(messageCounter.MessageCount);
});
}
catch(Exception exception)
{
ExceptionCallback?.Invoke(exception);
return 0;
callback?.Invoke(0d);
}
}
// WebRequest
public double GetNumberOfAllNewMessages()
public void GetNumberOfAllNewMessagesAsync(Action<double> callback)
{
var unixTime = DateTime.UtcNow.GetUnixTimeStamp();
var messageCount = 0d;
messageCount += LoadNumberOfNewMessagesFromServer(0);
if (messageCount > 0)
LoadNumberOfNewMessagesFromServerAsync(0, numberOfNewMessages =>
{
LastTimeStamp = unixTime;
if(numberOfNewMessages > 0)
{
LastTimeStamp = DateTime.UtcNow.GetUnixTimeStamp();
}
return messageCount;
callback?.Invoke(numberOfNewMessages);
});
}
// WebRequest
private double LoadNumberOfNewMessagesFromServer(long pGroupId)
private void LoadNumberOfNewMessagesFromServerAsync(long groupId, Action<double> callback)
{
try
{
var url = ChatDaten.ServerUrl + Constants.LoadOwnChatNewsUrl + pGroupId + "/" + LastTimeStamp;
var url = $"{ChatDaten.ServerUrl}{Constants.LoadOwnChatNewsUrl}{groupId}/{LastTimeStamp}";
var webRequest = WebRequest.Create(url);
var client = new RestClient(url);
var request = new RestRequest();
webRequest.Credentials = CredentialCache.DefaultCredentials;
webRequest.Headers[Constants.Token] = ChatDaten.AuthToken;
webRequest.Headers[Constants.CustomerId] = ChatDaten.Kundennummer;
((HttpWebRequest) webRequest).KeepAlive = false;
request.AddHeader(Constants.Token, ChatDaten.AuthToken);
request.AddHeader(Constants.CustomerId, ChatDaten.Kundennummer);
var response = webRequest.GetResponse();
client.ExecuteAsync(request, response =>
{
var messageCounter = JsonConvert.DeserializeObject<MessageCounter>(response.Content);
var responseFromServer = Utils.ReadStream(response);
var messageCounter = JsonConvert.DeserializeObject<MessageCounter>(responseFromServer);
ThreadExceptionCallback?.Invoke(null);
return messageCounter.MessageCount;
callback?.Invoke(messageCounter.MessageCount);
});
}
catch(Exception exception)
{
ThreadExceptionCallback?.Invoke(exception);
return 0;
}
}
// WebRequest: LoadGroups
public IOrderedEnumerable<Contact> NeueGroupklassenKontakte()
{
var contacts = new List<Contact>();
var groupData = LoadGroups();
contacts.AddRange(GenerateContactsFromServerResponse(groupData.Response.Groups.ToArray(), true));
return contacts.OrderByDescending(r => r.TimeStamp);
}
private ChatGruppenDaten LoadGroups()
private void LoadGroupsAsync(Action<ChatGruppenDaten> callback)
{
try
{
var url = ChatDaten.ServerUrl + Constants.GetChatGroupsUrl;
var url = $"{ChatDaten.ServerUrl}{Constants.GetChatGroupsUrl}";
var request = WebRequest.Create(url);
var client = new RestClient(url);
var request = new RestRequest();
request.Credentials = CredentialCache.DefaultCredentials;
request.Headers[Constants.Token] = ChatDaten.AuthToken;
request.Headers[Constants.CustomerId] = ChatDaten.Kundennummer;
request.AddHeader(Constants.Token, ChatDaten.AuthToken);
request.AddHeader(Constants.CustomerId, ChatDaten.Kundennummer);
var response = request.GetResponse();
client.ExecuteAsync(request, response =>
{
var contacts = JsonConvert.DeserializeObject<ChatGruppenDaten>(response.Content);
var responseFromServer = Utils.ReadStream(response);
var jsonDaten = JsonConvert.DeserializeObject<ChatGruppenDaten>(responseFromServer);
response.Close();
return jsonDaten;
callback?.Invoke(contacts);
});
}
catch(Exception exception)
{
ExceptionCallback?.Invoke(exception);
return null;
}
}
public void AddNewMessage(string pMessage, long pGroupId)
public void UpdateContactList(Action<IOrderedEnumerable<Contact>> callback)
{
try
{
LoadGroupsAsync(rawData =>
{
var contacts = GenerateContactsFromServerResponse(rawData.Response.Groups.ToArray(), true);
callback?.Invoke(contacts.OrderByDescending(c => c.TimeStamp));
});
}
catch(Exception exception)
{
ExceptionCallback?.Invoke(exception);
}
}
public List<ChatMessage> AddNewMessage(string pMessage, long pGroupId, ChatMessage previousMessage)
{
var result = new List<ChatMessage>();
if(previousMessage != null)
{
result.Add(previousMessage);
}
try
{
var username = string.Empty;
@@ -460,17 +365,19 @@ namespace ChatController.HauptKlassen
var time = DateTime.Now;
Messages.Add(new ChatMessage(username, pMessage, time, true, pGroupId, 0));
result.Add(new ChatMessage(username, pMessage, time, true, pGroupId, 0, 0));
AddSeparators();
return AddSeparators(result);
}
catch (Exception exception)
{
ExceptionCallback?.Invoke(exception);
}
return result;
}
// TODO: Funktioniert nicht mit der Version von RestSharp, die mit .NET Version 4.5 kompatibel ist
// ToDo: Funktioniert nicht mit der Version von RestSharp, die mit .NET Version 4.5 kompatibel ist
public void SendMessageAsync(string message, long groupId)
{
try
@@ -609,13 +516,20 @@ namespace ChatController.HauptKlassen
}
}
public void AddNewFile(string pFile, string pOriginalFilePath, long pGroupId)
public List<ChatMessage> AddNewFile(string pFile, string pOriginalFilePath, long pGroupId, ChatMessage previousMessage)
{
var result = new List<ChatMessage>();
if (previousMessage != null)
{
result.Add(previousMessage);
}
try
{
if (string.IsNullOrEmpty(pFile) || string.IsNullOrEmpty(pOriginalFilePath))
{
return;
return result;
}
var message = _UserMessages.Response.Messages.Last();
@@ -661,12 +575,13 @@ namespace ChatController.HauptKlassen
bitmapImage.BeginInit();
bitmapImage.StreamSource = new MemoryStream(stream.ToArray());
bitmapImage.EndInit();
bitmapImage.Freeze();
var filename = Path.GetFileName(pOriginalFilePath).ToLower();
filename = filename.Replace(".bmp", ".jpg");
Messages.Add(new ChatMessage(message.User_Name, filename, sendTime, true, bitmapImage, pFile, filename, pGroupId, file.LongLength));
result.Add(new ChatMessage(message.User_Name, filename, sendTime, true, bitmapImage, pFile, filename, pGroupId, file.LongLength, message.Id));
}
}
@@ -675,22 +590,31 @@ namespace ChatController.HauptKlassen
}
else
{
Messages.Add(new ChatMessage(message.User_Name, Path.GetFileName(pFile), sendTime, message.Smaller_Image, true, pFile, pGroupId, 0));
result.Add(new ChatMessage(message.User_Name, Path.GetFileName(pFile), sendTime, message.Smaller_Image, true, pFile, pGroupId, 0, message.Id));
}
AddSeparators();
return AddSeparators(result);
}
catch (Exception exception)
{
ExceptionCallback?.Invoke(exception);
}
return result;
}
public void AddMediumContextDerNachrichtView(byte[] pFile, string pFileName, long pGroupId)
public List<ChatMessage> AddMediumContextDerNachrichtView(byte[] pFile, string pFileName, long pGroupId, ChatMessage previousMessage)
{
var result = new List<ChatMessage>();
if (string.IsNullOrEmpty(pFileName))
{
return;
return result;
}
if(previousMessage != null)
{
result.Add(previousMessage);
}
var message = _UserMessages.Response.Messages.Last();
@@ -705,18 +629,19 @@ namespace ChatController.HauptKlassen
bitmapImage.BeginInit();
bitmapImage.StreamSource = memoryStream;
bitmapImage.EndInit();
bitmapImage.Freeze();
memoryStream.Close();
ImageSource logo = bitmapImage;
Messages.Add(new ChatMessage(message.User_Name, Path.GetFileName(pFileName), sendtime, true, logo, pFileName, Path.GetFileName(pFileName), pGroupId, memoryStream.Length));
result.Add(new ChatMessage(message.User_Name, Path.GetFileName(pFileName), sendtime, true, logo, pFileName, Path.GetFileName(pFileName), pGroupId, memoryStream.Length, message.Id));
}
else
{
Messages.Add(new ChatMessage(message.User_Name, Path.GetFileName(pFileName), sendtime, message.Smaller_Image, true, pFileName, pGroupId, 0));
result.Add(new ChatMessage(message.User_Name, Path.GetFileName(pFileName), sendtime, message.Smaller_Image, true, pFileName, pGroupId, 0, message.Id));
}
AddSeparators();
return AddSeparators(result);
}
public void SendFileToContact(Contact currentContact, string pFile, string pOriginalFilePath)
@@ -747,8 +672,8 @@ namespace ChatController.HauptKlassen
var fileName = Path.GetFileName(pOriginalFilePath).ToLower();
if (Constants.ImageFileExtensions.Contains(Path.GetExtension(fileName).ToUpperInvariant())){
if (Constants.ImageFileExtensions.Contains(Path.GetExtension(fileName).ToUpperInvariant()))
{
fileName = fileName.Replace(".bmp", ".jpg");
SendMediaMessage(fileName, currentContact.GroupId, mediaFile);
@@ -821,7 +746,7 @@ namespace ChatController.HauptKlassen
public void SaveFileAs(ChatMessage pChatMessage)
{
if (pChatMessage.ImageSources != null)
if (pChatMessage.PictureSource != null)
{
SaveAs(1, Path.GetFileName(pChatMessage.OriginalImage), DownloadMediaFile(pChatMessage.OriginalImage));
}
@@ -912,7 +837,7 @@ namespace ChatController.HauptKlassen
var mediaFile = File.ReadAllBytes(fileList[0]);
AddMediumContextDerNachrichtView(mediaFile, fileName, pGroupOid);
pChatMainControl.AddMessages(AddMediumContextDerNachrichtView(mediaFile, fileName, pGroupOid, pChatMainControl.GetFirstMessage()));
CollectionViewSource.GetDefaultView(pChatMainControl.ChatListBox.ItemsSource).Refresh();
@@ -934,7 +859,7 @@ namespace ChatController.HauptKlassen
{
var text = (string) dataObject.GetData(DataFormats.StringFormat);
AddNewMessage(text, pGroupOid);
pChatMainControl.AddMessages(AddNewMessage(text, pGroupOid, pChatMainControl.GetFirstMessage()));
CollectionViewSource.GetDefaultView(pChatMainControl.ChatListBox.ItemsSource).Refresh();
@@ -951,7 +876,7 @@ namespace ChatController.HauptKlassen
Image image = bitmap;
AddMediumContextDerNachrichtView(Utils.ImageToByteArray(image), imageName, pGroupOid);
pChatMainControl.AddMessages(AddMediumContextDerNachrichtView(Utils.ImageToByteArray(image), imageName, pGroupOid, pChatMainControl.GetFirstMessage()));
CollectionViewSource.GetDefaultView(pChatMainControl.ChatListBox.ItemsSource).Refresh();
@@ -987,66 +912,79 @@ namespace ChatController.HauptKlassen
{
try
{
using (var form = new Form())
ShowPictureWindow(currentContact.Image, currentContact.Name);
}
catch (Exception exception)
{
var bitmap = currentContact.ProfilePicture;
ExceptionCallback?.Invoke(exception);
}
}
form.StartPosition = FormStartPosition.CenterScreen;
var bitmapWidth = bitmap.Width;
var bitmapHeight = bitmap.Height;
var aspectRatio = bitmapWidth / (double) bitmapHeight;
var primaryScreenWidth = SystemParameters.PrimaryScreenWidth;
var primaryScreenHeight = SystemParameters.PrimaryScreenHeight;
var maxWidth = bitmapWidth;
var maxHeight = bitmapHeight;
if(maxWidth > primaryScreenWidth || maxHeight > primaryScreenHeight)
public void ShowPictureWindow(ImageSource imageSource, string title)
{
if(primaryScreenWidth > primaryScreenHeight)
try
{
maxHeight = (int) (.9 * primaryScreenHeight);
maxWidth = (int) (maxHeight * aspectRatio);
var imageWidth = Convert.ToInt32(imageSource.Width);
var imageHeight = Convert.ToInt32(imageSource.Height);
var imageAspectRatio = imageWidth / (double)imageHeight;
var primaryScreenWidth2 = SystemParameters.PrimaryScreenWidth;
var primaryScreenHeight2 = SystemParameters.PrimaryScreenHeight;
var windowMaxWidth = imageWidth;
var windowMaxHeight = imageHeight;
if (windowMaxWidth > primaryScreenWidth2 || windowMaxHeight > primaryScreenHeight2)
{
if (primaryScreenWidth2 > primaryScreenHeight2)
{
windowMaxHeight = (int)(.9 * primaryScreenHeight2);
windowMaxWidth = (int)(windowMaxHeight * imageAspectRatio);
}
else
{
maxWidth = (int) (.9 * primaryScreenWidth);
maxHeight = (int) (maxWidth * aspectRatio);
windowMaxWidth = (int)(.9 * primaryScreenWidth2);
windowMaxHeight = (int)(windowMaxWidth * imageAspectRatio);
}
}
var maximumSize = new Size(maxWidth, maxHeight);
var maximumWindowSize = new System.Windows.Size(windowMaxWidth, windowMaxHeight);
form.Size = maximumSize;
var minHeight = 232 / imageAspectRatio;
var minWidth = 232d;
form.FormBorderStyle = FormBorderStyle.Sizable;
form.MaximizeBox = false;
form.Text = currentContact.Name;
form.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
var pictureBox = new PictureBox
var window = new Window
{
Dock = DockStyle.Fill,
Image = bitmap,
SizeMode = PictureBoxSizeMode.Zoom,
Padding = new Padding(0),
Margin = new Padding(0)
Title = title,
MinHeight = minHeight,
MinWidth = minWidth
};
form.MinimumSize = new Size(232, (int)(232 / aspectRatio));
var grid = new Grid
{
Width = maximumWindowSize.Width,
Height = maximumWindowSize.Height,
MinHeight = minHeight,
MinWidth = minWidth
};
form.Padding = new Padding(0);
form.Margin = new Padding(0);
var image = new System.Windows.Controls.Image
{
Source = imageSource,
Margin = new Thickness(0)
};
form.Controls.Add(pictureBox);
grid.Children.Clear();
grid.Children.Add(image);
form.ShowDialog();
}
window.SizeToContent = SizeToContent.WidthAndHeight;
window.Content = grid;
window.Margin = new Thickness(0);
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
window.ShowDialog();
}
catch (Exception exception)
{
@@ -1054,68 +992,22 @@ namespace ChatController.HauptKlassen
}
}
public void ShowPicture(string originalImage, Action downloadCompletedCallback)
public void ShowPicture(string originalImage, long groupId, Action<ImageSource, string> downloadCompletedCallback)
{
if(originalImage == null)
{
return;
}
try
{
var webClient = new WebClient();
webClient.DownloadDataCompleted += (s, e) =>
Utils.DownloadImageAsync(originalImage, $"group-{groupId}", CacheCategory.MessageAttachment, imageSource =>
{
try
{
using(var form = new Form())
{
using(var ms = new MemoryStream(e.Result))
{
var image = Image.FromStream(ms);
var splitName = originalImage.Split('/');
var last = splitName.LastOrDefault();
using(var bitmap = new Bitmap(image))
{
short orient = 0;
const int orientationId = 0x0112;
if(image.PropertyIdList.Contains(orientationId))
{
var item = image.GetPropertyItem(orientationId);
orient = BitConverter.ToInt16(item.Value, 0);
bitmap.SetPropertyItem(item);
}
var flipType = Utils.OrientationToFlipType(orient.ToString());
bitmap.RotateFlip(flipType);
form.StartPosition = FormStartPosition.CenterScreen;
form.ClientSize = bitmap.Size;
form.FormBorderStyle = FormBorderStyle.Sizable;
form.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
using(var pictureBox = new PictureBox())
{
pictureBox.Dock = DockStyle.Fill;
pictureBox.Image = bitmap;
pictureBox.SizeMode = PictureBoxSizeMode.Zoom;
form.Controls.Add(pictureBox);
downloadCompletedCallback?.Invoke();
form.ShowDialog();
}
}
}
}
}
catch(Exception exception)
{
ExceptionCallback?.Invoke(exception);
}
};
webClient.DownloadDataAsync(new Uri(originalImage));
downloadCompletedCallback?.Invoke(imageSource, last ?? "Bild");
});
}
catch (Exception exception)
{
@@ -1143,7 +1035,7 @@ namespace ChatController.HauptKlassen
});
}
public List<Contact> GroupklassenAktuallisieren(ChatGruppenDaten chatDaten)
public List<Contact> UpdateContacts(ChatGruppenDaten chatDaten)
{
try
{
@@ -1193,25 +1085,18 @@ namespace ChatController.HauptKlassen
var key = $"group-{groupInput.Oid}";
var cacheInstance = OwnChatCache.GetInstance();
var imgSrc = cacheInstance.GetImageSourceFromCache(key);
if(imgSrc == null)
{
imgSrc = Utils.AvatarToImageSourceConverter(groupInput.Avatar, groupInput.OnlyEmployees, groupInput.Users.Length > 2);
cacheInstance.AddImageToCache(key, imgSrc);
}
var bmp = cacheInstance.GetBitmapFromCache(key);
if(bmp == null)
{
bmp = Utils.ConvertAvatarToBitmap(groupInput.Avatar, groupInput.OnlyEmployees, groupInput.Users.Length > 2);
cacheInstance.AddBitmapToCache(key, bmp);
}
contacts.Add(new Contact(groupInput.Name, groupInput.LastMessage, formattedTime, groupInput.Oid, userIdManage, groupInput.OnlyEmployees, groupInput.Users.Length, groupInput.CanWrite, groupInput.AccentColor, bmp, imgSrc));
contacts.Add(new Contact(
groupInput.Name,
groupInput.LastMessage,
formattedTime,
groupInput.Oid,
userIdManage,
groupInput.OnlyEmployees,
groupInput.Users.Length,
groupInput.CanWrite,
groupInput.AccentColor,
groupInput.Avatar,
key));
if(pShouldUpdateLastTimeStamp)
{
@@ -1230,8 +1115,15 @@ namespace ChatController.HauptKlassen
return contacts;
}
public void AddMessagesFromServerResponse(Messages[] pMessages)
public List<ChatMessage> AddMessagesFromServerResponse(Messages[] pMessages, ChatMessage previousMessage)
{
var result = new List<ChatMessage>();
if(previousMessage != null)
{
result.Add(previousMessage);
}
foreach (var message in pMessages)
{
var time = DateTime.Parse(message.Timestamp.Date);
@@ -1242,22 +1134,26 @@ namespace ChatController.HauptKlassen
if (!string.IsNullOrEmpty(message.File))
{
Messages.Add(Constants.ImageFileExtensions.Contains(Path.GetExtension(message.File).ToUpperInvariant()) ? //SmallerImage ist null
new ChatMessage(message.User_Name, messageText, formattedTime, isLoggedInUsersMessage, DownloadImage(message.Smaller_Image), message.File, message.Original_Filename, message.GroupId, message.FileSize) :
new ChatMessage(message.User_Name, messageText, formattedTime, message.Smaller_Image, isLoggedInUsersMessage, message.File, message.GroupId, message.FileSize));
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);
result.AddIfNotIn(message2Add);
}
else
{
Messages.Add(new ChatMessage(message.User_Name, message.Text, formattedTime, isLoggedInUsersMessage, message.GroupId, message.FileSize));
var message2Add2 = new ChatMessage(message.User_Name, message.Text, formattedTime, isLoggedInUsersMessage, message.GroupId, message.FileSize, message.Id);
result.AddIfNotIn(message2Add2);
}
}
AddSeparators();
return AddSeparators(result);
}
private void AddSeparators()
private static List<ChatMessage> AddSeparators(List<ChatMessage> chatMessages)
{
var messagesWithoutSeparators = Messages.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>();
@@ -1268,7 +1164,7 @@ namespace ChatController.HauptKlassen
{
if(message.SendTime.Date != previousMessage.SendTime.Date)
{
var separatorMessage = new ChatMessage(null, null, message.SendTime.Date, false, 0, 0) { IsSeparator = true };
var separatorMessage = new ChatMessage(null, null, message.SendTime.Date, false, 0, 0, -1) { IsSeparator = true };
separators.Add(separatorMessage);
@@ -1277,9 +1173,52 @@ namespace ChatController.HauptKlassen
}
}
messagesWithoutSeparators.AddRange(separators);
chatMessages.AddRange(separators);
Messages = messagesWithoutSeparators.OrderBy(message => message.SendTime).ToList();
return chatMessages;
}
public void DownloadFileAsync(string uri, string path, Action callback)
{
try
{
var client = new RestClient(uri);
var request = new RestRequest();
request.AddHeader(Constants.Token, ChatDaten.AuthToken);
request.AddHeader(Constants.CustomerId, ChatDaten.Kundennummer);
client.ExecuteAsync(request, response =>
{
if(response.StatusCode == HttpStatusCode.OK)
{
response.RawBytes.SaveAs(path);
}
else
{
throw new Exception("Die Datei konnte nicht heruntergeladen werden.");
}
callback?.Invoke();
});
}
catch (Exception exception)
{
ExceptionCallback?.Invoke(exception);
}
}
}
public class ChatMessageComparer : IComparer
{
public int Compare(object x, object y)
{
if(x is ChatMessage message1 && y is ChatMessage message2)
{
return message1.SendTime.CompareTo(message2.SendTime);
}
return 0;
}
}
}

View File

@@ -12,6 +12,7 @@ using ChatController.Utilities;
using Newtonsoft.Json;
using RestSharp;
namespace ChatController.HauptKlassen
{
public class Login
@@ -65,9 +66,20 @@ namespace ChatController.HauptKlassen
_Tenant = tenant;
_ShouldShowMessageBox = false;
LookupServerUrlAsync(isSuccessful => { callback(ServerUrl); });
// TODO: Ändern, sonst wird keine Fehlermeldung angezeigt!
LookupServerUrlAsync(isSuccessful => { callback(ServerUrl); }, null);
}
// Wird im BeWoPlaner benutzt
public Login(string tenant, Action<string> callback, Action<string> exceptionCallback)
{
_Tenant = tenant;
_ShouldShowMessageBox = false;
LookupServerUrlAsync(isSuccessful => { callback(ServerUrl); }, exceptionCallback);
}
// Wird im BeWoPlaner benutzt
public ChatDatenUebergabe AnmeldevorgangDurchFuehren()
{
if(ServerErmittlung())
@@ -125,7 +137,7 @@ namespace ChatController.HauptKlassen
errorMessage => { exceptionCallback?.Invoke(errorMessage); });
}
});
}, errorMessage => { exceptionCallback?.Invoke(errorMessage); });
}
catch (Exception exception)
{
@@ -133,7 +145,7 @@ namespace ChatController.HauptKlassen
}
}
public void LookupServerUrlAsync(Action<bool> callback)
public void LookupServerUrlAsync(Action<bool> callback, Action<string> exceptionCallback)
{
try
{
@@ -163,9 +175,10 @@ namespace ChatController.HauptKlassen
result = true;
break;
case 1:
MessageBox.Show("Fehler: Kundennummer unbekannt.\nBitte überprüfen Sie die Anmeldeinformationen.", "ownChat Info", MessageBoxButton.OK, MessageBoxImage.Asterisk);
exceptionCallback?.Invoke("Fehler: Kundennummer unbekannt.\nBitte überprüfen Sie die Anmeldeinformationen.");
break;
case 2:
exceptionCallback?.Invoke("Der Diensttyp ist für die angegebene Kundennummer nicht definiert.");
MessageBox.Show("Der Diensttyp ist für die angegebene Kundennummer nicht definiert.", "ownChat Info", MessageBoxButton.OK, MessageBoxImage.Asterisk);
break;
}
@@ -175,7 +188,7 @@ namespace ChatController.HauptKlassen
}
catch (Exception exception)
{
MessageBox.Show("Fehler: Es konnte keine Verbindung aufgebaut werden.", "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
exceptionCallback?.Invoke("Fehler: Es konnte keine Verbindung aufgebaut werden.");
}
}
@@ -463,8 +476,6 @@ namespace ChatController.HauptKlassen
});
}
#region Maximal erlaubte File Größe
public long GetMaiximumAllowedFileUploadSize(string pToken, string pCustomerId)
{
long maximumFileSize;
@@ -517,7 +528,5 @@ namespace ChatController.HauptKlassen
callback?.Invoke(maxUploadFileSize);
});
}
#endregion
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -11,6 +11,7 @@ namespace ChatController.Utilities
public static readonly string EmployeeDefaultImagePath = "pack://application:,,,/ChatController;component/Ressourcen/employee_default.png";
public static readonly string CustomerDefaultImagePath = "pack://application:,,,/ChatController;component/Ressourcen/client_default.png";
public static readonly string NormalGroupDefaultImagePath = "pack://application:,,,/ChatController;component/Ressourcen/mitarbeiter-team-avatar.png";
public static readonly string ImagePlaceholderPath = "pack://application:,,,/ChatController;component/Ressourcen/ownchat_image_placeholder.png";
public static readonly string Token = "Token";
public static readonly string CustomerId = "CustomerID";
@@ -31,5 +32,7 @@ namespace ChatController.Utilities
public static readonly string MultipartContentTypeValue = "multipart/form-data";
public static readonly string TenantAndChatCodeFileName = "ownChat.txt";
public static readonly string ProfilePictureCacheName = "profile-picture";
}
}

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
@@ -12,6 +11,7 @@ using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using ChatController.Core;
using RestSharp;
using MessageBox = System.Windows.MessageBox;
using PixelFormat = System.Drawing.Imaging.PixelFormat;
@@ -26,62 +26,19 @@ namespace ChatController.Utilities
public static DateTime DefaultDate = new DateTime(1, 1, 1);
public static ImageSource AvatarToImageSourceConverter(string pAvatarPath, bool pIsEmployee, bool pIsGroup)
public static void DownloadProfilePictureAsync(string pathToProfilePicture, string key, Action<ImageSource> callback)
{
return CreateImageSourceFromPath(pAvatarPath, pIsGroup, pIsEmployee);
var cache = OwnChatCache.GetInstance();
var cachedProfileImage = cache.GetCachedProfilePicture(key);
if(cachedProfileImage != null)
{
callback?.Invoke(cachedProfileImage);
return;
}
public static Bitmap ConvertAvatarToBitmap(string linkToPicture, bool isEmployee, bool isGroup)
{
Bitmap bitmap = null;
if(!string.IsNullOrWhiteSpace(linkToPicture))
{
Debug.WriteLine("Lade Bitmap herunter...");
var client = new RestClient(linkToPicture);
var request = new RestRequest(Method.GET)
{
ResponseWriter = responseStream =>
{
try
{
bitmap = new Bitmap(responseStream);
}
catch(Exception exception)
{
}
}
};
request.AddHeader(Constants.Token, AuthToken);
request.AddHeader(Constants.CustomerId, Tenant);
client.DownloadData(request);
}
if(bitmap != null)
{
return bitmap;
}
var defaultBitmap = (BitmapImage) GetDefaultImageSource(isGroup, isEmployee);
using(var outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(defaultBitmap));
enc.Save(outStream);
return new Bitmap(outStream);
}
}
public static void DownloadProfilePictureAsync(string avatarPath, bool isEmployee, bool isGroup, Action<ImageSource> callback)
{
var url = avatarPath;
var url = pathToProfilePicture;
var client = new RestClient(url);
var request = new RestRequest
@@ -97,16 +54,69 @@ namespace ChatController.Utilities
localStream.Position = 0;
bitmap.BeginInit();
bitmap.StreamSource = localStream;
bitmap.EndInit();
bitmap.Freeze();
cache.AddProfilePictureToCache(key, bitmap);
callback?.Invoke(bitmap);
}
};
request.AddHeader(Constants.Token, AuthToken);
request.AddHeader(Constants.CustomerId, Tenant);
client.ExecuteAsync(request, response => { /*Das übernimmt der ResponseWriter von oben*/ });
}
public static void DownloadImageAsync(string uri, string key, CacheCategory cacheCategory, Action<ImageSource> callback)
{
if(string.IsNullOrEmpty(uri))
{
callback?.Invoke(null);
return;
}
var cache = OwnChatCache.GetInstance();
var cachedImage = cache.GetImageSourceFromCache(key, uri, cacheCategory);
if (cachedImage != null)
{
callback?.Invoke(cachedImage);
return;
}
var url = uri;
var client = new RestClient(url);
var request = new RestRequest
{
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 => { });
}
private static ImageSource GetDefaultImageSource(bool pIsGroup, bool pIsEmployee)
@@ -127,61 +137,21 @@ namespace ChatController.Utilities
resultBitmapImage.BeginInit();
resultBitmapImage.UriSource = new Uri(defaultImage);
resultBitmapImage.EndInit();
resultBitmapImage.Freeze();
return resultBitmapImage;
}
public static ImageSource CreateImageSourceFromPath(string pPathToImageFile, bool pIsGroup = false, bool pIsEmployee = false)
public static ImageSource GetPicturePlaceholder()
{
if (!string.IsNullOrEmpty(pPathToImageFile))
{
Debug.WriteLine("Lade Bild herunter...");
var resultBitmapImage = new BitmapImage();
Bitmap bitmap = null;
resultBitmapImage.BeginInit();
resultBitmapImage.UriSource = new Uri(Constants.ImagePlaceholderPath);
resultBitmapImage.EndInit();
resultBitmapImage.Freeze();
var client = new RestClient(pPathToImageFile);
var request = new RestRequest(Method.GET)
{
ResponseWriter = stream =>
{
try
{
bitmap = new Bitmap(stream);
}
catch (ArgumentException)
{
bitmap = null;
}
}
};
request.AddHeader(Constants.Token, AuthToken);
request.AddHeader(Constants.CustomerId, Tenant);
client.DownloadData(request);
if (bitmap != null)
{
using (var memoryStream = new MemoryStream())
{
bitmap.Save(memoryStream, ImageFormat.Png);
memoryStream.Position = 0;
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = memoryStream;
bitmapImage.EndInit();
return bitmapImage;
}
}
}
return GetDefaultImageSource(pIsGroup, pIsEmployee);
return resultBitmapImage;
}
public static string ReadStream(WebResponse response)
@@ -262,7 +232,7 @@ namespace ChatController.Utilities
}
}
public static ImageSource GetImageSourceFromIcon(Icon pIcon)
public static ImageSource ConvertIconToImageSource(Icon pIcon)
{
var bitmap = new Bitmap(pIcon.Width, pIcon.Height);
@@ -443,20 +413,30 @@ namespace ChatController.Utilities
}
*/
public Bitmap ConvertStreamToBitmap(Stream imageStream)
public static int GetHeightFromThumbnailUri(string uri)
{
try
/*
https://test.ownchat.de/document.png
https://test.ownchat.de/profile/view-image/{customerid}/{width}/{height}/{filename}
https://test.ownchat.de/message/view-image/{customerid}/{group}/{height}/{filename}
*/
if (uri != null && uri.Contains("/"))
{
var image = Image.FromStream(imageStream);
var splitUri = uri.Split('/');
return null;
}
catch(Exception exception)
if(splitUri.Length>=2)
{
throw exception;
var heightStr = splitUri[splitUri.Length - 2];
if(int.TryParse(heightStr, out var height))
{
return height;
}
}
}
return 100;
}
}
}

View File

@@ -0,0 +1,32 @@
using System.Windows.Controls;
using System.Windows.Media;
namespace ChatController.Utilities
{
public class WpfUtils
{
public static void ScrollToBottomOfListBox(ListBox listBox)
{
if (VisualTreeHelper.GetChildrenCount(listBox) > 0)
{
var border = (Border)VisualTreeHelper.GetChild(listBox, 0);
var scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
scrollViewer?.ScrollToBottom();
}
}
public static ScrollViewer GetListBoxScrollViewer(ListBox listBox)
{
if (VisualTreeHelper.GetChildrenCount(listBox) > 0)
{
var border = (Border)VisualTreeHelper.GetChild(listBox, 0);
var scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
return scrollViewer;
}
return null;
}
}
}

View File

@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ClrHeapAllocationAnalyzer" version="3.0.0" targetFramework="net45" />
<package id="RestSharp" version="105.2.3" targetFramework="net45" />
</packages>