//--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\ #region --Misc Methods (Public)-- /// <summary> /// Retries to download the image from the given ChatMessageTable. /// </summary> /// <param name="msg">The ChatMessageTable containing the image url.</param> /// <returns>The image container.</returns> public ImageTable retryImageDownload(ChatMessageTable msg) { if (msg.isImage) { ImageTable img = getImageForMessage(msg); if (img == null) { img = new ImageTable() { messageId = msg.id, path = null, state = DownloadState.WAITING, progress = 0 }; } else { img.state = DownloadState.WAITING; img.progress = 0; img.path = null; } Task.Run(async() => { update(img); await downloadImageAsync(img, msg.message); }); return(img); } return(null); }
public async Task deleteImageAsync(ChatMessageTable msg) { ImageTable image = await getImageAsync(msg); if (!(image is null)) { // Cancel download: ConnectionHandler.INSTANCE.IMAGE_DOWNLOAD_HANDLER.CancelDownload(image); // Try to delete local file: try { if (!string.IsNullOrEmpty(image.TargetFolderPath) && !string.IsNullOrEmpty(image.TargetFileName)) { string path = image.GetFullPath(); StorageFile file = await StorageFile.GetFileFromPathAsync(path); if (!(file is null)) { await file.DeleteAsync(); } } Logger.Info("Deleted: " + image.TargetFileName); } catch (Exception e) { Logger.Error("Failed to delete image: " + image.TargetFileName, e); } // Delete DB entry: dB.Delete(image); } }
private void C_OmemoSessionBuildError(XMPPClient client, XMPP_API.Classes.Events.OmemoSessionBuildErrorEventArgs args) { Task.Run(() => { ChatTable chat = ChatDBManager.INSTANCE.getChat(ChatTable.generateId(args.CHAT_JID, client.getXMPPAccount().getBareJid())); if (!(chat is null)) { // Add an error chat message: ChatMessageTable msg = new ChatMessageTable() { id = ChatMessageTable.generateErrorMessageId(AbstractMessage.getRandomId(), chat.id), chatId = chat.id, date = DateTime.Now, fromUser = args.CHAT_JID, isImage = false, message = "Failed to encrypt and send " + args.MESSAGES.Count + " OMEMO message(s) with:\n" + args.ERROR, state = MessageState.UNREAD, type = MessageMessage.TYPE_ERROR }; ChatDBManager.INSTANCE.setChatMessage(msg, true, false); // Set chat messages to encrypted failed: setOmemoChatMessagesSendFailed(args.MESSAGES, chat); } }); }
public static void showChatTextToast(ChatMessageTable msg, ChatTable chat) { ToastContent toastContent = new ToastContent { Visual = new ToastVisual { BindingGeneric = new ToastBindingGeneric { Children = { new AdaptiveText() { Text = chat.chatJabberId, HintMaxLines = 1 }, new AdaptiveText() { Text = msg.message } }, AppLogoOverride = new ToastGenericAppLogo { Source = chat.chatType == ChatType.CHAT ? DEFAULT_USER_IMAGE_PATH : DEFAULT_MUC_IMAGE_PATH, HintCrop = ToastGenericAppLogoCrop.Circle } } }, Actions = getActions(msg, chat), DisplayTimestamp = msg.date, Launch = new ChatToastActivation(chat.id, msg.id).generate() }; popToast(toastContent, chat); }
private static ToastActionsCustom getActions(ChatMessageTable msg, ChatTable chat) { return(new ToastActionsCustom() { /*Inputs = * { * new ToastTextBox(TEXT_BOX_ID) * { * PlaceholderContent = "Reply" * } * },*/ Buttons = { /*new ToastButton("Send", new SendReplyToastActivation(chat.id, false).generate()) * { * ActivationType = ToastActivationType.Background, * ImageUri = SEND_BUTTON_IMAGE_PATH, * TextBoxId = TEXT_BOX_ID, * },*/ new ToastButton("Mark chat as read", new MarkChatAsReadToastActivation(chat.id, false).generate()) { ActivationType = ToastActivationType.Background }, new ToastButton("Mark as read", new MarkMessageAsReadToastActivation(msg.id, false).generate()) { ActivationType = ToastActivationType.Background } } }); }
public void markMessageAsRead(ChatMessageTable msg) { msg.state = MessageState.READ; dB.InsertOrReplace(msg); msg.onChanged(); ChatMessageChanged?.Invoke(this, new ChatMessageChangedEventArgs(msg, false)); }
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\ #region --Constructors-- #endregion //--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\ #region --Set-, Get- Methods-- public async Task <ImageTable> getImageAsync(ChatMessageTable msg) { await GET_IMAGE_SEMA.WaitAsync(); // Is already downloading: ImageTable img = (ImageTable)await ConnectionHandler.INSTANCE.IMAGE_DOWNLOAD_HANDLER.FindAsync((x) => { return(x is ImageTable imageTable && string.Equals(imageTable.messageId, msg.id)); }); if (img is null) { // Is in the DB: List <ImageTable> list = dB.Query <ImageTable>(true, "SELECT * FROM " + DBTableConsts.IMAGE_TABLE + " WHERE " + nameof(ImageTable.messageId) + " = ?;", msg.id); if (list.Count > 0) { img = list[0]; } else { // Create a new image entry: StorageFolder folder = await ConnectionHandler.INSTANCE.IMAGE_DOWNLOAD_HANDLER.GetCacheFolderAsync(); img = new ImageTable() { messageId = msg.id, SourceUrl = msg.message, TargetFileName = ConnectionHandler.INSTANCE.IMAGE_DOWNLOAD_HANDLER.CreateUniqueFileName(msg.message), TargetFolderPath = folder.Path, State = DownloadState.NOT_QUEUED, Progress = 0, }; setImage(img); } } GET_IMAGE_SEMA.Release(); return(img); }
private static ToastActionsCustom getActions(ChatMessageTable msg, ChatTable chat) { return(new ToastActionsCustom { Inputs = { new ToastTextBox(TEXT_BOX_ID) { PlaceholderContent = "Reply" } }, Buttons = { new ToastButton("Send", new SendReplyToastActivation(chat.id, msg.id).generate()) { ActivationType = ToastActivationType.Background, ImageUri = chat.omemoEnabled ? SEND_BUTTON_ENCRYPTED_IMAGE_PATH : SEND_BUTTON_IMAGE_PATH, TextBoxId = TEXT_BOX_ID, }, new ToastButton("Mark chat as read", new MarkChatAsReadToastActivation(chat.id, false).generate()) { ActivationType = ToastActivationType.Background }, new ToastButton("Mark as read", new MarkMessageAsReadToastActivation(msg.id).generate()) { ActivationType = ToastActivationType.Background } } }); }
private void cacheImage(ChatMessageTable msg) { if (!Settings.getSettingBoolean(SettingsConsts.DISABLE_IMAGE_AUTO_DOWNLOAD)) { Task.Run(async() => await ConnectionHandler.INSTANCE.IMAGE_DOWNLOAD_HANDLER.DownloadImageAsync(msg)); } }
public static void showChatTextEncryptedToast(ChatMessageTable msg, ChatTable chat) { var toastContent = new ToastContent() { Visual = new ToastVisual() { BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = chat.chatJabberId, HintMaxLines = 1 }, new AdaptiveText() { Text = "You received an encrypted message!" } }, AppLogoOverride = new ToastGenericAppLogo() { Source = chat.chatType == ChatType.CHAT ? DEFAULT_USER_IMAGE_PATH : DEFAULT_MUC_IMAGE_PATH, HintCrop = ToastGenericAppLogoCrop.Default } } }, Actions = getActions(msg, chat), DisplayTimestamp = msg.date, Launch = new ChatToastActivation(chat.id, false).generate() }; popToast(toastContent, chat); }
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\ #region --Constructors-- #endregion //--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\ #region --Set-, Get- Methods-- #endregion //--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\ #region --Misc Methods (Public)-- public void UpdateView(ChatTable chat, ChatMessageTable message) { if (chat is null || message is null) { return; } Text = message.message; IsCarbonCopy = message.isCC; IsEncrypted = message.isEncrypted; Date = message.date; MessageType = message.type; IsImage = message.isImage; State = message.state; if (State == MessageState.UNREAD) { Task.Run(() => ChatDBManager.INSTANCE.markMessageAsRead(message)); } if (chat.chatType == ChatType.MUC) { NicknameText = message.fromUser; } else { NicknameText = string.Empty; } }
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\ #region --Constructors-- /// <summary> /// Basic Constructor /// </summary> /// <history> /// 27/08/2017 Created [Fabian Sauter] /// </history> public ChatMasterControl() { this.InitializeComponent(); this.subscriptionRequest = false; this.lastChatMessage = null; this.updateBookmarkHelper = null; }
private void markMessageAsRead(ChatMessageTable msg) { msg.state = MessageState.READ; update(msg); msg.onChanged(); ChatMessageChanged?.Invoke(this, new ChatMessageChangedEventArgs(msg)); }
private void setOmemoChatMessagesSendFailed(IList <OmemoMessageMessage> messages, ChatTable chat) { foreach (OmemoMessageMessage msg in messages) { string msgId = ChatMessageTable.generateId(msg.ID, chat.id); ChatDBManager.INSTANCE.updateChatMessageState(msgId, MessageState.ENCRYPT_FAILED); } }
public void markMessageAsRead(string id) { ChatMessageTable msg = getChatMessageById(id); if (msg != null) { markMessageAsRead(msg); } }
private async Task SendChatMessageAsync(ChatDataTemplate chat, string message) { MessageMessage toSendMsg; string from = chat.Client.getXMPPAccount().getFullJid(); string to = chat.Chat.chatJabberId; string chatType = chat.Chat.chatType == ChatType.CHAT ? MessageMessage.TYPE_CHAT : MessageMessage.TYPE_GROUPCHAT; bool reciptRequested = true; if (chat.Chat.omemoEnabled) { if (chat.Chat.chatType == ChatType.CHAT) { toSendMsg = new OmemoMessageMessage(from, to, message, chatType, reciptRequested); } else { // ToDo: Add MUC OMEMO support throw new NotImplementedException("Sending encrypted messages for MUC is not supported right now!"); } } else { toSendMsg = chat.Chat.chatType == ChatType.CHAT ? new MessageMessage(from, to, message, chatType, reciptRequested) : new MessageMessage(from, to, message, chatType, chat.MucInfo.nickname, reciptRequested); } // Create a copy for the DB: ChatMessageTable toSendMsgDB = new ChatMessageTable(toSendMsg, chat.Chat) { state = toSendMsg is OmemoMessageMessage ? MessageState.TO_ENCRYPT : MessageState.SENDING }; // Set the chat message id for later identification: toSendMsg.chatMessageId = toSendMsgDB.id; // Update chat last active: chat.Chat.lastActive = DateTime.Now; // Update DB: await Task.Run(() => { ChatDBManager.INSTANCE.setChatMessage(toSendMsgDB, true, false); ChatDBManager.INSTANCE.setChat(chat.Chat, false, true); }); // Send the message: if (toSendMsg is OmemoMessageMessage toSendOmemoMsg) { await chat.Client.sendOmemoMessageAsync(toSendOmemoMsg, chat.Chat.chatJabberId, chat.Client.getXMPPAccount().getBareJid()); } else { await chat.Client.SendAsync(toSendMsg); } }
private async Task cacheImageAsync(ChatMessageTable msg) { if (!Settings.getSettingBoolean(SettingsConsts.DISABLE_IMAGE_AUTO_DOWNLOAD)) { ImageTable img = await ImageDBManager.INSTANCE.getImageAsync(msg); await ConnectionHandler.INSTANCE.IMAGE_DOWNLOAD_HANDLER.StartDownloadAsync(img); } }
private void C_NewDeliveryReceipt(XMPPClient client, NewDeliveryReceiptEventArgs args) { Task.Run(() => { string to = Utils.getBareJidFromFullJid(args.MSG.getTo()); string from = Utils.getBareJidFromFullJid(args.MSG.getFrom()); string chatId = ChatTable.generateId(from, to); string msgId = ChatMessageTable.generateId(args.MSG.RECEIPT_ID, chatId); ChatDBManager.INSTANCE.setMessageAsDeliverd(msgId, true); }); }
//--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\ #region --Set-, Get- Methods-- public void setMessageAsDeliverd(string id, bool triggerMessageChanged) { dB.Execute("UPDATE " + DBTableConsts.CHAT_MESSAGE_TABLE + " SET state = ? WHERE id = ?", MessageState.DELIVERED, id); if (triggerMessageChanged) { ChatMessageTable msg = getChatMessageById(id); if (msg != null) { ChatMessageChanged?.Invoke(this, new ChatMessageChangedEventArgs(msg, false)); } } }
private async Task onMUCErrorMessageAsync(XMPPClient client, MUCErrorMessage errorMessage) { string room = Utils.getBareJidFromFullJid(errorMessage.getFrom()); if (room != null) { string chatId = ChatTable.generateId(room, client.getXMPPAccount().getBareJid()); ChatTable muc = ChatDBManager.INSTANCE.getChat(chatId); if (muc != null) { MUCChatInfoTable info = MUCDBManager.INSTANCE.getMUCInfo(chatId); if (info != null) { Logger.Error("Received an error message for MUC: " + muc.chatJabberId + "\n" + errorMessage.ERROR_MESSAGE); stopMUCJoinHelper(muc); if (info.state != MUCState.DISCONNECTED) { await sendMUCLeaveMessageAsync(client, muc, info); } switch (errorMessage.ERROR_CODE) { // No access - user got baned: case 403: MUCDBManager.INSTANCE.setMUCState(info.chatId, MUCState.BANED, true); addChatInfoMessage(info.chatId, room, "Unable to join room!\nYou are baned from this room."); return; default: MUCDBManager.INSTANCE.setMUCState(info.chatId, MUCState.ERROR, true); break; } // Add an error chat message: ChatMessageTable msg = new ChatMessageTable() { id = ChatMessageTable.generateErrorMessageId(errorMessage.ID ?? AbstractMessage.getRandomId(), muc.id), chatId = muc.id, date = DateTime.Now, fromUser = errorMessage.getFrom(), isImage = false, message = "Code: " + errorMessage.ERROR_CODE + "\nType: " + errorMessage.ERROR_TYPE + "\nMessage:\n" + errorMessage.ERROR_MESSAGE, state = MessageState.UNREAD, type = MessageMessage.TYPE_ERROR }; ChatDBManager.INSTANCE.setChatMessage(msg, true, false); } } } }
public void UpdateLastAction(ChatTable chat) { Task.Run(() => { ChatMessageTable lastMsg = ChatDBManager.INSTANCE.getLastChatMessageForChat(chat.id); if (lastMsg is null) { LastActionIconText = ""; LastActionIconVisability = Visibility.Collapsed; LastActionState = MessageState.READ; } else { // Text and icon: LastActionState = lastMsg.state; if (lastMsg.isImage) { LastActionIconText = "\uE722"; LastActionIconVisability = Visibility.Visible; LastActionText = lastMsg.message ?? "You received an image"; } else { switch (lastMsg.type) { case DirectMUCInvitationMessage.TYPE_MUC_DIRECT_INVITATION: LastActionIconText = "\uE8F2"; LastActionIconVisability = Visibility.Visible; LastActionText = "You have been invited to a MUC room"; break; case MessageMessage.TYPE_ERROR: LastActionIconText = "\xE7BA"; LastActionIconVisability = Visibility.Visible; LastActionText = lastMsg.message ?? "You received an error message"; break; case MUCHandler.TYPE_CHAT_INFO: LastActionIconText = "\uE946"; LastActionIconVisability = Visibility.Visible; LastActionText = (lastMsg.message ?? "-"); break; default: LastActionIconVisability = Visibility.Collapsed; LastActionText = lastMsg.message ?? ""; break; } } } }); }
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\ #region --Constructors-- #endregion //--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\ #region --Set-, Get- Methods-- /// <summary> /// /// </summary> /// <param name="msg"></param> /// <returns></returns> public async Task <ImageTable> getImageAsync(ChatMessageTable msg) { ImageTable img = (ImageTable)await ConnectionHandler.INSTANCE.IMAGE_DOWNLOAD_HANDLER.FindAsync((x) => { return(x is ImageTable imageTable && string.Equals(imageTable.messageId, msg.id)); }); if (img is null) { List <ImageTable> list = dB.Query <ImageTable>(true, "SELECT * FROM " + DBTableConsts.IMAGE_TABLE + " WHERE " + nameof(ImageTable.messageId) + " = ?;", msg.id); if (list.Count > 0) { img = list[0]; } } return(img); }
/// <summary> /// Returns the image container from a given ChatMessageTable. /// </summary> /// <param name="msg">The ChatMessageTable.</param> /// <returns>The corresponding image container.</returns> public ImageTable getImageForMessage(ChatMessageTable msg) { ImageTable img = downloading.Find(x => string.Equals(x.messageId, msg.id)); if (img == null) { List <ImageTable> list = dB.Query <ImageTable>(true, "SELECT * FROM " + DBTableConsts.IMAGE_TABLE + " WHERE messageId = ?;", msg.id); if (list.Count > 0) { img = list[0]; } } return(img); }
/// <summary> /// Continues all outstanding downloads. /// </summary> private void contiuneAllDownloads() { List <ImageTable> list = dB.Query <ImageTable>(true, "SELECT * FROM " + DBTableConsts.IMAGE_TABLE + " WHERE state = 0 OR state = 1;"); foreach (ImageTable img in list) { Task.Run(async() => { // Reset image progress: img.progress = 0; ChatMessageTable msg = ChatDBManager.INSTANCE.getChatMessageById(img.messageId); await downloadImageAsync(img, msg.message); }); } }
public void setChatMessage(ChatMessageTable message, bool triggerNewChatMessage, bool triggerMessageChanged) { update(message); if (triggerNewChatMessage) { NewChatMessage?.Invoke(this, new NewChatMessageEventArgs(message)); if (message.isImage) { cacheImage(message); } } if (triggerMessageChanged) { ChatMessageChanged?.Invoke(this, new ChatMessageChangedEventArgs(message)); } }
public void setChatMessage(ChatMessageTable message, bool triggerNewChatMessage, bool triggerMessageChanged) { dB.InsertOrReplace(message); if (triggerNewChatMessage) { NewChatMessage?.Invoke(this, new NewChatMessageEventArgs(message)); if (message.isImage && !Settings.getSettingBoolean(SettingsConsts.DISABLE_IMAGE_AUTO_DOWNLOAD)) { cacheImage(message); } } if (triggerMessageChanged) { ChatMessageChanged?.Invoke(this, new ChatMessageChangedEventArgs(message, false)); } }
private void addChatInfoMessage(string chatId, string fromUser, string message) { ChatMessageTable msg = new ChatMessageTable { id = ChatMessageTable.generateId(AbstractMessage.getRandomId(), chatId), chatId = chatId, date = DateTime.Now, fromUser = fromUser, isImage = false, message = message, state = MessageState.UNREAD, type = TYPE_CHAT_INFO }; ChatDBManager.INSTANCE.setChatMessage(msg, true, false); }
public async Task deleteChatMessageAsync(ChatMessageTable message, bool triggerMessageChanged) { if (message.isImage) { await ImageDBManager.INSTANCE.deleteImageAsync(message); } if (string.Equals(message.type, DirectMUCInvitationMessage.TYPE_MUC_DIRECT_INVITATION)) { deleteMucDirectInvite(message); } dB.Delete(message); if (triggerMessageChanged) { ChatMessageChanged?.Invoke(this, new ChatMessageChangedEventArgs(message, true)); } }
/// <summary> /// Creates a new task, downloads the image from the given message and stores it locally. /// </summary> /// <param name="msg">The ChatMessageTable containing the image url.</param> public void downloadImage(ChatMessageTable msg) { if (msg.isImage) { Task.Run(async() => { ImageTable img = new ImageTable() { messageId = msg.id, path = null, state = DownloadState.WAITING, progress = 0 }; update(img); await downloadImageAsync(img, msg.message); }); } }
//--------------------------------------------------------Events:---------------------------------------------------------------------\\ #region --Events-- private async void INSTANCE_NewChatMessage(ChatDBManager handler, NewChatMessageEventArgs args) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { ChatMessageTable msg = args.MESSAGE; if (Chat != null && Chat.id.Equals(msg.chatId)) { // Only update for unread messages: if (msg.state == MessageState.UNREAD) { msg.state = MessageState.READ; ChatDBManager.INSTANCE.setChatMessage(msg, false, true); } chatMessages.Add(new ChatMessageDataTemplate() { message = msg, chat = Chat }); } }); }