public ChatItem(IChatModel chatModel) { InitializeComponent(); if (chatModel == null) { chatModel = new TextChatModel() { Author = "System", Body = "No chat messages were found regarding this client.", Inbound = true, Time = DateTime.Now }; } ChatModel = chatModel; if (chatModel.Inbound) { bodyPanel.Dock = DockStyle.Left; authorLabel.Dock = DockStyle.Left; bodyPanel.BackColor = Color.FromArgb(100, 101, 165); bodyTextBox.BackColor = Color.FromArgb(100, 101, 165); } else { bodyPanel.Dock = DockStyle.Right; authorLabel.Dock = DockStyle.Right; bodyTextBox.TextAlign = HorizontalAlignment.Right; } //Fills in the label. if (chatModel.Time > DateTime.Today) { authorLabel.Text = $"{chatModel.Author ?? "System"}, {chatModel.Time.ToShortTimeString()}"; } else { authorLabel.Text = $"{chatModel.Author ?? "System"}, {chatModel.Time.ToShortDateString()}"; } switch (chatModel.Type) { case "text": var textmodel = chatModel as TextChatModel; bodyTextBox.Text = textmodel.Body.Trim(); break; case "image": var imagemodel = chatModel as ImageChatModel; bodyTextBox.Visible = false; bodyPanel.BackgroundImage = imagemodel.Image; bodyPanel.BackColor = Color.GhostWhite; bodyPanel.BackgroundImageLayout = ImageLayout.Stretch; break; case "attachment": var attachmentmodel = chatModel as AttachmentChatModel; bodyPanel.BackColor = Color.OrangeRed; bodyTextBox.BackColor = Color.OrangeRed; bodyTextBox.Text = "Click to download: " + attachmentmodel.Filename; bodyTextBox.Click += DownloadAttachment; break; default: break; } }
//Cross-tested this with the Twilio API and the RingCentral API, and async messaging is the way to go. async void SendMessage(object sender, EventArgs e) { string tonumber = phoneLabel.Text; string chatmessage = chatTextbox.Text; IChatModel chatModel = null; TextChatModel textModel = null; //Each IChatModel is specifically built for a single purpose. For that reason, if you want to display a text item AND and image, you'd make two IChatModels for //their respective purposes. AttachmentChatModel and ImageChatModel, however, can really be used interchangeably. if (chatbox_info.Attachment != null && chatbox_info.AttachmentType.Contains("image")) { chatModel = new ImageChatModel() { Author = chatbox_info.User, Image = Image.FromStream(new MemoryStream(chatbox_info.Attachment)), ImageName = chatbox_info.AttachmentName, Inbound = false, Read = true, Time = DateTime.Now, }; } else if (chatbox_info.Attachment != null) { chatModel = new AttachmentChatModel() { Author = chatbox_info.User, Attachment = chatbox_info.Attachment, Filename = chatbox_info.AttachmentName, Read = true, Inbound = false, Time = DateTime.Now }; } if (!string.IsNullOrWhiteSpace(chatmessage) && chatmessage != chatbox_info.ChatPlaceholder) { textModel = new TextChatModel() { Author = chatbox_info.User, Body = chatmessage, Inbound = false, Read = true, Time = DateTime.Now }; } try { /* * * INSERT SENDING LOGIC HERE. Again, this is just a UserControl, not a complete app. For the Ringcentral API, I was able to reduce this section * down to a single method. * */ if (chatModel != null) { AddMessage(chatModel); CancelAttachment(null, null); } if (textModel != null) { AddMessage(textModel); chatTextbox.Text = string.Empty; } } catch (Exception exc) { //If any exception is found, then it is printed on the screen. Feel free to change this method if you don't want people to see exceptions. textModel = new TextChatModel() { Author = chatbox_info.User, Body = "The message could not be processed. Please see the reason below.\r\n" + exc.Message, Inbound = false, Read = true, Time = DateTime.Now }; AddMessage(textModel); } }