64
64
@menuActionHandler =" menuActionHandler"
65
65
@messageActionHandler =" messageActionHandler"
66
66
@sendMessageReaction =" sendMessageReaction"
67
+ @typingMessage =" typingMessage"
67
68
/>
68
69
</div >
69
70
</template >
70
71
71
72
<script >
72
73
import {
74
+ firebase ,
73
75
roomsRef ,
74
76
usersRef ,
75
77
filesRef ,
76
- deleteDbField ,
77
- firebase
78
+ deleteDbField
78
79
} from ' @/firestore'
79
80
import { parseTimestamp , isSameDay } from ' @/utils/dates'
80
81
import ChatWindow from ' ./../../src/ChatWindow'
@@ -118,6 +119,7 @@ export default {
118
119
119
120
mounted () {
120
121
this .fetchRooms ()
122
+ this .updateUserOnlineStatus ()
121
123
},
122
124
123
125
destroyed () {
@@ -147,14 +149,21 @@ export default {
147
149
async fetchRooms () {
148
150
this .resetRooms ()
149
151
150
- const rooms = await roomsRef
151
- .where (' users' , ' array-contains' , this .currentUserId )
152
- .get ()
152
+ const query = roomsRef .where (
153
+ ' users' ,
154
+ ' array-contains' ,
155
+ this .currentUserId
156
+ )
153
157
158
+ const rooms = await query .get ()
159
+
160
+ const roomList = []
154
161
const rawRoomUsers = []
155
162
const rawMessages = []
156
163
157
164
rooms .forEach (room => {
165
+ roomList[room .id ] = { ... room .data (), users: [] }
166
+
158
167
const rawUsers = []
159
168
160
169
room .data ().users .map (userId => {
@@ -178,14 +187,11 @@ export default {
178
187
rawMessages .push (this .getLastMessage (room))
179
188
})
180
189
181
- let roomList = []
182
-
183
190
const users = await Promise .all (rawRoomUsers)
184
191
185
- users .map (user => {
186
- if (roomList[user .roomId ]) roomList[user .roomId ].users .push (user)
187
- else roomList[user .roomId ] = { users: [user] }
188
- })
192
+ users .map (user => roomList[user .roomId ].users .push (user))
193
+
194
+ this .listenUsersOnlineStatus (users)
189
195
190
196
const roomMessages = await Promise .all (rawMessages).then (messages => {
191
197
return messages .map (message => {
@@ -227,6 +233,8 @@ export default {
227
233
this .rooms = this .rooms .concat (formattedRooms)
228
234
this .loadingRooms = false
229
235
this .rooms .map ((room , index ) => this .listenLastMessage (room, index))
236
+
237
+ this .listenRoomsTypingUsers (query)
230
238
},
231
239
232
240
getLastMessage (room ) {
@@ -261,7 +269,7 @@ export default {
261
269
const timestampFormat = isSameDay (date, new Date ()) ? ' HH:mm' : ' DD/MM/YY'
262
270
263
271
let timestamp = parseTimestamp (message .timestamp , timestampFormat)
264
- if (timestampFormat === ' HH:mm' ) timestamp = ' Today, ' + timestamp
272
+ if (timestampFormat === ' HH:mm' ) timestamp = ` Today, ${ timestamp} `
265
273
266
274
let content = message .content
267
275
if (message .file ) content = ` ${ message .file .name } .${ message .file .type } `
@@ -465,6 +473,87 @@ export default {
465
473
})
466
474
},
467
475
476
+ typingMessage ({ message, roomId }) {
477
+ const dbAction = message
478
+ ? firebase .firestore .FieldValue .arrayUnion (this .currentUserId )
479
+ : firebase .firestore .FieldValue .arrayRemove (this .currentUserId )
480
+
481
+ roomsRef .doc (roomId).update ({
482
+ typingUsers: dbAction
483
+ })
484
+ },
485
+
486
+ async listenRoomsTypingUsers (query ) {
487
+ query .onSnapshot (rooms => {
488
+ rooms .forEach (room => {
489
+ const foundRoom = this .rooms .find (r => r .roomId === room .id )
490
+ if (foundRoom) foundRoom .typingUsers = room .data ().typingUsers
491
+ })
492
+ })
493
+ },
494
+
495
+ updateUserOnlineStatus () {
496
+ const userStatusRef = firebase
497
+ .database ()
498
+ .ref (' /status/' + this .currentUserId )
499
+
500
+ const isOfflineData = {
501
+ state: ' offline' ,
502
+ last_changed: firebase .database .ServerValue .TIMESTAMP
503
+ }
504
+
505
+ const isOnlineData = {
506
+ state: ' online' ,
507
+ last_changed: firebase .database .ServerValue .TIMESTAMP
508
+ }
509
+
510
+ firebase
511
+ .database ()
512
+ .ref (' .info/connected' )
513
+ .on (' value' , snapshot => {
514
+ if (snapshot .val () == false ) return
515
+
516
+ userStatusRef
517
+ .onDisconnect ()
518
+ .set (isOfflineData)
519
+ .then (() => {
520
+ userStatusRef .set (isOnlineData)
521
+ })
522
+ })
523
+ },
524
+
525
+ listenUsersOnlineStatus (users ) {
526
+ users .map (user => {
527
+ firebase
528
+ .database ()
529
+ .ref (' /status/' + user ._id )
530
+ .on (' value' , snapshot => {
531
+ if (! snapshot .val ()) return
532
+
533
+ const foundUser = users .find (u => snapshot .key === u ._id )
534
+
535
+ if (foundUser) {
536
+ const timestampFormat = isSameDay (
537
+ new Date (snapshot .val ().last_changed ),
538
+ new Date ()
539
+ )
540
+ ? ' HH:mm'
541
+ : ' DD MMMM, HH:mm'
542
+
543
+ const timestamp = parseTimestamp (
544
+ new Date (snapshot .val ().last_changed ),
545
+ timestampFormat
546
+ )
547
+
548
+ const last_changed =
549
+ timestampFormat === ' HH:mm' ? ` today, ${ timestamp} ` : timestamp
550
+
551
+ foundUser .status = { ... snapshot .val (), last_changed }
552
+ }
553
+ })
554
+ })
555
+ },
556
+
468
557
addRoom () {
469
558
this .resetForms ()
470
559
this .addNewRoom = true
0 commit comments