import { Injectable } from '@angular/core'; import { RoomService } from './room.service'; import { WsChatService } from 'src/app/services/chat/ws-chat.service'; import { MessageService } from 'src/app/services/chat/message.service' import { SessionStore } from 'src/app/store/session.service'; import { capitalizeTxt } from 'src/plugin/text' import { Rooms, Update as room } from 'src/app/models/chatMethod'; import { Storage } from '@ionic/storage'; import { Platform } from '@ionic/angular'; import { SqliteService } from 'src/app/services/sqlite.service'; import { ChatService } from 'src/app/services/chat.service'; import { NativeNotificationService } from 'src/app/services/native-notification.service'; import { SortService } from '../functions/sort.service'; import { chatUser } from 'src/app/models/chatMethod'; import { NfService } from 'src/app/services/chat/nf.service' @Injectable({ providedIn: 'root' }) export class WsChatMethodsService { dm: {[key: string]: RoomService} = {} group: {[key: string]: RoomService} = {} _dm = [] _group = [] loadingWholeList = false dmCount = 0; groupCount = 0; currentRoom: RoomService = null users: chatUser[] = [] constructor( private WsChatService: WsChatService, private storage: Storage, private platform: Platform, private sqlservice: SqliteService, private NativeNotificationService: NativeNotificationService, private sortService: SortService, private ChatService: ChatService, private NfService: NfService, ) { (async()=>{ await this.restoreRooms() await this.getAllRooms(); this.subscribeToRoom() // await this.getUser() this.getUserStatus() })() this.WsChatService.registerCallback({ type: 'reConnect', funx: ()=>{ /** * @description when the phone is in the background for a long time it could disconnects from the socket then the socket reconnects automatically, * when the connection is lost the subscribe is also lost, so we have to subscribe again when reconnection is establish. */ this.subscribeToRoom() this.currentRoom.loadHistory({forceUpdate: true}) for (const id in this.dm) { this.dm[id].hasLoadHistory = false } for (const id in this.group) { this.group[id].hasLoadHistory = false } } }) // this.WsChatService.registerCallback({ // type:'Onmessage', // funx:(message) => { // if(message.msg =='changed' && message.collection == "stream-room-messages") { // if(message.fields.args[0].rid) { // // new message // const ChatMessage = message.fields.args[0] // const messageId = ChatMessage.rid // setTimeout(()=>{ // this.sortRoomList() // }, 100) // } // } else if(message.msg =='changed' && message.collection == "stream-notify-room") { // if(message.fields.eventName.includes('deleteMessage')) { // // delete message // const DeletedMessageId = message.fields.args[0]._id; // setTimeout(()=>{ // this.sortRoomList() // }, 100) // } else if(message.fields.eventName.includes('typing')) { // } // } // } // }) } getRoomFromDb() { this.storage.get('Rooms').then((rooms) => { rooms.result.update.forEach((roomData: room) => { this.prepareRoom(roomData); }); }) } openRoom(roomId) { if(this.currentRoom) { this.currentRoom.roomLeave() } if(this.getDmRoom(roomId)) { this.currentRoom = this.getDmRoom(roomId) } else if(this.getGroupRoom(roomId)) { this.currentRoom = this.getGroupRoom(roomId) } this.currentRoom.open() } async restoreRooms() { try { const rooms = await this.storage.get('Rooms'); if(rooms) { await rooms.result.update.forEach( async (roomData: room) => { await this.prepareRoom(roomData); }); } } catch(e){} this.sortRoomList() } async getAllRooms () { this.loadingWholeList = true //this.getRoomFromDb(); const rooms = await this.WsChatService.getRooms(); await this.storage.remove('Rooms'); await this.storage.set('Rooms', rooms); console.log('rooms', rooms) this.dm = {} this.group = {} this._dm = [] this._group = [] await rooms.result.update.forEach( async (roomData: room) => { await this.prepareRoom(roomData); }); this.sortRoomList() this.loadingWholeList = false } /** * @description sort room list by last message date */ sortRoomList =() => { this._dm = this.sortService.sortDate(this._dm,'_updatedAt').reverse() this._group = this.sortService.sortDate(this._group,'_updatedAt').reverse() } /** * @description subscribe all room */ subscribeToRoom() { for (const id in this.dm) { this.defaultSubtribe(id) } for (const id in this.group) { this.defaultSubtribe(id) } this.WsChatService.streamNotifyLogged().then((subscription=>{ console.log('streamRoomMessages', subscription) })) } /** * @description when a new room is create, needs to subtribe in order to receive updates * @param id * @param roomData */ subscribeToRoomUpdate(id, roomData) { this.defaultSubtribe(id) this.prepareRoom(roomData); this.getGroupRoom(id).loadHistory({}); } /** * @deprecated things a room need to subscribe on * @param id room id */ private defaultSubtribe(id: any) { this.WsChatService.streamRoomMessages(id).then((subscription)=>{ //console.log('streamRoomMessages', subscription) }) this.WsChatService.subStreamNotifyRoom(id, 'typing', false) this.WsChatService.streamNotifyRoomDeleteMessage(id).then((subscription)=>{ //console.log('streamNotifyRoomDeleteMessage', subscription); }) } /** * @description create a representation of an room in these instance this.dm, this.group ... * @param roomData */ prepareRoom(roomData) { let room:RoomService; room = new RoomService(this.WsChatService, new MessageService(this.storage, this.NfService, this.WsChatService), this.storage, this.platform, this.sqlservice, this.NativeNotificationService, this.sortService, this.ChatService, this.NfService) room.setData({ customFields: roomData.customFields, id: this.getRoomId(roomData), name: this.getRoomName(roomData), t: roomData.t, lastMessage: this.getRoomLastMessage(roomData), _updatedAt: new Date(roomData._updatedAt['$date']) }) room.receiveMessage() room.getAllUsers = this.getUsers room.receiveMessageDelete(); room.sortRoomList = this.sortRoomList let roomId = this.getRoomId(roomData) if(this.isIndividual(roomData)) { this.dm[roomId] = room this._dm.push(room) this.dmCount++ } else { this.group[roomId] = room this._group.push(room) this.groupCount++ } } getReceptorName(roomData) { try { return roomData.usernames.find((e)=> e != SessionStore.user.RochetChatUser) } catch(e) { return '*' } } /** * @description update user status. this method is called once only * @param id user ID */ private getUserStatus(id?:string) { // this.WsChatService.getUserStatus((d) => { // const username = d.fields.args[0][1] // const statusNum = d.fields.args[0][2] // const statusText = this.statusNumberToText(statusNum) // const user = this.getUserByName(username) // if(user) { // user.status = statusText // } // }) } getUserByName(username) { return this.users.find((user)=> user.username == username) } /** * @description convert rocketchat statues num to readable string * @param text * @returns */ statusNumberToText(text) { if(text == '0') { return "offline" } else if(text == '1') { return "online" } else if(text == '2') { return "away" } else if(text == '3') { return "busy" } } deleteMessage(id?) { return this.WsChatService.deleteMessage(id); } leaveRoom(id?) { return this.WsChatService.leaveRoom(id); } hidingRoom(id?) { return this.WsChatService.hidingRoom(id); } addRoomOwner(roomid, userId){ return this.WsChatService.addRoomOwner(roomid, userId); } createPrivateRoom(groupName, username, customFields){ return this.WsChatService.createPrivateRoom(groupName, username, customFields); } getDmRoom(id): RoomService { try { return this.dm[id] } catch(e) {} } getGroupRoom(id): RoomService { try { return this.group[id] } catch(e) {} } getRoomName(roomData: room) { if(this.isIndividual(roomData)) { const names: String[] = roomData.usernames const roomName = names.filter((name)=>{ return name != SessionStore.user.RochetChatUser })[0] const firstName = capitalizeTxt(roomName.split('.')[0]) const lastName = capitalizeTxt(roomName.split('.')[1]) return firstName + ' ' + lastName } else { return roomData.fname } } getRoomId(roomData:room) { return roomData._id } getRoomLastMessage(roomData: room):any { return roomData.lastMessage } private isIndividual(roomData: room) { return !roomData.fname } getUsers = () =>{ return this.users } async getUser() { let _res = await this.ChatService.getAllUsers().toPromise() let user = _res['users'].filter(data => data.username != SessionStore.user.RochetChatUser); user = user.sort((a,b) => { if(a.name < b.name) { return -1; } if(a.name > b.name) { return 1; } return 0; }); this.users = user } getUserOfRoom(roomId){ return this.WsChatService.getUserOfRoom(roomId); } }