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 { 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' import { ChangeProfileService } from '../change-profile.service'; import { ChatStorageService } from './chat-storage.service'; import { ChatMethodsService } from './chat-methods.service'; import { AESEncrypt } from '../aesencrypt.service' import { AttachmentsService } from 'src/app/services/attachments.service'; import { NetworkServiceService} from 'src/app/services/network-service.service'; @Injectable({ providedIn: 'root' }) export class WsChatMethodsService { dm: {[key: string]: RoomService} = {} group: {[key: string]: RoomService} = {} _dm: RoomService[] = [] _group: RoomService[] = [] loadingWholeList = false; dmCount = 0; groupCount = 0; currentRoom: RoomService = null users: chatUser[] = [] sessionStore = SessionStore delete = [] 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, private changeProfileService: ChangeProfileService, private chatService: ChatService, private ChatStorageService: ChatStorageService, private ChatMethodsService:ChatMethodsService, private AESEncrypt: AESEncrypt, private AttachmentsService:AttachmentsService, private NetworkServiceService: NetworkServiceService, ) { this.loadChat() 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() if(this.currentRoom) { 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 } } }) } private loadChat() { this.ReLoadChat() } async ReLoadChat() { await this.restoreRooms(); await this.getAllRooms(); this.subscribeToRoom(); // await this.getUser(); this.getUserStatus(); } clearChat() { this.dm = {} this.group = {} this._dm = [] this._group = [] this.loadingWholeList = false; this.dmCount = 0; this.groupCount = 0; this.currentRoom = null this.users = [] } 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() } getRoomById(roomId) { if(this.getDmRoom(roomId)) { return this.getDmRoom(roomId) } else if(this.getGroupRoom(roomId)) { return this.getGroupRoom(roomId) } } async restoreRooms() { try { const rooms = await this.storage.get('Rooms'); if(rooms) { for (let roomData of rooms.result.update) { await this.prepareRoom(roomData); } } } catch(e){} setTimeout(() => { this.sortRoomList() }, 10000) } async getAllRooms () { this.loadingWholeList = true const rooms = await this.WsChatService.getRooms(); try { await this.storage.remove('Rooms'); } catch(e) {} let index = 0 if(rooms?.result?.update) { for (let roomData of rooms.result.update) { const roomId = this.getRoomId(roomData); if(roomData.t == 'd') { const res = await this.chatService.getMembers(roomId).toPromise(); const members = res['members']; const users = members.filter(data => data.username != this.sessionStore.user.UserName); rooms.result.update[index]['members'] = users await this.prepareRoom(roomData); } else { if (roomData.t === 'p') { const res = await this.chatService.getGroupMembers(roomId).toPromise() const members = res['members']; const users = members.filter(data => data.username != this.sessionStore.user.UserName); rooms.result.update[index]['members'] = users await this.prepareRoom(roomData); } else { const res = await this.chatService.getChannelMembers(roomId).toPromise() const members = res['members']; const users = members.filter(data => data.username != this.sessionStore.user.UserName); rooms.result.update[index]['members'] = users await this.prepareRoom(roomData); } } index++; } } await this.storage.set('Rooms', rooms); console.log("Done") setTimeout(() => { this.sortRoomList() }, 1000) setTimeout(() => { this.sortRoomList() }, 10000) 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() { console.log('subcribe/////////////////////////////////') for (const id in this.dm) { this.defaultSubtribe(id) } for (const id in this.group) { this.defaultSubtribe(id) } this.WsChatService.streamNotifyLogged().then((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) => { const room = this.getRoomById(id); room.status.receive.message = true; }) this.WsChatService.subStreamNotifyRoom(id, 'typing', false).then((subscription) => { const room = this.getRoomById(id); room.status.receive.typing = true; // }) this.WsChatService.subStreamNotifyRoom(id, 'readMessage', false).then((subscription) => { const room = this.getRoomById(id); room.status.receive.readMessage = true; // console.log(subscription, "subStreamNotifyRoom"); // }) this.WsChatService.streamNotifyRoomDeleteMessage(id).then((subscription) => { const room = this.getRoomById(id); room.status.receive.deleteMessage = true; // console.log(subscription); // }) } private fix_updatedAt(message) { if (message.result) { message.result._updatedAt = message.result._updatedAt['$date'] } else if(message._updatedAt) { if(message._updatedAt.hasOwnProperty('$date')) { message._updatedAt = message._updatedAt['$date'] } } return message } /** * @description create a representation of an room in these instance this.dm, this.group ... * @param roomData */ prepareRoom(roomData) { /** * @description data used to define or create room */ roomData = this.fix_updatedAt(roomData) const setData = { customFields: roomData.customFields, id: this.getRoomId(roomData), name: this.getRoomName(roomData), t: roomData.t, lastMessage: this.getRoomLastMessage(roomData), _updatedAt: new Date( roomData._updatedAt || roomData._updatedAt['$date']), u : roomData.u || {}, members: roomData.members } let roomId = this.getRoomId(roomData); if (setData.name != 'Rocket Cat') { // create room if(!this.roomExist(roomId)) { let room:RoomService = new RoomService(this.WsChatService, new MessageService(this.storage, this.NfService, this.WsChatService, this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt, this.AttachmentsService, this.NetworkServiceService), this.storage, this.platform, this.sqlservice, this.NativeNotificationService, this.sortService, this.ChatService, this.NfService , this.ChatStorageService, this.ChatMethodsService, this.AESEncrypt, this.AttachmentsService, this.NetworkServiceService, this) room.setData(setData) room.receiveMessage() room.getAllUsers = this.getUsers room.receiveMessageDelete(); room.sortRoomList = this.sortRoomList // create individual room if(this.isIndividual(roomData)) { this.dm[roomId] = room this._dm.push(room) // console.log(this._dm) this.dmCount++ } else { // create group room this.group[roomId] = room this._group.push(room) this.groupCount++ } } else { // in this case room is already present, therefor it will only be necessary, // to redefine if(this.dm[roomId]) { this.dm[roomId].setData(setData) } else if(this.group[roomId]) { this.group[roomId].setData(setData) } } } } deleteRoom(roomId) { this.delete.push(roomId) delete this.group[roomId]; this._group = this._group.filter((e)=> e.id != roomId); } deleteRecently(roomId) { return this.delete.includes(roomId) } roomExist(roomId) { return this.dm[roomId]?.id || this.group[roomId]?.id } getReceptorName(roomData) { try { return roomData.usernames.find((e)=> e != SessionStore.user.UserName) } 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) this.users.forEach((user, index) => { if(user.username == username) { this.users[index].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); } async hideRoom(id) { this._dm.forEach((md, index)=>{ if(md.id == id) { this._dm.splice(index, 1) delete this.dm[id] } }); this._group.forEach((group, index)=>{ if(group.id == id) { this._group.splice(index, 1) delete this.group[id] } }) } hidingRoom(id?) { return this.WsChatService.hidingRoom(id).then(()=>{ // this.hideRoom(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): string { if(this.isIndividual(roomData)) { const names: String[] = roomData.usernames const roomName = names.filter((name, index)=>{ return name != SessionStore.user.UserName })[0] if(roomName) { const firstName = capitalizeTxt(roomName.split('.')[0]) const lastName = capitalizeTxt(roomName.split('.')[1]) return firstName + ' ' + lastName } else { return 'Sem nome' } } 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 users = _res['users'].filter(data => data.username != SessionStore.user.UserName); users = users.sort((a,b) => { if(a.name < b.name) { return -1; } if(a.name > b.name) { return 1; } return 0; }); users.forEach((user, index) => { // user[index].status = this.statusNumberToText(user[index].status) }) this.users = users } getUserOfRoom(roomId){ return this.WsChatService.getUserOfRoom(roomId); } }