Korero – Blame information for rev 2

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Diagnostics;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text.RegularExpressions;
8 using System.Threading;
9 using System.Threading.Tasks;
10 using System.Windows.Forms;
11 using Korero.Communication;
12 using Korero.Database;
13 using Korero.Economy;
14 using Korero.Profile;
15 using Korero.Properties;
16 using Korero.Serialization;
17 using Korero.Utilities;
18 using Serilog;
19  
20 namespace Korero.Chat
21 {
22 public partial class ChatForm : Form
23 {
24 #region Private Delegates, Events, Enums, Properties, Indexers and Fields
25  
26 private readonly CancellationToken _cancellationToken;
27  
28 private readonly CancellationTokenSource _cancellationTokenSource;
29  
30 private readonly Task _loadMessagesTask;
31  
32 private readonly MainForm _mainForm;
33  
34 private readonly MqttCommunication _mqttCommunication;
35  
36 private AutoResponseForm _autoResponseForm;
37  
38 private AvatarProfileForm _avatarProfileForm;
39  
40 private GroupProfileForm _groupProfileForm;
41  
42 private NewConversationForm _newConversationForm;
43  
44 private PaymentForm _paymentForm;
45  
46 #endregion
47  
48 #region Constructors, Destructors and Finalizers
49  
50 public ChatForm()
51 {
52 InitializeComponent();
53  
54 _cancellationTokenSource = new CancellationTokenSource();
55 _cancellationToken = _cancellationTokenSource.Token;
56  
57 chatListBox.SetDoubleBuffered();
58 }
59  
60 public ChatForm(MainForm mainForm, MqttCommunication mqttCommunication) : this()
61 {
62 _mainForm = mainForm;
63 _mqttCommunication = mqttCommunication;
64  
65 _loadMessagesTask = LoadUnseenMessages(_mainForm.MessageDatabase);
66  
67 _mqttCommunication.NotificationReceived += MqttCommunication_NotificationReceived;
68 }
69  
70 /// <summary>
71 /// Clean up any resources being used.
72 /// </summary>
73 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
74 protected override void Dispose(bool disposing)
75 {
76 if (disposing && components != null)
77 {
78 components.Dispose();
79 }
80  
81 _mqttCommunication.NotificationReceived -= MqttCommunication_NotificationReceived;
82  
83 base.Dispose(disposing);
84 }
85  
86 #endregion
87  
88 #region Event Handlers
2 office 89 private void ChatForm_Load(object sender, EventArgs e)
90 {
91 Utilities.WindowState.FormTracker.Track(this);
92 }
1 office 93  
94 private async void MqttCommunication_NotificationReceived(object sender, MqttNotificationEventArgs e)
95 {
96 switch (e.Notification["notification"])
97 {
98 case "group":
99 var databaseMessageGroup = new DatabaseMessageGroup(e.Notification["firstname"],
100 e.Notification["lastname"], e.Notification["message"], e.Notification["group"], DateTime.Now);
101  
102 var messageConversationGroup = new ConversationGroup(databaseMessageGroup);
103  
104 chatListBox.InvokeIfRequired(listBox =>
105 {
106 var item = listBox.Items.OfType<Conversation>()
107 .FirstOrDefault(conversation => conversation.Name == messageConversationGroup.Name);
108 switch (item == null)
109 {
110 case true:
111 listBox.Items.Add(messageConversationGroup);
112 messageConversationGroup.Seen = false;
113 listBox.Refresh();
114 break;
115 default:
116 // If the conversation is not selected then highlight it.
117 if (listBox.SelectedItem != null)
118 {
119 if (((Conversation) listBox.SelectedItem).Name != item.Name)
120 {
121 item.Seen = false;
122 listBox.Refresh();
123 }
124 }
125  
126 break;
127 }
128  
129 var index = listBox.SelectedIndex;
130 if (index == -1)
131 {
132 return;
133 }
134  
135 if (((Conversation) listBox.Items[index]).Name != messageConversationGroup.Name)
136 {
137 return;
138 }
139  
140 chatTextBox.InvokeIfRequired(textBox =>
141 {
142 textBox.AppendText(
143 $"{databaseMessageGroup.FirstName} {databaseMessageGroup.LastName}: {databaseMessageGroup.Message}" +
144 Environment.NewLine);
145 });
146 });
147 break;
148 case "message":
149 var databaseMessage = new DatabaseMessage(e.Notification["firstname"], e.Notification["lastname"],
150 e.Notification["message"], DateTime.Now);
151 var messageConversation = new ConversationAvatar(databaseMessage);
152  
153 chatListBox.InvokeIfRequired(listBox =>
154 {
155 var item = listBox.Items.OfType<Conversation>()
156 .FirstOrDefault(conversation => conversation.Name == messageConversation.Name);
157  
158 switch (item == null)
159 {
160 case true:
161 listBox.Items.Add(messageConversation);
162 messageConversation.Seen = false;
163 listBox.Refresh();
164 break;
165 default:
166 // If the conversation is not selected then highlight it.
167 if (listBox.SelectedItem != null)
168 {
169 if (((Conversation) listBox.SelectedItem).Name != item.Name)
170 {
171 item.Seen = false;
172 listBox.Refresh();
173 }
174 }
175  
176 break;
177 }
178  
179 var index = listBox.SelectedIndex;
180 if (index == -1)
181 {
182 return;
183 }
184  
185 if (((Conversation) listBox.Items[index]).Name != messageConversation.Name)
186 {
187 return;
188 }
189  
190 chatTextBox.InvokeIfRequired(textBox =>
191 {
192 textBox.AppendText(
193 $"{databaseMessage.FirstName} {databaseMessage.LastName}: {databaseMessage.Message}" +
194 Environment.NewLine);
195 });
196 });
197  
198 // Send away message if the current status is set to away.
199 if (Settings.Default.CurrentStatus == Resources.Away)
200 {
201 var data = new Dictionary<string, string>
202 {
203 {"command", "tell"},
204 {"group", Settings.Default.Group},
205 {"password", Settings.Default.Password},
206 {"entity", "avatar"},
207 {"firstname", messageConversation.FirstName},
208 {"lastname", messageConversation.LastName},
209 {"message", Settings.Default.AutoResponseText}
210 };
211  
212 var callback =
213 await _mqttCommunication.SendCommand(new Command(data), _cancellationToken);
214  
215 if (callback == null || !callback.Success)
216 {
217 if (callback != null)
218 {
219 Log.Warning("Command {Command} has failed with {Error}.",
220 callback.Command, callback.Error);
221 }
222  
223 break;
224 }
225  
226 var databaseSelfMessage = new DatabaseMessage(messageConversation.FirstName,
227 messageConversation.LastName, Settings.Default.AutoResponseText, DateTime.Now);
228  
229 await _mainForm.MessageDatabase.SaveSelfMessage(databaseSelfMessage);
230  
231 chatListBox.InvokeIfRequired(async listBox =>
232 {
233 var item = listBox.Items.OfType<Conversation>()
234 .FirstOrDefault(conversation => conversation.Name == messageConversation.Name);
235  
236 switch (item == null)
237 {
238 case true:
239 listBox.Items.Add(messageConversation);
240 messageConversation.Seen = false;
241 listBox.Refresh();
242 break;
243 default:
244 // If the conversation is not selected then highlight it.
245 if (listBox.SelectedItem != null)
246 {
247 switch (((Conversation) listBox.SelectedItem).Name != item.Name)
248 {
249 case true:
250 item.Seen = false;
251 listBox.Refresh();
252  
253 break;
254 default:
255 data = new Dictionary<string, string>
256 {
257 {"command", "getselfdata"},
258 {"group", Settings.Default.Group},
259 {"password", Settings.Default.Password},
260 {"data", new CSV(new[] {"FirstName", "LastName"})}
261 };
262  
263 callback = await _mqttCommunication.SendCommand(
264 new Command(data),
265 _cancellationToken);
266  
267 if (callback == null || !callback.Success)
268 {
269 if (callback != null)
270 {
271 Log.Warning("Command {Command} has failed with {Error}.",
272 "getselfdata", callback.Error);
273 }
274  
275 break;
276 }
277  
278 chatTextBox.InvokeIfRequired(textBox =>
279 {
280 textBox.AppendText(
281 $"{callback["FirstName"].FirstOrDefault()} {callback["LastName"].FirstOrDefault()}: {databaseSelfMessage.Message}" +
282 Environment.NewLine);
283 });
284 break;
285 }
286 }
287  
288 break;
289 }
290 });
291 }
292  
293 break;
294 }
295 }
296  
297 private async void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
298 {
299 var listBox = (ListBox) sender;
300  
301 var index = listBox.SelectedIndex;
302 if (index == -1)
303 {
304 return;
305 }
306  
307 var item = listBox.Items[index];
308 if (item == null)
309 {
310 return;
311 }
312  
313 // Mark the conversation as seen.
314 ((Conversation) item).Seen = true;
315 await _mainForm.MessageDatabase.MarkConversationSeen($"{((Conversation) item).Name}", true);
316 chatListBox.Refresh();
317  
318 chatTextBox.Clear();
319 switch (item)
320 {
321 case ConversationAvatar conversationAvatar:
322 var messages = await _mainForm.MessageDatabase.LoadMessages(conversationAvatar.FirstName,
323 conversationAvatar.LastName,
324 (int) Settings.Default.ChatMessageHistoryLength);
325 var selfMessages =
326 await _mainForm.MessageDatabase.LoadSelfMessages(conversationAvatar.FirstName,
327 conversationAvatar.LastName,
328 (int) Settings.Default.ChatMessageHistoryLength);
329  
330 var data = new Dictionary<string, string>
331 {
332 {"command", "getselfdata"},
333 {"group", Settings.Default.Group},
334 {"password", Settings.Default.Password},
335 {"data", new CSV(new[] {"FirstName", "LastName"})}
336 };
337  
338 var callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken);
339  
340 if (callback == null || !callback.Success)
341 {
342 if (callback != null)
343 {
344 Log.Warning("Command {Command} has failed with {Error}.",
345 callback.Command, callback.Error);
346 }
347  
348 break;
349 }
350  
351 var selfDatabaseMessage = selfMessages.Select(selfMessage =>
352 new DatabaseMessage(callback["FirstName"].FirstOrDefault(),
353 callback["LastName"].FirstOrDefault(), selfMessage.Message,
354 selfMessage.Time)).ToList();
355  
356 var databaseMessages = messages.Concat(selfDatabaseMessage).ToList();
357 databaseMessages.Sort(new DatabaseMessageTimeComparer());
358  
359 foreach (var message in databaseMessages)
360 {
361 chatTextBox.AppendText($"{message.FirstName} {message.LastName}: {message.Message}" +
362 Environment.NewLine);
363 }
364  
365 break;
366 case ConversationGroup groupConversation:
367 chatTextBox.InvokeIfRequired(textBox => { textBox.Clear(); });
368  
369 var groupMessages = await _mainForm.MessageDatabase.LoadMessagesGroup(groupConversation.Name,
370 (int) Settings.Default.ChatMessageHistoryLength);
371 var groupDatabaseMessages = groupMessages.ToList();
372 groupDatabaseMessages.Sort(new DatabaseMessageTimeComparer());
373  
374 foreach (var message in groupDatabaseMessages)
375 {
376 chatTextBox.AppendText($"{message.FirstName} {message.LastName}: {message.Message}" +
377 Environment.NewLine);
378 }
379  
380 break;
381 }
382 }
383  
384 private async void Button1_Click(object sender, EventArgs e)
385 {
386 await SendMessage();
387 }
388  
389 private async void TextBox1_KeyPress(object sender, KeyPressEventArgs e)
390 {
391 if (e.KeyChar != (char) Keys.Enter)
392 {
393 return;
394 }
395  
396 await SendMessage();
397 }
398  
399 private void NewToolStripMenuItem_Click(object sender, EventArgs e)
400 {
401 if (_newConversationForm != null)
402 {
403 return;
404 }
405  
406 _newConversationForm = new NewConversationForm(_mainForm.MqttCommunication);
407 _newConversationForm.NewConversationSelected += AvatarFormAvatarSelected;
408 _newConversationForm.Closing += NewConversationForm_Closing;
409 _newConversationForm.Show();
410 }
411  
412 private async void AvatarFormAvatarSelected(object sender, NewConversationSelectedEventArgs e)
413 {
414 switch (e.Conversation)
415 {
416 case ConversationAvatar newConversationAvatar:
417 var messageConversation =
418 new ConversationAvatar(newConversationAvatar.FirstName, newConversationAvatar.LastName);
419 await _mainForm.MessageDatabase.MarkConversationSeen(
420 $"{newConversationAvatar.FirstName} {newConversationAvatar.LastName}", true);
421  
422 chatListBox.InvokeIfRequired(listBox =>
423 {
424 if (!listBox.Items.OfType<ConversationAvatar>().Contains(messageConversation))
425 {
426 listBox.Items.Add(messageConversation);
427 }
428  
429 listBox.SelectedItem = messageConversation;
430 });
431 break;
432 case ConversationGroup newConversationGroup:
433 var messageConversationGroup = new ConversationGroup(newConversationGroup.Name);
434 await _mainForm.MessageDatabase.MarkConversationSeen($"{newConversationGroup.Name}", true);
435  
436 chatListBox.InvokeIfRequired(listBox =>
437 {
438 if (!listBox.Items.OfType<ConversationGroup>().Contains(messageConversationGroup))
439 {
440 listBox.Items.Add(messageConversationGroup);
441 }
442  
443 listBox.SelectedItem = messageConversationGroup;
444 });
445 break;
446 }
447 }
448  
449 private void NewConversationForm_Closing(object sender, CancelEventArgs e)
450 {
451 if (_newConversationForm == null)
452 {
453 return;
454 }
455  
456 _newConversationForm.NewConversationSelected -= AvatarFormAvatarSelected;
457 _newConversationForm.Closing -= NewConversationForm_Closing;
458 _newConversationForm.Dispose();
459 _newConversationForm = null;
460 }
461  
462 private void SplitContainer1_Paint(object sender, PaintEventArgs e)
463 {
464 var control = (SplitContainer) sender;
465 // paint the three dots
466 var points = new Point[3];
467 var w = control.Width;
468 var h = control.Height;
469 var d = control.SplitterDistance;
470 var sW = control.SplitterWidth;
471  
472 //calculate the position of the points
473 if (control.Orientation == Orientation.Horizontal)
474 {
475 points[0] = new Point(w / 2, d + sW / 2);
476 points[1] = new Point(points[0].X - 10, points[0].Y);
477 points[2] = new Point(points[0].X + 10, points[0].Y);
478 }
479 else
480 {
481 points[0] = new Point(d + sW / 2, h / 2);
482 points[1] = new Point(points[0].X, points[0].Y - 10);
483 points[2] = new Point(points[0].X, points[0].Y + 10);
484 }
485  
486 foreach (var p in points)
487 {
488 p.Offset(-2, -2);
489 e.Graphics.FillEllipse(SystemBrushes.ControlDark,
490 new Rectangle(p, new Size(3, 3)));
491  
492 p.Offset(1, 1);
493 e.Graphics.FillEllipse(SystemBrushes.ControlLight,
494 new Rectangle(p, new Size(3, 3)));
495 }
496 }
497  
498 private void CloseToolStripMenuItem_Click(object sender, EventArgs e)
499 {
500 var index = chatListBox.SelectedIndex;
501 if (index == -1)
502 {
503 return;
504 }
505  
506 var selectedItem = chatListBox.SelectedItem;
507 chatListBox.ClearSelected();
508 chatListBox.Items.Remove(selectedItem);
509 chatTextBox.Clear();
510 }
511  
512 private async void OpenAllToolStripMenuItem_Click(object sender, EventArgs e)
513 {
514 await LoadAllMessages(_mainForm.MessageDatabase);
515 }
516  
517 private void CloseAllToolStripMenuItem1_Click(object sender, EventArgs e)
518 {
519 chatListBox.Items.Clear();
520 chatTextBox.Clear();
521 }
522  
523 private void ChatListBox_DrawItem(object sender, DrawItemEventArgs e)
524 {
525 var listBox = (ListBox) sender;
526  
527 if (e.Index == -1)
528 {
529 return;
530 }
531  
532 var item = (Conversation) listBox.Items[e.Index];
533  
534 if (item == null)
535 {
536 return;
537 }
538  
539 if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
540 {
541 e.Graphics.FillRectangle(new SolidBrush(SystemColors.Highlight), e.Bounds);
542 if (item.Seen)
543 {
544 e.Graphics.DrawString(item.Name, e.Font, new SolidBrush(SystemColors.HighlightText), e.Bounds);
545 return;
546 }
547  
548 e.Graphics.DrawString(item.Name, e.Font, new SolidBrush(Settings.Default.SeenMessageColor), e.Bounds);
549  
550 return;
551 }
552  
553 e.Graphics.FillRectangle(new SolidBrush(chatListBox.BackColor), e.Bounds);
554 if (item.Seen)
555 {
556 e.Graphics.DrawString(item.Name, e.Font, new SolidBrush(chatListBox.ForeColor), e.Bounds);
557 return;
558 }
559  
560 e.Graphics.DrawString(item.Name, e.Font, new SolidBrush(Settings.Default.SeenMessageColor), e.Bounds);
561 }
562  
563 private void SearchTextBox_TextChanged(object sender, EventArgs e)
564 {
565 if (string.IsNullOrEmpty(searchTextBox.Text))
566 {
567 chatTextBox.SelectAll();
568 chatTextBox.SelectionBackColor = searchTextBox.BackColor;
569 chatTextBox.SelectionStart = chatTextBox.Text.Length;
570 chatTextBox.ScrollToCaret();
571 return;
572 }
573  
574 Regex regex;
575 try
576 {
577 regex = new Regex(searchTextBox.Text);
578 }
579 catch
580 {
581 chatTextBox.SelectAll();
582 chatTextBox.SelectionBackColor = searchTextBox.BackColor;
583 chatTextBox.SelectionStart = chatTextBox.Text.Length;
584 chatTextBox.ScrollToCaret();
585 return;
586 }
587  
588 var matches = regex.Matches(chatTextBox.Text);
589 chatTextBox.SelectAll();
590 chatTextBox.SelectionBackColor = searchTextBox.BackColor;
591 foreach (Match match in matches)
592 {
593 chatTextBox.Select(match.Index, match.Length);
594 chatTextBox.SelectionBackColor = Settings.Default.ChatSearchHighlight;
595 }
596 }
597  
598 private void ChatTextBox_TextChanged(object sender, EventArgs e)
599 {
600 var richTextBox = (RichTextBox) sender;
601  
602 richTextBox.ScrollToCaret();
603 }
604  
605 private void ProfileToolStripMenuItem_Click(object sender, EventArgs e)
606 {
607 var index = chatListBox.SelectedIndex;
608 if (index == -1)
609 {
610 return;
611 }
612  
613 var selectedItem = chatListBox.SelectedItem;
614  
615 switch (selectedItem)
616 {
617 case ConversationAvatar conversationAvatar:
618 if (_avatarProfileForm != null)
619 {
620 return;
621 }
622  
623 _avatarProfileForm = new AvatarProfileForm(_mainForm, conversationAvatar.FirstName,
624 conversationAvatar.LastName, _mqttCommunication);
625 _avatarProfileForm.Closing += AvatarProfileForm_Closing;
626 _avatarProfileForm.Show();
627 break;
628 case ConversationGroup conversationGroup:
629 if (_groupProfileForm != null)
630 {
631 return;
632 }
633  
634 _groupProfileForm = new GroupProfileForm(_mainForm, conversationGroup.Name, _mqttCommunication);
635 _groupProfileForm.Closing += GroupProfileForm_Closing;
636 _groupProfileForm.Show();
637 break;
638 }
639 }
640  
641 private void GroupProfileForm_Closing(object sender, CancelEventArgs e)
642 {
643 if (_groupProfileForm == null)
644 {
645 return;
646 }
647  
648 _groupProfileForm.Closing -= GroupProfileForm_Closing;
649 _groupProfileForm.Dispose();
650 _groupProfileForm = null;
651 }
652  
653 private void AvatarProfileForm_Closing(object sender, CancelEventArgs e)
654 {
655 if (_avatarProfileForm == null)
656 {
657 return;
658 }
659  
660 _avatarProfileForm.Closing -= AvatarProfileForm_Closing;
661 _avatarProfileForm.Dispose();
662 _avatarProfileForm = null;
663 }
664  
665 private async void AddToFriendsToolStripMenuItem_Click(object sender, EventArgs e)
666 {
667 var index = chatListBox.SelectedIndex;
668 if (index == -1)
669 {
670 return;
671 }
672  
673 var selectedItem = chatListBox.SelectedItem;
674  
675 switch (selectedItem)
676 {
677 case ConversationAvatar conversationAvatar:
678 var data = new Dictionary<string, string>
679 {
680 {"command", "offerfriendship"},
681 {"group", Settings.Default.Group},
682 {"password", Settings.Default.Password},
683 {"firstname", conversationAvatar.FirstName},
684 {"lastname", conversationAvatar.LastName}
685 };
686  
687 var callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken);
688  
689 if (callback == null || !callback.Success)
690 {
691 if (callback != null)
692 {
693 Log.Warning("Command {Command} has failed with {Error}.",
694 callback.Command, callback.Error);
695 }
696 }
697  
698 break;
699 }
700 }
701  
702 private void ChatTextBox_LinkClicked(object sender, LinkClickedEventArgs e)
703 {
704 Process.Start(e.LinkText);
705 }
706  
707 private void SetAutoResponseToolStripMenuItem_Click(object sender, EventArgs e)
708 {
709 if (_autoResponseForm != null)
710 {
711 return;
712 }
713  
714 _autoResponseForm = new AutoResponseForm();
715 _autoResponseForm.AutoResponseSet += AutoResponseForm_AutoResponseSet;
716 _autoResponseForm.Closing += AutoResponseForm_Closing;
717 _autoResponseForm.Show();
718 }
719  
720 private void AutoResponseForm_AutoResponseSet(object sender, AutoResponseSetEventArgs e)
721 {
722 }
723  
724 private void AutoResponseForm_Closing(object sender, CancelEventArgs e)
725 {
726 if (_autoResponseForm == null)
727 {
728 return;
729 }
730  
731 _autoResponseForm.AutoResponseSet -= AutoResponseForm_AutoResponseSet;
732 _autoResponseForm.Closing -= AutoResponseForm_Closing;
733 _autoResponseForm.Dispose();
734 _autoResponseForm = null;
735 }
736  
737 private void ToolStripComboBox2_SelectedIndexChanged(object sender, EventArgs e)
738 {
739 var toolStripComboBox = (ToolStripComboBox) sender;
740  
741 var index = toolStripComboBox.SelectedIndex;
742 if (index == -1)
743 {
744 return;
745 }
746  
747 var selectedItem = (string) toolStripComboBox.SelectedItem;
748  
749 Settings.Default.CurrentStatus = selectedItem;
750 }
751  
752 private async void OfferTeleportToolStripMenuItem_Click(object sender, EventArgs e)
753 {
754 var index = chatListBox.SelectedIndex;
755 if (index == -1)
756 {
757 return;
758 }
759  
760 var selectedItem = (Conversation) chatListBox.SelectedItem;
761  
762 if (!(selectedItem is ConversationAvatar conversationAvatar))
763 {
764 return;
765 }
766  
767 var data = new Dictionary<string, string>
768 {
769 {"command", "lure"},
770 {"group", Settings.Default.Group},
771 {"password", Settings.Default.Password},
772 {"firstname", conversationAvatar.FirstName},
773 {"lastname", conversationAvatar.LastName}
774 };
775  
776 var callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken);
777  
778 if (callback == null || !callback.Success)
779 {
780 if (callback != null)
781 {
782 Log.Warning("Command {Command} has failed with {Error}.",
783 callback.Command, callback.Error);
784 }
785 }
786 }
787  
788 public void ChatForm_FormClosing(object sender, EventArgs e)
789 {
790 _cancellationTokenSource.Cancel();
791 }
792  
793 private void PayToolStripMenuItem_Click(object sender, EventArgs e)
794 {
795 var index = chatListBox.SelectedIndex;
796 if (index == -1)
797 {
798 return;
799 }
800  
801 switch (chatListBox.SelectedItem)
802 {
803 case ConversationAvatar conversationAvatar:
804 if (_paymentForm != null)
805 {
806 return;
807 }
808  
809 _paymentForm = new PaymentForm(conversationAvatar.FirstName, conversationAvatar.LastName, _mainForm,
810 _mqttCommunication);
811 _paymentForm.Closing += PaymentForm_Closing;
812 _paymentForm.Show();
813 break;
814 case ConversationGroup conversationGroup:
815 if (_paymentForm != null)
816 {
817 return;
818 }
819  
820 _paymentForm = new PaymentForm(conversationGroup.Name, _mainForm, _mqttCommunication);
821 _paymentForm.Closing += PaymentForm_Closing;
822 _paymentForm.Show();
823 break;
824 }
825 }
826  
827 private void PaymentForm_Closing(object sender, CancelEventArgs e)
828 {
829 if (_paymentForm == null)
830 {
831 return;
832 }
833  
834 _paymentForm.Closing -= PaymentForm_Closing;
835 _paymentForm.Dispose();
836 _paymentForm = null;
837 }
838  
839 #endregion
840  
841 #region Public Methods
842  
843 public void CreateOrSelect(string name)
844 {
845 var found = false;
846 chatListBox.InvokeIfRequired(listBox =>
847 {
848 foreach (var item in listBox.Items.OfType<Conversation>())
849 {
850 if (item.Name != name)
851 {
852 continue;
853 }
854  
855 listBox.SelectedItem = item;
856 found = true;
857 break;
858 }
859 });
860  
861  
862 if (found)
863 {
864 return;
865 }
866  
867 var conversation = new ConversationAvatar(name);
868 chatListBox.InvokeIfRequired(listBox =>
869 {
870 listBox.Items.Add(conversation);
871 listBox.SelectedItem = conversation;
872 });
873 }
874  
875 #endregion
876  
877 #region Private Methods
878  
879 private async Task SendMessage()
880 {
881 var index = chatListBox.SelectedIndex;
882 if (index == -1)
883 {
884 return;
885 }
886  
887 var text = typeTextBox.Text;
888 typeTextBox.InvokeIfRequired(textBox => { textBox.Clear(); });
889 Dictionary<string, string> data;
890 Callback callback;
891 switch (chatListBox.Items[index])
892 {
893 case ConversationGroup conversationGroup:
894 data = new Dictionary<string, string>
895 {
896 {"command", "tell"},
897 {"group", Settings.Default.Group},
898 {"password", Settings.Default.Password},
899 {"entity", "group"},
900 {"target", conversationGroup.Name},
901 {"message", text}
902 };
903  
904 callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken);
905  
906 if (callback == null || !callback.Success)
907 {
908 if (callback != null)
909 {
910 Log.Warning("Command {Command} has failed with {Error}.",
911 callback.Command, callback.Error);
912 }
913 }
914  
915 break;
916 case ConversationAvatar conversation:
917 data = new Dictionary<string, string>
918 {
919 {"command", "tell"},
920 {"group", Settings.Default.Group},
921 {"password", Settings.Default.Password},
922 {"entity", "avatar"},
923 {"firstname", conversation.FirstName},
924 {"lastname", conversation.LastName},
925 {"message", text}
926 };
927  
928 callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken);
929  
930 if (callback == null || !callback.Success)
931 {
932 if (callback != null)
933 {
934 Log.Warning("Command {Command} has failed with {Error}.",
935 callback.Command, callback.Error);
936 }
937  
938 break;
939 }
940  
941 data = new Dictionary<string, string>
942 {
943 {"command", "getselfdata"},
944 {"group", Settings.Default.Group},
945 {"password", Settings.Default.Password},
946 {"data", new CSV(new[] {"FirstName", "LastName"})}
947 };
948  
949 callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken);
950  
951 if (callback == null || !callback.Success)
952 {
953 if (callback != null)
954 {
955 Log.Warning("Command {Command} has failed with {Error}.",
956 callback.Command, callback.Error);
957 }
958  
959 break;
960 }
961  
962 await _mainForm.MessageDatabase.SaveSelfMessage(new DatabaseMessage(conversation.FirstName,
963 conversation.LastName, text, DateTime.Now));
964  
965 chatTextBox.InvokeIfRequired(textBox =>
966 {
967 textBox.AppendText(
968 $"{callback["FirstName"].FirstOrDefault()} {callback["LastName"].FirstOrDefault()}: {text}" +
969 Environment.NewLine);
970 });
971 break;
972 }
973 }
974  
975 private async Task LoadUnseenMessages(MessageDatabase messageDatabase)
976 {
977 foreach (var message in await messageDatabase.LoadConversations())
978 {
979 chatListBox.InvokeIfRequired(listBox =>
980 {
981 if (message.Seen)
982 {
983 return;
984 }
985  
986 if (listBox.Items.OfType<Conversation>().Any(conversation => conversation.Name == message.Name))
987 {
988 return;
989 }
990  
991 listBox.Items.Add(message);
992 });
993 }
994  
995 foreach (var message in await messageDatabase.LoadSelfConversations())
996 {
997 chatListBox.InvokeIfRequired(listBox =>
998 {
999 if (message.Seen)
1000 {
1001 return;
1002 }
1003  
1004 if (listBox.Items.OfType<Conversation>().Any(conversation => conversation.Name == message.Name))
1005 {
1006 return;
1007 }
1008  
1009 listBox.Items.Add(message);
1010 });
1011 }
1012  
1013 foreach (var message in await messageDatabase.LoadGroupConversations())
1014 {
1015 chatListBox.InvokeIfRequired(listBox =>
1016 {
1017 if (message.Seen)
1018 {
1019 return;
1020 }
1021  
1022 if (listBox.Items.OfType<Conversation>().Any(conversation => conversation.Name == message.Name))
1023 {
1024 return;
1025 }
1026  
1027 listBox.Items.Add(message);
1028 });
1029 }
1030 }
1031  
1032 private async Task LoadAllMessages(MessageDatabase messageDatabase)
1033 {
1034 foreach (var message in await messageDatabase.LoadConversations())
1035 {
1036 chatListBox.InvokeIfRequired(listBox =>
1037 {
1038 if (listBox.Items.OfType<Conversation>().Any(conversation => conversation.Name == message.Name))
1039 {
1040 return;
1041 }
1042  
1043 listBox.Items.Add(message);
1044 });
1045 }
1046  
1047 foreach (var message in await messageDatabase.LoadSelfConversations())
1048 {
1049 chatListBox.InvokeIfRequired(listBox =>
1050 {
1051 if (listBox.Items.OfType<Conversation>().Any(conversation => conversation.Name == message.Name))
1052 {
1053 return;
1054 }
1055  
1056 listBox.Items.Add(message);
1057 });
1058 }
1059  
1060 foreach (var message in await messageDatabase.LoadGroupConversations())
1061 {
1062 chatListBox.InvokeIfRequired(listBox =>
1063 {
1064 if (listBox.Items.OfType<Conversation>().Any(conversation => conversation.Name == message.Name))
1065 {
1066 return;
1067 }
1068  
1069 listBox.Items.Add(message);
1070 });
1071 }
1072 }
1073  
1074 #endregion
2 office 1075  
1076  
1 office 1077 }
1078 }