-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMessagesViewModel.vb
202 lines (201 loc) · 8.81 KB
/
MessagesViewModel.vb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
Imports System.Threading.Tasks
Imports DevExpress.DevAV.Chat
Imports DevExpress.DevAV.Chat.Commands
Imports DevExpress.DevAV.Chat.Events
Imports DevExpress.DevAV.Chat.Model
Imports DevExpress.Mvvm
Imports DevExpress.Mvvm.DataAnnotations
Imports DevExpress.Mvvm.POCO
Namespace DXHtmlMessengerSample.ViewModels
Public Class MessagesViewModel
Inherits ChannelViewModel
Public Sub New()
MyBase.New()
Messages = New Message() {}
Messenger.Default.Register(Of Contact)(Me, AddressOf OnContact)
End Sub
Public Overrides Sub OnDestroy()
MyBase.OnDestroy()
Messenger.Default.Unregister(Of Contact)(Me, AddressOf OnContact)
End Sub
Protected Overrides Sub OnConnected(ByVal channel As IChannel)
MyBase.OnConnected(channel)
channel.Subscribe(AddressOf OnMessageEvents)
channel.Subscribe(AddressOf OnContactEvents)
End Sub
Protected Overrides Async Sub OnChannelReady()
Await LoadMessages(Channel, Contact)
Await DispatcherService?.BeginInvoke(AddressOf UpdateUIOnChannelReady)
End Sub
Async Sub OnContactEvents(ByVal events As Dictionary(Of Long, ContactEvent))
If Contact IsNot Nothing Then
Dim [event] As ContactEvent = Nothing
If events.TryGetValue(Contact.ID, [event]) Then
If TypeOf [event] Is UnreadChanged OrElse TypeOf [event] Is NewMessages Then
Await LoadMessages(Channel, Contact)
End If
End If
If events.Count > 0 Then
Await DispatcherService?.BeginInvoke(AddressOf RaiseMessagesChanged)
End If
If TypeOf [event] Is NewMessages Then
Await DispatcherService?.BeginInvoke(AddressOf RaiseContactChanged)
End If
End If
End Sub
Dim updatedMessagesIdicesCore As HashSet(Of Integer) = New HashSet(Of Integer)
Async Sub OnMessageEvents(ByVal events As Dictionary(Of Long, MessageEvent))
updatedMessagesIdicesCore.Clear()
Dim [event] As MessageEvent = Nothing
Dim index As Integer = 0
For Each message As Message In Messages
If events.TryGetValue(message.ID, [event]) And updatedMessagesIdicesCore.Add(index) Then
[event].Apply(message)
End If
index = index + 1
Next message
If events.Count > 0 Then
Await DispatcherService?.BeginInvoke(AddressOf RaiseMessagesUpdated)
End If
End Sub
Sub UpdateUIOnChannelReady()
Me.RaisePropertyChanged(Function(x) x.Messages)
UpdateActions()
End Sub
Sub RaiseMessagesChanged()
Me.RaisePropertyChanged(Function(x) x.Messages)
End Sub
Sub RaiseMessagesUpdated()
Me.RaisePropertyChanged(Function(x) x.UpdatedMessageIndices)
updatedMessagesIdicesCore.Clear()
End Sub
Async Sub OnContact(ByVal contact As Contact)
Await LoadMessages(Channel, contact)
Await DispatcherService?.BeginInvoke(Sub() Me.Contact = contact)
End Sub
Async Function LoadMessages(ByVal channel As IChannel, ByVal contact As Contact) As Task
If channel IsNot Nothing AndAlso contact IsNot Nothing Then
Dim history = Await channel.GetHistory(contact)
Await DispatcherService?.BeginInvoke(Sub() Messages = history)
End If
End Function
Public Overridable Property Contact() As Contact
Sub RaiseContactChanged()
Me.RaisePropertyChanged(Function(x) x.Contact)
End Sub
Protected Sub OnContactChanged()
UpdateActions()
End Sub
Public Function CanExecuteActions() As Boolean
Return (Channel IsNot Nothing) AndAlso (Contact IsNot Nothing)
End Function
Protected Sub UpdateActions()
Me.RaiseCanExecuteChanged(Sub(x) x.SendMessage())
Me.RaiseCanExecuteChanged(Sub(x) x.PhoneCall())
Me.RaiseCanExecuteChanged(Sub(x) x.VideoCall())
Me.RaiseCanExecuteChanged(Sub(x) x.ShowContact())
Me.RaiseCanExecuteChanged(Sub(x) x.ShowUser())
End Sub
Public Overridable Property Messages() As IReadOnlyCollection(Of Message)
Public ReadOnly Property UpdatedMessageIndices() As IReadOnlyCollection(Of Integer)
Get
Return updatedMessagesIdicesCore.ToArray()
End Get
End Property
Private lastMessage As Message
Protected Sub OnMessagesChanged()
lastMessage = Messages.LastOrDefault()
End Sub
Public Overridable Property MessageText() As String
Protected Sub OnMessageTextChanged()
Me.RaiseCanExecuteChanged(Sub(x) x.SendMessage())
End Sub
Public Function CanSendMessage() As Boolean
Return CanExecuteActions() AndAlso Not String.IsNullOrEmpty(MessageText)
End Function
Public Sub SendMessage()
If Channel IsNot Nothing Then
Channel.Send(New AddMessage(Contact, MessageText))
End If
MessageText = Nothing
End Sub
Public Sub Update()
Me.RaiseCanExecuteChanged(Sub(x) x.SendMessage())
End Sub
<Command(CanExecuteMethodName:=NameOf(CanExecuteActions))>
Public Async Sub PhoneCall()
Dim contactInfo = Await Channel.GetUserInfo(Contact.ID)
DoCall("Phone Call: " & contactInfo.MobilePhone)
End Sub
<Command(CanExecuteMethodName:=NameOf(CanExecuteActions))>
Public Async Sub VideoCall()
Dim contactInfo = Await Channel.GetUserInfo(Contact.ID)
DoCall("Video Call: " & contactInfo.MobilePhone)
End Sub
Sub DoCall(ByVal [call] As String)
Dim msgService = Me.GetRequiredService(Of IMessageBoxService)()
msgService.ShowMessage([call])
End Sub
<Command(CanExecuteMethodName:=NameOf(CanExecuteActions))>
Public Async Sub ShowContact()
Dim contactInfo = Await Channel.GetUserInfo(Contact.ID)
MessengerViewModel.ShowContactInfo(Me, contactInfo)
End Sub
<Command(CanExecuteMethodName:=NameOf(CanExecuteActions))>
Public Async Sub ShowUser()
Dim userInfo = Await Channel.GetUserInfo(Channel.UserName)
MessengerViewModel.ShowUserInfo(Me, userInfo)
End Sub
Public Overridable Property SelectedMessage() As Message
Protected Sub OnSelectedMessageChanged()
Me.RaiseCanExecuteChanged(Sub(x) x.DeleteMessage())
Me.RaiseCanExecuteChanged(Sub(x) x.CopyMessage())
Me.RaiseCanExecuteChanged(Sub(x) x.CopyMessageText())
Me.RaiseCanExecuteChanged(Sub(x) x.LikeMessage())
End Sub
Public Function CanDeleteMessage() As Boolean
Return (SelectedMessage IsNot Nothing) AndAlso Not SelectedMessage.IsDeleted
End Function
Public Sub DeleteMessage()
If Channel IsNot Nothing Then
Channel.Send(New DeleteMessage(SelectedMessage.ID))
End If
End Sub
Public Function CanCopyMessage() As Boolean
Return (SelectedMessage IsNot Nothing) AndAlso Not SelectedMessage.IsDeleted
End Function
Public Sub CopyMessage()
Try
Dim message As String = "[" & SelectedMessage.StatusText & "] " & SelectedMessage.Owner.UserName & System.Environment.NewLine & SelectedMessage.Text
System.Windows.Forms.Clipboard.SetText(message)
Catch
End Try
End Sub
Public Function CanCopyMessageText() As Boolean
Return (SelectedMessage IsNot Nothing) AndAlso Not SelectedMessage.IsDeleted
End Function
Public Sub CopyMessageText()
Try
System.Windows.Forms.Clipboard.SetText(SelectedMessage.Text)
Catch
End Try
End Sub
Public Function CanLikeMessage() As Boolean
Return (SelectedMessage IsNot Nothing) AndAlso Not SelectedMessage.IsLiked
End Function
Public Sub LikeMessage()
If Channel IsNot Nothing Then
Channel.Send(New LikeMessage(SelectedMessage.ID))
End If
End Sub
<Command(False)>
Public Sub OnMessageRead(ByVal message As Message)
If lastMessage IsNot Nothing AndAlso message Is lastMessage Then
lastMessage = Nothing
If Channel IsNot Nothing Then
Channel.Send(New ReadMessages(Contact))
End If
End If
End Sub
End Class
End Namespace