1057 lines
38 KiB
C#
1057 lines
38 KiB
C#
using ChatController.ChatKlassen;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Web.UI.WebControls;
|
|
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 ChatController.Annotations;
|
|
using ChatController.Core;
|
|
using ChatController.Extensions;
|
|
using ChatController.LoginKlassen;
|
|
using ChatController.Utilities;
|
|
using ChatController.Utilities.Extensions;
|
|
using RestSharp;
|
|
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 ChatController.Security;
|
|
|
|
namespace ChatController.HauptKlassen
|
|
{
|
|
// Ist quasi das ViewModel
|
|
public class Chat : INotifyPropertyChanged
|
|
{
|
|
private static DateTime _DefaultTime = new DateTime(1970, 1, 1);
|
|
|
|
public Action<Exception> ExceptionCallback { get; set; }
|
|
public Action<Exception> ThreadExceptionCallback { get; set; }
|
|
|
|
private readonly List<Contact> _Contacts = new List<Contact>();
|
|
|
|
public static ChatDatenUebergabe ChatDaten { get; set; }
|
|
|
|
private UserMessages _UserMessages;
|
|
private UserMessages _AdditionalUserMessages;
|
|
|
|
private string _NextPage;
|
|
private bool _HasNextPage;
|
|
|
|
public long LastTimeStamp { get; set; }
|
|
|
|
public Chat(ChatDatenUebergabe chatDaten, Action<Exception> exceptionCallback, Action<Exception> threadExceptionCallback)
|
|
{
|
|
ChatDaten = chatDaten;
|
|
ExceptionCallback = exceptionCallback;
|
|
ThreadExceptionCallback = threadExceptionCallback;
|
|
|
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
|
|
|
PinCertificate();
|
|
}
|
|
|
|
private static void PinCertificate()
|
|
{
|
|
ServicePointManager.ServerCertificateValidationCallback = CertificateChecker.PinPublicKey;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public List<Contact> AddContacts()
|
|
{
|
|
var groupInputs = ChatDaten?.AlleGruppen?.Response?.Groups?.ToArray() ?? new GroupInput[0];
|
|
_Contacts.AddRange(GenerateContactsFromServerResponse(groupInputs, true));
|
|
|
|
return _Contacts;
|
|
}
|
|
|
|
// 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(false == contact is null)
|
|
{
|
|
LoadMessagesFromServerAsync(contact.GroupId, delegate
|
|
{
|
|
callback?.Invoke(AddMessagesFromServerResponse(_UserMessages?.Response?.Messages ?? new OwnChatMessage[0], previousMessage));
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
callback?.Invoke(new List<ChatMessage>());
|
|
}
|
|
|
|
private void LoadMessagesFromServerAsync(long groupId, Action callback)
|
|
{
|
|
var url = $"{ChatDaten.ServerUrl}{Constants.LoadMessagesForGroupUrl}{groupId}";
|
|
|
|
var client = new RestClient(url);
|
|
var request = new RestRequest();
|
|
|
|
request.AddHeader(Constants.Token, ChatDaten.AuthToken);
|
|
request.AddHeader(Constants.CustomerId, ChatDaten.Kundennummer);
|
|
|
|
client.ExecuteAsync(request, response =>
|
|
{
|
|
_UserMessages = JsonConvert.DeserializeObject<UserMessages>(response.Content);
|
|
|
|
if(_UserMessages?.Response?.HasMorePages ?? false)
|
|
{
|
|
_NextPage = _UserMessages.Response.NextPage;
|
|
_HasNextPage = true;
|
|
}
|
|
else
|
|
{
|
|
_HasNextPage = false;
|
|
}
|
|
|
|
callback?.Invoke();
|
|
});
|
|
}
|
|
|
|
|
|
|
|
public void LoadMoreMessagesAsync(Contact contact, ChatMessage previousMessage, Action<List<ChatMessage>> callback)
|
|
{
|
|
LoadMoreMessagesFromServerAsync(contact.GroupId, _NextPage, () =>
|
|
{
|
|
callback?.Invoke(AddMessagesFromServerResponse(_AdditionalUserMessages?.Response?.Messages ?? new OwnChatMessage[0], previousMessage));
|
|
});
|
|
}
|
|
|
|
private void LoadMoreMessagesFromServerAsync(long groupId, string page, Action callback)
|
|
{
|
|
if(page is null || !page.Contains("="))
|
|
{
|
|
callback?.Invoke();
|
|
return;
|
|
}
|
|
|
|
var pageParam = page.Split('=')[1];
|
|
|
|
var url = $"{ChatDaten.ServerUrl}/api/chat/messages?groupid={groupId}&page={pageParam}";
|
|
|
|
var client = new RestClient(url);
|
|
var request = new RestRequest();
|
|
|
|
request.AddHeader(Constants.Token, ChatDaten.AuthToken);
|
|
request.AddHeader(Constants.CustomerId, ChatDaten.Kundennummer);
|
|
|
|
client.ExecuteAsync(request, response =>
|
|
{
|
|
_AdditionalUserMessages = null;
|
|
_AdditionalUserMessages = JsonConvert.DeserializeObject<UserMessages>(response.Content);
|
|
|
|
if(_AdditionalUserMessages?.Response?.HasMorePages ?? false)
|
|
{
|
|
_NextPage = _AdditionalUserMessages.Response.NextPage;
|
|
}
|
|
|
|
_HasNextPage = _AdditionalUserMessages?.Response?.HasMorePages ?? false;
|
|
|
|
callback?.Invoke();
|
|
});
|
|
}
|
|
|
|
private double _FormerMessagesCount;
|
|
|
|
public void CheckIfNewMessagesExistAsync(long groupId, Action<bool> callback)
|
|
{
|
|
#if DEBUG
|
|
if(_UserMessages?.Response is null)
|
|
{
|
|
throw new Exception("Too many requests.");
|
|
}
|
|
#endif
|
|
|
|
var span = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
|
|
var timespan = Convert.ToInt64(span.TotalSeconds);
|
|
|
|
if(!(_UserMessages is null) && _UserMessages.Response.Messages.Length > 0)
|
|
{
|
|
timespan = _UserMessages.Response.Messages.First().CreatedAt;
|
|
}
|
|
|
|
GetNumberOfNewMessagesAsync(groupId, timespan, numberOfNewMessages =>
|
|
{
|
|
var hasNewMessages = numberOfNewMessages != _FormerMessagesCount;
|
|
|
|
_FormerMessagesCount = numberOfNewMessages;
|
|
|
|
callback?.Invoke(hasNewMessages);
|
|
});
|
|
}
|
|
|
|
private void GetNumberOfNewMessagesAsync(long groupId, long lastTimeStamp, Action<double> callback)
|
|
{
|
|
try
|
|
{
|
|
var url = $"{ChatDaten.ServerUrl}{Constants.LoadOwnChatNewsUrl}{groupId}/{lastTimeStamp}";
|
|
|
|
var client = new RestClient(url);
|
|
var request = new RestRequest();
|
|
|
|
request.AddHeader(Constants.Token, ChatDaten.AuthToken);
|
|
request.AddHeader(Constants.CustomerId, ChatDaten.Kundennummer);
|
|
|
|
client.ExecuteAsync(request, response =>
|
|
{
|
|
var messageCounter = JsonConvert.DeserializeObject<MessageCounter>(response.Content);
|
|
|
|
callback?.Invoke(messageCounter?.MessageCount ?? 0);
|
|
});
|
|
}
|
|
catch(Exception exception)
|
|
{
|
|
callback?.Invoke(0d);
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
public void GetNumberOfAllNewMessagesAsync(Action<double> callback)
|
|
{
|
|
LoadNumberOfNewMessagesFromServerAsync(0, numberOfNewMessages =>
|
|
{
|
|
if(numberOfNewMessages > 0)
|
|
{
|
|
LastTimeStamp = DateTime.UtcNow.GetUnixTimeStamp();
|
|
}
|
|
|
|
callback?.Invoke(numberOfNewMessages);
|
|
});
|
|
}
|
|
|
|
private void LoadNumberOfNewMessagesFromServerAsync(long groupId, Action<double> callback)
|
|
{
|
|
var url = $"{ChatDaten.ServerUrl}{Constants.LoadOwnChatNewsUrl}{groupId}/{LastTimeStamp}";
|
|
|
|
var client = new RestClient(url);
|
|
var request = new RestRequest();
|
|
|
|
request.AddHeader(Constants.Token, ChatDaten.AuthToken);
|
|
request.AddHeader(Constants.CustomerId, ChatDaten.Kundennummer);
|
|
|
|
client.ExecuteAsync(request, response =>
|
|
{
|
|
var messageCounter = JsonConvert.DeserializeObject<MessageCounter>(response.Content);
|
|
|
|
callback?.Invoke(messageCounter?.MessageCount ?? 0);
|
|
});
|
|
}
|
|
|
|
private void LoadGroupsAsync(Action<ChatGruppenDaten> callback)
|
|
{
|
|
var url = $"{ChatDaten.ServerUrl}{Constants.GetChatGroupsUrl}";
|
|
|
|
var client = new RestClient(url);
|
|
var request = new RestRequest();
|
|
|
|
request.AddHeader(Constants.Token, ChatDaten.AuthToken);
|
|
request.AddHeader(Constants.CustomerId, ChatDaten.Kundennummer);
|
|
|
|
client.ExecuteAsync(request, response =>
|
|
{
|
|
var contacts = JsonConvert.DeserializeObject<ChatGruppenDaten>(response.Content);
|
|
|
|
callback?.Invoke(contacts);
|
|
});
|
|
}
|
|
|
|
public void UpdateContactList(Action<IOrderedEnumerable<Contact>> callback)
|
|
{
|
|
LoadGroupsAsync(rawData =>
|
|
{
|
|
if(rawData.Response is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var contacts = GenerateContactsFromServerResponse(rawData.Response.Groups.ToArray(), true);
|
|
|
|
callback?.Invoke(contacts.OrderByDescending(c => c.TimeStamp));
|
|
});
|
|
}
|
|
|
|
public List<ChatMessage> AddNewMessage(string pMessage, long pGroupId, ChatMessage previousMessage)
|
|
{
|
|
var time = DateTime.Now;
|
|
|
|
var chatMessage = new ChatMessage(pGroupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, pMessage, time, true, 0, null, null, null, null, null, ChatMessageType.Message, ChatDaten.LoggedInUser.Response.User.Oid);
|
|
|
|
var messages = new List<ChatMessage>();
|
|
|
|
if(!(previousMessage is null))
|
|
{
|
|
messages.Add(previousMessage);
|
|
}
|
|
|
|
messages.Add(chatMessage);
|
|
|
|
var result = AddSeparators(messages);
|
|
|
|
result.Remove(previousMessage);
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task SendMessage(string message, long groupId)
|
|
{
|
|
var endurl = ChatDaten.ServerUrl + Constants.SendMessageUrl;
|
|
|
|
using(var multiPartContent = new MultipartFormDataContent())
|
|
{
|
|
multiPartContent.Add(new StringContent(groupId.ToString()), "groupid");
|
|
multiPartContent.Add(new StringContent(message), "text");
|
|
|
|
var requestUri = new Uri(endurl);
|
|
|
|
var httpRequest = new HttpRequestMessage {Method = HttpMethod.Post, RequestUri = requestUri, Content = multiPartContent};
|
|
|
|
httpRequest.Headers.Add("Token", ChatDaten.AuthToken);
|
|
httpRequest.Headers.Add("CustomerID", ChatDaten.Kundennummer);
|
|
|
|
var httpClient = new HttpClient();
|
|
await httpClient.SendAsync(httpRequest, CancellationToken.None);
|
|
}
|
|
}
|
|
|
|
public string OpenFile()
|
|
{
|
|
var openFileDialog = new OpenFileDialog
|
|
{
|
|
Filter = Resource.OpenFileDialogFilter_Test
|
|
};
|
|
|
|
var result = openFileDialog.ShowDialog();
|
|
|
|
return result == DialogResult.OK ? openFileDialog.FileName : null;
|
|
}
|
|
|
|
public List<ChatMessage> AddNewFile(string pathToScaledFile, string originalFilePath, long groupId, ChatMessage previousMessage, string chatBoxText)
|
|
{
|
|
var result = new List<ChatMessage>();
|
|
|
|
if(string.IsNullOrEmpty(pathToScaledFile) || string.IsNullOrEmpty(originalFilePath))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
var messageId = 0;
|
|
var userName = ChatDaten.LoggedInUser.Response.User.UserName;
|
|
var sendTime = DateTime.Now;
|
|
var fileName = Path.GetFileName(pathToScaledFile);
|
|
var imageFile = GetImageFile(pathToScaledFile, out var fileSize);
|
|
var isImage = Constants.ImageFileExtensions.Contains(Path.GetExtension(pathToScaledFile).ToUpperInvariant());
|
|
var messageText = string.IsNullOrWhiteSpace(chatBoxText) ? fileName : chatBoxText;
|
|
var filePath = isImage ? null : pathToScaledFile;
|
|
var originalImage = isImage ? pathToScaledFile : null;
|
|
var imageName = isImage ? fileName : null;
|
|
var linkToThumbnail = isImage ? null : $"{ChatDaten.ServerUrl}/document.png";
|
|
var logo = isImage ? imageFile : null;
|
|
var chatMessageType = isImage ? ChatMessageType.Image : ChatMessageType.Document;
|
|
var senderId = ChatDaten.LoggedInUser.Response.User.Oid;
|
|
|
|
var chatMessage = new ChatMessage(groupId, messageId, userName, messageText, sendTime, true, fileSize, filePath, originalImage, imageName, linkToThumbnail, logo, chatMessageType, senderId);
|
|
|
|
result = AddSeparators(new List<ChatMessage> { previousMessage, chatMessage });
|
|
|
|
result.Remove(previousMessage);
|
|
|
|
return result;
|
|
}
|
|
|
|
private static BitmapImage GetImageFile(string pathToScaledFile, out long fileSize)
|
|
{
|
|
if(!File.Exists(pathToScaledFile) || !Constants.ImageFileExtensions.Contains(Path.GetExtension(pathToScaledFile).ToUpperInvariant()))
|
|
{
|
|
fileSize = 0L;
|
|
return null;
|
|
}
|
|
|
|
byte[] file;
|
|
using(Stream reader = File.Open(pathToScaledFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
|
{
|
|
file = Utils.ReadFully(reader);
|
|
}
|
|
|
|
using(var memoryStream = new MemoryStream(file))
|
|
{
|
|
var image = Image.FromStream(memoryStream);
|
|
|
|
using(var bitmap = new Bitmap(image))
|
|
{
|
|
using(var stream = new MemoryStream())
|
|
{
|
|
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);
|
|
|
|
bitmap.Save(stream, ImageFormat.Jpeg);
|
|
|
|
var bitmapImage = new BitmapImage();
|
|
|
|
bitmapImage.BeginInit();
|
|
bitmapImage.StreamSource = new MemoryStream(stream.ToArray());
|
|
bitmapImage.EndInit();
|
|
bitmapImage.Freeze();
|
|
|
|
fileSize = memoryStream.Length;
|
|
return bitmapImage;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public List<ChatMessage> AddFileToMessage(byte[] file, string fileName, long groupId, ChatMessage previousMessage)
|
|
{
|
|
var result = new List<ChatMessage>();
|
|
|
|
if (string.IsNullOrEmpty(fileName))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
if(!(previousMessage is null))
|
|
{
|
|
result.Add(previousMessage);
|
|
}
|
|
|
|
var message = _UserMessages.Response.Messages.Last();
|
|
|
|
var sendtime = DateTime.Now;
|
|
|
|
if(Constants.ImageFileExtensions.Contains(Path.GetExtension(fileName).ToUpperInvariant()))
|
|
{
|
|
var bitmapImage = new BitmapImage();
|
|
var memoryStream = new MemoryStream(file);
|
|
|
|
bitmapImage.BeginInit();
|
|
bitmapImage.StreamSource = memoryStream;
|
|
bitmapImage.EndInit();
|
|
bitmapImage.Freeze();
|
|
|
|
memoryStream.Close();
|
|
ImageSource logo = bitmapImage;
|
|
|
|
// 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
|
|
{
|
|
// Dokument
|
|
var chatMessage = new ChatMessage(groupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, Path.GetFileName(fileName), sendtime, true, 0, fileName, null, null, message.SmallerImage, null, ChatMessageType.Document, ChatDaten.LoggedInUser.Response.User.Oid);
|
|
result.Add(chatMessage);
|
|
}
|
|
|
|
return AddSeparators(result);
|
|
}
|
|
|
|
public async Task SendFileToContact(Contact currentContact, string scaledImagePath, string originalFilePath, string message)
|
|
{
|
|
await SendFile(scaledImagePath, currentContact, originalFilePath, message);
|
|
}
|
|
|
|
private async Task SendFile(string pFile, Contact currentContact, string pOriginalFilePath, string message)
|
|
{
|
|
if(string.IsNullOrEmpty(pOriginalFilePath))
|
|
{
|
|
return;
|
|
}
|
|
|
|
byte[] mediaFile;
|
|
using(Stream reader = File.OpenRead(pFile))
|
|
{
|
|
mediaFile = Utils.ReadFully(reader);
|
|
}
|
|
|
|
var fileName = Path.GetFileName(pOriginalFilePath).ToLower();
|
|
|
|
if(Constants.ImageFileExtensions.Contains(Path.GetExtension(fileName).ToUpperInvariant()))
|
|
{
|
|
fileName = fileName.Replace(".bmp", ".jpg");
|
|
}
|
|
|
|
await SendMediaMessage(fileName, currentContact.GroupId, mediaFile, message);
|
|
}
|
|
|
|
private HttpRequestMessage _HttpRequest;
|
|
|
|
private async Task SendMediaMessage(string fileName, long groupId, byte[] mediaFile, string message)
|
|
{
|
|
try
|
|
{
|
|
using (var multiPartContent = new MultipartFormDataContent())
|
|
{
|
|
var requestUri = new Uri(ChatDaten.ServerUrl + Constants.SendMessageUrl);
|
|
|
|
multiPartContent.Add(new ByteArrayContent(mediaFile, 0, mediaFile.Length), "file", fileName);
|
|
multiPartContent.Add(new StringContent(groupId.ToString()), "groupid");
|
|
|
|
if(!string.IsNullOrWhiteSpace(message))
|
|
{
|
|
multiPartContent.Add(new StringContent(message), "text");
|
|
}
|
|
|
|
_HttpRequest = new HttpRequestMessage
|
|
{
|
|
Method = HttpMethod.Post,
|
|
RequestUri = requestUri,
|
|
Content = multiPartContent
|
|
};
|
|
|
|
_HttpRequest.Headers.Add(Constants.Token, ChatDaten.AuthToken);
|
|
_HttpRequest.Headers.Add(Constants.CustomerId, ChatDaten.Kundennummer);
|
|
|
|
var httpClient = new HttpClient();
|
|
await httpClient.SendAsync(_HttpRequest, HttpCompletionOption.ResponseContentRead);
|
|
}
|
|
}
|
|
catch(Exception)
|
|
{
|
|
}
|
|
}
|
|
|
|
public ContextMenu ErstelleKontextMenue()
|
|
{
|
|
var contextMenu = new ContextMenu();
|
|
|
|
var item1 = new System.Windows.Controls.MenuItem();
|
|
var item2 = new System.Windows.Controls.MenuItem();
|
|
var item3 = new System.Windows.Controls.MenuItem();
|
|
|
|
contextMenu.Items.Add(item1);
|
|
contextMenu.Items.Add(item2);
|
|
contextMenu.Items.Add(item3);
|
|
|
|
item1.Header = "Speichern unter";
|
|
item1.Visibility = Visibility.Visible;
|
|
|
|
item2.Header = "Einfügen";
|
|
item2.Visibility = Visibility.Visible;
|
|
|
|
item3.Header = "Kopieren";
|
|
item3.Visibility = Visibility.Visible;
|
|
|
|
return contextMenu;
|
|
}
|
|
|
|
public void SaveFileAs(ChatMessage pChatMessage)
|
|
{
|
|
var originalImage = pChatMessage.OriginalImage;
|
|
|
|
var fileUri = originalImage;
|
|
|
|
if(originalImage is null)
|
|
{
|
|
fileUri = pChatMessage.FilePath;
|
|
}
|
|
|
|
if(fileUri is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SaveAs(Path.GetFileName(fileUri), DownloadMediaFile(fileUri));
|
|
}
|
|
|
|
private static byte[] DownloadMediaFile(string uriToFile)
|
|
{
|
|
byte[] mediaFile;
|
|
|
|
using(var webClient = new WebClient())
|
|
{
|
|
webClient.Credentials = CredentialCache.DefaultCredentials;
|
|
webClient.Headers[Constants.Token] = ChatDaten.AuthToken;
|
|
webClient.Headers[Constants.CustomerId] = ChatDaten.Kundennummer;
|
|
mediaFile = webClient.DownloadData(uriToFile);
|
|
}
|
|
|
|
return mediaFile;
|
|
}
|
|
|
|
private static void SaveAs(string pFileName, byte[] pMediaFile)
|
|
{
|
|
var saveFileDialog = new SaveFileDialog {FileName = pFileName};
|
|
|
|
saveFileDialog.Title = "ownChat";
|
|
|
|
saveFileDialog.Filter = "All files (*.*)|*.*";
|
|
saveFileDialog.DefaultExt = Path.GetExtension(pFileName);
|
|
|
|
if(saveFileDialog.DefaultExt.Length > 0)
|
|
{
|
|
saveFileDialog.AddExtension = true;
|
|
saveFileDialog.Filter = $"{saveFileDialog.DefaultExt} files (*.{saveFileDialog.DefaultExt})|*.{saveFileDialog.DefaultExt}|{saveFileDialog.Filter}";
|
|
saveFileDialog.FilterIndex = 0;
|
|
}
|
|
|
|
saveFileDialog.ShowDialog();
|
|
|
|
if (string.IsNullOrEmpty(saveFileDialog.FileName))
|
|
{
|
|
return;
|
|
}
|
|
|
|
using (var fileStream = (FileStream)saveFileDialog.OpenFile())
|
|
{
|
|
fileStream.Write(pMediaFile, 0, pMediaFile.Length);
|
|
}
|
|
}
|
|
|
|
public async Task Paste(long pGroupOid, ChatMainControl pChatMainControl)
|
|
{
|
|
var dataObject = Clipboard.GetDataObject();
|
|
|
|
if(dataObject is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(dataObject.GetDataPresent(DataFormats.FileDrop))
|
|
{
|
|
if(dataObject.GetData(DataFormats.FileDrop) is string[] fileList)
|
|
{
|
|
var pathToFile = fileList[0];
|
|
|
|
if(File.Exists(pathToFile))
|
|
{
|
|
var fileName = Path.GetFileName(pathToFile);
|
|
|
|
var mediaFile = File.ReadAllBytes(pathToFile);
|
|
|
|
pChatMainControl.AddMessages(AddFileToMessage(mediaFile, fileName, pGroupOid, pChatMainControl.GetFirstMessage()));
|
|
|
|
CollectionViewSource.GetDefaultView(pChatMainControl.ChatListBox.ItemsSource).Refresh();
|
|
|
|
pChatMainControl.ChatListBox.Items.MoveCurrentToLast();
|
|
pChatMainControl.ChatListBox.ScrollIntoView(pChatMainControl.ChatListBox.Items.CurrentItem);
|
|
|
|
await SendMediaMessage(fileName, pGroupOid, mediaFile, null);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(dataObject.GetDataPresent(DataFormats.Text))
|
|
{
|
|
var text = (string) dataObject.GetData(DataFormats.StringFormat);
|
|
|
|
pChatMainControl.AddMessages(AddNewMessage(text, pGroupOid, pChatMainControl.GetFirstMessage()));
|
|
|
|
CollectionViewSource.GetDefaultView(pChatMainControl.ChatListBox.ItemsSource).Refresh();
|
|
|
|
pChatMainControl.ChatListBox.Items.MoveCurrentToLast();
|
|
pChatMainControl.ChatListBox.ScrollIntoView(pChatMainControl.ChatListBox.Items.CurrentItem);
|
|
|
|
await SendMessage(text, pGroupOid);
|
|
}
|
|
else if(dataObject.GetDataPresent(DataFormats.Bitmap))
|
|
{
|
|
var bitmap = (Bitmap) dataObject.GetData(DataFormats.Bitmap);
|
|
|
|
var imageName = Utils.GenerateTempName() + ".jpg";
|
|
|
|
Image image = bitmap;
|
|
|
|
pChatMainControl.AddMessages(AddFileToMessage(Utils.ImageToByteArray(image), imageName, pGroupOid, pChatMainControl.GetFirstMessage()));
|
|
|
|
CollectionViewSource.GetDefaultView(pChatMainControl.ChatListBox.ItemsSource).Refresh();
|
|
|
|
pChatMainControl.ChatListBox.Items.MoveCurrentToLast();
|
|
pChatMainControl.ChatListBox.ScrollIntoView(pChatMainControl.ChatListBox.Items.CurrentItem);
|
|
|
|
await SendMediaMessage(imageName, pGroupOid, Utils.ImageToByteArray(image), null);
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show("Der Zwischen-Speicher kann nicht verarbeitet werden.", "Fehler", MessageBoxButton.OK);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Copy(object pData, int pDataType)
|
|
{
|
|
switch(pDataType)
|
|
{
|
|
case 1:
|
|
Clipboard.SetData(DataFormats.Text, pData);
|
|
break;
|
|
case 2:
|
|
Clipboard.SetData(DataFormats.Bitmap, pData);
|
|
break;
|
|
case 3:
|
|
Clipboard.SetData(DataFormats.FileDrop, pData);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void ShowProfilePicture(Contact currentContact)
|
|
{
|
|
ShowPictureWindow(currentContact.Image, currentContact.Name);
|
|
}
|
|
|
|
public void ShowPictureWindow(ImageSource imageSource, string title)
|
|
{
|
|
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 > .8 * primaryScreenWidth2 || windowMaxHeight > .8 * primaryScreenHeight2)
|
|
{
|
|
if(primaryScreenWidth2 > primaryScreenHeight2)
|
|
{
|
|
windowMaxHeight = (int)(.8 * primaryScreenHeight2);
|
|
windowMaxWidth = (int)(windowMaxHeight * imageAspectRatio);
|
|
}
|
|
else
|
|
{
|
|
windowMaxWidth = (int)(.8 * primaryScreenWidth2);
|
|
windowMaxHeight = (int)(windowMaxWidth * imageAspectRatio);
|
|
}
|
|
}
|
|
|
|
var maximumWindowSize = new System.Windows.Size(windowMaxWidth, windowMaxHeight);
|
|
|
|
var minHeight = 232 / imageAspectRatio;
|
|
var minWidth = 232d;
|
|
|
|
var window = new Window
|
|
{
|
|
Title = title,
|
|
MinHeight = minHeight,
|
|
MinWidth = minWidth
|
|
};
|
|
|
|
var grid = new Grid
|
|
{
|
|
Width = maximumWindowSize.Width,
|
|
Height = maximumWindowSize.Height,
|
|
MinHeight = minHeight,
|
|
MinWidth = minWidth
|
|
};
|
|
|
|
var image = new System.Windows.Controls.Image
|
|
{
|
|
Source = imageSource,
|
|
Margin = new Thickness(0)
|
|
};
|
|
|
|
grid.Children.Clear();
|
|
grid.Children.Add(image);
|
|
|
|
window.SizeToContent = SizeToContent.WidthAndHeight;
|
|
window.Content = grid;
|
|
window.Margin = new Thickness(0);
|
|
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
|
|
|
window.ShowDialog();
|
|
}
|
|
|
|
public void ShowPicture(string originalImage, long groupId, Action<ImageSource, string> downloadCompletedCallback)
|
|
{
|
|
if(originalImage is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Utils.DownloadImageAsync(originalImage, $"group-{groupId}", CacheCategory.MessageAttachment, imageSource =>
|
|
{
|
|
var splitName = originalImage.Split('/');
|
|
var last = splitName.LastOrDefault();
|
|
|
|
downloadCompletedCallback?.Invoke(imageSource, last ?? "Bild");
|
|
});
|
|
}
|
|
|
|
public async Task ReloadGroupsAsync(Action<ChatGruppenDaten> callback)
|
|
{
|
|
var url = ChatDaten.ServerUrl + Constants.GetChatGroupsUrl;
|
|
|
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
|
|
|
// ToDo: Durch HttpClient ersetzen
|
|
|
|
using(var httpClient = new HttpClient())
|
|
{
|
|
httpClient.DefaultRequestHeaders.Add(Constants.Token, ChatDaten.AuthToken);
|
|
httpClient.DefaultRequestHeaders.Add(Constants.CustomerId, ChatDaten.Kundennummer);
|
|
|
|
var test = await httpClient.GetStringAsync(url);
|
|
|
|
var gruppen = JsonConvert.DeserializeObject<ChatGruppenDaten>(test);
|
|
}
|
|
|
|
|
|
|
|
var client = new RestClient(url);
|
|
var request = new RestRequest();
|
|
|
|
request.AddHeader(Constants.Token, ChatDaten.AuthToken);
|
|
request.AddHeader(Constants.CustomerId, ChatDaten.Kundennummer);
|
|
|
|
client.ExecuteAsync(request, response =>
|
|
{
|
|
var groups = JsonConvert.DeserializeObject<ChatGruppenDaten>(response.Content);
|
|
|
|
callback?.Invoke(groups);
|
|
});
|
|
}
|
|
|
|
public List<Contact> UpdateContacts(ChatGruppenDaten chatDaten)
|
|
{
|
|
_Contacts.Clear();
|
|
|
|
if(!(chatDaten?.Response is null))
|
|
{
|
|
_Contacts.AddRange(GenerateContactsFromServerResponse(chatDaten.Response.Groups.ToArray()));
|
|
}
|
|
|
|
return _Contacts;
|
|
}
|
|
|
|
public List<Contact> GenerateContactsFromServerResponse(GroupInput[] pGroupInputs, bool pShouldUpdateLastTimeStamp = false)
|
|
{
|
|
var contacts = new List<Contact>();
|
|
|
|
foreach(var groupInput in pGroupInputs)
|
|
{
|
|
var formattedTime = new DateTime();
|
|
|
|
var latestMessage = groupInput.LastMessage;
|
|
|
|
if(latestMessage?.Text != null)// && latestMessage?.Timestamp != null)
|
|
{
|
|
var timeStamp = DateTime.Parse(latestMessage.Timestamp.Date);
|
|
|
|
var clientZone = TimeZoneInfo.Local;
|
|
|
|
formattedTime = TimeZoneInfo.ConvertTimeFromUtc(timeStamp, clientZone);
|
|
}
|
|
|
|
string userIdManage = null;
|
|
|
|
foreach(var user in groupInput.Users)
|
|
{
|
|
if(user.Oid != ChatDaten.Userid)
|
|
{
|
|
if(!user.Is_Employee && !string.IsNullOrEmpty(user.Userid_Manage))
|
|
{
|
|
userIdManage = user.Userid_Manage;
|
|
}
|
|
}
|
|
}
|
|
|
|
var key = $"group-{groupInput.Oid}";
|
|
|
|
contacts.Add(new Contact(
|
|
groupInput.Name,
|
|
groupInput.LastMessage,
|
|
formattedTime,
|
|
groupInput.Oid,
|
|
userIdManage,
|
|
groupInput.OnlyEmployees,
|
|
groupInput.Users.Length,
|
|
groupInput.CanWrite,
|
|
groupInput.AccentColor,
|
|
groupInput.Avatar,
|
|
key, groupInput.Users.ToDictionary(user => user.Oid, user => user.Picture)));
|
|
|
|
if(!pShouldUpdateLastTimeStamp || latestMessage?.Timestamp?.Date is null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var time = DateTime.Parse(latestMessage.Timestamp.Date);
|
|
|
|
//var unixTimeStamp = latestMessage.Timestamp.Value.GetUnixTimeStamp();
|
|
var unixTimeStamp = time.GetUnixTimeStamp();
|
|
|
|
if(LastTimeStamp < unixTimeStamp)
|
|
{
|
|
LastTimeStamp = unixTimeStamp;
|
|
}
|
|
}
|
|
|
|
Task.Run(() =>
|
|
{
|
|
var userId2Uris = new Dictionary<long, string>();
|
|
foreach(var contact in contacts)
|
|
{
|
|
foreach(var test in contact.UserId2Uri)
|
|
{
|
|
userId2Uris.AddAndIgnoreDuplicates(test.Key, test.Value);
|
|
}
|
|
}
|
|
|
|
Utils.DownloadUserProfilePicturesSync(userId2Uris);
|
|
|
|
foreach(var contact in contacts)
|
|
{
|
|
contact.Image = Utils.DownloadImageSync(contact.ProfilePicturePath, null, contact.GroupId);
|
|
}
|
|
});
|
|
|
|
return contacts;
|
|
}
|
|
|
|
public List<ChatMessage> AddMessagesFromServerResponse(OwnChatMessage[] pMessages, ChatMessage previousMessage)
|
|
{
|
|
var result = new List<ChatMessage>();
|
|
|
|
foreach(var message in pMessages ?? new OwnChatMessage[0])
|
|
{
|
|
var time = DateTime.Parse(message.Timestamp.Date);
|
|
|
|
var clientZone = TimeZoneInfo.Local;
|
|
var formattedTime = TimeZoneInfo.ConvertTimeFromUtc(time, clientZone);
|
|
|
|
var isLoggedInUsersMessage = false == ChatDaten.Userid is null && message.UserId == ChatDaten.Userid.Value;
|
|
var messageText = message.Text ?? (string.IsNullOrEmpty(message.FileProtected) ? string.Empty : message.OriginalFilename);
|
|
|
|
if(false == string.IsNullOrEmpty(message.FileProtected))
|
|
{
|
|
var message2Add = Constants.ImageFileExtensions.Contains(Path.GetExtension(message.FileProtected).ToUpperInvariant()) ? //SmallerImage ist null
|
|
new ChatMessage(message.GroupId, message.Id, message.UserName, messageText, formattedTime, isLoggedInUsersMessage, message.FileSize, message.SmallerImage, message.FileProtected, message.OriginalFilename, null, null, ChatMessageType.Image, message.UserId) :
|
|
new ChatMessage(message.GroupId, message.Id, message.UserName, messageText, formattedTime, isLoggedInUsersMessage, 0, message.FileProtected, null, null, message.SmallerImage, null, ChatMessageType.Document, message.UserId);
|
|
|
|
result.AddIfNotIn(message2Add);
|
|
}
|
|
else
|
|
{
|
|
var chatMessage = new ChatMessage(message.GroupId, message.Id, message.UserName, message.Text, formattedTime, isLoggedInUsersMessage, message.FileSize, null, null, null, null, null, ChatMessageType.Message, message.UserId);
|
|
|
|
result.AddIfNotIn(chatMessage);
|
|
}
|
|
}
|
|
|
|
return AddSeparators(result);
|
|
}
|
|
|
|
private static List<ChatMessage> AddSeparators(List<ChatMessage> chatMessages)
|
|
{
|
|
if(chatMessages is null)
|
|
{
|
|
chatMessages = new List<ChatMessage>();
|
|
}
|
|
|
|
var messagesWithoutSeparators = chatMessages.Where(message => message != null && false == message.IsSeparator).OrderBy(message => message.SendTime).ToList();
|
|
|
|
var separators = new List<ChatMessage>();
|
|
|
|
var previousMessage = messagesWithoutSeparators.OrderBy(message => message.SendTime).FirstOrDefault();
|
|
|
|
foreach(var message in messagesWithoutSeparators.OrderBy(message => message.SendTime))
|
|
{
|
|
if(false == message.Equals(previousMessage) && false == previousMessage is null)
|
|
{
|
|
if(message.SendTime.Date != previousMessage.SendTime.Date)
|
|
{
|
|
var separatorMessage = new ChatMessage(0, -1, null, null, message.SendTime.Date, false, 0, null, null, null, null, null, ChatMessageType.Separator, 0);
|
|
|
|
separators.Add(separatorMessage);
|
|
|
|
previousMessage = message;
|
|
}
|
|
}
|
|
}
|
|
|
|
chatMessages.AddRange(separators);
|
|
|
|
return chatMessages;
|
|
}
|
|
|
|
public void DownloadFileAsync(string uri, string path, Action callback)
|
|
{
|
|
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();
|
|
});
|
|
}
|
|
|
|
private bool _IsInBroadcastMode;
|
|
|
|
public bool IsInBroadcastMode
|
|
{
|
|
get => _IsInBroadcastMode;
|
|
set
|
|
{
|
|
_IsInBroadcastMode = value;
|
|
OnPropertyChanged(nameof(IsInBroadcastMode));
|
|
}
|
|
}
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
|
|
[NotifyPropertyChangedInvocator]
|
|
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
}
|
|
|
|
public class ChatMessageComparer : IComparer
|
|
{
|
|
public int Compare(object x, object y)
|
|
{
|
|
return x is ChatMessage message1 && y is ChatMessage message2 ? message1.SendTime.CompareTo(message2.SendTime) : 0;
|
|
}
|
|
}
|
|
}
|