private async void Page_OnLoaded(object sender, RoutedEventArgs e) { // load name of the user Title = "Chatting with " + (await SharedStuff.Database.Table <DatabaseHelper.Users>().Where(row => row.Username == Username) .FirstAsync()).Name; // load fist 100 messages var messages = await SharedStuff.Database.QueryAsync <DatabaseHelper.Messages> (DatabaseHelper.LastRowsQuery(0, 100), Username); if (messages.Count < 100) // prevent additional load on db { _reachedEnd = true; } foreach (var message in messages) { if (message.Type == 0) { MessagesList.Insert(0, new ChatMessagesNotify { MyMessage = message.MyMessage, Message = message.Payload, FullDate = message.Date, Type = message.Type, Sent = 0, Progress = 101 }); } else if (message.Type == 1) { var fileInfo = await SharedStuff.Database.Table <DatabaseHelper.Files>() .FirstAsync(file => file.Token == message.Payload); var downloadButtonIcon = PackIconKind.Download; if (!string.IsNullOrEmpty(fileInfo.Location)) { downloadButtonIcon = File.Exists(fileInfo.Location) ? PackIconKind.File : PackIconKind.DownloadOff; } MessagesList.Insert(0, new ChatMessagesNotify { MyMessage = message.MyMessage, Message = fileInfo.Name, FullDate = message.Date, Type = message.Type, Sent = 0, Token = message.Payload, DownloadButtonIcon = downloadButtonIcon, Progress = 101 }); } } MainScrollViewer.ScrollToBottom(); // Go to the last of scroll view that is actually the first of it MainScrollViewer.UpdateLayout(); _stopLoading = false; }
/// <summary> /// Add message to UI /// </summary> /// <param name="message">The message to add</param> public void AddMessage(ChatMessagesNotify message) { _lastMessageIndex++; //TODO: Will this make some problems when the message is not sent? Application.Current.Dispatcher.Invoke(() => MessagesList.Add(message)); if (!message.MyMessage) { _stopLoading = true; // scroll to bottom if needed MainScrollViewer.UpdateLayout(); if (MainScrollViewer.ScrollableHeight - MainScrollViewer.VerticalOffset < 30) { MainScrollViewer.ScrollToBottom(); MainScrollViewer.UpdateLayout(); } _stopLoading = false; } }
/// <summary> /// Use this method to get older messages when VerticalOffset reaches 0 (scrolled to top) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void MainScrollViewer_OnScrollChanged(object sender, ScrollChangedEventArgs e) { if (!_stopLoading && !_reachedEnd && Math.Abs(e.VerticalOffset) < 1) // load more messages { _stopLoading = true; // get last height double lastHeight = MainScrollViewer.ScrollableHeight; var messages = await SharedStuff.Database.QueryAsync <DatabaseHelper.Messages> (DatabaseHelper.LastRowsQuery(_lastMessageIndex, 100), Username); _lastMessageIndex += 100; // check if we have reached the end if (messages.Count < 100) { _reachedEnd = true; } if (messages.Count == 0) { return; } // insert these messages at the end of the list view (that is first of the collation) foreach (var message in messages) { /*MessagesList.Insert(0, new ChatMessagesNotify * { * MyMessage = message.MyMessage, * Message = message.Payload, * FullDate = message.Date, * Type = message.Type * });*/ if (message.Type == 0) { MessagesList.Insert(0, new ChatMessagesNotify { MyMessage = message.MyMessage, Message = message.Payload, FullDate = message.Date, Type = message.Type, Sent = 0, Progress = 101 }); } else if (message.Type == 1) { var fileInfo = await SharedStuff.Database.Table <DatabaseHelper.Files>() .FirstAsync(file => file.Token == message.Payload); var downloadButtonIcon = PackIconKind.Download; if (!string.IsNullOrEmpty(fileInfo.Location)) { downloadButtonIcon = File.Exists(fileInfo.Location) ? PackIconKind.File : PackIconKind.DownloadOff; } MessagesList.Insert(0, new ChatMessagesNotify { MyMessage = message.MyMessage, Message = fileInfo.Name, FullDate = message.Date, Type = message.Type, Sent = 0, Token = message.Payload, DownloadButtonIcon = downloadButtonIcon, Progress = 101 }); } } MainScrollViewer.UpdateLayout(); MainScrollViewer.ScrollToVerticalOffset(MainScrollViewer.ScrollableHeight - lastHeight); // tricky part; calculate the delta of height adding and go to that position from top MainScrollViewer.UpdateLayout(); _stopLoading = false; } }
private async void MessageTextBox_OnKeyDown(object sender, KeyEventArgs e) { if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) { if (Keyboard.IsKeyDown(Key.Enter)) { string message = MessageTextBox.Text.Trim().TrimEnd(Environment.NewLine.ToCharArray()); // do not send the message if it's empty if (string.IsNullOrWhiteSpace(message)) { return; } if (SharedStuff.Websocket.IsAlive) { string id = Guid.NewGuid().ToString(); await Task.Run(() => SendMessage(message, id)); // send message over network var msgUi = new ChatMessagesNotify { MyMessage = true, Message = message, FullDate = DateTime.Now, Type = 0, Sent = 1 }; AddMessage(msgUi); // add it to ui SharedStuff.PendingMessages.Add(id, msgUi); // add message to pending messages } else { var msgUi = new ChatMessagesNotify { MyMessage = true, Message = message, FullDate = DateTime.Now, Type = 0, Sent = 2 }; AddMessage(msgUi); } // finalizing UI MessageTextBox.Text = ""; MessageTextBox.Focus(); _stopLoading = true; MainScrollViewer.ScrollToBottom(); MainScrollViewer.UpdateLayout(); _stopLoading = false; SendButtonIcon.Kind = PackIconKind.Attachment; SendButton.ToolTip = "Send File"; } } if (string.IsNullOrWhiteSpace(MessageTextBox.Text)) // show attachment icon { SendButtonIcon.Kind = PackIconKind.Attachment; SendButton.ToolTip = "Send File"; } else { SendButtonIcon.Kind = PackIconKind.Send; SendButton.ToolTip = "Send Message"; } }
private async void SendBtnClicked(object sender, RoutedEventArgs e) { string message = MessageTextBox.Text.Trim(); // initialize file send if (string.IsNullOrWhiteSpace(message)) { OpenFileDialog ofd = new OpenFileDialog { Title = "Send File" }; bool?result = ofd.ShowDialog(); if (result.HasValue && result.Value) { string key = (await SharedStuff.Database.Table <DatabaseHelper.Users>().Where(user => user.Username == Username) .FirstAsync()).Key; // at first request a token string id = Guid.NewGuid().ToString(); var msgUi = new ChatMessagesNotify { MyMessage = true, Message = Path.GetFileName(ofd.FileName), FullDate = DateTime.Now, Type = 1, Sent = 1, FilePath = ofd.FileName, With = Username }; SharedStuff.PendingMessages.Add(id, msgUi); // create json string json = JsonConvert.SerializeObject(new JsonTypes.SendMessage { Type = 2, Id = id, Payload = new JsonTypes.SendMessagePayload { To = Username, Message = Path.GetFileName(ofd.FileName) } }); SharedStuff.Websocket.SendAsync(json, null); AddMessage(msgUi); } } else { if (SharedStuff.Websocket.IsAlive) { string id = Guid.NewGuid().ToString(); await Task.Run(() => SendMessage(message, id)); var msgUi = new ChatMessagesNotify { MyMessage = true, Message = message, FullDate = DateTime.Now, Type = 0, Sent = 1 }; AddMessage(msgUi); // add it to ui SharedStuff.PendingMessages.Add(id, msgUi); // add message to pending messages } else { var msgUi = new ChatMessagesNotify { MyMessage = true, Message = message, FullDate = DateTime.Now, Type = 0, Sent = 2 }; AddMessage(msgUi); } // finalizing UI MessageTextBox.Text = ""; MessageTextBox.Focus(); _stopLoading = true; MainScrollViewer.ScrollToBottom(); MainScrollViewer.UpdateLayout(); _stopLoading = false; SendButtonIcon.Kind = PackIconKind.Attachment; SendButton.ToolTip = "Send File"; } }