import { Injectable } from '@angular/core'; import { Message } from 'src/app/models/chatMethod'; import { Storage } from '@ionic/storage'; import { SessionStore } from 'src/app/store/session.service'; import { capitalizeTxt } from 'src/plugin/text' import { NfService } from 'src/app/services/chat/nf.service' import { WsChatService } from 'src/app/services/chat/ws-chat.service'; import { showDateDuration } from 'src/plugin/showDateDuration'; import { ChatStorageService } from './chat-storage.service' import { ChatMethodsService } from './chat-methods.service' import { MessageModel } from '../../models/beast-orm' import { AESEncrypt } from '../aesencrypt.service' import { HttpEventType } from '@angular/common/http'; import { AttachmentsService } from 'src/app/services/attachments.service'; import { NetworkServiceService , ConnectionStatus} from 'src/app/services/network-service.service'; @Injectable({ providedIn: 'root' }) export class MessageService { customFields channels = [] mentions = [] msg = '' rid = '' ts = {} u = { name: '', username: '', _id: "" } t = '' _id = '' id = '' // table id _updatedAt file attachments offline = true displayType = '' temporaryData: any = {} hasFile = false hasSendAttachment = false sendAttempt = 0 uploadingFile = false errorUploadingAttachment = false loadHistory = false duration = '' localReference = null viewed = [] received = [] addToDb = false messageSend = false delate = false delateRequest = false downloadLoader: boolean = false downloadAttachments = false; downloadAttachmentsTemp = 0; constructor(private storage: Storage, private NfService: NfService, private WsChatService: WsChatService, private ChatStorageService: ChatStorageService, private ChatMethodsService: ChatMethodsService, private AESEncrypt: AESEncrypt, private AttachmentsService: AttachmentsService, private NetworkServiceService: NetworkServiceService) { } setData({customFields = {}, channels, mentions, msg ,rid ,ts, u, t, _id, id, _updatedAt, file, attachments, temporaryData, localReference , viewed = [], received = [], delate = false, delateRequest =false, }:Message) { this.channels = channels || [] this.mentions = mentions || [] this.msg = msg || "" this.rid = rid this.ts = ts this.u = u || { name: this.usernameToDisplayName(SessionStore.user.UserName), username: SessionStore.user.UserName, _id: ""} this.t = t this._id = _id || "" this._updatedAt = _updatedAt || new Date().getTime() this.file = file this.temporaryData = temporaryData this.localReference = localReference || null this.id = id this.delate = delate this.delateRequest = delateRequest if(this.attachments?.length >= 1 && attachments?.length >= 1) { this.attachments[0] = Object.assign(this.attachments[0], attachments[0]) } else { this.attachments = attachments } this.viewed = [...new Set([...viewed,...this.viewed])]; this.received = [...new Set([...received,...this.received])]; if(!this.ts) { this.offline = true this.messageSend = false } else { this.messageSend = true this.offline = false } if (this.file) { if(this.file.type) { if(typeof(this.file.type) == 'string') { this.hasFile = true } } } if(this.hasFile) { if(this.file.type != 'application/webtrix') { this.displayType = this.file.type.replace('application/','').toUpperCase() } } this.calDateDuration() } private usernameToDisplayName(username) { const firstName = capitalizeTxt(username.split('.')[0]) const lastName = capitalizeTxt(username.split('.')[1]) return firstName + ' ' + lastName } async send(): Promise { this.sendAttempt++; if(!this.hasFile) { const params = { roomId:this.rid, msg:this.msg, localReference: this.localReference } await this.sendRequest(params) } else { this.uploadingFile = true let uploadSuccessfully = false if(this.hasSendAttachment == false) { uploadSuccessfully = await this.NfService.beforeSendAttachment(this) } this.uploadingFile = false if(uploadSuccessfully) { this.hasSendAttachment = true this.errorUploadingAttachment = false this.temporaryData = {} const params = {roomId:this.rid, msg: this.msg, attachments: this.attachments, file: this.file, localReference: this.localReference} await this.sendRequest(params) } else if(this.WsChatService.isLogin == false) { this.WsChatService.registerCallback({ type: 'reConnect', funx: async ()=> { this.send() return true } }) } else if(uploadSuccessfully == false) { this.errorUploadingAttachment = true return new Promise((resolve, reject) => { reject(false) }) } } } async sendRequest(params) { if(params?.attachments) { if(params?.attachments[0]?.image_url) { delete params?.attachments[0]?.image_url } } if(this.NetworkServiceService.getCurrentNetworkStatus() == ConnectionStatus.Online) { this.WsChatService.send(params).then( (ChatMessage: any) => { ChatMessage = ChatMessage.message.result this.messageSend = true this.redefinedMessage(ChatMessage) } ) } else { this.WsChatService.registerCallback({ type: 'reConnect', funx: async ()=> { this.send() return true } }) } } async redefinedMessage(ChatMessage , update = true) { ChatMessage = this.NfService.fix_updatedAt(ChatMessage) const message = this.getChatObj() ChatMessage = Object.assign(message, ChatMessage) this.setData(ChatMessage) await this.save() } downloadFileMsg() { this.downloadLoader = true; let downloadFile = ""; this.AttachmentsService.downloadFile(this.file.guid).subscribe(async (event) => { if (event.type === HttpEventType.DownloadProgress) { } else if (event.type === HttpEventType.Response) { if (this.file.type == "application/img") { downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), '')); } else if (this.file.type != "application/img") { downloadFile = new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''); } this.attachments[0] = { image_url: downloadFile, name: this.attachments[0].name, title: this.attachments[0].title, title_link: downloadFile, title_link_download: this.attachments[0].title_link_download, ts: this.attachments[0].ts } // save the changes to the storage this.save() this.downloadLoader = false; this.downloadAttachments = true this.downloadAttachmentsTemp++; } }, ()=>{ // error this.downloadLoader = false; this.downloadAttachments = false this.downloadAttachmentsTemp++; }); } private calDateDuration(date = null) { this.duration = showDateDuration(date || this._updatedAt); } async delateStatusFalse() { this.delate = true this.save() } async delateDB() { const message = await MessageModel.get({_id: this._id}) await message.delete() } isSenderIsNotMe(ChatMessage) { return SessionStore.user.UserName != ChatMessage.u.username } messageOwnerById(id) { return SessionStore.user.UserName != this.u.username } private getChatObj() { return { channels: this.channels, mentions: this.mentions, //msg: this.AESEncrypt.encrypt(this.msg, SessionStore.user.UserName), msg:this.msg, rid: this.rid, ts: this.ts, u: this.u, _id: this._id, id: this.id, _updatedAt: this._updatedAt, messageSend: this.messageSend, offline: this.offline, viewed: this.viewed, received: this.received, localReference: this.localReference, attachments: this.attachments, file: this.file, delate: this.delate } } async addMessageDB() { if(!this.addToDb) { this.addToDb = true const message = this.getChatObj() delete message.id const createdMessage = await MessageModel.create(message) this.id = createdMessage.id } } async save() { const message = this.getChatObj() await MessageModel.update(message) } decryptMessage() { try { // this.msg = this.AESEncrypt.decrypt(this.msg, SessionStore.user.UserName) } catch (error) {} } }