@@ -11,7 +11,6 @@ import {
11
11
INewMessage ,
12
12
IChatMessage ,
13
13
IConfig ,
14
- IMessage ,
15
14
IUser
16
15
} from './types' ;
17
16
@@ -35,9 +34,14 @@ export interface IChatModel extends IDisposable {
35
34
readonly user ?: IUser ;
36
35
37
36
/**
38
- * The signal emitted when a new message is received .
37
+ * The chat messages list .
39
38
*/
40
- get incomingMessage ( ) : ISignal < IChatModel , IMessage > ;
39
+ readonly messages : IChatMessage [ ] ;
40
+
41
+ /**
42
+ * The signal emitted when the messages list is updated.
43
+ */
44
+ readonly messagesUpdated : ISignal < IChatModel , void > ;
41
45
42
46
/**
43
47
* Send a message, to be defined depending on the chosen technology.
@@ -49,7 +53,7 @@ export interface IChatModel extends IDisposable {
49
53
addMessage ( message : INewMessage ) : Promise < boolean | void > | boolean | void ;
50
54
51
55
/**
52
- * Optional, to update a message from the chat.
56
+ * Optional, to update a message from the chat panel .
53
57
*
54
58
* @param id - the unique ID of the message.
55
59
* @param message - the updated message.
@@ -84,9 +88,25 @@ export interface IChatModel extends IDisposable {
84
88
/**
85
89
* Function to call when a message is received.
86
90
*
87
- * @param message - the new message, containing user information and body.
91
+ * @param message - the message with user information and body.
92
+ */
93
+ messageAdded ( message : IChatMessage ) : void ;
94
+
95
+ /**
96
+ * Function called when messages are inserted.
97
+ *
98
+ * @param index - the index of the first message of the list.
99
+ * @param messages - the messages list.
88
100
*/
89
- onMessage ( message : IMessage ) : void ;
101
+ messagesInserted ( index : number , messages : IChatMessage [ ] ) : void ;
102
+
103
+ /**
104
+ * Function called when messages are deleted.
105
+ *
106
+ * @param index - the index of the first message to delete.
107
+ * @param count - the number of messages to delete.
108
+ */
109
+ messagesDeleted ( index : number , count : number ) : void ;
90
110
}
91
111
92
112
/**
@@ -102,6 +122,13 @@ export class ChatModel implements IChatModel {
102
122
this . _config = options . config ?? { } ;
103
123
}
104
124
125
+ /**
126
+ * The chat messages list.
127
+ */
128
+ get messages ( ) : IChatMessage [ ] {
129
+ return this . _messages ;
130
+ }
131
+
105
132
/**
106
133
* The chat model ID.
107
134
*/
@@ -123,11 +150,10 @@ export class ChatModel implements IChatModel {
123
150
}
124
151
125
152
/**
126
- *
127
- * The signal emitted when a new message is received.
153
+ * The signal emitted when the messages list is updated.
128
154
*/
129
- get incomingMessage ( ) : ISignal < IChatModel , IMessage > {
130
- return this . _incomingMessage ;
155
+ get messagesUpdated ( ) : ISignal < IChatModel , void > {
156
+ return this . _messagesUpdated ;
131
157
}
132
158
133
159
/**
@@ -140,7 +166,7 @@ export class ChatModel implements IChatModel {
140
166
addMessage ( message : INewMessage ) : Promise < boolean | void > | boolean | void { }
141
167
142
168
/**
143
- * Optional, to update a message from the chat.
169
+ * Optional, to update a message from the chat panel .
144
170
*
145
171
* @param id - the unique ID of the message.
146
172
* @param message - the message to update.
@@ -180,18 +206,54 @@ export class ChatModel implements IChatModel {
180
206
*
181
207
* @param message - the message with user information and body.
182
208
*/
183
- onMessage ( message : IMessage ) : void {
184
- if ( message . type === 'msg' ) {
185
- message = this . formatChatMessage ( message as IChatMessage ) ;
209
+ messageAdded ( message : IChatMessage ) : void {
210
+ const messageIndex = this . _messages . findIndex ( msg => msg . id === message . id ) ;
211
+ if ( messageIndex > - 1 ) {
212
+ // The message is an update of an existing one.
213
+ // Let's remove it to avoid position conflict if timestamp has changed.
214
+ this . _messages . splice ( messageIndex , 1 ) ;
215
+ }
216
+ // Find the first message that should be after this one.
217
+ let nextMsgIndex = this . _messages . findIndex ( msg => msg . time > message . time ) ;
218
+ if ( nextMsgIndex === - 1 ) {
219
+ // There is no message after this one, so let's insert the message at the end.
220
+ nextMsgIndex = this . _messages . length ;
186
221
}
222
+ // Insert the message.
223
+ this . messagesInserted ( nextMsgIndex , [ message ] ) ;
224
+ }
187
225
188
- this . _incomingMessage . emit ( message ) ;
226
+ /**
227
+ * Function called when messages are inserted.
228
+ *
229
+ * @param index - the index of the first message of the list.
230
+ * @param messages - the messages list.
231
+ */
232
+ messagesInserted ( index : number , messages : IChatMessage [ ] ) : void {
233
+ const formattedMessages : IChatMessage [ ] = [ ] ;
234
+ messages . forEach ( message => {
235
+ formattedMessages . push ( this . formatChatMessage ( message ) ) ;
236
+ } ) ;
237
+ this . _messages . splice ( index , 0 , ...formattedMessages ) ;
238
+ this . _messagesUpdated . emit ( ) ;
239
+ }
240
+
241
+ /**
242
+ * Function called when messages are deleted.
243
+ *
244
+ * @param index - the index of the first message to delete.
245
+ * @param count - the number of messages to delete.
246
+ */
247
+ messagesDeleted ( index : number , count : number ) : void {
248
+ this . _messages . splice ( index , count ) ;
249
+ this . _messagesUpdated . emit ( ) ;
189
250
}
190
251
252
+ private _messages : IChatMessage [ ] = [ ] ;
191
253
private _id : string = '' ;
192
254
private _config : IConfig ;
193
255
private _isDisposed = false ;
194
- private _incomingMessage = new Signal < IChatModel , IMessage > ( this ) ;
256
+ private _messagesUpdated = new Signal < IChatModel , void > ( this ) ;
195
257
}
196
258
197
259
/**
0 commit comments